diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e68cb97d..cf7db5ccd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,9 +78,10 @@ else() endif() endif() -## Compiler flags +## Compiler flags, CPACK configuration and other Apple specific code. IF(APPLE) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") + include(${PROJECT_SOURCE_DIR}/mk/macosx/CMakeLists.txt) ENDIF(APPLE) IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW) @@ -196,14 +197,23 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW) # Release compiler flags SET(CMAKE_CXX_FLAGS_RELEASE "-O3 ${CMAKE_CXX_FLAGS_RELEASE} -O3 ") - SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") ## Strip binary + IF(CMAKE_GENERATOR STREQUAL Xcode) + SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") ## Strip binary + ELSE() + SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") ## Strip binary + ENDIF() # Release with debug info compiler flags SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 ") # Release minimum size compiler flags SET(CMAKE_CXX_FLAGS_MINSIZEREL "-O3 ${CMAKE_CXX_FLAGS_MINSIZEREL} -O3 ") - SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} -s") ## Strip binary + SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") ## Strip binary + IF(CMAKE_GENERATOR STREQUAL Xcode) + SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") ## Strip binary + ELSE() + SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") ## Strip binary + ENDIF() # Get the git revision info for the binary SET(HAS_GIT "FALSE") @@ -242,12 +252,11 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW) ENDIF() ENDIF() - IF(APPLE AND NOT CMAKE_COMPILER_IS_GNUCXX) - SET(GIT_VERSION_CMD "-DGITVERSION='\\\\'${GIT_LIVE_REV_CMD}\\\\''") - ELSE() - SET(GIT_VERSION_CMD "-DGITVERSION='\\\"${GIT_LIVE_REV_CMD}\\\"'") -# SET(SVN_VERSION_CMD "-DSVNVERSION='\\\"`svnversion -n ${PROJECT_SOURCE_DIR}`\\\"'") - ENDIF() + IF(CMAKE_GENERATOR STREQUAL Xcode) + SET(GIT_VERSION_CMD "-DGITVERSION='\\\\'${GIT_LIVE_REV_CMD}\\\\''") + ELSE() + SET(GIT_VERSION_CMD "-DGITVERSION='\\\"${GIT_LIVE_REV_CMD}\\\"'") + ENDIF() IF(CMAKE_INSTALL_PREFIX STREQUAL "") MESSAGE(STATUS "*NOTE: NOT USING a Custom Data Install Path...") @@ -269,14 +278,9 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW) ENDIF() IF(NOT CUSTOM_DATA_INSTALL_PATH) - IF(APPLE) - SET(CUSTOM_DATA_INSTALL_PATH "'\\\\'${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}\\\\''" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)") - ELSE() - SET(CUSTOM_DATA_INSTALL_PATH "\"${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}\"" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)") - ENDIF() + SET (CUSTOM_DATA_INSTALL_PATH "\"${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}\"" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)") ENDIF() SET(CUSTOM_DATA_INSTALL_PATH_VALUE "-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}") - ADD_DEFINITIONS("-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}") SET(PKG_DATADIR ${CUSTOM_DATA_INSTALL_PATH_VALUE}) SET(PKG_BINDIR ${MEGAGLEST_BIN_INSTALL_PATH}) @@ -361,10 +365,6 @@ IF(EXISTS "${PROJECT_SOURCE_DIR}/source/") #endif() ADD_SUBDIRECTORY( ${PROJECT_SOURCE_DIR}/source/tools/glexemel ) - IF(APPLE) - include(${PROJECT_SOURCE_DIR}/mk/macosx/CMakeLists.txt) - ENDIF() - ADD_SUBDIRECTORY( ${PROJECT_SOURCE_DIR}/source/tests ) ENDIF() @@ -381,38 +381,7 @@ IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") MESSAGE(WARNING ">> CLANG is NOT currently compatible as it does not support the following essential GCC compiler settings: -frounding-math -fsignaling-nans") ENDIF() -SET(CPACK_GENERATOR "DEB") -SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Mark Vejvoda") #required -SET(CPACK_DEBIAN_PACKAGE_DEPENDS " - libcurl4-gnutls-dev | libcurl4-nss-dev, - libfontconfig1-dev, - libftgl-dev, - libglew-dev, - libircclient-dev, - libjpeg-dev, - liblua5.1-0-dev, - libminiupnpc-dev, - libogg-dev, - libopenal-dev, - libpng12-dev, - libsdl1.2-dev, - libvlc-dev, - libvorbis-dev, - libwxgtk2.8-dev, - libxerces-c2-dev, - libxml2-dev, - libz-dev, - libfribidi-dev") - -#find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") -#if(DPKG_PROGRAM) -# execute_process( -# COMMAND ${DPKG_PROGRAM} --print-architecture -# OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE -# OUTPUT_STRIP_TRAILING_WHITESPACE -# ) -#endif(DPKG_PROGRAM) - +# CPack configuration shared accross platforms SET(CPACK_PACKAGE_NAME ${PKG_NAME}) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MegaGlest") SET(CPACK_PACKAGE_VENDOR "megaglest.org") @@ -422,12 +391,50 @@ SET(CPACK_PACKAGE_INSTALL_DIRECTORY "megaglest") SET(CPACK_PACKAGE_VERSION_MAJOR ${VER_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${VER_MINOR}) SET(CPACK_PACKAGE_VERSION_PATCH ${VER_RELEASE}) -IF(WIN32) - SET(CPACK_NSIS_DISPLAY_NAME "MegaGlest") - SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/mk/windoze/glest.ico") - SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/mk/windoze/megaglest.ico") - SET(CPACK_NSIS_URL_INFO_ABOUT "http://megaglest.org") -ENDIF() + + +# Debian specific generator options +IF(NOT DEFINED CPACK_GENERATOR) + SET(CPACK_GENERATOR "DEB") + SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Mark Vejvoda") #required + SET(CPACK_DEBIAN_PACKAGE_DEPENDS " + libcurl4-gnutls-dev | libcurl4-nss-dev, + libfontconfig1-dev, + libftgl-dev, + libglew-dev, + libircclient-dev, + libjpeg-dev, + liblua5.1-0-dev, + libminiupnpc-dev, + libogg-dev, + libopenal-dev, + libpng12-dev, + libsdl1.2-dev, + libvlc-dev, + libvorbis-dev, + libwxgtk2.8-dev, + libxerces-c2-dev, + libxml2-dev, + libz-dev, + libfribidi-dev") + + #find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") + #if(DPKG_PROGRAM) + # execute_process( + # COMMAND ${DPKG_PROGRAM} --print-architecture + # OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE + # OUTPUT_STRIP_TRAILING_WHITESPACE + # ) + #endif(DPKG_PROGRAM) +ENDIF(NOT DEFINED CPACK_GENERATOR) + +IF(CPACK_GENERATOR STREQUAL "NSIS") + SET(CPACK_NSIS_DISPLAY_NAME "MegaGlest") + SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/mk/windoze/glest.ico") + SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/mk/windoze/megaglest.ico") + SET(CPACK_NSIS_URL_INFO_ABOUT "http://megaglest.org") +ENDIF(CPACK_GENERATOR STREQUAL "NSIS") + INCLUDE(CPack) get_directory_property( DirDefs DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS ) diff --git a/data/glest_game b/data/glest_game index b1fc026f2..12bb08b14 160000 --- a/data/glest_game +++ b/data/glest_game @@ -1 +1 @@ -Subproject commit b1fc026f227d6947c0bf685d1c705561f2d3909f +Subproject commit 12bb08b14d36fb86a327bcf480872884ce9121ec diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index eb60da72f..51f01ddbc 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -3,6 +3,30 @@ MEGAGLEST CHANGELOG To see a timeline of detail changes please visit: https://github.com/MegaGlest/megaglest-source/commits/master +v3.11.0 +- healthbars with a lot of options +- multi shot / multi-projectiles with different timings,sounds and particle systems +- several camera shake effects +- new tileset "pine rock" +- some new maps +- improve switching settings when connected to a headless server +- support for team unit sharing +- team resource sharing +- tags feature +- Attack boosts fixed in many ways +- Attack boosts and upgrades now support upgrading attack speed +- timed particles and mesh bound particles really work now. +- unit height independend particle positioning ( flat-particle-positions ) +- CPU players multiplier are displayed in debug view +- You can have non commandable units +- Units spawned by an attack skill can get an attack command +- Unit and Splash particles can be speeded up ( accelerated ) +- Looting https://github.com/MegaGlest/megaglest-source/pull/17 +- HP and EP starting values +- can be given https://docs.megaglest.org/XML/Unit#target-height +- +several bugfixes + +v3.10.0 This version was skipped because of version number trouble. v3.9.1 - Backward compatible with 3.9.0 diff --git a/mk/fedora/megaglest-rpm-meta/SOURCES/megaglest.png b/mk/fedora/megaglest-rpm-meta/SOURCES/megaglest.png index ce23c576a..80d7b1ef1 100644 Binary files a/mk/fedora/megaglest-rpm-meta/SOURCES/megaglest.png and b/mk/fedora/megaglest-rpm-meta/SOURCES/megaglest.png differ diff --git a/mk/linux/coverity-scan.sh b/mk/linux/coverity-scan.sh index bd0f31fdf..2df3f862c 100755 --- a/mk/linux/coverity-scan.sh +++ b/mk/linux/coverity-scan.sh @@ -32,6 +32,9 @@ PROJECT=MegaGlest # E-Mail address of registered Coverity Scan user with project access # EMAIL=x +# Where to store the data gathered by the Coverity Scan Build Tool +BUILDTOOL=cov-int + # read in config settings if [ ! -f ${CURRENTDIR}/.coverity-scan ] ; then echo "-----------------------------------------" @@ -44,24 +47,17 @@ fi # echo "Read config values: TOKEN [$TOKEN] EMAIL [$EMAIL] COVERITY_ANALYSIS_ROOT [$COVERITY_ANALYSIS_ROOT] NUMCORES [${NUMCORES}]" # exit 1 +GITBRANCH=$(git rev-parse --abbrev-ref HEAD | tr '/' '_') +GITVERSION_SHA1=$(git log -1 --format=%h) +GITVERSION_REV=$(git rev-list HEAD --count) +VERSION=${GITBRANCH}.${GITVERSION_REV}.${GITVERSION_SHA1} + # Included from shared functions detect_system -computername=$(hostname) -#DESCRIPTION=${distribution}-${release}-${architecture}_${computername} -DESCRIPTION=${distribution}-${architecture}_${computername} - -# Where to store the data gathered by the Coverity Scan Build Tool -BUILDTOOL=cov-int - -# ------------------------------------------------------------------------------ - -GITVERSION_SHA1=$(git log -1 --format=%h) -GITVERSION_REV=$(git rev-list HEAD --count) - -VERSION=${GITVERSION_REV}.${GITVERSION_SHA1} -FILENAME=${PROJECT}_${DESCRIPTION}_${VERSION} - +#DESCRIPTION=${distribution}-${release}-${architecture}_${hostname} +DESCRIPTION=${GITBRANCH}.${GITVERSION_SHA1}.${distribution}-${architecture}.${hostname} +FILENAME=${PROJECT}.${DESCRIPTION} # echo "FILENAME = [${FILENAME}]" # exit 1 @@ -105,3 +101,6 @@ else rm -rf ${BUILDTOOL}/ fi +# This currently fails to detect the following error situation, as reported in the HTML of the HTTP response (to the upload request): +# ERROR: Too many build submitted. Wait for few days before submitting next build: Refer build frequency at https://scan.coverity.com/faq#frequency + diff --git a/mk/linux/make-data-archive.sh b/mk/linux/make-data-archive.sh index a25a4dcaf..28a98d631 100755 --- a/mk/linux/make-data-archive.sh +++ b/mk/linux/make-data-archive.sh @@ -66,6 +66,13 @@ mkdir -p "$RELEASEDIR/data/core/misc_textures/flags/" cd "$RELEASEDIR/data/core/misc_textures/flags/" git archive --remote ${REPODIR}/data/glest_game/data/core/misc_textures HEAD:flags | tar x +echo "Removing non required files ..." +cd "$CURRENTDIR" +# START +# remove cegui data +rm -rf "$RELEASEDIR/data/cegui" +# END + cd "$CURRENTDIR" echo "creating data archive: $PACKAGE" [[ -f "${RELEASEDIR_ROOT}/$PACKAGE" ]] && rm "${RELEASEDIR_ROOT}/$PACKAGE" diff --git a/mk/linux/makedata.sh b/mk/linux/makedata.sh index b5ebe25e7..7244c4bb1 100755 --- a/mk/linux/makedata.sh +++ b/mk/linux/makedata.sh @@ -79,6 +79,8 @@ cd "$CURRENTDIR" # START # remove embedded data rm -rf "$RELEASEDIR/data/core/fonts" +# remove cegui data +rm -rf "$RELEASEDIR/data/cegui" # END echo "creating $PACKAGE" diff --git a/mk/linux/megaglest.png b/mk/linux/megaglest.png index 65e5d9862..ed8e8baf6 100644 Binary files a/mk/linux/megaglest.png and b/mk/linux/megaglest.png differ diff --git a/mk/linux/mg-version.sh b/mk/linux/mg-version.sh index 617b285ce..1334a9a8c 100755 --- a/mk/linux/mg-version.sh +++ b/mk/linux/mg-version.sh @@ -6,7 +6,7 @@ OLD_MG_VERSION=3.9.1 OLD_MG_VERSION_BINARY=3.9.1 -MG_VERSION=3.10.0-dev +MG_VERSION=3.11.0 if [ "$1" = "--oldversion" ]; then echo "$OLD_MG_VERSION" diff --git a/mk/linux/mojosetup/megaglest-installer/meta/glestforumsheader.jpg b/mk/linux/mojosetup/megaglest-installer/meta/glestforumsheader.jpg index a22f9ff3e..c4fd7ebd3 100644 Binary files a/mk/linux/mojosetup/megaglest-installer/meta/glestforumsheader.jpg and b/mk/linux/mojosetup/megaglest-installer/meta/glestforumsheader.jpg differ diff --git a/mk/linux/mojosetup/megaglest-installer/meta/megaglestinstallscreen.jpg b/mk/linux/mojosetup/megaglest-installer/meta/megaglestinstallscreen.jpg index 1f16190be..f25cc287a 100644 Binary files a/mk/linux/mojosetup/megaglest-installer/meta/megaglestinstallscreen.jpg and b/mk/linux/mojosetup/megaglest-installer/meta/megaglestinstallscreen.jpg differ diff --git a/mk/linux/mojosetup/megaglest-installer/scripts/config.lua b/mk/linux/mojosetup/megaglest-installer/scripts/config.lua index 6a51536a4..d55084399 100644 --- a/mk/linux/mojosetup/megaglest-installer/scripts/config.lua +++ b/mk/linux/mojosetup/megaglest-installer/scripts/config.lua @@ -1,5 +1,5 @@ -local GAME_INSTALL_SIZE = 730000000; -local GAME_VERSION = "3.10.0-dev"; +local GAME_INSTALL_SIZE = 680000000; +local GAME_VERSION = "3.11.0"; local _ = MojoSetup.translate diff --git a/mk/linux/setupBuildDeps.sh b/mk/linux/setupBuildDeps.sh index 11536af3d..5517f5bb4 100755 --- a/mk/linux/setupBuildDeps.sh +++ b/mk/linux/setupBuildDeps.sh @@ -148,11 +148,17 @@ case $distribution in $installcommand if [ $? != 0 ]; then error_during_installation; exit 1; fi ;; - 11.10|12.04|12.10|13.04|13.10|14.04) + 11.10|12.04|12.10|13.04|13.10) installcommand='apt-get install '"$APT_OPTIONS"' build-essential cmake libsdl1.2-dev libalut-dev libgl1-mesa-dev libglu1-mesa-dev libvorbis-dev libwxbase2.8-dev libwxgtk2.8-dev libx11-dev liblua5.1-0-dev libjpeg-dev libpng12-dev libcurl4-gnutls-dev libxml2-dev libircclient-dev libglew-dev libftgl-dev libfribidi-dev libvlc-dev libcppunit-dev' $installcommand if [ $? != 0 ]; then error_during_installation; exit 1; fi ;; + 14.04|14.10) + installcommand='apt-get install '"$APT_OPTIONS"' build-essential cmake libsdl1.2-dev libalut-dev libgl1-mesa-dev libglu1-mesa-dev libvorbis-dev libwxbase3.0-dev libwxgtk3.0-dev libx11-dev liblua5.1-0-dev libjpeg-dev libpng12-dev libcurl4-gnutls-dev libxml2-dev libircclient-dev libglew-dev libftgl-dev libfribidi-dev libvlc-dev libcppunit-dev' + $installcommand + if [ $? != 0 ]; then error_during_installation; exit 1; fi + ;; + *) installcommand='apt-get install '"$APT_OPTIONS"' build-essential cmake libsdl1.2-dev libalut-dev libgl1-mesa-dev libglu1-mesa-dev libvorbis-dev libwxbase2.8-dev libwxgtk2.8-dev libx11-dev liblua5.1-0-dev libjpeg-dev libpng12-dev libcurl4-gnutls-dev libxml2-dev libircclient-dev libglew-dev libftgl-dev libfribidi-dev libvlc-dev libcppunit-dev' unsupported_release diff --git a/mk/linux/start_megaglest b/mk/linux/start_megaglest index 80cc5e947..bcb242528 100755 --- a/mk/linux/start_megaglest +++ b/mk/linux/start_megaglest @@ -206,6 +206,11 @@ TASN_LINKEDLIBNAME='libtasn1.so.3' TASN_LIBLOOKUP1=${TASN_LINKEDLIBNAME} TASN_LIBLOOKUP2='libtasn1.so.' +RTMP_LINKEDLIBNAME='librtmp.so.0' +RTMP_LIBLOOKUP1=${RTMP_LINKEDLIBNAME} +RTMP_LIBLOOKUP2='librtmp.so.' + + if [ "$OS_TYPE"'_' = 'x86_64_' ]; then DIRECTFB_LINKEDLIBNAME='libdirectfb-1.2.so.0' DIRECTFB_LIBLOOKUP1=${DIRECTFB_LINKEDLIBNAME} @@ -284,6 +289,7 @@ findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${VLCCORE_LINKEDLIBNAME}" "$VLCCORE_ findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${VLC_LINKEDLIBNAME}" "$VLC_LIBLOOKUP1" "$VLC_LIBLOOKUP2" findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${GCRYPT_LINKEDLIBNAME}" "$GCRYPT_LIBLOOKUP1" "$GCRYPT_LIBLOOKUP2" findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${TASN_LINKEDLIBNAME}" "$TASN_LIBLOOKUP1" "$TASN_LIBLOOKUP2" +findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${RTMP_LINKEDLIBNAME}" "$RTMP_LIBLOOKUP1" "$RTMP_LIBLOOKUP2" ./megaglest $@ diff --git a/mk/macosx/CMakeLists.txt b/mk/macosx/CMakeLists.txt index dfb4947f1..cecf5f9b1 100644 --- a/mk/macosx/CMakeLists.txt +++ b/mk/macosx/CMakeLists.txt @@ -25,38 +25,34 @@ IF(NOT CONFIG_HAS_BEEN_RUN_BEFORE) ENDIF() ENDIF(NOT CONFIG_HAS_BEEN_RUN_BEFORE) - +# Include extra paths to search for includes; this is the default system wide macports path. +INCLUDE_DIRECTORIES(/opt/local/include) +LINK_DIRECTORIES(/opt/local/lib) ##install part -#extracting the current version... -EXECUTE_PROCESS( - COMMAND /usr/bin/sed - -n -e "s/.*glestVersionString = \"v\\\(.*\\\)\";.*/\\1/p" - - game_util.cpp - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/source/glest_game/facilities" - OUTPUT_VARIABLE MEGAGLEST_VERSION ) - -#for some reason the MEGAGLEST_VERSION can containts return like thus remove it -STRING(REGEX REPLACE "\n" "" MEGAGLEST_VERSION "${MEGAGLEST_VERSION}") - -set(CPACK_PACKAGE_FILE_NAME MegaGlest-${MEGAGLEST_VERSION}) - -CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/mk/macosx/Info.plist" "${CMAKE_CURRENT_BINARY_DIR}/Info.plist") - +# This changes Info.plist from something with variables and CMakeisms to +# something that can be installed on disk. +CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/mk/macosx/Info.plist" + "${CMAKE_CURRENT_BINARY_DIR}/Info.plist") include (InstallRequiredSystemLibraries) +# Use bundle generator (OSX has 3 other options if you feel adventurous) +set (CPACK_GENERATOR "Bundle") + +# The following CPACK_* options are all required +set (CPACK_PACKAGE_FILE_NAME MegaGlest-${VER_MAJOR}.${VER_MINOR}.${VER_RELEASE}) +set (CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/mk/macosx/MegaGlest.icns") + set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/docs/COPYRIGHT.source_code.txt") -set (CPACK_GENERATOR Bundle) set (CPACK_BUNDLE_NAME "MegaGlest") set (CPACK_BUNDLE_STARTUP_COMMAND "${PROJECT_SOURCE_DIR}/data/glest_game/megaglest") set (CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/mk/macosx/MegaGlest.icns") -set (CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/mk/macosx/MegaGlest.icns") set (CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_BINARY_DIR}/Info.plist") -#set (CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/mk/macosx/Info.plist.template") + +# Install files in to the package (FIXME: how? we sure?) INSTALL(FILES ${LUA_LIBRARIES} DESTINATION ../Frameworks @@ -73,6 +69,4 @@ STRING(REGEX REPLACE ";.*" "" SDL_LIBRARY_DIR "${SDL_LIBRARY}") # ${PNG_LIBRARY} # DESTINATION ../Frameworks # ) - -include (CPack) - + diff --git a/mk/macosx/Info.plist b/mk/macosx/Info.plist index 2de7a43d6..253720350 100644 --- a/mk/macosx/Info.plist +++ b/mk/macosx/Info.plist @@ -5,13 +5,13 @@ CFBundleDevelopmentRegion English CFBundleExecutable - MegaGlest + megaglest CFBundleGetInfoString - ${MEGAGLEST_VERSION}, © 2001-2010 The Glest Team All Rights Reserved. + ${VER_MAJOR}.${VER_MINOR}.${VER_RELEASE}, © 2001-2015 The Glest Team All Rights Reserved. CFBundleIconFile MegaGlest CFBundleIdentifier - geovah.MegaGlest + org.megaglest.v${VER_MAJOR}-${VER_MINOR}-${VER_RELEASE} CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -19,11 +19,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - ${MEGAGLEST_VERSION} + ${VER_MAJOR}.${VER_MINOR}.${VER_RELEASE} CFBundleSignature - ???? + MGGL CFBundleVersion - ${MEGAGLEST_VERSION} + ${VER_MAJOR}.${VER_MINOR}.${VER_RELEASE} NSMainNibFile MainMenu NSPrincipalClass diff --git a/mk/shared/glestkeys.ini b/mk/shared/glestkeys.ini index 8d150748e..a3018425a 100644 --- a/mk/shared/glestkeys.ini +++ b/mk/shared/glestkeys.ini @@ -42,6 +42,7 @@ HotKeySelectedUnitsAttack=A HotKeySelectedUnitsStop=S HotKeyToggleOSMouseEnabled=/ ChatTeamMode=H +ToggleHealthbars=# ToggleMusic=K SaveGUILayout=f10 SetMarker=X diff --git a/mk/windoze/Glest_vc2012.sln b/mk/windoze/Glest_vc2012.sln index 8f9bd775f..b78dd1369 100644 --- a/mk/windoze/Glest_vc2012.sln +++ b/mk/windoze/Glest_vc2012.sln @@ -37,9 +37,9 @@ Global Release with error catching|Mixed Platforms = Release with error catching|Mixed Platforms Release with error catching|Win32 = Release with error catching|Win32 Release with error catching|x64 = Release with error catching|x64 - Release_NO_STREFLOP|Mixed Platforms = Release_NO_STREFLOP|Mixed Platforms - Release_NO_STREFLOP|Win32 = Release_NO_STREFLOP|Win32 - Release_NO_STREFLOP|x64 = Release_NO_STREFLOP|x64 + Release_WITHOUT_STREFLOP|Mixed Platforms = Release_WITHOUT_STREFLOP|Mixed Platforms + Release_WITHOUT_STREFLOP|Win32 = Release_WITHOUT_STREFLOP|Win32 + Release_WITHOUT_STREFLOP|x64 = Release_WITHOUT_STREFLOP|x64 Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 Release|x64 = Release|x64 @@ -81,12 +81,12 @@ Global {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release with error catching|Win32.Build.0 = Release|Win32 {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release with error catching|x64.ActiveCfg = Release|x64 {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release with error catching|x64.Build.0 = Release|x64 - {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release|Win32 - {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release|Win32 - {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_NO_STREFLOP|Win32.ActiveCfg = Release|Win32 - {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_NO_STREFLOP|Win32.Build.0 = Release|Win32 - {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_NO_STREFLOP|x64.ActiveCfg = Release|x64 - {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_NO_STREFLOP|x64.Build.0 = Release|x64 + {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release|Mixed Platforms.Build.0 = Release|Win32 {407355A4-D12A-4E3B-A7EB-A835E573B376}.Release|Win32.ActiveCfg = Release|Win32 @@ -135,12 +135,12 @@ Global {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release with error catching|Win32.Build.0 = Release|Win32 {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release with error catching|x64.ActiveCfg = Release|x64 {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release with error catching|x64.Build.0 = Release|x64 - {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release|Win32 - {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release|Win32 - {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_NO_STREFLOP|Win32.ActiveCfg = Release|Win32 - {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_NO_STREFLOP|Win32.Build.0 = Release|Win32 - {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_NO_STREFLOP|x64.ActiveCfg = Release|x64 - {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_NO_STREFLOP|x64.Build.0 = Release|x64 + {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release|Mixed Platforms.Build.0 = Release|Win32 {3BAC3FE8-1CC4-487D-802A-E0A04B39BB6A}.Release|Win32.ActiveCfg = Release|Win32 @@ -189,12 +189,12 @@ Global {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release with error catching|Win32.Build.0 = Release|Win32 {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release with error catching|x64.ActiveCfg = Release_NO_STREFLOP|x64 {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release with error catching|x64.Build.0 = Release_NO_STREFLOP|x64 - {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release_NO_STREFLOP|Win32 - {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release_NO_STREFLOP|Win32 - {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_NO_STREFLOP|Win32.ActiveCfg = Release_NO_STREFLOP|Win32 - {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_NO_STREFLOP|Win32.Build.0 = Release_NO_STREFLOP|Win32 - {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_NO_STREFLOP|x64.ActiveCfg = Release_NO_STREFLOP|x64 - {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_NO_STREFLOP|x64.Build.0 = Release_NO_STREFLOP|x64 + {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|x64 + {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release|Mixed Platforms.Build.0 = Release|Win32 {8DAA0C24-95CD-4F66-B4C5-19ABDD771746}.Release|Win32.ActiveCfg = Release|Win32 @@ -243,12 +243,12 @@ Global {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release with error catching|Win32.Build.0 = Release|Win32 {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release with error catching|x64.ActiveCfg = Release_NO_STREFLOP|x64 {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release with error catching|x64.Build.0 = Release_NO_STREFLOP|x64 - {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release_NO_STREFLOP|Win32 - {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release_NO_STREFLOP|Win32 - {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_NO_STREFLOP|Win32.ActiveCfg = Release_NO_STREFLOP|Win32 - {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_NO_STREFLOP|Win32.Build.0 = Release_NO_STREFLOP|Win32 - {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_NO_STREFLOP|x64.ActiveCfg = Release_NO_STREFLOP|x64 - {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_NO_STREFLOP|x64.Build.0 = Release_NO_STREFLOP|x64 + {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release|Mixed Platforms.Build.0 = Release|Win32 {6B0C65F1-D031-46AF-AC0D-7C38892D2952}.Release|Win32.ActiveCfg = Release|Win32 @@ -297,12 +297,12 @@ Global {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release with error catching|Win32.Build.0 = Release|Win32 {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release with error catching|x64.ActiveCfg = Release_NO_STREFLOP|x64 {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release with error catching|x64.Build.0 = Release_NO_STREFLOP|x64 - {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release_NO_STREFLOP|Win32 - {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release_NO_STREFLOP|Win32 - {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_NO_STREFLOP|Win32.ActiveCfg = Release_NO_STREFLOP|Win32 - {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_NO_STREFLOP|Win32.Build.0 = Release_NO_STREFLOP|Win32 - {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_NO_STREFLOP|x64.ActiveCfg = Release_NO_STREFLOP|x64 - {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_NO_STREFLOP|x64.Build.0 = Release_NO_STREFLOP|x64 + {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release|Mixed Platforms.Build.0 = Release|Win32 {5D09BE33-81EC-450B-8A7B-2E7B941ADC56}.Release|Win32.ActiveCfg = Release|Win32 @@ -351,12 +351,12 @@ Global {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release with error catching|Win32.Build.0 = Release|Win32 {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release with error catching|x64.ActiveCfg = Release_NO_STREFLOP|x64 {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release with error catching|x64.Build.0 = Release_NO_STREFLOP|x64 - {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release_NO_STREFLOP|Win32 - {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release_NO_STREFLOP|Win32 - {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_NO_STREFLOP|Win32.ActiveCfg = Release_NO_STREFLOP|Win32 - {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_NO_STREFLOP|Win32.Build.0 = Release_NO_STREFLOP|Win32 - {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_NO_STREFLOP|x64.ActiveCfg = Release_NO_STREFLOP|x64 - {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_NO_STREFLOP|x64.Build.0 = Release_NO_STREFLOP|x64 + {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release|Mixed Platforms.Build.0 = Release|Win32 {FE5C7C7C-F109-44F5-8329-25A4E24F162C}.Release|Win32.ActiveCfg = Release|Win32 @@ -405,12 +405,12 @@ Global {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release with error catching|Win32.Build.0 = Release|Win32 {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release with error catching|x64.ActiveCfg = Release|x64 {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release with error catching|x64.Build.0 = Release|x64 - {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release|Win32 - {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release|Win32 - {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_NO_STREFLOP|Win32.ActiveCfg = Release|Win32 - {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_NO_STREFLOP|Win32.Build.0 = Release|Win32 - {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_NO_STREFLOP|x64.ActiveCfg = Release|x64 - {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_NO_STREFLOP|x64.Build.0 = Release|x64 + {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release|Mixed Platforms.Build.0 = Release|Win32 {9A3DE527-6000-40BB-B971-F0FCAD9FF519}.Release|Win32.ActiveCfg = Release|Win32 @@ -459,12 +459,12 @@ Global {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release with error catching|Win32.Build.0 = Release_NO_STREFLOP|Win32 {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release with error catching|x64.ActiveCfg = Release_NO_STREFLOP|x64 {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release with error catching|x64.Build.0 = Release_NO_STREFLOP|x64 - {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_NO_STREFLOP|Mixed Platforms.ActiveCfg = Release_NO_STREFLOP|Win32 - {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_NO_STREFLOP|Mixed Platforms.Build.0 = Release_NO_STREFLOP|Win32 - {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_NO_STREFLOP|Win32.ActiveCfg = Release_NO_STREFLOP|Win32 - {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_NO_STREFLOP|Win32.Build.0 = Release_NO_STREFLOP|Win32 - {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_NO_STREFLOP|x64.ActiveCfg = Release_NO_STREFLOP|x64 - {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_NO_STREFLOP|x64.Build.0 = Release_NO_STREFLOP|x64 + {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_WITHOUT_STREFLOP|Mixed Platforms.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_WITHOUT_STREFLOP|Mixed Platforms.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_WITHOUT_STREFLOP|Win32.ActiveCfg = Release_WITHOUT_STREFLOP|Win32 + {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_WITHOUT_STREFLOP|Win32.Build.0 = Release_WITHOUT_STREFLOP|Win32 + {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_WITHOUT_STREFLOP|x64.ActiveCfg = Release_WITHOUT_STREFLOP|x64 + {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release_WITHOUT_STREFLOP|x64.Build.0 = Release_WITHOUT_STREFLOP|x64 {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release|Mixed Platforms.Build.0 = Release|Win32 {CDF4DDB9-945E-4D0D-9F0E-2BBEB5D22141}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/mk/windoze/Installer/MegaGlestInstaller.nsi b/mk/windoze/Installer/MegaGlestInstaller.nsi index 93db8f001..c971680aa 100644 --- a/mk/windoze/Installer/MegaGlestInstaller.nsi +++ b/mk/windoze/Installer/MegaGlestInstaller.nsi @@ -4,7 +4,7 @@ !define APNAME MegaGlest !define APNAME_OLD Mega-Glest !define APVER_OLD 3.9.1 -!define APVER 3.10.0-dev +!define APVER 3.11.0 Name "${APNAME} ${APVER}" SetCompressor /FINAL /SOLID lzma @@ -16,7 +16,7 @@ UninstallIcon "..\..\shared\megaglest.ico" !define MUI_UNICON "..\..\shared\megaglest.ico" InstallDir "$PROGRAMFILES\${APNAME}" ShowInstDetails show -BGGradient 0xDF9437 0xffffff +;BGGradient 0xDF9437 0xffffff ; Request application privileges for Windows Vista RequestExecutionLevel none @@ -31,6 +31,8 @@ PageEx license LicenseData "..\..\..\data\glest_game\docs\cc-by-sa-3.0-unported.txt" PageExEnd +;---- add local plugins dir +!addPluginDir "plugins" ;-------------------------------- ; Images not included! ; Use your own animated GIFs please @@ -67,7 +69,7 @@ Function myGUIInit File megaglestinstallscreen.jpg FindWindow $0 '_Nb' - EBanner::show /NOUNLOAD /FIT=BOTH /HWND=$0 "$PLUGINSDIR\megaglestinstallscreen.jpg" + #EBanner::show /NOUNLOAD /FIT=BOTH /HWND=$0 "$PLUGINSDIR\megaglestinstallscreen.jpg" #BgImage::SetBg /NOUNLOAD /FILLSCREEN "$PLUGINSDIR\megaglestinstallscreen.jpg" #BgImage::Redraw /NOUNLOAD @@ -81,7 +83,7 @@ Function un.myGUIInit File megaglestinstallscreen.jpg FindWindow $0 '_Nb' - EBanner::show /NOUNLOAD /FIT=BOTH /HWND=$0 "$PLUGINSDIR\megaglestinstallscreen.jpg" + #EBanner::show /NOUNLOAD /FIT=BOTH /HWND=$0 "$PLUGINSDIR\megaglestinstallscreen.jpg" FunctionEnd Function MUIGUIInit @@ -173,7 +175,7 @@ FunctionEnd Function .onGUIEnd - EBanner::stop + #EBanner::stop FunctionEnd @@ -235,7 +237,7 @@ Section "${APNAME} (required)" File /r /x .svn /x mydata "..\..\..\source\tools\glexemel\*.*" SetOutPath $INSTDIR - File /r /x .svn /x mydata "..\..\..\data\glest_game\data" + File /r /x .svn /x mydata /x cegui "..\..\..\data\glest_game\data" File /r /x .svn /x mydata "..\..\..\data\glest_game\docs" File /r /x .svn /x mydata "..\..\..\data\glest_game\maps" File /r /x .svn /x mydata "..\..\..\data\glest_game\scenarios" diff --git a/mk/windoze/Installer/MegaGlestUpdater.nsi b/mk/windoze/Installer/MegaGlestUpdater.nsi index 363426c38..2afb3d96a 100644 --- a/mk/windoze/Installer/MegaGlestUpdater.nsi +++ b/mk/windoze/Installer/MegaGlestUpdater.nsi @@ -2,10 +2,10 @@ ; General Attributes !define APNAME MegaGlest -!define APVER 3.10.0-dev +!define APVER 3.11.0 !define APNAME_OLD Mega-Glest !define APVER_OLD 3.9.1 -!define APVER_UPDATE 3.10.0-dev +!define APVER_UPDATE 3.11.0 Name "${APNAME} ${APVER_UPDATE}" SetCompressor /FINAL /SOLID lzma diff --git a/mk/windoze/Installer/make_installer.sh b/mk/windoze/Installer/make_installer.sh new file mode 100755 index 000000000..fa7e92305 --- /dev/null +++ b/mk/windoze/Installer/make_installer.sh @@ -0,0 +1,6 @@ +#/bin/bash + +# for this script nsis is needed +# windows binaries must be installed from snapshots.megaglest.org +makensis MegaGlestInstaller.nsi + diff --git a/mk/windoze/Installer/megaglestinstallscreen.jpg b/mk/windoze/Installer/megaglestinstallscreen.jpg index 1f16190be..f25cc287a 100644 Binary files a/mk/windoze/Installer/megaglestinstallscreen.jpg and b/mk/windoze/Installer/megaglestinstallscreen.jpg differ diff --git a/mk/windoze/Installer/plugins/AccessControl.dll b/mk/windoze/Installer/plugins/AccessControl.dll new file mode 100644 index 000000000..0de0324fc Binary files /dev/null and b/mk/windoze/Installer/plugins/AccessControl.dll differ diff --git a/mk/windoze/Installer/plugins/AccessControl.txt b/mk/windoze/Installer/plugins/AccessControl.txt new file mode 100644 index 000000000..b8e0a4d3d --- /dev/null +++ b/mk/windoze/Installer/plugins/AccessControl.txt @@ -0,0 +1,253 @@ +ACCESS CONTROL PLUGIN +--------------------- + +Written by Mathias Hasselmann +Modifications by: +* Afrow UK +* AndersK + +The AccessControl plugin for NSIS provides a set of functions related +Windows NT access control list (ACL) management. + + +MODIFICATIONS +------------- + +v1.0.8.1 - 7th July 2014 - AndersK +* Don't require SE_RESTORE_NAME and SE_TAKE_OWNERSHIP_NAME when changing owner. +* Fixed broken return value when trustee parsing failed + +v1.0.8.0 - 24th March 2014 - AndersK +* Added basic String SID parsing in the emulated ConvertStringSidToSid (Broken in v1.0.6) +* Fixed WinNT4 and Win95 support? (Unicode DLL will not load on Win95 but will probably load on Win98) +* Fixed leaks from ParseSid and ConvertSidToStringSid +* NameToSid and SidToName now pushes "error" and error details +* Better GetCurrentUserName error handling (Still returns the problematic "error" string) + +v1.0.7.0 - 25th February 2012 - Afrow UK +* Fixed DisableFileInheritance (broken in v1.0.5.0). + +v1.0.6.0 - 26th January 2012 - Afrow UK +* Wrote replacements for ConvertSidToStringSid/ConvertStringSidToSid for + backwards compatibility with Windows NT4/ME (ANSI build only). +* Loads RegSetKeySecurity/RegGetKeySecurity functions at run-time for + backwards compatibility with Windows NT4/ME (ANSI build only). +* Removed commented out legacy code. + +v1.0.5.0 - 25th January 2012 - Afrow UK +* Removed IsUserTheAdministrator. +* Added NameToSid. +* Major code cleanup/rewrite. +* Proper Unicode build (with Unicode plugin API). +* Support for 64-bit registry (SetRegView 64). +* Functions now return "ok" on success or "error" otherwise. On "error", + the next item on the stack will be the error description. +* Added version information resource. + +23rd January 2008 - Afrow UK +* Added function IsUserTheAdministrator. +* Cleaned up code. Rebuilt as pure cpp, decreasing DLL size. +* No longer using gobal temp variable for strings. + +7th January 2008 - Afrow UK +* Fixed registry instructions. + +8th November 2007 - Afrow UK +* EnableInheritance/DisableInheritance names changed. +* Functions added: + EnableFileInheritance + DisableFileInheritance + EnableRegKeyInheritance + DisableRegKeyInheritance + GetFileOwner + GetFileGroup + GetRegKeyOwner + GetRegKeyGroup + ClearOnFile + ClearOnRegKey + GetCurrentUserName + SidToName + +21st August 2007 - Afrow UK +* Added /noinherit switch to prevent child objects inheriting a + particular permission. +* Added EnableInheritance and DisableInheritance functions. +* Removed code to print items in the install log. + +13th July 2007 - kichik +* Return proper error codes (return value instead of GetLastError()) + +30th June 2006 - Afrow UK +* Error MessageBox removed. +* Error messages are now just returned on NSIS stack. + + +CONVENTIONS +----------- + + + A valid Windows(tm) filename (ie. "C:\WINDOWS\" or + "\\HOSTNAME\SHARE"). + + + The well-known root of a registry key. Following values are defined: + + HKCR - HKEY_CLASSES_ROOT + HKLM - HKEY_LOCAL_MACHINE + HKCU - HKEY_CURRENT_USER + HKU - HKEY_USERS + + + The name of the registry to alter (ie. "Software\Microsoft\Windows"). + + + A valid Windows(tm) account. The account can be specified as relative + account name (ie. "Administrator" or "Everyone"), a qualified account + name (ie. "Domain\Administrator") or as security identifier (SID, + ie. "(S-1-5-32-545)"). "BUILTIN\USERS" is also a valid account name. + For a list of trustee names, open up + Control Panel > Administrative Tools > Computer Management > + Local Users and Groups. + WinNT4 uses a emulated version of ConvertStringSidToSid and + only supports the following SDDL strings: AN, AU, BA, BU, IU, SY and WD + + + A combination of access rights (ie. "FullAccess" or + "GenericRead + GenericWrite"). + For a full list of access rights, open the AccessControl.cpp source + file in Notepad. + +/NOINHERIT + Ensures the specified ACEs (Access Control Entries) are not inherited + by child nodes (i.e for directory or registry key objects). + +HANDLING ERRORS +--------------- + +To handle errors, check the result on the stack: + + AccessControl::SetOnRegKey HKLM Software\MyApp Stuart FullAccess + Pop $R0 + ${If} $R0 == error + Pop $R0 + DetailPrint `AccessControl error: $R0` + ${EndIf} + +FUNCTIONS +--------- + +GrantOnFile [/NOINHERIT] +GrantOnRegKey [/NOINHERIT] +Pop $Result ; "ok" or "error" + error details + + Makes sure that the trustee get the requested access rights on + that object. + +--------- + +SetOnFile [/NOINHERIT] +SetOnRegKey [/NOINHERIT] +Pop $Result ; "ok" or "error" + error details + + Replaces any existing access rights for the trustee on the object + with the specified access rights. + +--------- + +ClearOnFile [/NOINHERIT] +ClearOnRegKey [/NOINHERIT] +Pop $Result ; "ok" or "error" + error details + + Replaces all trustees on the object with the specified trustee and + access rights. + +--------- + +DenyOnFile [/NOINHERIT] +DenyOnRegKey [/NOINHERIT] +Pop $Result ; "ok" or "error" + error details + + Explicitly denies an access right on a object. + +--------- + +RevokeOnFile [/NOINHERIT] +RevokeOnRegKey [/NOINHERIT] +Pop $Result ; "ok" or "error" + error details + + Removes a formerly defined access right for that object. + Note that access rights will still be revoked even if they are + inherited. + +--------- + +SetFileOwner +SetRegKeyOwner +Pop $Result ; "ok" or "error" + error details + + Changes the owner of an object. + +--------- + +GetFileOwner +GetRegKeyOwner +Pop $Owner ; or "error" + error details + + Gets the owner of an object. + +--------- + +SetFileGroup +SetRegKeyGroup +Pop $Result ; "ok" or "error" + error details + + Changes the primary group of the object. + +--------- + +GetFileGroup +GetRegKeyGroup +Pop $Group ; or "error" + error details + + Gets the primary group of the object. + +--------- + +EnableFileInheritance +EnableRegKeyInheritance +Pop $Result ; "ok" or "error" + error details + + Enables inheritance of parent object permissions. + +--------- + +DisableFileInheritance +DisableRegKeyInheritance +Pop $Result ; "ok" or "error" + error details + + Disables inheritance of parent object permissions. + +--------- + +SidToName +Pop $Domain ; or "error" + error details +Pop $Username + + Converts an SID on the local machine to the corresponding username and + domain name. + +--------- + +NameToSid +Pop $SID ; or "error" + error details + + Gets the SID of the specified username on the local machine. + +--------- + +GetCurrentUserName +Pop $Username ; or "error" + + Gets the username of the current user running the setup. + +--------- \ No newline at end of file diff --git a/mk/windoze/build-mg-2012.bat b/mk/windoze/build-mg-2012.bat index 1cddc6058..54b43bf15 100644 --- a/mk/windoze/build-mg-2012.bat +++ b/mk/windoze/build-mg-2012.bat @@ -161,13 +161,15 @@ rem if "%2" == "rebuild" msbuild %msBuildMaxCPU% /p:Configuration=Release;Platfo rem /p:VCTargetsPath=%MSBUILD_PATH_MG_x64%; rem if "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:detailed /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release;Platform=x64;PlatformToolset=v110 /m /t:Rebuild Glest_vc2012.sln -if "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:q /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release;Platform=x64;PlatformToolset=v110 /m /t:Rebuild Glest_vc2012.sln +rem if "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:q /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release;Platform=x64;PlatformToolset=v110 /m /t:Rebuild Glest_vc2012.sln +if "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:q /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release_WITHOUT_STREFLOP;Platform=x64;PlatformToolset=v110 /m /t:Rebuild Glest_vc2012.sln rem if not "%2" == "rebuild" msbuild /detailedsummary %msBuildMaxCPU% /p:BuildInParallel=%BuildInParallel% /p:Configuration=Release Glest_vc2010.sln rem if not "%2" == "rebuild" msbuild %msBuildMaxCPU% /p:Configuration=Release;Platform=x64 /v:q /m /p:PlatformToolset=v110_xp Glest_vc2012.sln rem if not "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:detailed /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release;Platform=x64;PlatformToolset=v110 /m Glest_vc2012.sln -if not "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:q /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release;Platform=x64;PlatformToolset=v110 /m Glest_vc2012.sln +rem if not "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:q /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release;Platform=x64;PlatformToolset=v110 /m Glest_vc2012.sln +if not "%2" == "rebuild" msbuild %msBuildMaxCPU% /v:q /p:TrackFileAccess=false;VCTargetsPath=%MSBUILD_PATH_MG_x64%;Configuration=Release_WITHOUT_STREFLOP;Platform=x64;PlatformToolset=v110 /m Glest_vc2012.sln rem pause execution so we can see the output before the batch file exits if not "%1" == "nopause" pause diff --git a/mk/windoze/vc2012/g2xml.vcxproj b/mk/windoze/vc2012/g2xml.vcxproj index 444b7e247..503e23f47 100644 --- a/mk/windoze/vc2012/g2xml.vcxproj +++ b/mk/windoze/vc2012/g2xml.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + Release_NO_STREFLOP + Win32 + + + Release_NO_STREFLOP + x64 + + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -31,12 +47,36 @@ true v110_xp + + Application + Unicode + true + v110_xp + + + Application + Unicode + true + v110_xp + Application Unicode true v110 + + Application + Unicode + true + v110 + + + Application + Unicode + true + v110 + Application Unicode @@ -51,9 +91,21 @@ + + + + + + + + + + + + @@ -68,20 +120,48 @@ true true .\..\..\data\glest_game\ + .\..\..\data\glest_game\ + .\..\..\data\glest_game\ $(Configuration)\ + $(Configuration)\ + $(Configuration)\ false + false + false false + false + false false + false + false false + false + false g2xml + + g2xml + + + g2xml + g2xmlx64 $(Platform)\$(Configuration)\$(TargetName)\ $(SolutionDir) + + g2xmlx64 + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + + + g2xmlx64 + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + Disabled @@ -140,6 +220,50 @@ MachineX86 + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + StreamingSIMDExtensions2 + + + true + Console + true + true + MachineX86 + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + StreamingSIMDExtensions2 + + + true + Console + true + true + MachineX86 + + MaxSpeed @@ -163,6 +287,52 @@ true + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + + + 4996 + + + true + Console + true + true + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + + + 4996 + + + true + Console + true + true + + diff --git a/mk/windoze/vc2012/g3d_viewer.vcxproj b/mk/windoze/vc2012/g3d_viewer.vcxproj index bd586c0b6..fa3f40405 100644 --- a/mk/windoze/vc2012/g3d_viewer.vcxproj +++ b/mk/windoze/vc2012/g3d_viewer.vcxproj @@ -17,6 +17,14 @@ Release_NO_STREFLOP x64 + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -43,10 +51,18 @@ Application v110_xp + + Application + v110_xp + Application v110 + + Application + v110 + Application @@ -65,9 +81,15 @@ + + + + + + @@ -82,22 +104,34 @@ true true .\..\..\..\data\glest_game\ + .\..\..\..\data\glest_game\ $(Configuration)/$(ProjectName)\ + $(Configuration)/$(ProjectName)\ false + false false + false $(Configuration)\ $(Configuration)\ true true megaglest_g3dviewer + megaglest_g3dviewer megaglest_g3dviewerx64 + megaglest_g3dviewerx64 false + false false + false $(Platform)\$(Configuration)\$(TargetName)\ $(SolutionDir) + + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + Disabled @@ -188,6 +222,42 @@ + + + /arch:SSE2 %(AdditionalOptions) + ..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\lib\vc_lib\mswu;..\..\..\source\shared_lib\include\util;..\..\..\source\shared_lib\include\graphics\gl;..\..\..\source\windows_deps_2012\include;..\..\..\source\shared_lib\include\graphics;..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\include;..\..\..\source\shared_lib\include\platform\sdl;../../../source/shared_lib/include/streflop;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/windows_deps_2012/curl-7.21.3/include;..\..\..\source\glest_game\graphics;..\..\..\source\shared_lib\include\xml;../../../source/windows_deps_2012/xerces-c-3.1.1/src;..\..\..\source\glest_game\global;..\..\..\source\glest_game\sound;..\..\..\source\shared_lib\include\sound;..\..\..\source\glest_game\game;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/lpng1510;..\..\..\source\glest_game\facilities;../../../source/windows_deps_2012/glew-1.7.0/include;..\..\..\source\shared_lib\include\xml\rapidxml;../../../source/shared_lib/include/platform/win32;%(AdditionalIncludeDirectories) + _WINDOWS;WIN32;NDEBUG;CURL_STATICLIB;UNICODE;_UNICODE;GLEW_STATIC;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + Async + MultiThreaded + StreamingSIMDExtensions2 + + + + + c:\temp\release\$(TargetName).pch + Level3 + ProgramDatabase + true + Fast + true + + + wxbase29u.lib;wxbase29u_net.lib;wxbase29u_xml.lib;wxexpat.lib;wxjpeg.lib;wxtiff.lib;wxmsw29u_adv.lib;wxmsw29u_aui.lib;wxmsw29u_core.lib;wxmsw29u_gl.lib;wxmsw29u_html.lib;wxmsw29u_media.lib;wxmsw29u_qa.lib;wxmsw29u_richtext.lib;wxmsw29u_xrc.lib;wxregexu.lib;winmm.lib;rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;oleaut32.lib;comctl32.lib;comdlg32.lib;uuid.lib;advapi32.lib;shell32.lib;libglest.lib;Dbghelp.lib;sdl.lib;sdlmain.lib;dxguid.lib;libstreflop.lib;libcurl.lib;ws2_32.lib;xerces-c_static_3.lib;libpng15.lib;jpeg.lib;ftgl_static.lib;freetype244MT.lib;glew32s.lib;zlibstat.lib;libeay32.lib;ssleay32.lib;%(AdditionalDependencies) + $(OutDir)\$(TargetFileName) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;../../../source/shared_lib/sources/streflop/libstreflop;$(DXSDK_DIR)/lib/x86;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x86;%(AdditionalLibraryDirectories) + true + Console + + + + + MachineX86 + false + + + + %(AdditionalOptions) @@ -225,6 +295,43 @@ + + + %(AdditionalOptions) + ..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\lib\vc_lib\mswu;..\..\..\source\shared_lib\include\util;..\..\..\source\shared_lib\include\graphics\gl;..\..\..\source\windows_deps_2012\include;..\..\..\source\shared_lib\include\graphics;..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\include;..\..\..\source\shared_lib\include\platform\sdl;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/windows_deps_2012/curl-7.21.3/include;..\..\..\source\glest_game\graphics;..\..\..\source\shared_lib\include\xml;../../../source/windows_deps_2012/xerces-c-3.1.1/src;..\..\..\source\glest_game\global;..\..\..\source\glest_game\sound;..\..\..\source\shared_lib\include\sound;..\..\..\source\glest_game\game;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/lpng1510;..\..\..\source\glest_game\facilities;../../../source/windows_deps_2012/glew-1.7.0/include;..\..\..\source\shared_lib\include\xml\rapidxml;../../../source/shared_lib/include/platform/win32;%(AdditionalIncludeDirectories) + _WINDOWS;WIN32;NDEBUG;CURL_STATICLIB;UNICODE;_UNICODE;GLEW_STATIC;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + Async + MultiThreaded + + + + + + + c:\temp\release\$(TargetName).pch + Level3 + ProgramDatabase + true + Fast + true + 4996 + + + wxbase29u.lib;wxbase29u_net.lib;wxbase29u_xml.lib;wxexpat.lib;wxjpeg.lib;wxtiff.lib;wxmsw29u_adv.lib;wxmsw29u_aui.lib;wxmsw29u_core.lib;wxmsw29u_gl.lib;wxmsw29u_html.lib;wxmsw29u_media.lib;wxmsw29u_qa.lib;wxmsw29u_richtext.lib;wxmsw29u_xrc.lib;wxregexu.lib;winmm.lib;rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;oleaut32.lib;comctl32.lib;comdlg32.lib;uuid.lib;advapi32.lib;shell32.lib;libglest.lib;Dbghelp.lib;sdl.lib;sdlmain.lib;dxguid.lib;libcurl.lib;ws2_32.lib;xerces-c_static_3.lib;libpng15.lib;jpeg.lib;ftgl_static.lib;freetype244MT.lib;glew32s.lib;zlibstat.lib;%(AdditionalDependencies) + $(OutDir)\$(TargetFileName) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;$(DXSDK_DIR)/lib/x64;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x64;%(AdditionalLibraryDirectories) + true + Console + + + + + false + + + + /arch:SSE2 %(AdditionalOptions) @@ -305,4 +412,4 @@ - + \ No newline at end of file diff --git a/mk/windoze/vc2012/glest_editor.vcxproj b/mk/windoze/vc2012/glest_editor.vcxproj index adcca78a8..072da3b41 100644 --- a/mk/windoze/vc2012/glest_editor.vcxproj +++ b/mk/windoze/vc2012/glest_editor.vcxproj @@ -17,6 +17,14 @@ Release_NO_STREFLOP x64 + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -43,10 +51,18 @@ Application v110_xp + + Application + v110_xp + Application v110 + + Application + v110 + Application @@ -65,9 +81,15 @@ + + + + + + @@ -82,22 +104,34 @@ true true .\..\..\..\data\glest_game\ + .\..\..\..\data\glest_game\ $(Configuration)/$(ProjectName)\ + $(Configuration)/$(ProjectName)\ false + false false + false $(Configuration)\ $(Configuration)\ true true megaglest_editor + megaglest_editor megaglest_editorx64 + megaglest_editorx64 false + false false + false $(Platform)\$(Configuration)\$(TargetName)\ $(SolutionDir) + + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + Disabled @@ -187,6 +221,41 @@ false + + + /arch:SSE2 %(AdditionalOptions) + ..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\lib\vc_lib\mswu;..\..\..\source\shared_lib\include\util;..\..\..\source\shared_lib\include\platform\win32;..\..\..\source\shared_lib\include\graphics\gl;..\..\..\source\windows_deps_2012\include;..\..\..\source\shared_lib\include\graphics;..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\include;..\..\..\source\shared_lib\include\platform\sdl;../../../source/shared_lib/include/streflop;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;..\..\..\source\glest_game\global;..\..\..\source\glest_game\game;..\..\..\source\glest_game\facilities;..\..\..\source\shared_lib\include\xml;..\..\..\source\shared_lib\include\xml\rapidxml;../../../source/windows_deps_2012/xerces-c-3.1.1/src;%(AdditionalIncludeDirectories) + _WINDOWS;WIN32;NDEBUG;CURL_STATICLIB;UNICODE;_UNICODE;GLEW_STATIC;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + Async + MultiThreaded + StreamingSIMDExtensions2 + + + + + + + Level3 + ProgramDatabase + true + + + wxbase29u.lib;wxbase29u_net.lib;wxbase29u_xml.lib;wxexpat.lib;wxjpeg.lib;wxmsw29u_adv.lib;wxmsw29u_aui.lib;wxmsw29u_core.lib;wxmsw29u_gl.lib;wxmsw29u_html.lib;wxmsw29u_media.lib;wxmsw29u_qa.lib;wxmsw29u_richtext.lib;wxmsw29u_xrc.lib;wxpng.lib;wxregexu.lib;wxtiff.lib;winmm.lib;rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;oleaut32.lib;comctl32.lib;comdlg32.lib;uuid.lib;advapi32.lib;shell32.lib;libglest.lib;sdl.lib;sdlmain.lib;dsound.lib;dxguid.lib;Dbghelp.lib;libcurl.lib;ws2_32.lib;ftgl_static.lib;freetype244MT.lib;zlibstat.lib;libeay32.lib;ssleay32.lib;%(AdditionalDependencies) + $(OutDir)\$(TargetFileName) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;$(DXSDK_DIR)/lib/x86;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x86;%(AdditionalLibraryDirectories) + true + Windows + + + + + MachineX86 + + + false + + %(AdditionalOptions) @@ -224,6 +293,43 @@ ;%(IgnoreSpecificDefaultLibraries) + + + %(AdditionalOptions) + ..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\lib\vc_lib\mswu;..\..\..\source\shared_lib\include\util;..\..\..\source\shared_lib\include\platform\win32;..\..\..\source\shared_lib\include\graphics\gl;..\..\..\source\windows_deps_2012\include;..\..\..\source\shared_lib\include\graphics;..\..\..\source\windows_deps_2012\wxWidgets-2.9.3\include;..\..\..\source\shared_lib\include\platform\sdl;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;..\..\..\source\glest_game\global;..\..\..\source\glest_game\game;..\..\..\source\glest_game\facilities;..\..\..\source\shared_lib\include\xml;..\..\..\source\shared_lib\include\xml\rapidxml;../../../source/windows_deps_2012/xerces-c-3.1.1/src;%(AdditionalIncludeDirectories) + _WINDOWS;WIN32;NDEBUG;CURL_STATICLIB;UNICODE;_UNICODE;GLEW_STATIC;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + Async + MultiThreaded + + + + + + + + + Level3 + ProgramDatabase + true + 4996 + + + wxbase29u.lib;wxbase29u_net.lib;wxbase29u_xml.lib;wxexpat.lib;wxjpeg.lib;wxmsw29u_adv.lib;wxmsw29u_aui.lib;wxmsw29u_core.lib;wxmsw29u_gl.lib;wxmsw29u_html.lib;wxmsw29u_media.lib;wxmsw29u_qa.lib;wxmsw29u_richtext.lib;wxmsw29u_xrc.lib;wxpng.lib;wxregexu.lib;wxtiff.lib;winmm.lib;rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;ole32.lib;oleaut32.lib;comctl32.lib;comdlg32.lib;uuid.lib;advapi32.lib;shell32.lib;libglest.lib;sdl.lib;sdlmain.lib;dsound.lib;dxguid.lib;Dbghelp.lib;libcurl.lib;ws2_32.lib;ftgl_static.lib;freetype244MT.lib;zlibstat.lib;%(AdditionalDependencies) + $(OutDir)\$(TargetFileName) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;$(DXSDK_DIR)/lib/x64;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x64;%(AdditionalLibraryDirectories) + true + Windows + + + + + + + false + ;%(IgnoreSpecificDefaultLibraries) + + /arch:SSE2 %(AdditionalOptions) @@ -302,4 +408,4 @@ - + \ No newline at end of file diff --git a/mk/windoze/vc2012/glest_game.vcxproj b/mk/windoze/vc2012/glest_game.vcxproj index 591bec3fa..f8a927fdc 100644 --- a/mk/windoze/vc2012/glest_game.vcxproj +++ b/mk/windoze/vc2012/glest_game.vcxproj @@ -17,6 +17,14 @@ Release_NO_STREFLOP x64 + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -48,12 +56,24 @@ true v110_xp + + Application + NotSet + true + v110_xp + Application NotSet true v110 + + Application + NotSet + true + v110 + Application NotSet @@ -76,9 +96,15 @@ + + + + + + @@ -91,9 +117,13 @@ .\..\..\..\data\glest_game\ $(Configuration)/$(ProjectName)\ .\..\..\..\data\glest_game\ + .\..\..\..\data\glest_game\ $(Configuration)/$(ProjectName)\ + $(Configuration)/$(ProjectName)\ false + false false + false $(Configuration)\ $(Configuration)\ false @@ -101,12 +131,18 @@ false false megaglest + megaglest megaglestx64 + megaglestx64 $(Platform)\$(Configuration)\$(TargetName)\ $(SolutionDir) + + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + Disabled @@ -247,6 +283,56 @@ + + + /arch:SSE2 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + false + false + ../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/platform/win32;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/shared_lib/include/xml/rapidxml;../../../source/glest_game/ai;../../../source/glest_game/facilities;../../../source/glest_game/game;../../../source/glest_game/global;../../../source/glest_game/graphics;../../../source/glest_game/gui;../../../source/glest_game/main;../../../source/glest_game/menu;../../../source/glest_game/network;../../../source/glest_game/sound;../../../source/glest_game/type_instances;../../../source/glest_game/types;../../../source/glest_game/world;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/sound/openal;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/streflop;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/libircclient/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/windows_deps_2012/google-breakpad\trunk\src\client\windows\;../../../source/windows_deps_2012/google-breakpad\trunk\src\;../../../source/shared_lib/include/compression + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_LIB;_WINDOWS;XML_LIBRARY;USE_PCH=1;_CRT_SECURE_NO_WARNINGS;USE_STREFLOP;STREFLOP_SSE;LIBM_COMPILING_FLT32;CURL_STATICLIB;UNICODE;XERCES_STATIC_LIBRARY;GLEW_STATIC;USE_FREETYPEGL;STATICLIB;USE_FTGL;FTGL_LIBRARY_STATIC;ZLIB_WINAPI;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + true + Async + MultiThreaded + true + StreamingSIMDExtensions2 + Precise + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + 4018;4244;4250;4503;%(DisableSpecificWarnings) + true + true + + + dsound.lib;dxguid.lib;glew32s.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;opengl32.lib;glu32.lib;wsock32.lib;libglest.lib;mmc.lib;lua.lib;xerces-c_static_3.lib;Dbghelp.lib;libpng15.lib;jpeg.lib;zlibstat.lib;sdl.lib;sdlmain.lib;winmm.lib;openal32.lib;iphlpapi.lib;libstreflop.lib;libcurl.lib;ws2_32.lib;libircclient.lib;freetype244MT.lib;ftgl_static.lib;libeay32.lib;ssleay32.lib;crash_generation_client.lib;exception_handler.lib;common.lib;processor_bits.lib;%(AdditionalDependencies) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;../../../source/shared_lib/sources/streflop/libstreflop;$(DXSDK_DIR)/lib/x86;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x86;%(AdditionalLibraryDirectories) + libcmtd.lib;%(IgnoreSpecificDefaultLibraries) + true + Console + + + + + + + false + + + MachineX86 + $(OutDir)$(TargetName)$(TargetExt) + true + true + + + + + + %(AdditionalOptions) @@ -297,6 +383,56 @@ + + + %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + false + false + ../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/platform/win32;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/shared_lib/include/xml/rapidxml;../../../source/glest_game/ai;../../../source/glest_game/facilities;../../../source/glest_game/game;../../../source/glest_game/global;../../../source/glest_game/graphics;../../../source/glest_game/gui;../../../source/glest_game/main;../../../source/glest_game/menu;../../../source/glest_game/network;../../../source/glest_game/sound;../../../source/glest_game/type_instances;../../../source/glest_game/types;../../../source/glest_game/world;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/sound/openal;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/libircclient/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/shared_lib/include/compression;../../../source/shared_lib/include/streflop/ + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_LIB;_WINDOWS;XML_LIBRARY;USE_PCH=1;_CRT_SECURE_NO_WARNINGS;STREFLOP_SSE;LIBM_COMPILING_FLT32;CURL_STATICLIB;UNICODE;XERCES_STATIC_LIBRARY;GLEW_STATIC;USE_FREETYPEGL_XXX;STATICLIB;USE_FTGL;FTGL_LIBRARY_STATIC;ZLIB_WINAPI;HAVE_GOOGLE_BREAKPAD_XXX;%(PreprocessorDefinitions) + true + Async + MultiThreaded + true + + + Precise + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + 4996;4018;4244;4250;4503;%(DisableSpecificWarnings) + true + true + + + libstreflop.lib;dxguid.lib;glew32s.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;opengl32.lib;glu32.lib;wsock32.lib;libglest.lib;mmc.lib;lua.lib;xerces-c_static_3.lib;Dbghelp.lib;libpng15.lib;jpeg.lib;zlibstat.lib;sdl.lib;sdlmain.lib;winmm.lib;openal64.lib;iphlpapi.lib;libcurl.lib;ws2_32.lib;libircclient.lib;freetype244MT.lib;ftgl_static.lib;libeay32.lib;ssleay32.lib;%(AdditionalDependencies) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;$(DXSDK_DIR)/lib/x64;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x64;%(AdditionalLibraryDirectories) + ;%(IgnoreSpecificDefaultLibraries) + true + Console + + + + + + + false + + + $(OutDir)$(TargetName)$(TargetExt) + true + true + + + + + + /arch:SSE2 %(AdditionalOptions) @@ -435,6 +571,7 @@ + @@ -562,4 +699,4 @@ - + \ No newline at end of file diff --git a/mk/windoze/vc2012/libstreflop.vcxproj b/mk/windoze/vc2012/libstreflop.vcxproj index 490fe48fa..95892b45e 100644 --- a/mk/windoze/vc2012/libstreflop.vcxproj +++ b/mk/windoze/vc2012/libstreflop.vcxproj @@ -25,6 +25,14 @@ Release_NO_STREFLOP x64 + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -66,12 +74,24 @@ true v110_xp + + StaticLibrary + MultiByte + true + v110_xp + StaticLibrary NotSet true v110 + + StaticLibrary + NotSet + true + v110 + StaticLibrary MultiByte @@ -99,9 +119,15 @@ + + + + + + @@ -114,7 +140,9 @@ .\ $(Configuration)/$(ProjectName)\ .\ + .\ $(Configuration)/$(ProjectName)\ + $(Configuration)/$(ProjectName)\ $(Configuration)\ $(Configuration)\ $(Configuration)\ @@ -123,11 +151,19 @@ libstreflop + + libstreflop + libstreflop .\ $(Platform)\$(Configuration)\$(TargetName)\ + + libstreflop + .\ + $(Platform)\$(Configuration)\$(TargetName)\ + Disabled @@ -184,6 +220,33 @@ true + + + /arch:SSE2 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + false + ..\..\..\source\shared_lib\include\streflop\libm\flt-32;..\..\..\source\shared_lib\include\streflop\libm\headers;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_PCH=1;USE_STREFLOP;STREFLOP_SSE;LIBM_COMPILING_FLT32;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + true + Async + MultiThreaded + true + StreamingSIMDExtensions2 + Precise + true + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + true + + + MachineX86 + true + + %(AdditionalOptions) @@ -213,6 +276,35 @@ true + + + %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + false + ..\..\..\source\shared_lib\include\streflop\libm\flt-32;..\..\..\source\shared_lib\include\streflop\libm\headers;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_PCH=1;USE_STREFLOP;STREFLOP_SSE;LIBM_COMPILING_FLT32;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + true + Async + MultiThreaded + true + + + Precise + true + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + true + 4996;4250;%(DisableSpecificWarnings) + + + MachineX64 + true + + /arch:SSE2 %(AdditionalOptions) @@ -378,4 +470,4 @@ - + \ No newline at end of file diff --git a/mk/windoze/vc2012/megaglest_tests.vcxproj b/mk/windoze/vc2012/megaglest_tests.vcxproj index d68f35a8b..14e23dd4b 100644 --- a/mk/windoze/vc2012/megaglest_tests.vcxproj +++ b/mk/windoze/vc2012/megaglest_tests.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + Release_NO_STREFLOP + Win32 + + + Release_NO_STREFLOP + x64 + + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -42,6 +58,20 @@ Unicode v110_xp + + Application + false + true + Unicode + v110_xp + + + Application + false + true + Unicode + v110_xp + Application false @@ -49,6 +79,20 @@ Unicode v110 + + Application + false + true + Unicode + v110 + + + Application + false + true + Unicode + v110 + @@ -61,9 +105,21 @@ + + + + + + + + + + + + true @@ -77,12 +133,34 @@ .\..\..\..\data\glest_game\ megaglest_tests + + false + .\..\..\..\data\glest_game\ + megaglest_tests + + + false + .\..\..\..\data\glest_game\ + megaglest_tests + megaglest_testsx64 false $(SolutionDir) $(Platform)\$(Configuration)\$(TargetName)\ + + megaglest_testsx64 + false + $(SolutionDir) + $(Platform)\$(Configuration)\$(TargetName)\ + + + megaglest_testsx64 + false + $(SolutionDir) + $(Platform)\$(Configuration)\$(TargetName)\ + @@ -158,6 +236,68 @@ Run unit tests + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;XML_LIBRARY;USE_PCH=1;_CRT_SECURE_NO_WARNINGS;USE_STREFLOP;STREFLOP_SSE;LIBM_COMPILING_FLT32;CURL_STATICLIB;UNICODE;XERCES_STATIC_LIBRARY;GLEW_STATIC;USE_FREETYPEGL;STATICLIB;USE_FTGL;FTGL_LIBRARY_STATIC;ZLIB_WINAPI;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + ../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/platform/win32;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/shared_lib/include/xml/rapidxml;../../../source/glest_game/ai;../../../source/glest_game/facilities;../../../source/glest_game/game;../../../source/glest_game/global;../../../source/glest_game/graphics;../../../source/glest_game/gui;../../../source/glest_game/main;../../../source/glest_game/menu;../../../source/glest_game/network;../../../source/glest_game/sound;../../../source/glest_game/type_instances;../../../source/glest_game/types;../../../source/glest_game/world;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/sound/openal;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/streflop;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/libircclient/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/windows_deps_2012/google-breakpad\trunk\src\client\windows\;../../../source/windows_deps_2012/google-breakpad\trunk\src\;../../../source/windows_deps_2012/cppunit/include + MultiThreaded + Fast + StreamingSIMDExtensions2 + + + Console + true + true + true + $(OutDir)\megaglest_tests.exe + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;../../../source/shared_lib/sources/streflop/libstreflop;$(DXSDK_DIR)/lib/x86;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x86;../../../source/windows_deps_2012/cppunit/lib;%(AdditionalLibraryDirectories) + dsound.lib;dxguid.lib;glew32s.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;opengl32.lib;glu32.lib;wsock32.lib;libglest.lib;mmc.lib;lua.lib;xerces-c_static_3.lib;Dbghelp.lib;libpng15.lib;jpeg.lib;zlibstat.lib;sdl.lib;sdlmain.lib;winmm.lib;openal32.lib;iphlpapi.lib;libstreflop.lib;libcurl.lib;ws2_32.lib;libircclient.lib;freetype244MT.lib;ftgl_static.lib;libeay32.lib;ssleay32.lib;crash_generation_client.lib;exception_handler.lib;common.lib;processor_bits.lib;cppunit.lib;%(AdditionalDependencies) + libcmtd.lib;%(IgnoreSpecificDefaultLibraries) + + + $(OutDir)\megaglest_tests.exe + + + Run unit tests + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;XML_LIBRARY;USE_PCH=1;_CRT_SECURE_NO_WARNINGS;USE_STREFLOP;STREFLOP_SSE;LIBM_COMPILING_FLT32;CURL_STATICLIB;UNICODE;XERCES_STATIC_LIBRARY;GLEW_STATIC;USE_FREETYPEGL;STATICLIB;USE_FTGL;FTGL_LIBRARY_STATIC;ZLIB_WINAPI;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + ../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/platform/win32;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/shared_lib/include/xml/rapidxml;../../../source/glest_game/ai;../../../source/glest_game/facilities;../../../source/glest_game/game;../../../source/glest_game/global;../../../source/glest_game/graphics;../../../source/glest_game/gui;../../../source/glest_game/main;../../../source/glest_game/menu;../../../source/glest_game/network;../../../source/glest_game/sound;../../../source/glest_game/type_instances;../../../source/glest_game/types;../../../source/glest_game/world;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/sound/openal;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/streflop;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/libircclient/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/windows_deps_2012/google-breakpad\trunk\src\client\windows\;../../../source/windows_deps_2012/google-breakpad\trunk\src\;../../../source/windows_deps_2012/cppunit/include + MultiThreaded + Fast + StreamingSIMDExtensions2 + + + Console + true + true + true + $(OutDir)\megaglest_tests.exe + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;../../../source/shared_lib/sources/streflop/libstreflop;$(DXSDK_DIR)/lib/x86;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x86;../../../source/windows_deps_2012/cppunit/lib;%(AdditionalLibraryDirectories) + dsound.lib;dxguid.lib;glew32s.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;opengl32.lib;glu32.lib;wsock32.lib;libglest.lib;mmc.lib;lua.lib;xerces-c_static_3.lib;Dbghelp.lib;libpng15.lib;jpeg.lib;zlibstat.lib;sdl.lib;sdlmain.lib;winmm.lib;openal32.lib;iphlpapi.lib;libstreflop.lib;libcurl.lib;ws2_32.lib;libircclient.lib;freetype244MT.lib;ftgl_static.lib;libeay32.lib;ssleay32.lib;crash_generation_client.lib;exception_handler.lib;common.lib;processor_bits.lib;cppunit.lib;%(AdditionalDependencies) + libcmtd.lib;%(IgnoreSpecificDefaultLibraries) + + + $(OutDir)\megaglest_tests.exe + + + Run unit tests + + Level3 @@ -192,6 +332,74 @@ Run unit tests + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;XML_LIBRARY;USE_PCH=1;_CRT_SECURE_NO_WARNINGS;USE_STREFLOP_XXX;STREFLOP_SSE_XXX;LIBM_COMPILING_FLT32_XXX;CURL_STATICLIB;UNICODE;XERCES_STATIC_LIBRARY;GLEW_STATIC;USE_FREETYPEGL;STATICLIB;USE_FTGL;FTGL_LIBRARY_STATIC;ZLIB_WINAPI;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + ../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/platform/win32;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/shared_lib/include/xml/rapidxml;../../../source/glest_game/ai;../../../source/glest_game/facilities;../../../source/glest_game/game;../../../source/glest_game/global;../../../source/glest_game/graphics;../../../source/glest_game/gui;../../../source/glest_game/main;../../../source/glest_game/menu;../../../source/glest_game/network;../../../source/glest_game/sound;../../../source/glest_game/type_instances;../../../source/glest_game/types;../../../source/glest_game/world;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/sound/openal;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/libircclient/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/windows_deps_2012/cppunit/include + MultiThreaded + Fast + + + true + 4996 + + + Console + true + true + true + $(OutDir)\$(TargetName)$(TargetExt) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;$(DXSDK_DIR)/lib/x64;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x64;../../../source/windows_deps_2012/cppunit/lib;%(AdditionalLibraryDirectories) + dsound.lib;dxguid.lib;glew32s.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;opengl32.lib;glu32.lib;wsock32.lib;libglest.lib;mmc.lib;lua.lib;xerces-c_static_3.lib;Dbghelp.lib;libpng15.lib;jpeg.lib;zlibstat.lib;sdl.lib;sdlmain.lib;winmm.lib;openal64.lib;iphlpapi.lib;libcurl.lib;ws2_32.lib;libircclient.lib;freetype244MT.lib;ftgl_static.lib;cppunit.lib;%(AdditionalDependencies) + ;%(IgnoreSpecificDefaultLibraries) + + + $(OutDir)\$(TargetName)$(TargetExt) + + + Run unit tests + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;XML_LIBRARY;USE_PCH=1;_CRT_SECURE_NO_WARNINGS;USE_STREFLOP_XXX;STREFLOP_SSE_XXX;LIBM_COMPILING_FLT32_XXX;CURL_STATICLIB;UNICODE;XERCES_STATIC_LIBRARY;GLEW_STATIC;USE_FREETYPEGL;STATICLIB;USE_FTGL;FTGL_LIBRARY_STATIC;ZLIB_WINAPI;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + ../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/platform/win32;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/shared_lib/include/xml/rapidxml;../../../source/glest_game/ai;../../../source/glest_game/facilities;../../../source/glest_game/game;../../../source/glest_game/global;../../../source/glest_game/graphics;../../../source/glest_game/gui;../../../source/glest_game/main;../../../source/glest_game/menu;../../../source/glest_game/network;../../../source/glest_game/sound;../../../source/glest_game/type_instances;../../../source/glest_game/types;../../../source/glest_game/world;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/sound/openal;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/windows_deps_2012/libircclient/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/windows_deps_2012/cppunit/include + MultiThreaded + Fast + + + true + 4996 + + + Console + true + true + true + $(OutDir)\$(TargetName)$(TargetExt) + ../../../source/windows_deps_2012/lib;../../../build/$(Configuration)/libglest;$(DXSDK_DIR)/lib/x64;../../../source/windows_deps_2012/Microsoft DirectX SDK %28November 2007%29/Lib/x64;../../../source/windows_deps_2012/cppunit/lib;%(AdditionalLibraryDirectories) + dsound.lib;dxguid.lib;glew32s.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;opengl32.lib;glu32.lib;wsock32.lib;libglest.lib;mmc.lib;lua.lib;xerces-c_static_3.lib;Dbghelp.lib;libpng15.lib;jpeg.lib;zlibstat.lib;sdl.lib;sdlmain.lib;winmm.lib;openal64.lib;iphlpapi.lib;libcurl.lib;ws2_32.lib;libircclient.lib;freetype244MT.lib;ftgl_static.lib;cppunit.lib;%(AdditionalDependencies) + ;%(IgnoreSpecificDefaultLibraries) + + + $(OutDir)\$(TargetName)$(TargetExt) + + + Run unit tests + + diff --git a/mk/windoze/vc2012/shared_lib.vcxproj b/mk/windoze/vc2012/shared_lib.vcxproj index ab349e497..f0cf14456 100644 --- a/mk/windoze/vc2012/shared_lib.vcxproj +++ b/mk/windoze/vc2012/shared_lib.vcxproj @@ -17,6 +17,14 @@ Release_NO_STREFLOP x64 + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -48,12 +56,24 @@ true v110_xp + + StaticLibrary + NotSet + true + v110_xp + StaticLibrary NotSet true v110 + + StaticLibrary + NotSet + true + v110 + StaticLibrary NotSet @@ -74,9 +94,15 @@ + + + + + + @@ -89,19 +115,30 @@ .\ $(Configuration)/$(ProjectName)\ .\ + .\ $(Configuration)/$(ProjectName)\ + $(Configuration)/$(ProjectName)\ $(Configuration)\ $(Configuration)\ libglest + + libglest + libglest .\ $(Platform)\$(Configuration)\$(TargetName)\ $(ExecutablePath) + + libglest + .\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(ExecutablePath) + Disabled @@ -193,6 +230,36 @@ true + + + /arch:SSE2 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + false + ../../../source/shared_lib/include;../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/xerces-c-3.1.1/src/xercesc/xinclude;../../../source/windows_deps_2012/lpng1510;../../../source/windows_deps_2012/jpeg-8a;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/sound/openal;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/streflop;../../../source/shared_lib/include/streflop/libm_flt32_source;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/shared_lib/include/platform/miniupnpc;../../../source/shared_lib/include/libircclient/include;../../../source/shared_lib/include/feathery_ftp;../../../source/windows_deps_2012/ftgl-2.1.3-rc5/src;../../../source/windows_deps_2012/freetype-2.4.4/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/shared_lib/include/graphics/md5;../../../source/shared_lib/include/streflop/softfloat;../../../source/shared_lib/include/xml/rapidxml;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/platform/win32;../../../source/windows_deps_2012/vlc-2.0.1/include;../../../source/windows_deps_2012/fribidi-0.19.5/lib;../../../source/windows_deps_2012/fribidi-0.19.5/charset;../../../source/shared_lib/include/compression;../../../source/shared_lib/sources/ + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_PCH=1;USE_STREFLOP;STREFLOP_SSE;STREFLOP_RANDOM_GEN_SIZE=32;LIBM_COMPILING_FLT32;CURL_STATICLIB;UNICODE;USE_FTGL;FTGL_LIBRARY_STATIC;TA3D_PLATFORM_MSVC;TA3D_PLATFORM_WINDOWS;STATICLIB;XERCES_STATIC_LIBRARY;GLEW_STATIC;XML_LIBRARY;ZLIB_WINAPI;HAS_LIBVLC;HAVE_FRIBIDI;HAVE_GOOGLE_BREAKPAD;%(PreprocessorDefinitions) + true + Async + MultiThreaded + true + StreamingSIMDExtensions2 + Precise + true + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + 4250;%(DisableSpecificWarnings) + true + + + libstreflop.lib;libcurl.lib;glew32s.lib;freetype244MT.lib;libvlc.lib;libfribidi.lib;%(AdditionalDependencies) + .\;..\..\..\source\windows_deps_2012\lib;%(AdditionalLibraryDirectories) + MachineX86 + true + + %(AdditionalOptions) @@ -226,6 +293,39 @@ ;%(IgnoreSpecificDefaultLibraries) + + + %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + false + ../../../source/shared_lib/include;../../../source/shared_lib/include/graphics;../../../source/shared_lib/include/graphics/gl;../../../source/shared_lib/include/platform;../../../source/shared_lib/include/sound;../../../source/shared_lib/include/util;../../../source/shared_lib/include/lua;../../../source/shared_lib/include/xml;../../../source/windows_deps_2012/include;../../../source/windows_deps_2012/xerces-c-3.1.1/src;../../../source/windows_deps_2012/xerces-c-3.1.1/src/xercesc/xinclude;../../../source/windows_deps_2012/lpng1510;../../../source/windows_deps_2012/jpeg-8a;../../../source/windows_deps_2012/SDL-1.2.15/include;../../../source/windows_deps_2012/openal-soft-1.14/include;../../../source/shared_lib/include/sound/openal;../../../source/shared_lib/include/platform/posix;../../../source/shared_lib/include/platform/common;../../../source/windows_deps_2012/curl-7.21.3/include;../../../source/shared_lib/include/map;../../../source/shared_lib/include/platform/miniupnpc;../../../source/shared_lib/include/libircclient/include;../../../source/shared_lib/include/feathery_ftp;../../../source/windows_deps_2012/ftgl-2.1.3-rc5/src;../../../source/windows_deps_2012/freetype-2.4.4/include;../../../source/windows_deps_2012/glew-1.7.0/include;../../../source/shared_lib/include/graphics/md5;../../../source/shared_lib/include/xml/rapidxml;../../../source/shared_lib/include/platform/sdl;../../../source/shared_lib/include/platform/win32;../../../source/windows_deps_2012/vlc-2.0.1/include;../../../source/windows_deps_2012/fribidi-0.19.5/lib;../../../source/windows_deps_2012/fribidi-0.19.5/charset;../../../source/shared_lib/include/compression;../../../source/shared_lib/sources/;../../../source/shared_lib/include/streflop/ + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_PCH=1;STREFLOP_SSE;STREFLOP_RANDOM_GEN_SIZE=32;LIBM_COMPILING_FLT32;CURL_STATICLIB;UNICODE;USE_FTGL;FTGL_LIBRARY_STATIC;TA3D_PLATFORM_MSVC;TA3D_PLATFORM_WINDOWS;STATICLIB;XERCES_STATIC_LIBRARY;GLEW_STATIC;XML_LIBRARY;ZLIB_WINAPI;HAS_LIBVLC_XXX;HAVE_FRIBIDI;HAVE_GOOGLE_BREAKPAD_XXX;%(PreprocessorDefinitions) + true + Async + MultiThreaded + true + + + Precise + true + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + 4996;4250;%(DisableSpecificWarnings) + true + + + libstreflop.lib;libcurl.lib;glew32s.lib;freetype244MT.lib;libfribidi.lib;libeay32.lib;ssleay32.lib;%(AdditionalDependencies) + .\;..\..\..\source\windows_deps_2012\lib;%(AdditionalLibraryDirectories) + MachineX64 + + + ;%(IgnoreSpecificDefaultLibraries) + + /arch:SSE2 %(AdditionalOptions) @@ -492,4 +592,4 @@ - + \ No newline at end of file diff --git a/mk/windoze/vc2012/xml2g.vcxproj b/mk/windoze/vc2012/xml2g.vcxproj index fdde12ce7..4ffc68db1 100644 --- a/mk/windoze/vc2012/xml2g.vcxproj +++ b/mk/windoze/vc2012/xml2g.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + Release_NO_STREFLOP + Win32 + + + Release_NO_STREFLOP + x64 + + + Release_WITHOUT_STREFLOP + Win32 + + + Release_WITHOUT_STREFLOP + x64 + Release Win32 @@ -31,12 +47,36 @@ true v110_xp + + Application + Unicode + true + v110_xp + + + Application + Unicode + true + v110_xp + Application Unicode true v110 + + Application + Unicode + true + v110 + + + Application + Unicode + true + v110 + Application Unicode @@ -51,9 +91,21 @@ + + + + + + + + + + + + @@ -68,20 +120,48 @@ true true .\..\..\..\data\glest_game\ + .\..\..\..\data\glest_game\ + .\..\..\..\data\glest_game\ $(Configuration)\ + $(Configuration)\ + $(Configuration)\ false + false + false false + false + false false + false + false false + false + false xml2g + + xml2g + + + xml2g + xml2gx64 $(Platform)\$(Configuration)\$(TargetName)\ $(SolutionDir) + + xml2gx64 + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + + + xml2gx64 + $(Platform)\$(Configuration)\$(TargetName)\ + $(SolutionDir) + Disabled @@ -149,6 +229,56 @@ MachineX86 + + + MaxSpeed + true + ..\..\..\source\windows_deps_2012\libxml2-2.7.7\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + StreamingSIMDExtensions2 + + + wsock32.lib;libxml2_a.lib;%(AdditionalDependencies) + ..\..\..\source\windows_deps_2012\lib\;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + + + MaxSpeed + true + ..\..\..\source\windows_deps_2012\libxml2-2.7.7\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + StreamingSIMDExtensions2 + + + wsock32.lib;libxml2_a.lib;%(AdditionalDependencies) + ..\..\..\source\windows_deps_2012\lib\;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + MaxSpeed @@ -175,6 +305,58 @@ true + + + MaxSpeed + true + ..\..\..\source\windows_deps_2012\libxml2-2.7.7\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + + + 4996 + + + wsock32.lib;libxml2_a.lib;%(AdditionalDependencies) + ..\..\..\source\windows_deps_2012\lib\;%(AdditionalLibraryDirectories) + true + Console + true + true + + + + + MaxSpeed + true + ..\..\..\source\windows_deps_2012\libxml2-2.7.7\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + true + + + 4996 + + + wsock32.lib;libxml2_a.lib;%(AdditionalDependencies) + ..\..\..\source\windows_deps_2012\lib\;%(AdditionalLibraryDirectories) + true + Console + true + true + + diff --git a/source/.gitignore b/source/.gitignore index 741757173..408dc5b76 100644 --- a/source/.gitignore +++ b/source/.gitignore @@ -1,3 +1,4 @@ /windows_deps*/ /glest_game/facilities/gitversion.h -/glest_game/site/ \ No newline at end of file +/glest_game/site/ +/Debug diff --git a/source/g3d_viewer/main.cpp b/source/g3d_viewer/main.cpp index 1276f73eb..1f0c9203b 100644 --- a/source/g3d_viewer/main.cpp +++ b/source/g3d_viewer/main.cpp @@ -299,6 +299,9 @@ MainWindow::MainWindow( std::pair > unitToLoad, this->appPath = appPath; Properties::setApplicationPath(executable_path(appPath)); + lastanim = 0; + model= NULL; + Config &config = Config::getInstance(); //getGlPlatformExtensions(); @@ -313,8 +316,6 @@ MainWindow::MainWindow( std::pair > unitToLoad, glCanvas->SetCurrent(); #endif - lastanim = 0; - model= NULL; unitPath = unitToLoad; if(modelPath != "") { @@ -480,12 +481,15 @@ void MainWindow::setupTimer() { } void MainWindow::setupStartupSettings() { - GLuint err = glewInit(); - if (GLEW_OK != err) { + + glCanvas->setCurrentGLContext(); + + GLuint err = glewInit(); + if (GLEW_OK != err) { fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); //return 1; throw std::runtime_error((char *)glewGetErrorString(err)); - } + } renderer= Renderer::getInstance(); @@ -552,8 +556,9 @@ MainWindow::~MainWindow(){ delete fileDialog; fileDialog = NULL; - delete model; - model = NULL; + //delete model; + //model = NULL; + if(renderer) renderer->end(); delete renderer; renderer = NULL; @@ -567,7 +572,7 @@ MainWindow::~MainWindow(){ void MainWindow::init() { #if wxCHECK_VERSION(2, 9, 3) - glCanvas->setCurrentGLContext(); + //glCanvas->setCurrentGLContext(); //printf("setcurrent #1\n"); #elif wxCHECK_VERSION(2, 9, 1) @@ -585,7 +590,9 @@ void MainWindow::init() { void MainWindow::onPaint(wxPaintEvent &event) { if(!IsShown()) return; -#if wxCHECK_VERSION(2, 9, 3) +#if wxCHECK_VERSION(2, 9, 4) + //glCanvas->setCurrentGLContext(); +#elif wxCHECK_VERSION(2, 9, 3) #elif wxCHECK_VERSION(2, 9, 1) glCanvas->setCurrentGLContext(); @@ -737,7 +744,6 @@ void MainWindow::onClose(wxCloseEvent &event){ particleSplashPathList.clear(); // as above if(timer) timer->Stop(); - if(renderer) renderer->end(); unitParticleSystems.clear(); unitParticleSystemTypes.clear(); @@ -747,8 +753,9 @@ void MainWindow::onClose(wxCloseEvent &event){ splashParticleSystems.clear(); // as above splashParticleSystemTypes.clear(); - delete model; - model = NULL; + //delete model; + //model = NULL; + if(renderer) renderer->end(); //printf("OnClose about to END\n"); //fflush(stdout); @@ -756,8 +763,8 @@ void MainWindow::onClose(wxCloseEvent &event){ delete timer; timer = NULL; - delete model; - model = NULL; + //delete model; + //model = NULL; delete renderer; renderer = NULL; @@ -1107,7 +1114,9 @@ void MainWindow::onMenuFileClearAll(wxCommandEvent &event) { splashParticleSystems.clear(); // as above splashParticleSystemTypes.clear(); - delete model; + //delete model; + //model = NULL; + if(model != NULL && renderer != NULL) renderer->endModel(rsGlobal, model); model = NULL; loadUnit("",""); @@ -1279,7 +1288,9 @@ void MainWindow::loadModel(string path) { //printf("Loading model [%s] %u of " MG_SIZE_T_SPECIFIER "\n",modelPath.c_str(),idx, this->modelPathList.size()); if(timer) timer->Stop(); - delete model; + //delete model; + if(model != NULL && renderer != NULL) renderer->endModel(rsGlobal, model); + model = NULL; model = renderer? renderer->newModel(rsGlobal, modelPath): NULL; statusbarText = getModelInfo(); @@ -1371,6 +1382,8 @@ void MainWindow::loadParticle(string path) { for(std::vector::const_iterator it= unitParticleSystemTypes.begin(); it != unitParticleSystemTypes.end(); ++it) { UnitParticleSystem *ups= new UnitParticleSystem(200); + + ups->setParticleType((*it)); (*it)->setValues(ups); if(size > 0) { //getCurrVectorFlat() + Vec3f(0.f, type->getHeight()/2.f, 0.f); @@ -1852,7 +1865,7 @@ void MainWindow::onTimer(wxTimerEvent &event) { string MainWindow::getModelInfo() { string str; - if(model!=NULL){ + if(model != NULL) { str+= "Meshes: "+intToStr(model->getMeshCount()); str+= ", Vertices: "+intToStr(model->getVertexCount()); str+= ", Triangles: "+intToStr(model->getTriangleCount()); @@ -2027,7 +2040,7 @@ GlCanvas::GlCanvas(MainWindow * mainWindow, int *args) } GlCanvas::~GlCanvas() { - delete this->context; + if(this->context) delete this->context; this->context = NULL; } @@ -2037,11 +2050,13 @@ void GlCanvas::setCurrentGLContext() { #if wxCHECK_VERSION(2, 9, 1) if(this->context == NULL) { this->context = new wxGLContext(this); + //printf("Set ctx [%p]\n",this->context); } #endif //printf("Set ctx [%p]\n",this->context); if(this->context) { wxGLCanvas::SetCurrent(*this->context); + //printf("Set ctx2 [%p]\n",this->context); } #else this->SetCurrent(); diff --git a/source/g3d_viewer/main.h b/source/g3d_viewer/main.h index d22020d58..e8142b8fa 100644 --- a/source/g3d_viewer/main.h +++ b/source/g3d_viewer/main.h @@ -201,6 +201,7 @@ public: void onKeyDown(wxKeyEvent &event); void setCurrentGLContext(); + wxGLContext * getCtx() { return context; } private: MainWindow *mainWindow; wxGLContext *context; diff --git a/source/g3d_viewer/renderer.cpp b/source/g3d_viewer/renderer.cpp index 86266a096..d8b7754ea 100644 --- a/source/g3d_viewer/renderer.cpp +++ b/source/g3d_viewer/renderer.cpp @@ -200,6 +200,10 @@ Model * Renderer::newModel(ResourceScope rs,const string &path,bool deletePixMap return modelManager->newModel(path,deletePixMapAfterLoad,loadedFileList,sourceLoader); } +void Renderer::endModel(ResourceScope rs,Model *model) { + modelManager->endModel(model); +} + void Renderer::init() { assertGl(); diff --git a/source/g3d_viewer/renderer.h b/source/g3d_viewer/renderer.h index c70b8eca6..f9a881461 100644 --- a/source/g3d_viewer/renderer.h +++ b/source/g3d_viewer/renderer.h @@ -147,6 +147,7 @@ public: Texture2D * getNewTexture2D(); Model *newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad=false,std::map > > *loadedFileList=NULL, string *sourceLoader=NULL); + void endModel(ResourceScope rs,Model *model); Texture2D *newTexture2D(ResourceScope rs) { return getNewTexture2D(); } void initTextureManager(); diff --git a/source/glest_game/ai/ai_rule.cpp b/source/glest_game/ai/ai_rule.cpp index 4894c8f83..e56a9106a 100644 --- a/source/glest_game/ai/ai_rule.cpp +++ b/source/glest_game/ai/ai_rule.cpp @@ -1224,7 +1224,7 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){ if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n",aiInterface->reqsOk(ct), this->getName().c_str()); if(aiInterface->reqsOk(ct)){ - defCt= ct; + //defCt= ct; producers.push_back(i); producersDefaultCommandType[i].push_back(ct); } @@ -1779,7 +1779,7 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt) { if(aiInterface->reqsOk(bct)) { builders.push_back(i); buildersDefaultCommandType[i].push_back(bct); - defBct= bct; + //defBct= bct; } } } diff --git a/source/glest_game/facilities/components.cpp b/source/glest_game/facilities/components.cpp index b94e37947..955f426d5 100644 --- a/source/glest_game/facilities/components.cpp +++ b/source/glest_game/facilities/components.cpp @@ -281,6 +281,8 @@ GraphicLabel::GraphicLabel() { editModeEnabled = false; maxEditWidth = -1; maxEditRenderWidth = -1; + renderBackground = false; + backgroundColor=Vec4f(0.2f,0.2f,0.2f,0.6f); isPassword = false; texture = NULL; } @@ -339,6 +341,7 @@ const int GraphicButton::defW= 90; GraphicButton::GraphicButton(std::string containerName, std::string objName) : GraphicComponent(containerName,objName) { lighted = false; + alwaysLighted = false; useCustomTexture = false; customTexture = NULL; } @@ -615,7 +618,7 @@ bool GraphicListBox::mouseClick(int x, int y,string advanceToItemStartingWith) { // class GraphicMessageBox // ===================================================== -const int GraphicMessageBox::defH= 240; +const int GraphicMessageBox::defH= 280; const int GraphicMessageBox::defW= 350; GraphicMessageBox::GraphicMessageBox(std::string containerName, std::string objName) : @@ -836,7 +839,7 @@ void GraphicScrollBar::init(int x, int y, bool horizontal,int length, int thickn bool GraphicScrollBar::mouseDown(int x, int y) { if(getVisible() && getEnabled() && getEditable()) { - if(activated) + if(activated && elementCount>0) { if( elementCount>visibleSize) { int pos; @@ -874,7 +877,10 @@ void GraphicScrollBar::setVisibleStart(int vs){ if(visibleStart<0) { visibleStart=0; } - float partSize=(float)getLength()/(float)elementCount; + float partSize = 0.f; + if(elementCount > 0) { + partSize = (float)getLength()/(float)elementCount; + } visibleCompPosStart=visibleStart*partSize; visibleCompPosEnd=visibleStart*partSize+visibleSize*partSize; if(visibleCompPosEnd>getLength()) { diff --git a/source/glest_game/facilities/components.h b/source/glest_game/facilities/components.h index 9bc43b69c..ef3e5898d 100644 --- a/source/glest_game/facilities/components.h +++ b/source/glest_game/facilities/components.h @@ -146,6 +146,8 @@ private: bool editModeEnabled; int maxEditWidth; int maxEditRenderWidth; + bool renderBackground; + Vec4f backgroundColor; vector textCharLength; bool isPassword; @@ -187,6 +189,11 @@ public: void setMaxEditWidth(int value) { maxEditWidth = value; } int getMaxEditWidth() const { return maxEditWidth; } + void setRenderBackground(bool value) { renderBackground = value; } + bool getRenderBackground() const { return renderBackground; } + Vec4f getBackgroundColor() const {return backgroundColor;} + void setBackgroundColor(Vec4f color) {this->backgroundColor= color;} + void setMaxEditRenderWidth(int value) { maxEditRenderWidth = value; } int getMaxEditRenderWidth() const { return maxEditRenderWidth; } @@ -205,6 +212,7 @@ public: private: bool lighted; + bool alwaysLighted; bool useCustomTexture; Texture *customTexture; @@ -219,9 +227,10 @@ public: void setUseCustomTexture(bool value) { useCustomTexture=value; } void setCustomTexture(Texture *value) { customTexture=value; } - bool getLighted() const {return lighted;} - + bool getLighted() const {return lighted||alwaysLighted;} void setLighted(bool lighted) {this->lighted= lighted;} + bool getAlwaysLighted() const {return alwaysLighted;} + void setAlwaysLighted(bool value) {this->alwaysLighted= value;} virtual bool mouseMove(int x, int y); }; diff --git a/source/glest_game/facilities/game_util.cpp b/source/glest_game/facilities/game_util.cpp index 55f8e3ec3..6fd7eead7 100644 --- a/source/glest_game/facilities/game_util.cpp +++ b/source/glest_game/facilities/game_util.cpp @@ -19,6 +19,7 @@ #include "platform_util.h" #include "conversion.h" #include "cache_manager.h" +#include "errno.h" #include "leak_dumper.h" using namespace Shared::Util; @@ -27,7 +28,13 @@ using namespace Shared::Platform; namespace Glest { namespace Game { const char *mailString = " http://bugs.megaglest.org"; -const string glestVersionString = "v3.10.0-dev"; + +// !! Use minor versions !! Only major and minor version control compatibility! +// typical version numbers look like this: v3.11-beta1.0 v3.12-dev v3.12.0 +// don't forget to update mk/linux/mg-version.sh +const string glestVersionString = "v3.11.0"; +const string lastCompatibleSaveGameVersionString = "v3.9.0"; + #if defined(GITVERSION) const string GIT_RawRev = string(GITVERSION); const string GIT_Rev = string("Rev: ") + string(GITVERSION); @@ -47,7 +54,7 @@ string getCrashDumpFileName(){ return "megaglest" + glestVersionString + ".dmp"; } -string getPlatformNameString() { +string getPlatformTypeNameString() { static string platform; if(platform == "") { #if defined(WIN32) @@ -89,27 +96,42 @@ string getPlatformNameString() { #else platform = "???"; #endif + } + return platform; +} + +string getPlatformArchTypeNameString() { + static string platform; + if(platform == "") { #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64) - platform += "-X64"; + platform = "-X64"; #elif defined(_M_ALPHA) || defined(__alpha__) - platform += "-ALPHA"; + platform = "-ALPHA"; #elif defined(_M_IA64) || defined(__ia64__) - platform += "-IA64"; + platform = "-IA64"; #elif defined(_M_MRX000) || defined(__mips__) - platform += "-MIPS"; + platform = "-MIPS"; #elif defined(_M_PPC) || defined(__powerpc__) - platform += "-POWERPC"; + platform = "-POWERPC"; #elif defined(__sparc__) - platform += "-SPARC"; + platform = "-SPARC"; #elif defined(_M_ARM_FP) || defined(__arm__) || defined(_M_ARM) - platform += "-ARM"; + platform = "-ARM"; #endif } return platform; } +string getPlatformNameString() { + static string platform; + if(platform == "") { + platform = getPlatformTypeNameString() + getPlatformArchTypeNameString(); + } + return platform; +} + string getGITRevisionString() { return GIT_Rev; } @@ -191,7 +213,7 @@ string getAboutString1(int i) { case 0: return "MegaGlest " + glestVersionString + " (" + "Shared Library " + sharedLibVersionString + ")"; case 1: return "Built: " + string(__DATE__) + " " + GIT_Rev; case 2: return "Copyright 2001-2010 The Glest Team"; - case 3: return "Copyright 2010-2014 The MegaGlest Team"; + case 3: return "Copyright 2010-2015 The MegaGlest Team"; } return ""; } @@ -349,4 +371,40 @@ void initSpecialStrings() { getCompileDateTime(); } +bool upgradeFilesInTemp() { + // Get path to temp files + string tempFilePath = "temp/"; + if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath; + } + else { + Config &config = Config::getInstance(); + string userData = config.getString("UserData_Root",""); + if(userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str()); + + // Move all files into binary folder + bool anyFailures = false; + vector fileList = getFolderTreeContentsListRecursively(tempFilePath, "", false, NULL); + for(unsigned int index = 0; index < fileList.size(); ++index) { + string fileName = fileList[index]; + string newFileName = Properties::getApplicationPath() + extractFileFromDirectoryPath(fileName); + bool result = renameFile(fileName,newFileName); + if(result == false) { + printf("FAILED Rename: [%s] to [%s] result = %d errno = %d\n",fileName.c_str(),newFileName.c_str(),result,errno); + + anyFailures = true; + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",fileName.c_str(),newFileName.c_str(),result); + } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Successfully updated!\n"); + + return (fileList.size() > 0 && anyFailures == false); +} + }}//end namespace diff --git a/source/glest_game/facilities/game_util.h b/source/glest_game/facilities/game_util.h index 059c74ea2..aab72efc2 100644 --- a/source/glest_game/facilities/game_util.h +++ b/source/glest_game/facilities/game_util.h @@ -29,10 +29,13 @@ namespace Glest{ namespace Game{ extern const char *mailString; extern const string glestVersionString; +extern const string lastCompatibleSaveGameVersionString; extern const string networkVersionString; void initSpecialStrings(); string getCrashDumpFileName(); +string getPlatformTypeNameString(); +string getPlatformArchTypeNameString(); string getPlatformNameString(); string getGITRevisionString(); string getRAWGITRevisionString(); @@ -51,6 +54,8 @@ string formatString(string str); string getGameReadWritePath(string lookupKey=""); string getGameCustomCoreDataPath(string originalBasePath, string uniqueFilePath); +bool upgradeFilesInTemp(); + }}//end namespace #endif diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index 4890cd69d..a9f10b75d 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -687,7 +687,7 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { // If > 50% of team vote yes, switch th eplayers team if(newTeamTotalMemberCount > 0 && newTeamVotedYes > 0 && - newTeamVotedYes / newTeamTotalMemberCount > 0.5) { + static_cast(newTeamVotedYes) / static_cast(newTeamTotalMemberCount) > 0.5) { Faction *faction = world->getFaction(factionIndex); int oldTeam = faction->getTeam(); faction->setTeam(vote->newTeam); @@ -765,21 +765,25 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); if(gameNetworkInterface != NULL) { ServerInterface *server = networkManager.getServerInterface(); - if(server->isClientConnected(playerIndex) == true) { + if(server != NULL && server->isClientConnected(playerIndex) == true) { MutexSafeWrapper safeMutex(server->getSlotMutex(playerIndex),CODE_AT_LINE); ConnectionSlot *slot = server->getSlot(playerIndex,false); if(slot != NULL) { - safeMutex.ReleaseLock(true); + safeMutex.ReleaseLock(); NetworkMessageQuit networkMessageQuit; slot->sendMessage(&networkMessageQuit); sleep(5); //printf("Sending nctDisconnectNetworkPlayer\n"); - safeMutex.Lock(); - slot = server->getSlot(playerIndex,false); - if(slot != NULL) { - slot->close(); + server = networkManager.getServerInterface(false); + if(server != NULL) { + MutexSafeWrapper safeMutex2(server->getSlotMutex(playerIndex),CODE_AT_LINE); + slot = server->getSlot(playerIndex,false); + if(slot != NULL) { + safeMutex2.ReleaseLock(); + slot->close(); + } } } } diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index a0fc693cb..e073ad025 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -115,6 +115,7 @@ Game::Game() : ProgramState(NULL) { renderFpsAvgTest=0; renderExtraTeamColor=0; photoModeEnabled=false; + healthbarMode=hbvUndefined; visibleHUD=false; timeDisplay=false; withRainEffect=false; @@ -190,11 +191,15 @@ void Game::resetMembers() { GameConstants::updateFps= 40; GameConstants::cameraFps= 100; captureAvgTestStatus = false; + updateFpsAvgTest=0; + renderFpsAvgTest=0; lastRenderLog2d = 0; - lastMasterServerGameStatsDump = 0; - totalRenderFps = 0; - lastMaxUnitCalcTime = 0; - renderExtraTeamColor = 0; + playerIndexDisconnect=0; + lastMasterServerGameStatsDump=0; + highlightCellTexture=NULL; + totalRenderFps =0; + lastMaxUnitCalcTime =0; + renderExtraTeamColor =0; mouseMoved= false; quitTriggeredIndicator = false; @@ -235,6 +240,7 @@ void Game::resetMembers() { scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5"); photoModeEnabled = Config::getInstance().getBool("PhotoMode","false"); + healthbarMode = Config::getInstance().getInt("HealthBarMode","0"); visibleHUD = Config::getInstance().getBool("VisibleHud","true"); timeDisplay = Config::getInstance().getBool("TimeDisplay","true"); withRainEffect = Config::getInstance().getBool("RainEffect","true"); @@ -269,6 +275,7 @@ void Game::resetMembers() { this->speed= 1; showFullConsole= false; setMarker = false; + cameraDragAllowed=false; camLeftButtonDown=false; camRightButtonDown=false; camUpButtonDown=false; @@ -309,6 +316,11 @@ Game::Game(Program *program, const GameSettings *gameSettings,bool masterserverM this->masterserverMode = masterserverMode; videoPlayer = NULL; playingStaticVideo = false; + highlightCellTexture = NULL; + playerIndexDisconnect=0; + updateFpsAvgTest=0; + renderFpsAvgTest=0; + cameraDragAllowed=false; if(this->masterserverMode == true) { printf("Starting a new game...\n"); @@ -328,6 +340,7 @@ void Game::endGame() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); quitGame(); + sleep(0); Object::setStateCallback(NULL); thisGamePtr = NULL; @@ -1242,7 +1255,8 @@ void Game::init(bool initForPreviewOnly) { //message box errorMessageBox.init(lang.getString("Ok")); errorMessageBox.setEnabled(false); - errorMessageBox.setY(mainMessageBox.getY() - mainMessageBox.getH() - 10); + errorMessageBox.setY(20); + //init world, and place camera commander.init(&world); @@ -2169,7 +2183,7 @@ void Game::update() { } if(currentCameraFollowUnit != NULL) { - Vec3f c=currentCameraFollowUnit->getCurrVector(); + Vec3f c=currentCameraFollowUnit->getCurrMidHeightVector(); int rotation=currentCameraFollowUnit->getRotation(); float angle=rotation+180; @@ -4109,8 +4123,7 @@ void Game::mouseDownLeft(int x, int y) { if(setMarker) { Vec2i targetPos; Vec2i screenPos(x,y-60); - Renderer &renderer= Renderer::getInstance(); - renderer.computePosition(screenPos, targetPos); + targetPos=getMouseCellPos(); //Vec2i surfaceCellPos = map->toSurfCoords(targetPos); @@ -4124,8 +4137,7 @@ void Game::mouseDownLeft(int x, int y) { if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) { Vec2i targetPos; Vec2i screenPos(x,y-60); - Renderer &renderer= Renderer::getInstance(); - renderer.computePosition(screenPos, targetPos); + targetPos=getMouseCellPos(); Vec2i surfaceCellPos = map->toSurfCoords(targetPos); MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note",world.getThisFaction()->getStartLocationIndex()); @@ -4139,14 +4151,13 @@ void Game::mouseDownLeft(int x, int y) { chatManager.switchOnEdit(this,500); //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - renderer.forceQuadCacheUpdate(); + Renderer::getInstance().forceQuadCacheUpdate(); } if(originalIsUnMarkCellEnabled == true && isUnMarkCellEnabled == true) { Vec2i targetPos; Vec2i screenPos(x,y-35); - Renderer &renderer= Renderer::getInstance(); - renderer.computePosition(screenPos, targetPos); + targetPos=getMouseCellPos(); Vec2i surfaceCellPos = map->toSurfCoords(targetPos); // if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) { @@ -4164,7 +4175,7 @@ void Game::mouseDownLeft(int x, int y) { //Renderer &renderer= Renderer::getInstance(); //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - renderer.forceQuadCacheUpdate(); + Renderer::getInstance().forceQuadCacheUpdate(); } } } @@ -4246,9 +4257,8 @@ void Game::mouseDownRight(int x, int y) { else { Vec2i targetPos; Vec2i screenPos(x,y); - Renderer &renderer= Renderer::getInstance(); - renderer.computePosition(screenPos, targetPos); - if(renderer.computePosition(screenPos, targetPos) == true && + targetPos=getMouseCellPos(); + if(isValidMouseCellPos() == true && map->isInsideSurface(map->toSurfCoords(targetPos)) == true) { gui.mouseDownRightGraphics(x, y,false); } @@ -4508,7 +4518,7 @@ void Game::mouseMove(int x, int y, const MouseState *ms) { lastMousePos.y = mouseY; Renderer &renderer= Renderer::getInstance(); - renderer.computePosition(Vec2i(mouseX, mouseY), mouseCellPos); + renderer.ccomputePosition(Vec2i(mouseX, mouseY), mouseCellPos); } catch(const exception &ex) { char szBuf[8096]=""; @@ -4528,6 +4538,15 @@ void Game::mouseMove(int x, int y, const MouseState *ms) { } } +bool Game::isValidMouseCellPos() const{ + if(world.getMap() == NULL){ + return false; + } + else { + return world.getMap()->isInside(mouseCellPos); + } +} + void Game::eventMouseWheel(int x, int y, int zDelta) { if(this->masterserverMode == true) { return; @@ -4566,7 +4585,7 @@ void Game::startCameraFollowUnit() { if(currentUnit != NULL) { currentCameraFollowUnit = currentUnit; getGameCameraPtr()->setState(GameCamera::sUnit); - getGameCameraPtr()->setPos(currentCameraFollowUnit->getCurrVector()); + getGameCameraPtr()->setPos(currentCameraFollowUnit->getCurrMidHeightVector()); int rotation=currentCameraFollowUnit->getRotation(); getGameCameraPtr()->stop(); @@ -4655,6 +4674,39 @@ void Game::keyDown(SDL_KeyboardEvent key) { } } + //Toggle Healthbars + else if(isKeyPressed(configKeys.getSDLKey("ToggleHealthbars"),key, false) == true) { + switch (healthbarMode) { + case hbvUndefined: + healthbarMode=hbvOff; + console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsOff")); + break; + case hbvOff: + healthbarMode=hbvAlways; + console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsAlways")); + break; + case hbvAlways: + healthbarMode=hbvIfNeeded; + console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsIfNeeded")); + break; + case hbvIfNeeded: + healthbarMode=hbvSelected; + console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsSelected")); + break; + case hbvSelected: + healthbarMode=hbvSelected | hbvIfNeeded; + console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsSelectedOrNeeded")); + break; + case (hbvSelected | hbvIfNeeded): + healthbarMode=hbvUndefined; + console.addLine(lang.getString("Healthbar")+": "+lang.getString("HealthbarsFactionDefault")); + break; + default: + printf("In [%s::%s Line: %d] Toggle Healthbars Hotkey - Invalid Value. Setting to default.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + healthbarMode=hbvUndefined; + break; + } + } //Toggle music //else if(key == configKeys.getCharKey("ToggleMusic")) { else if(isKeyPressed(configKeys.getSDLKey("ToggleMusic"),key, false) == true) { @@ -5205,7 +5257,7 @@ void Game::render3d(){ if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); //selection circles - renderer.renderSelectionEffects(); + renderer.renderSelectionEffects(healthbarMode); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSelectionEffects]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); @@ -5256,6 +5308,11 @@ void Game::render3d(){ if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderParticleManager]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + //renderOnTopBars (aka Healthbars) + if(photoModeEnabled == false) { + renderer.renderHealthBars(healthbarMode); + } + //mouse 3d renderer.renderMouse3d(); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderMouse3d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis()); @@ -5411,11 +5468,11 @@ string Game::getDebugStats(std::map &factionDebugInfo) { factionInfo += " [" + formatString(this->gameSettings.getFactionTypeName(i)) + " team: " + intToStr(this->gameSettings.getTeam(i)) + "]"; -// bool showResourceDebugInfo = false; +// bool showResourceDebugInfo = true; // if(showResourceDebugInfo == true) { // factionInfo +=" res: "; // for(int j = 0; j < world.getTechTree()->getResourceTypeCount(); ++j) { -// factionInfo += intToStr(world.getFaction(i)->getResource(j)->getAmount()); +// factionInfo += world.getFaction(i)->getResource(j)->getType()->getName()+":"+intToStr(world.getFaction(i)->getResource(j)->getAmount()); // factionInfo += " "; // } // } @@ -5629,7 +5686,7 @@ void Game::render2d() { if(this->masterserverMode == false) { renderer.renderResourceStatus(); } - renderer.renderConsole(&console,showFullConsole); + renderer.renderConsole(&console,showFullConsole?consoleFull:consoleNormal); } //2d mouse @@ -6650,7 +6707,7 @@ void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,cons Lang &lang= Lang::getInstance(); string gameVer = versionNode->getAttribute("version")->getValue(); - if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false) { + if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false){ char szBuf[8096]=""; snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str()); throw megaglest_runtime_error(szBuf,true); @@ -6711,7 +6768,10 @@ void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,cons Lang &lang= Lang::getInstance(); string gameVer = versionNode->getAttribute("version")->getValue(); - if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false) { + // this is the version check for loading normal save games from menu_state_load_game + if (gameVer != glestVersionString + && (compareMajorMinorVersion(gameVer, lastCompatibleSaveGameVersionString) < 0 + || compareMajorMinorVersion(glestVersionString, gameVer) < 0)) { char szBuf[8096]=""; snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str()); throw megaglest_runtime_error(szBuf,true); @@ -6729,6 +6789,12 @@ void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,cons XmlNode *selectionNode = guiNode->getChild("Selection"); XmlNode *statsNode = worldNode->getChild("Stats"); XmlNode *minimapNode = worldNode->getChild("Minimap"); + + if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false){ + char szBuf[8096]=""; + snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str()); + throw megaglest_runtime_error(szBuf,true); + } // This is explored fog of war for the host player, clear it minimapNode->clearChild("fowPixmap1"); @@ -6801,7 +6867,13 @@ void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,cons newGame->tickCount = gameNode->getAttribute("tickCount")->getIntValue(); //bool paused; - newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0; + if(newGame->inJoinGameLoading==true){ + newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0; + }else{ + //newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0; + newGame->paused = true; + } + if(newGame->paused) newGame->console.addLine(lang.getString("GamePaused")); //bool gameOver; newGame->gameOver = gameNode->getAttribute("gameOver")->getIntValue() != 0; //bool renderNetworkStatus; diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 1ebfc6c61..a3b22d9cc 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -141,6 +141,7 @@ private: static const int renderTeamColorPlaneBit=2; bool photoModeEnabled; + int healthbarMode; bool visibleHUD; bool timeDisplay; bool withRainEffect; @@ -256,6 +257,9 @@ public: Program *getProgram() {return program;} + Vec2i getMouseCellPos() const {return mouseCellPos;} + bool isValidMouseCellPos() const; + void removeUnitFromSelection(const Unit *unit); bool addUnitToSelection(Unit *unit); void addUnitToGroupSelection(Unit *unit,int groupIndex); diff --git a/source/glest_game/game/game_constants.h b/source/glest_game/game/game_constants.h index eb0bd2198..7e4daeedd 100644 --- a/source/glest_game/game/game_constants.h +++ b/source/glest_game/game/game_constants.h @@ -144,6 +144,7 @@ public: static const char *folder_path_tutorials; static const char *NETWORK_SLOT_UNCONNECTED_SLOTNAME; + static const char *NETWORK_SLOT_CLOSED_SLOTNAME; static const char *folder_path_screenshots; diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index 7b2e31372..37947383f 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -85,6 +85,7 @@ enum NetworkPlayerStatusType { class GameSettings { private: + string gameName; string description; string map; string tileset; @@ -189,6 +190,7 @@ public: // default copy constructor will do fine, and will maintain itself ;) //get + const string &getGameName() const {return gameName;} const string &getDescription() const {return description;} const string &getMap() const {return map;} const string &getTileset() const {return tileset;} @@ -394,6 +396,7 @@ public: const string &getGameUUID() const {return gameUUID;} //set + void setGameName(const string& gameName) {this->gameName= gameName;} void setDescription(const string& description) {this->description= description;} void setMap(const string& map) {this->map= map;} void setTileset(const string& tileset) {this->tileset= tileset;} @@ -556,6 +559,7 @@ public: string result = ""; result += "Game ID = " + gameUUID + "\n"; + result += "gameName = " + gameName + "\n"; result += "description = " + description + "\n"; result += "mapFilterIndex = " + intToStr(mapFilterIndex) + "\n"; result += "map = " + map + "\n"; @@ -613,6 +617,8 @@ public: gameSettingsNode->addAttribute("gameUUID",gameUUID, mapTagReplacements); +// string gameName; + gameSettingsNode->addAttribute("gameName",gameName, mapTagReplacements); // string description; gameSettingsNode->addAttribute("description",description, mapTagReplacements); // string map; @@ -750,6 +756,13 @@ public: gameUUID = gameSettingsNode->getAttribute("gameUUID")->getValue(); } +// string gameName; + if(gameSettingsNode->hasAttribute("gameName") == true) { + gameName = gameSettingsNode->getAttribute("gameName")->getValue(); + } + else { + gameName = "oldSavegame"; + } // string description; description = gameSettingsNode->getAttribute("description")->getValue(); // string map; diff --git a/source/glest_game/game/script_manager.cpp b/source/glest_game/game/script_manager.cpp index 61aed8140..20e133e51 100644 --- a/source/glest_game/game/script_manager.cpp +++ b/source/glest_game/game/script_manager.cpp @@ -252,6 +252,7 @@ void ScriptManager::init(World* world, GameCamera *gameCamera, const XmlNode *ro luaScript.registerFunction(shakeCameraOnUnit, "shakeCameraOnUnit"); luaScript.registerFunction(createUnit, "createUnit"); luaScript.registerFunction(createUnitNoSpacing, "createUnitNoSpacing"); + luaScript.registerFunction(setLockedUnitForFaction, "setLockedUnitForFaction"); luaScript.registerFunction(destroyUnit, "destroyUnit"); luaScript.registerFunction(giveKills, "giveKills"); luaScript.registerFunction(morphToUnit, "morphToUnit"); @@ -1032,8 +1033,11 @@ void ScriptManager::shakeCamera(int shakeIntensity, int shakeDuration, bool came if (cameraDistanceAffected) { Unit *unit = world->findUnitById(unitId); - gameCamera->shake(shakeDuration, shakeIntensity,cameraDistanceAffected, unit->getCurrVector()); - } else { + if(unit) { + gameCamera->shake(shakeDuration, shakeIntensity,cameraDistanceAffected, unit->getCurrMidHeightVector()); + } + } + else { gameCamera->shake(shakeDuration, shakeIntensity,cameraDistanceAffected, Vec3f(0.f,0.f,0.f)); } } @@ -1048,6 +1052,16 @@ void ScriptManager::createUnitNoSpacing(const string &unitName, int factionIndex world->createUnit(unitName, factionIndex, pos, false); } +void ScriptManager::setLockedUnitForFaction(const string &unitName, int factionIndex , bool lock){ + if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%s] factionIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unitName.c_str(),factionIndex); + if(world->getFactionCount()>factionIndex) { + const UnitType *ut= world->getFaction(factionIndex)->getType()->getUnitType(unitName); + world->getFaction(factionIndex)->setLockedUnitForFaction(ut,lock); + } else { + throw megaglest_runtime_error("Invalid faction index in setLockedUnitForFaction: " + intToStr(factionIndex),true); + } +} + void ScriptManager::destroyUnit(int unitId){ if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unitId); Unit *unit = world->findUnitById(unitId); @@ -1531,7 +1545,12 @@ int ScriptManager::getUnitFaction(int unitId) { const string ScriptManager::getUnitName(int unitId) { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return world->findUnitById(unitId)->getType()->getName(false); + string result = ""; + Unit *unit = world->findUnitById(unitId); + if(unit) { + result = world->findUnitById(unitId)->getType()->getName(false); + } + return result; } const string ScriptManager::getUnitDisplayName(int unitId) { @@ -1715,7 +1734,7 @@ int ScriptManager::isFreeCellsOrHasUnit(int field, int unitId, Vec2i pos) { if(unit == NULL) { throw megaglest_runtime_error("unit == NULL",true); } - int result = world->getMap()->isFreeCellsOrHasUnit(pos,unit->getType()->getSize(),static_cast(field),unit,NULL,true); + int result = world->getMap()->isFreeCellsOrHasUnit(pos,unit->getType()->getSize(),static_cast(field),unit); if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s] unitId = %d, [%s] pos [%s] field = %d result = %d\n",__FUNCTION__,unitId,unit->getType()->getName(false).c_str(),pos.getString().c_str(),field,result); @@ -1725,7 +1744,7 @@ int ScriptManager::isFreeCellsOrHasUnit(int field, int unitId, Vec2i pos) { int ScriptManager::isFreeCells(int unitSize, int field, Vec2i pos) { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - int result = world->getMap()->isFreeCellsOrHasUnit(pos,unitSize,static_cast(field),NULL,NULL,true); + int result = world->getMap()->isFreeCellsOrHasUnit(pos,unitSize,static_cast(field),NULL); if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s] unitSize = %d, pos [%s] field = %d result = %d\n",__FUNCTION__,unitSize,pos.getString().c_str(),field,result); @@ -2320,6 +2339,33 @@ int ScriptManager::destroyUnit(LuaHandle* luaHandle) { return luaArguments.getReturnCount(); } + +int ScriptManager::setLockedUnitForFaction(LuaHandle* luaHandle) { + LuaArguments luaArguments(luaHandle); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%s] factionIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,luaArguments.getString(-3).c_str(),luaArguments.getInt(-2)); + + try { + thisScriptManager->setLockedUnitForFaction( + luaArguments.getString(-3), + luaArguments.getInt(-2), + (luaArguments.getInt(-1) == 0 ? false : true)); + } + catch(const megaglest_runtime_error &ex) { + char szErrBuf[8096]=""; + snprintf(szErrBuf,8096,"In [%s::%s %d]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + string sErrBuf = string(szErrBuf) + string("\nThe game may no longer be stable!\nerror [") + string(ex.what()) + string("]\n"); + + SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,sErrBuf.c_str()); + + thisScriptManager->addMessageToQueue(ScriptManagerMessage(sErrBuf.c_str(), "error",-1,-1,true)); + thisScriptManager->onMessageBoxOk(false); + } + + return luaArguments.getReturnCount(); +} + int ScriptManager::giveKills(LuaHandle* luaHandle) { LuaArguments luaArguments(luaHandle); diff --git a/source/glest_game/game/script_manager.h b/source/glest_game/game/script_manager.h index c95f1430c..53141d813 100644 --- a/source/glest_game/game/script_manager.h +++ b/source/glest_game/game/script_manager.h @@ -282,6 +282,7 @@ private: void createUnit(const string &unitName, int factionIndex, Vec2i pos); void createUnitNoSpacing(const string &unitName, int factionIndex, Vec2i pos); + void setLockedUnitForFaction(const string &unitName, int factionIndex , bool lock); void destroyUnit(int unitId); void giveKills(int unitId, int amount); void morphToUnit(int unitId,const string &morphName, int ignoreRequirements); @@ -448,6 +449,7 @@ private: static int createUnit(LuaHandle* luaHandle); static int createUnitNoSpacing(LuaHandle* luaHandle); + static int setLockedUnitForFaction(LuaHandle* luaHandle); static int destroyUnit(LuaHandle* luaHandle); static int giveKills(LuaHandle* luaHandle); static int morphToUnit(LuaHandle* luaHandle); diff --git a/source/glest_game/global/config.cpp b/source/glest_game/global/config.cpp index 2f75caeda..be21d2729 100644 --- a/source/glest_game/global/config.cpp +++ b/source/glest_game/global/config.cpp @@ -44,6 +44,7 @@ const char *GameConstants::folder_path_tilesets = "tilesets"; const char *GameConstants::folder_path_tutorials = "tutorials"; const char *GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME = "???"; +const char *GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME = "Closed"; const char *GameConstants::folder_path_screenshots = "screens/"; diff --git a/source/glest_game/global/core_data.cpp b/source/glest_game/global/core_data.cpp index 6315d5d0d..3c4153095 100644 --- a/source/glest_game/global/core_data.cpp +++ b/source/glest_game/global/core_data.cpp @@ -78,6 +78,9 @@ CoreData::CoreData() { statusNotReadyTexture=NULL; statusBRBTexture=NULL; + healthbarTexture=NULL; + healthbarBackgroundTexture=NULL; + miscTextureList.clear(); displayFont=NULL; @@ -114,30 +117,30 @@ void CoreData::cleanup() { waterSounds.getSoundsPtr()->clear(); } -Texture2D *CoreData::getTextureBySystemId(TextureSystemType type) const { +Texture2D *CoreData::getTextureBySystemId(TextureSystemType type) { Texture2D *result = NULL; switch(type) { case tsyst_logoTexture: - result = logoTexture; + result = getLogoTexture(); break; //std::vector logoTextureList; case tsyst_backgroundTexture: - result = backgroundTexture; + result = getBackgroundTexture(); break; case tsyst_fireTexture: - result = fireTexture; + result = getFireTexture(); break; case tsyst_teamColorTexture: - result = teamColorTexture; + result = getTeamColorTexture(); break; case tsyst_snowTexture: - result = snowTexture; + result = getSnowTexture(); break; case tsyst_waterSplashTexture: - result = waterSplashTexture; + result = getWaterSplashTexture(); break; case tsyst_customTexture: - result = customTexture; + result = getCustomTexture(); break; case tsyst_buttonSmallTexture: result = buttonSmallTexture; @@ -181,6 +184,12 @@ Texture2D *CoreData::getTextureBySystemId(TextureSystemType type) const { case tsyst_statusBRBTexture: result = statusBRBTexture; break; + case tsyst_healthbarTexture: + result = healthbarTexture; + break; + case tsyst_healthbarBackgroundTexture: + result = healthbarBackgroundTexture; + break; //std::vector miscTextureList; } @@ -417,6 +426,24 @@ Texture2D *CoreData::getGameWinnerTexture() { return gameWinnerTexture; } +Texture2D *CoreData::getHealthbarTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&healthbarTexture,data_path, + CORE_MISC_TEXTURES_PATH + "healthbar.png", tsyst_healthbarTexture, + true, false, false, true); + + return healthbarTexture; +} + +Texture2D *CoreData::getHealthbarBackgroundTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&healthbarBackgroundTexture,data_path, + CORE_MISC_TEXTURES_PATH + "healthbarBackground.png", tsyst_healthbarBackgroundTexture, + true, false, false, true); + + return healthbarBackgroundTexture; +} + void CoreData::loadLogoTextureExtraIfRequired() { int loadAttemptLookupKey = tsyst_COUNT + 1; if(itemLoadAttempted.find(loadAttemptLookupKey) == itemLoadAttempted.end()) { diff --git a/source/glest_game/global/core_data.h b/source/glest_game/global/core_data.h index b184338e7..f8e415595 100644 --- a/source/glest_game/global/core_data.h +++ b/source/glest_game/global/core_data.h @@ -78,6 +78,9 @@ private: Texture2D *statusNotReadyTexture; Texture2D *statusBRBTexture; + Texture2D *healthbarTexture; + Texture2D *healthbarBackgroundTexture; + std::vector miscTextureList; Font2D *displayFont; @@ -133,6 +136,8 @@ public: tsyst_statusReadyTexture, tsyst_statusNotReadyTexture, tsyst_statusBRBTexture, + tsyst_healthbarTexture, + tsyst_healthbarBackgroundTexture, tsyst_COUNT }; @@ -147,7 +152,7 @@ public: void loadFonts(); // Textures - Texture2D *getTextureBySystemId(TextureSystemType type) const; + Texture2D *getTextureBySystemId(TextureSystemType type); Texture2D *getBackgroundTexture(); Texture2D *getFireTexture(); @@ -171,6 +176,9 @@ public: Texture2D *getStatusBRBTexture(); Texture2D *getGameWinnerTexture(); + Texture2D *getHealthbarTexture(); + Texture2D *getHealthbarBackgroundTexture(); + size_t getLogoTextureExtraCount(); Texture2D *getLogoTextureExtra(int idx); diff --git a/source/glest_game/graphics/particle_type.cpp b/source/glest_game/graphics/particle_type.cpp index 5c6e67f03..12caa3560 100644 --- a/source/glest_game/graphics/particle_type.cpp +++ b/source/glest_game/graphics/particle_type.cpp @@ -305,6 +305,7 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){ for(Children::iterator i=children.begin(); i!=children.end(); ++i){ UnitParticleSystem *child = new UnitParticleSystem(); child->setParticleOwner(ats->getParticleOwner()); + child->setParticleType((*i)); (*i)->setValues(child); ats->addChild(child); child->setState(ParticleSystem::sPlay); @@ -345,8 +346,12 @@ void ParticleSystemType::loadGame(const XmlNode *rootNode) { size = particleSystemTypeNode->getAttribute("size")->getFloatValue(); sizeNoEnergy = particleSystemTypeNode->getAttribute("sizeNoEnergy")->getFloatValue(); speed = particleSystemTypeNode->getAttribute("speed")->getFloatValue(); - speedUpRelative = particleSystemTypeNode->getAttribute("speedUpRelative")->getFloatValue(); - speedUpConstant = particleSystemTypeNode->getAttribute("speedUpConstant")->getFloatValue(); + if(particleSystemTypeNode->hasAttribute("speedUpRelative")){ + speedUpRelative = particleSystemTypeNode->getAttribute("speedUpRelative")->getFloatValue(); + } + if(particleSystemTypeNode->hasAttribute("speedUpConstant")){ + speedUpConstant = particleSystemTypeNode->getAttribute("speedUpConstant")->getFloatValue(); + } gravity = particleSystemTypeNode->getAttribute("gravity")->getFloatValue(); emissionRate = particleSystemTypeNode->getAttribute("emissionRate")->getFloatValue(); energyMax = particleSystemTypeNode->getAttribute("energyMax")->getIntValue(); @@ -367,7 +372,6 @@ void ParticleSystemType::loadGame(const XmlNode *rootNode) { children.push_back(child); } } - minmaxEnabled = (particleSystemTypeNode->getAttribute("minmaxEnabled")->getIntValue() != 0); minHp = particleSystemTypeNode->getAttribute("minHp")->getIntValue(); maxHp = particleSystemTypeNode->getAttribute("maxHp")->getIntValue(); diff --git a/source/glest_game/graphics/particle_type.h b/source/glest_game/graphics/particle_type.h index 6373e792c..0291cbbf7 100644 --- a/source/glest_game/graphics/particle_type.h +++ b/source/glest_game/graphics/particle_type.h @@ -52,7 +52,7 @@ class UnitParticleSystemType; /// A type of particle system // =========================================================== -class ParticleSystemType { +class ParticleSystemType : public ParticleSystemTypeInterface { protected: string type; Texture2D *texture; diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 8638650e2..79534fb9a 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -582,10 +582,15 @@ void Renderer::manageDeferredParticleSystems() { CoreData::TextureSystemType textureSystemId = static_cast( ps->getTextureFileLoadDeferredSystemId()); + + //printf("Load DEFERRED particle i = %d textureSystemId = %d\n",i,textureSystemId); + if(textureSystemId != CoreData::tsyst_NONE) { Texture2D *texture= CoreData::getInstance().getTextureBySystemId(textureSystemId); //printf("Loading texture from system [%d] [%p]\n",textureSystemId,texture); ps->setTexture(texture); + + //printf("#2 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture); } else { Texture2D *texture= newTexture2D(rs); @@ -601,6 +606,7 @@ void Renderer::manageDeferredParticleSystems() { texture->load(textureFile); ps->setTexture(texture); } + //printf("#3 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture); } } if(dynamic_cast(ps) != NULL) { @@ -977,7 +983,7 @@ bool Renderer::validateParticleSystemStillExists(ParticleSystem * particleSystem } void Renderer::removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner,ResourceScope rs) { - return particleManager[rs]->removeParticleSystemsForParticleOwner(particleOwner); + particleManager[rs]->removeParticleSystemsForParticleOwner(particleOwner); } void Renderer::cleanupParticleSystems(vector &particleSystems, ResourceScope rs) { @@ -1061,11 +1067,11 @@ void Renderer::setupLighting() { Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; if(world->toRenderUnit(unit) && - unit->getCurrVector().dist(gameCamera->getPos()) < maxLightDist && + unit->getCurrMidHeightVector().dist(gameCamera->getPos()) < maxLightDist && unit->getType()->getLight() && unit->isOperative()) { //printf("$$$ Show light for faction: %s # %d / %d for Unit [%d - %s]\n",world->getFaction(i)->getType()->getName().c_str(),lightCount,maxLights,unit->getId(),unit->getFullName().c_str()); - Vec4f pos= Vec4f(unit->getCurrVector()); + Vec4f pos= Vec4f(unit->getCurrMidHeightVector()); pos.y+=4.f; GLenum lightEnum= GL_LIGHT0 + lightCount; @@ -1642,11 +1648,11 @@ void Renderer::renderMouse2d(int x, int y, int anim, float fade) { if(game->isMarkCellMode() == true) { const Texture2D *texture= game->getMarkCellTexture(); - renderTextureQuad(x-18,y-50,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f); + renderTextureQuad(x,y,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f); } if(game->isUnMarkCellMode() == true) { const Texture2D *texture= game->getUnMarkCellTexture(); - renderTextureQuad(x-18,y-50,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f); + renderTextureQuad(x,y,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f); } } @@ -2082,8 +2088,7 @@ void Renderer::renderConsoleLine(int lineIndex, int xPosition, int yPosition, in xPosition, (lineIndex * lineHeight) + yPosition); } -void Renderer::renderConsole(const Console *console,const bool showFullConsole, - const bool showMenuConsole, int overrideMaxConsoleLines){ +void Renderer::renderConsole(const Console *console, ConsoleMode mode , int overrideMaxConsoleLines){ if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { return; } @@ -2095,7 +2100,7 @@ void Renderer::renderConsole(const Console *console,const bool showFullConsole, glPushAttrib(GL_ENABLE_BIT); glEnable(GL_BLEND); - if(showFullConsole) { + if(mode==consoleFull) { int x= console->getXPos()-5; int y= console->getYPos()-5; int h= console->getLineHeight()*console->getStoredLineCount(); @@ -2130,7 +2135,7 @@ void Renderer::renderConsole(const Console *console,const bool showFullConsole, } } } - else if(showMenuConsole) { + else if(mode==consoleStoredOnly) { int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines); for(int i = 0; i < console->getStoredLineCount() && i < allowedMaxLines; ++i) { const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); @@ -2144,7 +2149,39 @@ void Renderer::renderConsole(const Console *console,const bool showFullConsole, } } } - else { + else if(mode==consoleStoredAndNormal) { + int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines); + float starttimestamp=-1; + int consoleIndex=0; + for(int i = 0; i < console->getLineCount() && i < allowedMaxLines; ++i) { + const ConsoleLineInfo &lineInfo = console->getLineItem(i); + if(starttimestamp>lineInfo.timeStamp || starttimestamp==-1) starttimestamp=lineInfo.timeStamp; + if(renderText3DEnabled == true) { + renderConsoleLine3D(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); + } + else { + renderConsoleLine(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); + } + consoleIndex++; + } + for(int i = 0; i < console->getStoredLineCount() && consoleIndex < allowedMaxLines; ++i) { + const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); + if( lineInfo.timeStampgetXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); + } + else { + renderConsoleLine(consoleIndex, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); + } + consoleIndex++; + } + } + } + else if(mode==consoleNormal) { for(int i = 0; i < console->getLineCount(); ++i) { const ConsoleLineInfo &lineInfo = console->getLineItem(i); if(renderText3DEnabled == true) { @@ -2336,25 +2373,13 @@ void Renderer::renderClock() { } } -bool Renderer::renderResourcesInTeamMode() { - bool result = false; - - if(game != NULL && game->getGui() != NULL) { - - if(game->isFlagType1BitEnabled(ft1_allow_shared_team_units) == true || - game->isFlagType1BitEnabled(ft1_allow_shared_team_resources) == true) { - - result = true; - } - } - return result; -} void Renderer::renderResourceStatus() { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { return; } const World *world = game->getWorld(); + Config &config= Config::getInstance(); if(world->getThisFactionIndex() < 0 || world->getThisFactionIndex() >= world->getFactionCount()) { @@ -2368,64 +2393,45 @@ void Renderer::renderResourceStatus() { int rowsRendered = 0; int resourceCountRendered = 0; - for(int techTreeResourceTypeIndex = 0; - techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); - ++techTreeResourceTypeIndex) { + bool twoRessourceLines=false; - const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); + bool sharedTeamUnits = game != NULL && game->getGui() != NULL + && game->isFlagType1BitEnabled(ft1_allow_shared_team_units) + == true; + bool sharedTeamResources = game != NULL && game->getGui() != NULL + && game->isFlagType1BitEnabled( + ft1_allow_shared_team_resources) == true; - if ( rt->getDisplayInHud() == false ) { - continue; + bool renderSharedTeamResources=false; + bool renderSharedTeamUnits=false; + bool renderLocalFactionResources=false; + + if(config.getBool("TwoLineTeamResourceRendering","false") == true) { + if( sharedTeamResources == true || sharedTeamUnits == true){ + twoRessourceLines=true; } - - const Faction *factionForResourceView = thisFaction; - bool localFactionResourcesOnly = false; - - if(renderResourcesInTeamMode() == true) { - - const Gui *gui = game->getGui(); - if(gui != NULL) { - - const Selection *selection = gui->getSelection(); - if(selection != NULL && selection->getCount() > 0 && selection->getFrontUnit() != NULL) { - - const Unit *selectedUnit = selection->getFrontUnit(); -// if(selectedUnit != NULL && selectedUnit->getType()->hasSkillClass(scBeBuilt) == true) { -// -// if(selectedUnit->getFactionIndex() == thisFaction->getIndex() || -// selectedUnit->getFaction()->isAlly(thisFaction) == true) { -// -// factionForResourceView = selectedUnit->getFaction(); -// localFactionResourcesOnly = true; -// } -// } - - if(selectedUnit != NULL && selectedUnit->getFaction()->isAlly(thisFaction) == true) { - factionForResourceView = selectedUnit->getFaction(); - localFactionResourcesOnly = true; - } - } - else { - factionForResourceView = thisFaction; - localFactionResourcesOnly = true; - } - } + if(sharedTeamResources == true){ + renderSharedTeamResources=true; + renderSharedTeamUnits=true; } - - //if any unit produces the resource - bool showResource = world->showResourceTypeForFaction(rt, factionForResourceView, false); - if(showResource == true) { - rowsRendered = renderResource(factionForResourceView,localFactionResourcesOnly, - rt, 0, resourceCountRendered); + else if(sharedTeamUnits == true){ + renderSharedTeamUnits=true; + renderLocalFactionResources=true; + } + else{ + renderLocalFactionResources=true; } } + else { + if(sharedTeamResources == true) + renderSharedTeamResources=true; + else if(sharedTeamUnits == true) + renderSharedTeamUnits=true; + else + renderLocalFactionResources=true; + } - // If we rendered single player resources above and we are in team mode, - // lets render team totals next - if(renderResourcesInTeamMode() == true) { - if(rowsRendered > 0 || resourceCountRendered > 0) { - rowsRendered++; - } + if(renderSharedTeamResources == true) { resourceCountRendered = 0; for(int techTreeResourceTypeIndex = 0; techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); @@ -2437,15 +2443,92 @@ void Renderer::renderResourceStatus() { continue; } - const Faction *factionForResourceView = thisFaction; - bool localFactionResourcesOnly = false; - - bool showResource = world->showResourceTypeForFaction(rt, factionForResourceView, localFactionResourcesOnly); + bool showResource = world->showResourceTypeForTeam(rt, thisFaction->getTeam()); if(showResource == true) { - renderResource(factionForResourceView,localFactionResourcesOnly, - rt, rowsRendered, resourceCountRendered); + rowsRendered = renderResource(thisFaction, + false, twoRessourceLines, rt, 0, + resourceCountRendered); } } + if(resourceCountRendered > 0) { + rowsRendered++; + } + } + + if(renderLocalFactionResources == true){ + resourceCountRendered = 0; + + const Faction *factionForResourceView = thisFaction; + bool localFactionResourcesOnly = true; + + for(int techTreeResourceTypeIndex = 0; + techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); + ++techTreeResourceTypeIndex) { + const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); + if ( rt->getDisplayInHud() == false ) { + continue; + } + + //if any unit produces the resource + bool showResource; + if (twoRessourceLines) + showResource = world->showResourceTypeForTeam(rt, + factionForResourceView->getTeam()); + else + showResource = world->showResourceTypeForFaction(rt, + factionForResourceView); + if(showResource == true) { + renderResource(factionForResourceView, localFactionResourcesOnly, + twoRessourceLines, rt, rowsRendered, resourceCountRendered); + } + } + if(resourceCountRendered > 0) { + rowsRendered++; + } + } + + if(renderSharedTeamUnits == true){ + resourceCountRendered = 0; + + const Faction *factionForResourceView = thisFaction; + bool localFactionResourcesOnly = true; + + const Gui *gui = game->getGui(); + if(gui != NULL) { + const Selection *selection = gui->getSelection(); + if(selection != NULL && selection->getCount() > 0 && selection->getFrontUnit() != NULL) { + const Unit *selectedUnit = selection->getFrontUnit(); + if(selectedUnit != NULL && selectedUnit->getFaction()->isAlly(thisFaction) == true) { + factionForResourceView = selectedUnit->getFaction(); + } + } + } + + for(int techTreeResourceTypeIndex = 0; + techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); + ++techTreeResourceTypeIndex) { + const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); + if ( rt->getDisplayInHud() == false ) { + continue; + } + + //if any unit produces the resource + bool showResource; + if (twoRessourceLines) + showResource = world->showResourceTypeForTeam(rt, + factionForResourceView->getTeam()); + else + showResource = world->showResourceTypeForFaction(rt, + factionForResourceView); + + if(showResource == true) { + renderResource(factionForResourceView, localFactionResourcesOnly, + twoRessourceLines, rt, rowsRendered, resourceCountRendered); + } + } + if(resourceCountRendered > 0) { + rowsRendered++; + } } glPopAttrib(); @@ -2454,29 +2537,35 @@ void Renderer::renderResourceStatus() { } int Renderer::renderResource(const Faction *factionForResourceView,bool localFactionResourcesOnly, - const ResourceType *rt, int startRow, int &resourceCountRendered) { + bool twoResourceLines, const ResourceType *rt, int startRow, int &resourceCountRendered) { const Metrics &metrics = Metrics::getInstance(); + const int MAX_RESOURCES_PER_ROW = 6; + + int resourceRowHeigth=30; + int resourceYStart=metrics.getVirtualH()-30; + if(twoResourceLines){ + // we need to save some space + resourceYStart=metrics.getVirtualH()-22; + resourceRowHeigth=16; + } //draw resource status if(localFactionResourcesOnly == true) { - string str = "*"; Vec4f resourceFontColor = Vec4f(factionForResourceView->getTexture()->getPixmapConst()->getPixel3f(0,0)); int resourceCol = 0; int resourceRow = startRow; - if(renderText3DEnabled == true) { - renderTextShadow3D( - str, CoreData::getInstance().getDisplayFontSmall3D(), - resourceFontColor, - resourceCol * 100 + 190, metrics.getVirtualH()-30 - (30 * resourceRow), false); - } - else { - renderTextShadow( - str, CoreData::getInstance().getDisplayFontSmall(), - resourceFontColor, - resourceCol * 100 + 190, metrics.getVirtualH()-30 - (30 * resourceRow), false); - } + int x=resourceCol * 100 + 190; + int y=resourceYStart - (resourceRowHeigth * resourceRow); + int h=16; + int w=8; + glColor3f(resourceFontColor.x,resourceFontColor.y,resourceFontColor.z); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y+h); + glVertex2i(x, y); + glVertex2i(x+w, y+h/2); + glEnd(); } const Resource *r = factionForResourceView->getResource(rt,localFactionResourcesOnly); @@ -2495,17 +2584,14 @@ int Renderer::renderResource(const Faction *factionForResourceView,bool localFac isNegativeConsumableDisplayCycle = true; if(r->getBalance() * 1 + r->getAmount() < 0) { - glColor3f(RED.x,RED.y,RED.z); resourceFontColor = RED; } else if(r->getBalance() * 3 + r->getAmount() < 0) { - glColor3f(ORANGE.x,ORANGE.y,ORANGE.z); resourceFontColor = ORANGE; } else if(r->getBalance() * 5 + r->getAmount() < 0) { - glColor3f(YELLOW.x,YELLOW.y,YELLOW.z); resourceFontColor = YELLOW; } @@ -2516,11 +2602,11 @@ int Renderer::renderResource(const Faction *factionForResourceView,bool localFac if(isNegativeConsumableDisplayCycle == false) { glColor3f(1.f, 1.f, 1.f); } - const int MAX_RESOURCES_PER_ROW = 6; + int resourceRow = startRow + (resourceCountRendered > 0 ? resourceCountRendered / MAX_RESOURCES_PER_ROW : 0); int resourceCol = resourceCountRendered % MAX_RESOURCES_PER_ROW; - renderQuad(resourceCol * 100 + 200, metrics.getVirtualH()-30 - (30 * resourceRow), 16, 16, rt->getImage()); + renderQuad(resourceCol * 100 + 200, resourceYStart - (resourceRowHeigth * resourceRow), 16, 16, rt->getImage()); if(rt->getClass() != rcStatic) { str+= "/" + intToStr(factionForResourceView->getStoreAmount(rt,localFactionResourcesOnly)); @@ -2539,13 +2625,13 @@ int Renderer::renderResource(const Faction *factionForResourceView,bool localFac renderTextShadow3D( str, CoreData::getInstance().getDisplayFontSmall3D(), resourceFontColor, - resourceCol * 100 + 220, metrics.getVirtualH()-30 - (30 * resourceRow), false); + resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false); } else { renderTextShadow( str, CoreData::getInstance().getDisplayFontSmall(), resourceFontColor, - resourceCol * 100 + 220, metrics.getVirtualH()-30 - (30 * resourceRow), false); + resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false); } ++resourceCountRendered; @@ -3053,6 +3139,33 @@ void Renderer::renderLabel(GraphicLabel *label) { } } + if(label->getRenderBackground()) + { + int x= label->getX(); + int y= label->getY(); + int h= label->getH(); + int w= label->getW(); + if(label->getMaxEditRenderWidth()>0){ + w= label->getMaxEditRenderWidth(); + } + Vec4f color=label->getBackgroundColor(); + if(h>0){ + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(color.x, color.y, color.z, color.w*label->getFade()) ; + + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y); + glVertex2i(x, y+h); + glVertex2i(x+w, y); + glVertex2i(x+w, y+h); + glEnd(); + glPopAttrib(); + } + } + if(label->getTexture()!=NULL ) { int x= label->getX(); @@ -3701,6 +3814,7 @@ void Renderer::renderListBox(GraphicListBox *listBox) { } void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { + const int headerHeight=25; if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { return; } @@ -3732,18 +3846,18 @@ void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; glBegin(GL_TRIANGLE_STRIP); - glVertex2i(messageBox->getX(), messageBox->getY()+9*messageBox->getH()/10); + glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()-headerHeight); glVertex2i(messageBox->getX(), messageBox->getY()); - glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + 9*messageBox->getH()/10); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()-headerHeight); glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()); glEnd(); glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; glBegin(GL_TRIANGLE_STRIP); glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()); - glVertex2i(messageBox->getX(), messageBox->getY()+9*messageBox->getH()/10); + glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()-headerHeight); glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()); - glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()+9*messageBox->getH()/10); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()+messageBox->getH()-headerHeight); glEnd(); glBegin(GL_LINE_LOOP); @@ -3762,10 +3876,10 @@ void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { glBegin(GL_LINE_STRIP); glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ; - glVertex2i(messageBox->getX(), messageBox->getY() + 90*messageBox->getH()/100); + glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH()-headerHeight); glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + 90*messageBox->getH()/100); + glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH()-headerHeight); glEnd(); glPopAttrib(); @@ -3796,12 +3910,12 @@ void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { //text renderTextShadow3D( wrappedText, messageBox->getFont3D(), fontColor, - messageBox->getX()+15, messageBox->getY()+7*messageBox->getH()/10, + messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight*2, false ); renderTextShadow3D( messageBox->getHeader(), messageBox->getFont3D(),fontColor, - messageBox->getX()+15, messageBox->getY()+93*messageBox->getH()/100, + messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight+8, false ); } @@ -3809,12 +3923,12 @@ void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { //text renderTextShadow( wrappedText, messageBox->getFont(), fontColor, - messageBox->getX()+15, messageBox->getY()+7*messageBox->getH()/10, + messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight*2, false ); renderTextShadow( messageBox->getHeader(), messageBox->getFont(),fontColor, - messageBox->getX()+15, messageBox->getY()+93*messageBox->getH()/100, + messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight+8, false ); } } @@ -5393,7 +5507,7 @@ void Renderer::renderMorphEffects(){ -void Renderer::renderSelectionEffects() { +void Renderer::renderSelectionEffects(int healthbarMode) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { return; } @@ -5427,24 +5541,41 @@ void Renderer::renderSelectionEffects() { currVec.y+= 0.3f; //selection circle + int finalHealthbarMode = hbvUndefined; + if(healthbarMode == hbvUndefined) { + finalHealthbarMode = unit->getFaction()->getType()->getHealthbarVisible(); + } + else { + finalHealthbarMode = healthbarMode; + } + bool healthbarsVisible =((finalHealthbarMode & hbvAlways) || + (finalHealthbarMode & hbvSelected) || + (finalHealthbarMode & hbvIfNeeded)); + float selectionCircleThickness = 0.2f; + float hpRatio = unit->getHpRatio(); + if(healthbarsVisible) { + selectionCircleThickness = 0.05f; + hpRatio = 1.0f; + } + if(world->getThisFactionIndex() == unit->getFactionIndex()) { if( showDebugUI == true && ((showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) && unit->getCommandSize() > 0 && dynamic_cast(unit->getCurrCommand()->getCommandType()) != NULL) { - glColor4f(unit->getHpRatio(), unit->getHpRatio(), unit->getHpRatio(), 0.3f); + glColor4f(hpRatio, hpRatio, hpRatio, 0.3f); } else { - glColor4f(0, unit->getHpRatio(), 0, 0.3f); + glColor4f(0, hpRatio, 0, 0.3f); } } else if ( world->getThisTeamIndex() == unit->getTeam()) { - glColor4f(unit->getHpRatio(), unit->getHpRatio(), 0, 0.3f); + glColor4f(hpRatio, hpRatio, 0, 0.3f); } - else{ - glColor4f(unit->getHpRatio(), 0, 0, 0.3f); + else { + glColor4f(hpRatio, 0, 0, 0.3f); } - renderSelectionCircle(currVec, unit->getType()->getSize(), selectionCircleRadius); + renderSelectionCircle(currVec, unit->getType()->getSize(), selectionCircleRadius,selectionCircleThickness); if( showDebugUI == true && (showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) { @@ -5468,7 +5599,7 @@ void Renderer::renderSelectionEffects() { } //magic circle - if(world->getThisFactionIndex() == unit->getFactionIndex() && unit->getType()->getMaxEp() > 0) { + if(!healthbarsVisible && world->getThisFactionIndex() == unit->getFactionIndex() && unit->getType()->getMaxEp() > 0) { glColor4f(unit->getEpRatio()/2.f, unit->getEpRatio(), unit->getEpRatio(), 0.5f); renderSelectionCircle(currVec, unit->getType()->getSize(), magicCircleRadius); } @@ -5480,7 +5611,7 @@ void Renderer::renderSelectionEffects() { if(effect.skillType->isAttackBoostEnabled() == true) { glColor4f(MAGENTA.x,MAGENTA.y,MAGENTA.z,MAGENTA.w); - renderSelectionCircle(currVec, unit->getType()->getSize(), effect.skillType->getAttackBoost()->radius); + renderSelectionCircle(currVec, 1, effect.skillType->getAttackBoost()->radius, .25f/effect.skillType->getAttackBoost()->radius); for(unsigned int i = 0; i < effect.currentAttackBoostUnits.size(); ++i) { // Remove attack boost upgrades from unit @@ -5610,6 +5741,116 @@ void Renderer::renderSelectionEffects() { glPopAttrib(); } +void Renderer::renderHealthBars(int healthbarMode){ + if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config= Config::getInstance(); + if(config.getBool("RecordMode","false") == true) { + return; + } + + if(config.getBool("PhotoMode")) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glLineWidth(2.f); + + VisibleQuadContainerCache &qCache = getQuadCache(); + if(qCache.visibleQuadUnitList.empty() == false) { + for(int visibleUnitIndex = 0; + visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + if(isHealthBarVisible(unit,healthbarMode)) { + float healthbarheight; + float healthbarthickness; + const Texture2D *healthbarTexture; + const Texture2D *healthbarBackgroundTexture; + bool healthbarLineBorder; + + //get settings of the faction + healthbarheight=unit->getFaction()->getType()->getHealthbarHeight(); + healthbarthickness=unit->getFaction()->getType()->getHealthbarThickness(); + healthbarLineBorder=unit->getFaction()->getType()->isHealthbarLineBorder(); + CoreData &coreData= CoreData::getInstance(); + //First try faction texture then use core Texture + if(unit->getFaction()->getType()->isHealthbarBorderTextureEnabled()) { + healthbarTexture=unit->getFaction()->getType()->getHealthbarTexture(); + if(healthbarTexture==NULL) { + healthbarTexture=coreData.getHealthbarTexture(); + } + } else { + healthbarTexture=NULL; + } + if(unit->getFaction()->getType()->isHealthbarBackgroundTextureEnabled()) { + healthbarBackgroundTexture=unit->getFaction()->getType()->getHealthbarBackgroundTexture(); + if(healthbarBackgroundTexture==NULL) { + healthbarBackgroundTexture=coreData.getHealthbarBackgroundTexture(); + } + } else { + healthbarBackgroundTexture=NULL; + } + + //replace them by the ones from the unit if existent + if(unit->getType()->getHealthbarVisible()!=hbvOff && unit->getType()->getHealthbarVisible()!=hbvUndefined) { + if(unit->getType()->getHealthbarHeight()!=-100.0f) { + healthbarheight=unit->getType()->getHealthbarHeight(); + } + if(unit->getType()->getHealthbarThickness()!=-1.0f) { + healthbarthickness=unit->getType()->getHealthbarThickness(); + } + } + + Vec3f currVec= unit->getCurrVectorFlat(); + if(healthbarheight==-100.0f) { + currVec.y+=unit->getType()->getHeight(); + } else { + currVec.y+=healthbarheight; + } + renderHealthBar(currVec,unit,healthbarthickness,healthbarLineBorder,healthbarTexture,healthbarBackgroundTexture); + } + } + } + glPopAttrib(); +} + +bool Renderer::isHealthBarVisible(const Unit *unit,int healthbarMode){ + int healthbarVisible=hbvUndefined; + //check options (hotkey) + if(healthbarMode==hbvUndefined) { + healthbarVisible=unit->getFaction()->getType()->getHealthbarVisible(); + } else { + healthbarVisible=healthbarMode; + } + + //replace them by the ones from the unit if existent + if(unit->getType()->getHealthbarVisible()!=hbvOff && unit->getType()->getHealthbarVisible()!=hbvUndefined) { + if(healthbarMode==hbvUndefined) { //don't override the visible setting when hotkey is not hbvUndefined + healthbarVisible=unit->getType()->getHealthbarVisible(); + } + } + + bool settingsWantToRenderThem=!(healthbarVisible==hbvUndefined || (healthbarVisible&hbvOff)) + && ((healthbarVisible&hbvAlways) + || ((healthbarVisible&hbvIfNeeded) && unit->getHp()getType()->getMaxHp()+unit->getTotalUpgrade()->getMaxHp()) + || ((healthbarVisible&hbvIfNeeded) && unit->getType()->getMaxEp() > 0 && unit->getEp()getType()->getMaxEp()+unit->getTotalUpgrade()->getMaxEp()) + || ((healthbarVisible&hbvIfNeeded) && unit->getProductionPercent() > 0) + || ((healthbarVisible&hbvSelected) && game->getGui()->isSelected(unit))); + + if(unit->isAlive() && (settingsWantToRenderThem)) { + return true; + } + return false; +} + void Renderer::renderWaterEffects(){ if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { return; @@ -6193,7 +6434,7 @@ void Renderer::renderVisibleMarkedCells(bool renderTextHint,int x, int y) { std::map markedCells = game->getMapMarkedCellList(); if(markedCells.empty() == false) { const Texture2D *texture= game->getMarkCellTexture(); - const int yOffset = 10; + const int yOffset = -40; for(std::map::iterator iterMap =markedCells.begin(); iterMap != markedCells.end(); ++iterMap) { @@ -6684,7 +6925,7 @@ void Renderer::renderMenuBackground(Camera *camera, float fade, Model *mainModel // ==================== computing ==================== -bool Renderer::computePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords) { +bool Renderer::ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords) { assertGl(); const Map* map= game->getWorld()->getMap(); const Metrics &metrics= Metrics::getInstance(); @@ -6820,7 +7061,7 @@ void Renderer::selectUsingFrustumSelection(Selection::UnitContainer &units, visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; if(unit != NULL && unit->isAlive()) { - Vec3f unitPos = unit->getCurrVector(); + Vec3f unitPos = unit->getCurrMidHeightVector(); bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData, unitPos.x, unitPos.y, unitPos.z, unit->getType()->getRenderSize()); if(insideQuad == true) { @@ -7519,7 +7760,10 @@ vector Renderer::renderUnitsFast(bool renderingShadows, bool colorPickin renderOnlyBuildings=true; } else { - //glClear(GL_DEPTH_BUFFER_BIT); + if(colorPickingSelection == true){ + // clear depth buffer to get units behind buildings rendered in front of them + glClear(GL_DEPTH_BUFFER_BIT); + } //glEnable(GL_DEPTH_TEST); renderOnlyBuildings=false; } @@ -7527,6 +7771,11 @@ vector Renderer::renderUnitsFast(bool renderingShadows, bool colorPickin visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + if(renderingShadows==false && unit->isAlive()==false){ + // no need to render dead units for selection + continue; + } + if(renderOnlyBuildings==true && unit->getType()->hasSkillClass(scMove)){ continue; } @@ -8215,6 +8464,174 @@ void Renderer::enableProjectiveTexturing() { } // ==================== private aux drawing ==================== +void Renderer::renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture, const Texture2D *backgroundTexture) { + if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + int numberOfBars=1; + int barCount=0; + float hp=unit->getHpRatio(); + float ep=-1.f; + if(unit->getType()->getTotalMaxEp(unit->getTotalUpgrade()) !=0 ) { + ep=unit->getEpRatio(); + numberOfBars++; + } + int productionPercent=unit->getProductionPercent(); + if(productionPercent!=-1) { + numberOfBars++; + } + int size=unit->getType()->getSize(); + + + Vec3f rightVector; + Vec3f upVector; + Vec3f rightVectorTexture; + Vec3f upVectorTexture; + v.y+=1; + float modelview[16]; + float width=(float)size/6+0.25f; + float red; + float green; + float brightness=0.8f; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + // get the current modelview state + glGetFloatv(GL_MODELVIEW_MATRIX , modelview); + rightVector= Vec3f(modelview[0], modelview[4], modelview[8]); + upVector= Vec3f(modelview[1], modelview[5], modelview[9]); + rightVectorTexture=rightVector*2; + upVectorTexture=upVector*4; + + //from green to yellow to red + + if(hp >= 0.75f) { + green=1; + red=1-((2*hp-1)-0.5f); + } else { + red=1; + green=0.5f+(2*hp-1); + } + + if(red>1.0f) red=1.0f; + if(green>1.0f) green=1.0f; + float yOffset=(float)numberOfBars/2.f; + + if(backgroundTexture!=NULL) { + //backgroundTexture + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(backgroundTexture)->getHandle()); + glColor4f(1.f,1.f,1.f,1.f); + //glColor4f(red+0.1f,green+0.1f,0.1f,0.5f); + glBegin(GL_QUADS); + glTexCoord2i(0,1); + glVertex3fv((v - (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); + glTexCoord2i(0,0); + glVertex3fv((v - (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); + glTexCoord2i(1,0); + glVertex3fv((v + (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); + glTexCoord2i(1,1); + glVertex3fv((v + (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); + glEnd(); + glDisable(GL_TEXTURE_2D); + } + + //healthbar + glColor4f(red*brightness,green*brightness,0.0f,0.4f); + //hpbar + barCount++; + internalRenderHp(numberOfBars,barCount,hp,v,width,height,rightVector,upVector); + + + if(ep > -1.0f) { + //epbar + barCount++; + //glColor4f(brightness,0,brightness,0.5f); + glColor4f(.15f*brightness,0.3f*brightness,0.8f*brightness,0.7f); + internalRenderHp(numberOfBars,barCount,ep,v,width,height,rightVector,upVector); + } + if(productionPercent!=-1) { + barCount++; + glColor4f(brightness,0,brightness,0.6f); + //glColor4f(0.0f*brightness,0.4f*brightness,0.2f*brightness,0.8f); + internalRenderHp(numberOfBars,barCount,(float)productionPercent/100,v,width,height,rightVector,upVector); + } + + +// glBegin(GL_QUADS); +// if(ep < -2.0f) { +// //hpbar +// glVertex3fv((v - (rightVector*width - upVector*height)).ptr()); +// glVertex3fv((v - (rightVector*width + upVector*height)).ptr()); +// glVertex3fv((v + (rightVector*hp*width - upVector*height)).ptr()); +// glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr()); +// +// } else { +// //hpbar +// glVertex3fv((v - (rightVector*width - upVector*height)).ptr()); +// glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr()); +// glVertex3fv((v + (rightVector*hp*width - upVector*height*0.0f)).ptr()); +// glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr()); +// //epbar +// glColor4f(brightness,0,brightness,0.4f); +// glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr()); +// glVertex3fv((v - (rightVector*width + upVector*height)).ptr()); +// glVertex3fv((v + (rightVector*ep*width - upVector*height)).ptr()); +// glVertex3fv((v + (rightVector*ep*width - upVector*height*0.0f)).ptr()); +// } +// glEnd(); + + if(lineBorder) { + //border + glColor4f(red*brightness,green*brightness,0.1f*brightness,0.5f); + glBegin(GL_LINE_LOOP); + glVertex3fv((v - (rightVector*width - upVector*height*yOffset)).ptr()); + glVertex3fv((v - (rightVector*width + upVector*height*yOffset)).ptr()); + glVertex3fv((v + (rightVector*width - upVector*height*yOffset)).ptr()); + glVertex3fv((v + (rightVector*width + upVector*height*yOffset)).ptr()); + glEnd(); + } + + if(texture!=NULL) { + //BorderTexture + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); + glColor4f(1.f,1.f,1.f,1.f); + //glColor4f(red+0.1f,green+0.1f,0.1f,0.5f); + glBegin(GL_QUADS); + glTexCoord2i(0,1); + glVertex3fv((v - (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); + glTexCoord2i(0,0); + glVertex3fv((v - (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); + glTexCoord2i(1,0); + glVertex3fv((v + (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); + glTexCoord2i(1,1); + glVertex3fv((v + (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); + glEnd(); + glDisable(GL_TEXTURE_2D); + } + + glPopMatrix(); +} + +void Renderer::internalRenderHp(int numberOfBars, int barNumber, float hp, + Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector) { + + float yOffset=(float)numberOfBars*singleHPheight/2; + float offsetTop=yOffset-singleHPheight*(barNumber-1); + float offsetBottom=yOffset-singleHPheight*barNumber; + offsetBottom=offsetBottom*-1; + hp=hp*2-1; + + glBegin(GL_QUADS); + glVertex3fv((posVector - (rightVector*width - upVector*offsetTop)).ptr()); + glVertex3fv((posVector - (rightVector*width + upVector*offsetBottom)).ptr()); + glVertex3fv((posVector + (rightVector*hp*width - upVector*offsetBottom)).ptr()); + glVertex3fv((posVector + (rightVector*hp*width + upVector*offsetTop)).ptr()); + glEnd(); +} void Renderer::renderSelectionCircle(Vec3f v, int size, float radius, float thickness) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { @@ -8234,6 +8651,13 @@ void Renderer::renderSelectionCircle(Vec3f v, int size, float radius, float thic gluDeleteQuadric(disc); glPopMatrix(); + // glBegin (GL_QUAD_STRIP); + // for (float k = 0; k <= 180; k=k+1) { + // float j=degToRad(k); + // glVertex3f(v.x+std::cos(j)*.9*radius*size, v.y+thickness, v.z+std::sin(j)*.9*radius*size); + // glVertex3f(v.x+std::cos(j)*radius*size, v.y, v.z+std::sin(j)*radius*size); + // } + // glEnd(); } void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2, @@ -8697,7 +9121,7 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame, bool unitCheckedForRender = false; if(VisibleQuadContainerCache::enableFrustumCalcs == true) { //bool insideQuad = PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z ); - bool insideQuad = CubeInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z, unit->getType()->getRenderSize()); + bool insideQuad = CubeInFrustum(quadCache.frustumData, unit->getCurrMidHeightVector().x, unit->getCurrMidHeightVector().y, unit->getCurrMidHeightVector().z, unit->getType()->getRenderSize()); bool renderInMap = world->toRenderUnit(unit); if(insideQuad == false || renderInMap == false) { unit->setVisible(false); @@ -9423,6 +9847,9 @@ Texture2D * Renderer::findTexture(string logoFilename) { void Renderer::cycleShowDebugUILevel() { //printf("#1 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles); + //if(showDebugUI == false) { + // showDebugUI = true; + //} if((showDebugUILevel & debugui_fps) != debugui_fps || (showDebugUILevel & debugui_unit_titles) != debugui_unit_titles) { showDebugUILevel |= debugui_fps; diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index ad7223b74..9a5f98147 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -183,6 +183,15 @@ public: //uint32 m_nVBOIndexes; // Indexes VBO Name }; +enum ConsoleMode { + consoleOff, + consoleNormal, + consoleFull, + consoleStoredOnly, + consoleStoredAndNormal, + + consoleCount +}; class Renderer : public RendererInterface, public BaseRenderer, @@ -496,7 +505,7 @@ public: void renderBackground(const Texture2D *texture); void renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha=1.f,const Vec3f *color=NULL); - void renderConsole(const Console *console, const bool showAll=false, const bool showMenuConsole=false, int overrideMaxConsoleLines=-1); + void renderConsole(const Console *console, ConsoleMode mode=consoleNormal, int overrideMaxConsoleLines=-1); void renderConsoleLine3D(int lineIndex, int xPosition, int yPosition, int lineHeight, Font3D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); void renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); @@ -548,7 +557,8 @@ public: void renderUnits(bool airUnits, const int renderFps); void renderUnitsToBuild(const int renderFps); - void renderSelectionEffects(); + void renderSelectionEffects(int healthbarMode); + void renderHealthBars(int healthbarMode); void renderWaterEffects(); void renderHud(); void renderMinimap(); @@ -558,7 +568,7 @@ public: void renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector characterModels,const Vec3f characterPosition, float anim); //computing - bool computePosition(const Vec2i &screenPos, Vec2i &worldPos,bool exactCoords=false); + bool ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos,bool exactCoords=false); void computeSelected(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp); void selectUsingColorPicking(Selection::UnitContainer &units, const Object *&obj,const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp); void selectUsingSelectionBuffer(Selection::UnitContainer &units,const Object *&obj, const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp); @@ -680,6 +690,9 @@ private: //private aux drawing void renderSelectionCircle(Vec3f v, int size, float radius, float thickness=0.2f); + bool isHealthBarVisible(const Unit *unit,int healthbarMode); + void renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture=NULL, const Texture2D *backgroundTexture=NULL); + void internalRenderHp(int numberOfBars, int barNumber, float hp, Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector); void renderTeamColorEffect(Vec3f &v, int heigth, int size, Vec3f color, const Texture2D *texture); void renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &color, float width); void renderTile(const Vec2i &pos); @@ -695,9 +708,8 @@ private: void render3dSetup(); void render3dMenuSetup(const MainMenu *mm); - bool renderResourcesInTeamMode(); int renderResource(const Faction *factionForResourceView, - bool localFactionResourcesOnly, const ResourceType *rt, + bool localFactionResourcesOnly,bool twoResourceLines, const ResourceType *rt, int startRow, int &resourceCountRendered); }; diff --git a/source/glest_game/graphics/unit_particle_type.cpp b/source/glest_game/graphics/unit_particle_type.cpp index f90cf44e1..0deeefd3f 100644 --- a/source/glest_game/graphics/unit_particle_type.cpp +++ b/source/glest_game/graphics/unit_particle_type.cpp @@ -218,6 +218,7 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){ for(Children::iterator i=children.begin(); i!=children.end(); ++i){ UnitParticleSystem *child = new UnitParticleSystem(); child->setParticleOwner(ups->getParticleOwner()); + child->setParticleType((*i)); (*i)->setValues(child); ups->addChild(child); } diff --git a/source/glest_game/gui/display.cpp b/source/glest_game/gui/display.cpp index 8ed4a3440..e66fdf74c 100644 --- a/source/glest_game/gui/display.cpp +++ b/source/glest_game/gui/display.cpp @@ -49,7 +49,7 @@ void Display::calculateUpDimensions(int index) { maxUpIndex=index; if(maxUpIndex+1>upCellSideCount*upCellSideCount){ upCellSideCount=upCellSideCount+1; - upImageSize=imageSize*cellSideCount/upCellSideCount+0.9f; + upImageSize = static_cast(imageSize) * static_cast(cellSideCount) / static_cast(upCellSideCount) + 0.9f; } } } diff --git a/source/glest_game/gui/gui.cpp b/source/glest_game/gui/gui.cpp index ef54cbd22..81ae45f37 100644 --- a/source/glest_game/gui/gui.cpp +++ b/source/glest_game/gui/gui.cpp @@ -256,8 +256,8 @@ void Gui::mouseMoveOutsideDisplay() { void Gui::mouseDownLeftGraphics(int x, int y, bool prepared) { if(selectingPos) { //give standard orders - Vec2i targetPos; - if(Renderer::getInstance().computePosition(Vec2i(x, y), targetPos) && + Vec2i targetPos=game->getMouseCellPos(); + if(game->isValidMouseCellPos() && world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true) { giveTwoClickOrders(x, y, prepared); } @@ -266,8 +266,8 @@ void Gui::mouseDownLeftGraphics(int x, int y, bool prepared) { //set meeting point else if(selectingMeetingPoint) { if(selection.isCommandable()) { - Vec2i targetPos; - if(Renderer::getInstance().computePosition(Vec2i(x, y), targetPos) && + Vec2i targetPos=game->getMouseCellPos(); + if(game->isValidMouseCellPos() && world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true) { commander->trySetMeetingPoint(selection.getFrontUnit(), targetPos); } @@ -287,15 +287,15 @@ void Gui::mouseDownRightGraphics(int x, int y , bool prepared) { } else if(selection.isCommandable()) { if(prepared) { - Vec2i targetPos; - if(Renderer::getInstance().computePosition(Vec2i(x, y), targetPos) && + Vec2i targetPos=game->getMouseCellPos(); + if(game->isValidMouseCellPos() && world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true) { givePreparedDefaultOrders(x, y); } } else { - Vec2i targetPos; - if(Renderer::getInstance().computePosition(Vec2i(x, y), targetPos) && + Vec2i targetPos=game->getMouseCellPos(); + if(game->isValidMouseCellPos() && world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true) { giveDefaultOrders(x, y); } @@ -314,7 +314,7 @@ void Gui::mouseUpLeftGraphics(int x, int y) { if(selection.isCommandable() && random.randRange(0, 1)==0){ SoundRenderer::getInstance().playFx( selection.getFrontUnit()->getType()->getSelectionSound(), - selection.getFrontUnit()->getCurrVector(), + selection.getFrontUnit()->getCurrMidHeightVector(), gameCamera->getPos()); } selectionQuad.disable(); @@ -331,7 +331,8 @@ void Gui::mouseMoveGraphics(int x, int y) { //compute position for building if(isPlacingBuilding()){ - validPosObjWorld= Renderer::getInstance().computePosition(Vec2i(x,y), posObjWorld); + posObjWorld=game->getMouseCellPos(); + validPosObjWorld= game->isValidMouseCellPos(); } display.setInfoText(""); @@ -488,7 +489,7 @@ void Gui::giveDefaultOrders(int x, int y,const Unit *targetUnit, bool paintMouse if(random.randRange(0, 1)==0){ SoundRenderer::getInstance().playFx( selection.getFrontUnit()->getType()->getCommandSound(), - selection.getFrontUnit()->getCurrVector(), + selection.getFrontUnit()->getCurrMidHeightVector(), gameCamera->getPos()); } } @@ -543,7 +544,7 @@ void Gui::giveTwoClickOrders(int x, int y , bool prepared) { if(random.randRange(0, 1) == 0) { SoundRenderer::getInstance().playFx( selection.getFrontUnit()->getType()->getCommandSound(), - selection.getFrontUnit()->getCurrVector(), + selection.getFrontUnit()->getCurrMidHeightVector(), gameCamera->getPos()); } } @@ -768,6 +769,7 @@ void Gui::computeInfoString(int posDisplay){ display.setInfoText(ct->getDesc(unit->getTotalUpgrade(),game->showTranslatedTechTree())); } else{ + display.setInfoText(ct->getReqDesc(game->showTranslatedTechTree())); if(ct->getClass()==ccUpgrade){ string text=""; const UpgradeCommandType *uct= static_cast(ct); @@ -779,8 +781,19 @@ void Gui::computeInfoString(int posDisplay){ } display.setInfoText(text+ct->getReqDesc(game->showTranslatedTechTree())); } - else{ - display.setInfoText(ct->getReqDesc(game->showTranslatedTechTree())); + //locked by scenario + else if(ct->getClass()==ccProduce){ + string text=""; + const ProduceCommandType *pct= static_cast(ct); + if(unit->getFaction()->isUnitLocked(pct->getProducedUnit())){ + display.setInfoText(lang.getString("LockedByScenario")+"\n\n"+ct->getReqDesc(game->showTranslatedTechTree())); + } + } + else if(ct->getClass()==ccMorph){ + const MorphCommandType *mct= static_cast(ct); + if(unit->getFaction()->isUnitLocked(mct->getMorphUnit())){ + display.setInfoText(lang.getString("LockedByScenario")+"\n\n"+ct->getReqDesc(game->showTranslatedTechTree())); + } } } } @@ -802,8 +815,14 @@ void Gui::computeInfoString(int posDisplay){ } else{ if(activeCommandType!=NULL && activeCommandType->getClass()==ccBuild){ + //locked by scenario const BuildCommandType *bct= static_cast(activeCommandType); - display.setInfoText(bct->getBuilding(posDisplay)->getReqDesc(game->showTranslatedTechTree())); + const Unit *unit= selection.getFrontUnit(); + if(unit->getFaction()->isUnitLocked(bct->getBuilding(posDisplay))){ + display.setInfoText(lang.getString("LockedByScenario")+"\n\n"+bct->getBuilding(posDisplay)->getReqDesc(game->showTranslatedTechTree())); + } else { + display.setInfoText(bct->getBuilding(posDisplay)->getReqDesc(game->showTranslatedTechTree())); + } } } } @@ -1142,8 +1161,7 @@ bool Gui::computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&t if(selObj != NULL) { selObj->resetHighlight(); // get real click pos - renderer.computePosition(screenPos, targetPos); - + targetPos=game->getMouseCellPos(); //validPosObjWorld= true; //posObjWorld = targetPos; @@ -1234,7 +1252,8 @@ bool Gui::computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&t } else{ targetUnit= NULL; - if(renderer.computePosition(screenPos, targetPos)){ + targetPos=game->getMouseCellPos(); + if(game->isValidMouseCellPos()){ validPosObjWorld= true; posObjWorld= targetPos; diff --git a/source/glest_game/gui/selection.cpp b/source/glest_game/gui/selection.cpp index 57a0129e0..c44f3483b 100644 --- a/source/glest_game/gui/selection.cpp +++ b/source/glest_game/gui/selection.cpp @@ -204,7 +204,7 @@ bool Selection::isMeetable() const{ } Vec3f Selection::getRefPos() const{ - return getFrontUnit()->getCurrVector(); + return getFrontUnit()->getCurrMidHeightVector(); } bool Selection::hasUnit(const Unit* unit) const { diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index f30be4828..82118f110 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -1147,6 +1147,7 @@ void MainWindow::eventKeyDown(SDL_KeyboardEvent key) { Renderer &renderer= Renderer::getInstance(); if(keystate.mod & (KMOD_LALT | KMOD_RALT)) { renderer.cycleShowDebugUILevel(); + printf("**Cycled Debug UI level to: %d\n",renderer.getShowDebugUILevel()); } else { bool showDebugUI = renderer.getShowDebugUI(); @@ -3511,8 +3512,8 @@ int handleCreateDataArchivesCommand(int argc, char** argv) { printf("Compress item [%s] is not valid!\n",compress_item.c_str()); return_value = 1; } - - return_value = 0; + else + return_value = 0; } else { printf("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); @@ -4438,6 +4439,10 @@ int glestMain(int argc, char** argv) { } createDirectoryPaths(tempDataPath); + string binaryNameOld = Properties::getApplicationPath() + extractFileFromDirectoryPath(PlatformExceptionHandler::application_binary) + "__REMOVE"; + if(fileExists(binaryNameOld)) { + removeFile(binaryNameOld); + } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_PORTS]) == true) { int foundParamIndIndex = -1; @@ -5059,7 +5064,7 @@ int glestMain(int argc, char** argv) { gameSettings->setFactionControl(i, ct); gameSettings->setStartLocationIndex(i, i); gameSettings->setResourceMultiplierIndex(i, 10); - gameSettings->setNetworkPlayerName(i, "Closed"); + gameSettings->setNetworkPlayerName(i, GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); } ControlType ct= ctHuman; diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 620a94f00..09e26ca85 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -44,7 +44,7 @@ static const int MAX_PING_LAG_COUNT = 6; static const double REPROMPT_DOWNLOAD_SECONDS = 7; //static const string ITEM_MISSING = "***missing***"; // above replaced with Lang::getInstance().getString("DataMissing","",true) -const int HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS = 4; +const int HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS = 2; static const char *HEADLESS_SAVED_GAME_FILENAME = "lastHeadlessGameSettings.mgg"; const int mapPreviewTexture_X = 5; @@ -71,6 +71,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM switchSetupRequestFlagType |= ssrft_NetworkPlayerName; updateDataSynchDetailText = false; launchingNewGame = false; + isfirstSwitchingMapMessage = true; this->zoomedMap = false; this->render_mapPreviewTexture_X = mapPreviewTexture_X; @@ -81,6 +82,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM needToBroadcastServerSettings=false; broadcastServerSettingsDelayTimer=0; lastGameSettingsReceivedCount=0; + noReceiveTimer=time(NULL)-100; // old but inititialized ( must be an "old" time ) soundConnectionCount=0; @@ -132,6 +134,9 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM settingsReceivedFromServer=false; initialSettingsReceivedFromServer=false; + validOriginalGameSettings=false; + validDisplayedGamesettings=false; + returnMenuInfo=joinMenuInfo; Lang &lang= Lang::getInstance(); @@ -179,6 +184,13 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM labelInfo.setFont(CoreData::getInstance().getMenuFontBig()); labelInfo.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelWaitingForPlayers.registerGraphicComponent(containerName,"labelInfo"); + labelWaitingForPlayers.init(30, 100); + labelWaitingForPlayers.setText(""); + labelWaitingForPlayers.setFont(CoreData::getInstance().getMenuFontBig()); + labelWaitingForPlayers.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelWaitingForPlayers.setTextColor(Vec3f(1.0f,1.0f,0.f)); + timerLabelFlash = time(NULL); labelDataSynchInfo.registerGraphicComponent(containerName,"labelDataSynchInfo"); labelDataSynchInfo.init(30, networkHeadPos-60); @@ -193,7 +205,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM labelFogOfWar.setText(lang.getString("FogOfWar")); listBoxFogOfWar.registerGraphicComponent(containerName,"listBoxFogOfWar"); - listBoxFogOfWar.init(xoffset+100, aPos, 130); + listBoxFogOfWar.init(xoffset+100, aPos, 150); listBoxFogOfWar.pushBackItem(lang.getString("Enabled")); listBoxFogOfWar.pushBackItem(lang.getString("Explored")); listBoxFogOfWar.pushBackItem(lang.getString("Disabled")); @@ -273,16 +285,6 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM buttonCancelDownloads.init(xoffset+620, 180, 150); buttonCancelDownloads.setText(lang.getString("CancelDownloads")); - listBoxPlayerStatus.registerGraphicComponent(containerName,"listBoxPlayerStatus"); - nonAdminPlayerStatusX = xoffset+460; - listBoxPlayerStatus.init(nonAdminPlayerStatusX, 180, 150); - listBoxPlayerStatus.setTextColor(Vec3f(1.0f,0.f,0.f)); - listBoxPlayerStatus.setLighted(true); - playerStatuses.push_back(lang.getString("PlayerStatusSetup")); - playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); - playerStatuses.push_back(lang.getString("PlayerStatusReady")); - listBoxPlayerStatus.setItems(playerStatuses); - // Network Frame Period xoffset=70; //map listBox @@ -362,6 +364,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM listBoxTeams[i].registerGraphicComponent(containerName,"listBoxTeams" + intToStr(i)); listBoxTeams[i].init(xoffset+650, setupPos-30-i*rowHeight, 60); listBoxTeams[i].setEditable(false); + listBoxTeams[i].setLighted(true); labelNetStatus[i].registerGraphicComponent(containerName,"labelNetStatus" + intToStr(i)); labelNetStatus[i].init(xoffset+715, setupPos-30-i*rowHeight, 60); @@ -453,17 +456,33 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM setupMapList(""); listBoxMap.setItems(formattedPlayerSortedMaps[0]); + int buttonx=170; + int buttony=180; + + listBoxPlayerStatus.registerGraphicComponent(containerName,"listBoxPlayerStatus"); + listBoxPlayerStatus.init(buttonx, buttony, 150); + listBoxPlayerStatus.setTextColor(Vec3f(1.0f,0.f,0.f)); + listBoxPlayerStatus.setLighted(true); + playerStatuses.push_back(lang.getString("PlayerStatusSetup")); + playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.getString("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + buttonx+=180; + + buttonDisconnect.registerGraphicComponent(containerName,"buttonDisconnect"); + buttonDisconnect.init(buttonx, buttony, 125); + buttonx+=130; + + buttonRestoreLastSettings.registerGraphicComponent(containerName,"buttonRestoreLastSettings"); + buttonRestoreLastSettings.init(buttonx, buttony, 220); + buttonRestoreLastSettings.setText(lang.getString("ReloadLastGameSettings")); + buttonx+=225; + buttonPlayNow.registerGraphicComponent(containerName,"buttonPlayNow"); - buttonPlayNow.init(220, 180, 125); + buttonPlayNow.init(buttonx, buttony, 125); buttonPlayNow.setText(lang.getString("PlayNow")); buttonPlayNow.setVisible(false); - buttonDisconnect.registerGraphicComponent(containerName,"buttonDisconnect"); - buttonDisconnect.init(350, 180, 125); - - buttonRestoreLastSettings.registerGraphicComponent(containerName,"buttonRestoreLastSettings"); - buttonRestoreLastSettings.init(480, 180, 220); - buttonRestoreLastSettings.setText(lang.getString("ReloadLastGameSettings")); // write hint to console: Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); @@ -641,6 +660,9 @@ void MenuStateConnectedGame::reloadUI() { labelInfo.setFont(CoreData::getInstance().getMenuFontBig()); labelInfo.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelWaitingForPlayers.setFont(CoreData::getInstance().getMenuFontBig()); + labelWaitingForPlayers.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelDataSynchInfo.setFont(CoreData::getInstance().getMenuFontBig()); labelDataSynchInfo.setFont3D(CoreData::getInstance().getMenuFontBig3D()); @@ -1531,6 +1553,7 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ switchSetupRequestFlagType, lang.getLanguage()); switchSetupRequestFlagType= ssrft_None; + noReceiveTimer=time(NULL); } break; } @@ -1571,7 +1594,7 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ } if(canGrabSlot == true) { - if(i < mapInfo.players && grabSlotButton[i].mouseClick(x, y)) { + if(clientInterface != NULL && i < mapInfo.players && grabSlotButton[i].mouseClick(x, y)) { //printf("Send slot switch request for slot = %d, myCurrentIndex = %d\n",i,myCurrentIndex); soundRenderer.playFx(coreData.getClickSoundB()); @@ -1608,7 +1631,7 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ } if(labelPlayerNames[i].mouseClick(x, y) && (activeInputLabel != &labelPlayerNames[i])){ - if(i == clientInterface->getPlayerIndex()){ + if(clientInterface != NULL && i == clientInterface->getPlayerIndex()){ setActiveInputLabel(&labelPlayerNames[i]); } } @@ -1724,14 +1747,17 @@ void MenuStateConnectedGame::broadCastGameSettingsToHeadlessServer(bool forceNow } } - GameSettings gameSettings = *clientInterface->getGameSettings(); - loadGameSettings(&gameSettings); + if(validDisplayedGamesettings){ + loadGameSettings(&displayedGamesettings); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("broadcast settings:\n%s\n",gameSettings.toString().c_str()); - //printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("broadcast settings:\n%s\n",displayedGamesettings.toString().c_str()); - clientInterface->broadcastGameSetup(&gameSettings); + //printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); + + clientInterface->broadcastGameSetup(&displayedGamesettings); + noReceiveTimer=time(NULL); + } } } @@ -2287,7 +2313,7 @@ void MenuStateConnectedGame::loadGameSettings(GameSettings *gameSettings) { gameSettings->setFactionTypeName(slotIndex, factionFiles[listBoxFactions[i].getSelectedItemIndex()]); gameSettings->setNetworkPlayerStatuses(slotIndex, npst_None); - gameSettings->setNetworkPlayerName(slotIndex, "Closed"); + gameSettings->setNetworkPlayerName(slotIndex, GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); closedCount++; } @@ -2475,14 +2501,6 @@ void MenuStateConnectedGame::render() { try { Renderer &renderer= Renderer::getInstance(); - if(isHeadlessAdmin() == true) { - listBoxPlayerStatus.setX(buttonRestoreLastSettings.getX() + - buttonRestoreLastSettings.getW() + 20); - } - else { - listBoxPlayerStatus.setX(nonAdminPlayerStatusX); - } - if(mainMessageBox.getEnabled()) { renderer.renderMessageBox(&mainMessageBox); } @@ -2510,10 +2528,8 @@ void MenuStateConnectedGame::render() { delete factionVideo; factionVideo = NULL; - NetworkManager &networkManager= NetworkManager::getInstance(); - ClientInterface* clientInterface= networkManager.getClientInterface(); - if(clientInterface != NULL) { - initFactionPreview(clientInterface->getGameSettings()); + if(validDisplayedGamesettings) { + initFactionPreview(&displayedGamesettings); } } } @@ -2575,15 +2591,18 @@ void MenuStateConnectedGame::render() { ClientInterface *clientInterface = networkManager.getClientInterface(); for(int i = 0; i < GameConstants::maxPlayers; ++i) { if(listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned) { + bool renderIt=true; //printf("Player #%d [%s] control = %d\n",i,labelPlayerNames[i].getText().c_str(),listBoxControls[i].getSelectedItemIndex()); - - labelPlayers[i].setVisible(true); - labelPlayerNames[i].setVisible(true); - listBoxControls[i].setVisible(true); - listBoxRMultiplier[i].setVisible(true); - listBoxFactions[i].setVisible(true); - listBoxTeams[i].setVisible(true); - labelNetStatus[i].setVisible(true); + if(labelNetStatus[i].getText() == GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME){ + renderIt=false; + } + labelPlayers[i].setVisible(renderIt); + labelPlayerNames[i].setVisible(renderIt); + listBoxControls[i].setVisible(renderIt); + listBoxRMultiplier[i].setVisible(renderIt); + listBoxFactions[i].setVisible(renderIt); + listBoxTeams[i].setVisible(renderIt); + labelNetStatus[i].setVisible(renderIt); } if(listBoxControls[i].getSelectedItemIndex() != ctClosed) { @@ -2631,6 +2650,12 @@ void MenuStateConnectedGame::render() { if(listBoxControls[i].getSelectedItemIndex() != ctClosed) { renderer.renderListBox(&listBoxRMultiplier[i]); renderer.renderListBox(&listBoxFactions[i]); + int teamnumber=listBoxTeams[i].getSelectedItemIndex(); + Vec3f teamcolor=Vec3f(1.0f,1.0f,1.0f); + if(teamnumber>=0 && teamnumber<8){ + teamcolor=crcPlayerTextureCache[teamnumber]->getPixmap()->getPixel3f(0, 0); + } + listBoxTeams[i].setTextColor(teamcolor); renderer.renderListBox(&listBoxTeams[i]); bool canGrabSlot = false; @@ -2672,9 +2697,11 @@ void MenuStateConnectedGame::render() { if(difftime((long int)time(NULL),timerLabelFlash) < 1) { renderer.renderLabel(&labelDataSynchInfo,&RED); + renderer.renderLabel(&labelWaitingForPlayers,&YELLOW); } else { renderer.renderLabel(&labelDataSynchInfo,&WHITE); + renderer.renderLabel(&labelWaitingForPlayers,&WHITE); } renderer.renderLabel(&labelMap); @@ -2792,7 +2819,7 @@ void MenuStateConnectedGame::render() { } } renderer.renderChatManager(&chatManager); - renderer.renderConsole(&console,showFullConsole,true); + renderer.renderConsole(&console,showFullConsole?consoleFull:consoleStoredAndNormal); if(difftime((long int)time(NULL),timerLabelFlash) > 2) { timerLabelFlash = time(NULL); @@ -2827,6 +2854,21 @@ void MenuStateConnectedGame::update() { //printf("#2 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); broadCastGameSettingsToHeadlessServer(false); + bool notCurrentlySwitching=(( difftime((long int) time(NULL), broadcastServerSettingsDelayTimer)) >= HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS ); + bool receiveAllowedNow=difftime((long int) time(NULL), noReceiveTimer) > 2 ; + bool newMessage= lastGameSettingsReceivedCount < clientInterface->getGameSettingsReceivedCount(); + if (validDisplayedGamesettings == false + || ( notCurrentlySwitching + && newMessage + && receiveAllowedNow )) { + + //printf("I take the whole settings top broadcastDelay=%d noReceiveTimer=%d\n", (int)difftime((long int) time(NULL), broadcastServerSettingsDelayTimer),(int)difftime((long int) time(NULL), noReceiveTimer)); + + displayedGamesettings = *(clientInterface->getGameSettings()); + originalGamesettings = displayedGamesettings; + validDisplayedGamesettings = true; + } + checkBoxAllowNativeLanguageTechtree.setEditable(isHeadlessAdmin()); checkBoxAllowNativeLanguageTechtree.setEnabled(isHeadlessAdmin()); @@ -2845,13 +2887,46 @@ void MenuStateConnectedGame::update() { checkBoxAllowTeamUnitSharing.setEditable(isHeadlessAdmin()); checkBoxAllowTeamResourceSharing.setEditable(isHeadlessAdmin()); + if(isHeadlessAdmin() == true) { + bool hasOtherPlayer=false; + bool hasOpenSlot=false; for(unsigned int i = 0; i < (unsigned int)GameConstants::maxPlayers; ++i) { - listBoxControls[i].setEditable(isHeadlessAdmin()); + if(displayedGamesettings.getFactionControl(i)==ctNetwork && clientInterface->getPlayerIndex()!=(int)i){ + hasOpenSlot=true; + } + if(displayedGamesettings.getFactionControl(i)==ctNetwork && + displayedGamesettings.getNetworkPlayerNameByPlayerIndex(i)!= GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME && + displayedGamesettings.getNetworkPlayerNameByPlayerIndex(i)!= GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME ){ + listBoxControls[i].setEditable(false); + if(clientInterface->getPlayerIndex()!=(int)i){ + hasOtherPlayer=true; + } + } + else if(clientInterface->getPlayerIndex()==(int)i){ + listBoxControls[i].setEditable(false); + } + else { + listBoxControls[i].setEditable(true); + } listBoxRMultiplier[i].setEditable(isHeadlessAdmin()); listBoxFactions[i].setEditable(isHeadlessAdmin()); listBoxTeams[i].setEditable(isHeadlessAdmin()); } + if (hasOtherPlayer) { + labelWaitingForPlayers.setText(""); + labelWaitingForPlayers.setVisible(false); + } else if (hasOpenSlot) { + labelWaitingForPlayers.setText(lang.getString("WaitingForPlayers")); + labelWaitingForPlayers.setVisible(true); + } else { + labelWaitingForPlayers.setText(lang.getString("OpenANetworkSLot")); + labelWaitingForPlayers.setVisible(true); + } + } + else { + labelWaitingForPlayers.setText(""); + labelWaitingForPlayers.setVisible(false); } if(difftime((long int)time(NULL),lastNetworkSendPing) >= GameConstants::networkPingInterval) { @@ -2874,7 +2949,7 @@ void MenuStateConnectedGame::update() { MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(fileFTPProgressList.empty() == true) { Lang &lang= Lang::getInstance(); - const vector languageList = clientInterface->getGameSettings()->getUniqueNetworkPlayerLanguages(); + const vector languageList = displayedGamesettings.getUniqueNetworkPlayerLanguages(); for(unsigned int i = 0; i < languageList.size(); ++i) { clientInterface->sendTextMessage(lang.getString("ConnectionTimedOut",languageList[i]) + " : " + doubleToStr(clientInterface->getLastPingLag(),2),-1,false,languageList[i]); sleep(1); @@ -2887,13 +2962,6 @@ void MenuStateConnectedGame::update() { pingCount++; if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - //update status label - if(clientInterface != NULL && clientInterface->isConnected()) { buttonDisconnect.setText(lang.getString("Disconnect")); if(clientInterface->getAllowDownloadDataSynch() == false) { @@ -2905,64 +2973,63 @@ void MenuStateConnectedGame::update() { label = label + ", " + clientInterface->getVersionString(); - const GameSettings *gameSettings = clientInterface->getGameSettings(); if(clientInterface->getAllowGameDataSynchCheck() == false && - gameSettings->getTileset() != "" && - gameSettings->getTech() != "" && - gameSettings->getMap() != "") { + displayedGamesettings.getTileset() != "" && + displayedGamesettings.getTech() != "" && + displayedGamesettings.getMap() != "") { Config &config = Config::getInstance(); MutexSafeWrapper safeMutexFTPProgress(ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL,string(__FILE__) + "_" + intToStr(__LINE__)); uint32 tilesetCRC = lastCheckedCRCTilesetValue; - if(lastCheckedCRCTilesetName != gameSettings->getTileset() && - gameSettings->getTileset() != "") { - //console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); - tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); - if(tilesetCRC == 0 || tilesetCRC != gameSettings->getTilesetCRC()) { - tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL, true); + if(lastCheckedCRCTilesetName != displayedGamesettings.getTileset() && + displayedGamesettings.getTileset() != "") { + //console.addLine("Checking tileset CRC [" + displayedGamesettings.getTileset() + "]"); + tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + displayedGamesettings.getTileset() + string("/*"), ".xml", NULL); + if(tilesetCRC == 0 || tilesetCRC != displayedGamesettings.getTilesetCRC()) { + tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + displayedGamesettings.getTileset() + string("/*"), ".xml", NULL, true); } // Test data synch //tilesetCRC++; lastCheckedCRCTilesetValue = tilesetCRC; - lastCheckedCRCTilesetName = gameSettings->getTileset(); + lastCheckedCRCTilesetName = displayedGamesettings.getTileset(); } uint32 techCRC = lastCheckedCRCTechtreeValue; - if(lastCheckedCRCTechtreeName != gameSettings->getTech() && - gameSettings->getTech() != "") { - //console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); - techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL); - //clientInterface->sendTextMessage("#1 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(gameSettings->getTechCRC()),-1, true, ""); + if(lastCheckedCRCTechtreeName != displayedGamesettings.getTech() && + displayedGamesettings.getTech() != "") { + //console.addLine("Checking techtree CRC [" + displayedGamesettings.getTech() + "]"); + techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + displayedGamesettings.getTech() + string("/*"), ".xml", NULL); + //clientInterface->sendTextMessage("#1 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); - if(techCRC == 0 || techCRC != gameSettings->getTechCRC()) { - techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL, true); - //clientInterface->sendTextMessage("#2 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(gameSettings->getTechCRC()),-1, true, ""); + if(techCRC == 0 || techCRC != displayedGamesettings.getTechCRC()) { + techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + displayedGamesettings.getTech() + string("/*"), ".xml", NULL, true); + //clientInterface->sendTextMessage("#2 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); } - if(techCRC != 0 && techCRC != gameSettings->getTechCRC() && + if(techCRC != 0 && techCRC != displayedGamesettings.getTechCRC() && listBoxTechTree.getSelectedItemIndex() >= 0 && listBoxTechTree.getSelectedItem() != Lang::getInstance().getString("DataMissing","",true)) { //time_t now = time(NULL); - time_t lastUpdateDate = getFolderTreeContentsCheckSumRecursivelyLastGenerated(config.getPathListForType(ptTechs,""), string("/") + gameSettings->getTech() + string("/*"), ".xml"); + time_t lastUpdateDate = getFolderTreeContentsCheckSumRecursivelyLastGenerated(config.getPathListForType(ptTechs,""), string("/") + displayedGamesettings.getTech() + string("/*"), ".xml"); const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 1; if( lastUpdateDate <= 0 || difftime((long int)time(NULL),lastUpdateDate) >= REFRESH_CRC_DAY_SECONDS) { - techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL, true); - //clientInterface->sendTextMessage("#3 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(gameSettings->getTechCRC()),-1, true, ""); + techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + displayedGamesettings.getTech() + string("/*"), ".xml", NULL, true); + //clientInterface->sendTextMessage("#3 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); } } // Test data synch //techCRC++; lastCheckedCRCTechtreeValue = techCRC; - lastCheckedCRCTechtreeName = gameSettings->getTech(); + lastCheckedCRCTechtreeName = displayedGamesettings.getTech(); - loadFactions(gameSettings,false); + loadFactions(&displayedGamesettings,false); factionCRCList.clear(); for(unsigned int factionIdx = 0; factionIdx < factionFiles.size(); ++factionIdx) { string factionName = factionFiles[factionIdx]; @@ -2972,28 +3039,28 @@ void MenuStateConnectedGame::update() { uint32 factionCRC = 0; //time_t now = time(NULL); - time_t lastUpdateDate = getFolderTreeContentsCheckSumRecursivelyLastGenerated(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml"); + time_t lastUpdateDate = getFolderTreeContentsCheckSumRecursivelyLastGenerated(config.getPathListForType(ptTechs,""), "/" + displayedGamesettings.getTech() + "/factions/" + factionName + "/*", ".xml"); const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24; if( lastUpdateDate <= 0 || difftime((long int)time(NULL),lastUpdateDate) >= REFRESH_CRC_DAY_SECONDS || - (techCRC != 0 && techCRC != gameSettings->getTechCRC())) { - factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + (techCRC != 0 && techCRC != displayedGamesettings.getTechCRC())) { + factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + displayedGamesettings.getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); } else { - factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL); + factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + displayedGamesettings.getTech() + "/factions/" + factionName + "/*", ".xml", NULL); } if(factionCRC == 0) { - factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + displayedGamesettings.getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); } if(factionCRC != 0) { - vector > serverFactionCRCList = gameSettings->getFactionCRCList(); + vector > serverFactionCRCList = displayedGamesettings.getFactionCRCList(); for(unsigned int factionIdx1 = 0; factionIdx1 < serverFactionCRCList.size(); ++factionIdx1) { pair &serverFaction = serverFactionCRCList[factionIdx1]; if(serverFaction.first == factionName) { if(serverFaction.second != factionCRC) { - factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + displayedGamesettings.getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); } break; } @@ -3006,10 +3073,10 @@ void MenuStateConnectedGame::update() { } uint32 mapCRC = lastCheckedCRCMapValue; - if(lastCheckedCRCMapName != gameSettings->getMap() && - gameSettings->getMap() != "") { + if(lastCheckedCRCMapName != displayedGamesettings.getMap() && + displayedGamesettings.getMap() != "") { Checksum checksum; - string file = Config::getMapPath(gameSettings->getMap(),"",false); + string file = Config::getMapPath(displayedGamesettings.getMap(),"",false); //console.addLine("Checking map CRC [" + file + "]"); checksum.addFile(file); mapCRC = checksum.getSum(); @@ -3017,22 +3084,23 @@ void MenuStateConnectedGame::update() { //mapCRC++; lastCheckedCRCMapValue = mapCRC; - lastCheckedCRCMapName = gameSettings->getMap(); + lastCheckedCRCMapName = displayedGamesettings.getMap(); } safeMutexFTPProgress.ReleaseLock(); - bool dataSynchMismatch = ((mapCRC != 0 && mapCRC != gameSettings->getMapCRC()) || - (tilesetCRC != 0 && tilesetCRC != gameSettings->getTilesetCRC()) || - (techCRC != 0 && techCRC != gameSettings->getTechCRC())); + bool dataSynchMismatch = ((mapCRC != 0 && mapCRC != displayedGamesettings.getMapCRC()) || + (tilesetCRC != 0 && tilesetCRC != displayedGamesettings.getTilesetCRC()) || + (techCRC != 0 && techCRC != displayedGamesettings.getTechCRC())); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nmapCRC [%d] gameSettings->getMapCRC() [%d]\ntilesetCRC [%d] gameSettings->getTilesetCRC() [%d]\ntechCRC [%d] gameSettings->getTechCRC() [%d]\n",mapCRC,gameSettings->getMapCRC(),tilesetCRC,gameSettings->getTilesetCRC(),techCRC,gameSettings->getTechCRC()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nmapCRC [%d] displayedGamesettings.getMapCRC() [%d]\ntilesetCRC [%d] displayedGamesettings.getTilesetCRC() [%d]\ntechCRC [%d] displayedGamesettings.getTechCRC() [%d]\n",mapCRC,displayedGamesettings.getMapCRC(),tilesetCRC,displayedGamesettings.getTilesetCRC(),techCRC,displayedGamesettings.getTechCRC()); - if(dataSynchMismatch == true) { - //printf("Data not synched: lmap %u rmap: %u ltile: %d rtile: %u ltech: %u rtech: %u\n",mapCRC,gameSettings->getMapCRC(),tilesetCRC,gameSettings->getTilesetCRC(),techCRC,gameSettings->getTechCRC()); + if(dataSynchMismatch == true && + ( difftime((long int)time(NULL),broadcastServerSettingsDelayTimer) >= HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS)) { + //printf("Data not synched: lmap %u rmap: %u ltile: %d rtile: %u ltech: %u rtech: %u\n",mapCRC,displayedGamesettings.getMapCRC(),tilesetCRC,displayedGamesettings.getTilesetCRC(),techCRC,displayedGamesettings.getTechCRC()); string labelSynch = lang.getString("DataNotSynchedTitle"); - if(mapCRC != 0 && mapCRC != gameSettings->getMapCRC() && + if(mapCRC != 0 && mapCRC != displayedGamesettings.getMapCRC() && listBoxMap.getSelectedItemIndex() >= 0 && listBoxMap.getSelectedItem() != Lang::getInstance().getString("DataMissing","",true)) { labelSynch = labelSynch + " " + lang.getString("Map"); @@ -3051,7 +3119,7 @@ void MenuStateConnectedGame::update() { } } - if(tilesetCRC != 0 && tilesetCRC != gameSettings->getTilesetCRC() && + if(tilesetCRC != 0 && tilesetCRC != displayedGamesettings.getTilesetCRC() && listBoxTileset.getSelectedItemIndex() >= 0 && listBoxTileset.getSelectedItem() != Lang::getInstance().getString("DataMissing","",true)) { labelSynch = labelSynch + " " + lang.getString("Tileset"); @@ -3069,7 +3137,7 @@ void MenuStateConnectedGame::update() { } } - if(techCRC != 0 && techCRC != gameSettings->getTechCRC() && + if(techCRC != 0 && techCRC != displayedGamesettings.getTechCRC() && listBoxTechTree.getSelectedItemIndex() >= 0 && listBoxTechTree.getSelectedItem() != Lang::getInstance().getString("DataMissing","",true)) { labelSynch = labelSynch + " " + lang.getString("TechTree"); @@ -3092,7 +3160,7 @@ void MenuStateConnectedGame::update() { string mismatchedFactionText = ""; vector mismatchedFactionTextList; - vector > serverFactionCRCList = gameSettings->getFactionCRCList(); + vector > serverFactionCRCList = displayedGamesettings.getFactionCRCList(); for(unsigned int factionIdx = 0; factionIdx < serverFactionCRCList.size(); ++factionIdx) { pair &serverFaction = serverFactionCRCList[factionIdx]; @@ -3332,18 +3400,67 @@ void MenuStateConnectedGame::update() { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); try { - if(clientInterface->getGameSettingsReceived() && + if(clientInterface->getGameSettingsReceived() && validDisplayedGamesettings && lastGameSettingsReceivedCount != clientInterface->getGameSettingsReceivedCount()) { - broadCastGameSettingsToHeadlessServer(needToBroadcastServerSettings); - lastGameSettingsReceivedCount = clientInterface->getGameSettingsReceivedCount(); bool errorOnMissingData = (clientInterface->getAllowGameDataSynchCheck() == false); - GameSettings *gameSettings = clientInterface->getGameSettingsPtr(); - //printf("Menu got new settings thisfactionindex = %d startlocation: %d control = %d\n",gameSettings->getThisFactionIndex(),clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()),gameSettings->getFactionControl(clientInterface->getGameSettings()->getThisFactionIndex())); - if ( difftime((long int)time(NULL),broadcastServerSettingsDelayTimer) >= HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS){ - setupUIFromGameSettings(gameSettings, errorOnMissingData); + const GameSettings *receivedGameSettings= clientInterface->getGameSettings(); + + //printf("Menu got new settings thisfactionindex = %d startlocation: %d control = %d\n",displayedGamesettings.getThisFactionIndex(),clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()),displayedGamesettings.getFactionControl(clientInterface->getGameSettings()->getThisFactionIndex())); + if ( difftime((long int)time(NULL),noReceiveTimer) < 3 || difftime((long int)time(NULL),broadcastServerSettingsDelayTimer) < HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS){ + // copy my current settings in UI to displayedSettings; + loadGameSettings(&displayedGamesettings); + // check if there are any changed fields from others clients + if(isHeadlessAdmin()){ + //printf("I am headless admin and will restore only some parts\n"); + // only copy those parts which are editable by normal clients + for (int i=0;igetFactionCount();i++){ + if(displayedGamesettings.getFactionControl(i)==ctNetwork){ + if(originalGamesettings.getTeam(i)==displayedGamesettings.getTeam(i)){ + displayedGamesettings.setTeam(i,receivedGameSettings->getTeam(i)); + originalGamesettings.setTeam(i,receivedGameSettings->getTeam(i)); + } + if(originalGamesettings.getFactionTypeName(i)==displayedGamesettings.getFactionTypeName(i)){ + displayedGamesettings.setFactionTypeName(i,receivedGameSettings->getFactionTypeName(i)); + originalGamesettings.setFactionTypeName(i,receivedGameSettings->getFactionTypeName(i)); + } + displayedGamesettings.setNetworkPlayerGameStatus(i,receivedGameSettings->getNetworkPlayerGameStatus(i)); + originalGamesettings.setNetworkPlayerGameStatus(i,receivedGameSettings->getNetworkPlayerGameStatus(i)); + displayedGamesettings.setNetworkPlayerName(i,receivedGameSettings->getNetworkPlayerName(i)); + originalGamesettings.setNetworkPlayerName(i,receivedGameSettings->getNetworkPlayerName(i)); + } + } + } + else{ + //printf("I am client and restore everything but not my line\n"); + // copy all received fields just not those which are editable for normal client + //store my changes + int i=clientInterface->getPlayerIndex(); + int team=displayedGamesettings.getTeam(i); + string faction=displayedGamesettings.getFactionTypeName(i); + int status=displayedGamesettings.getNetworkPlayerGameStatus(i); + string networkPlayerName=displayedGamesettings.getNetworkPlayerName(i); + displayedGamesettings=*receivedGameSettings; + originalGamesettings=*receivedGameSettings; + + displayedGamesettings.setTeam(i,team); + originalGamesettings.setTeam(i,team); + displayedGamesettings.setFactionTypeName(i,faction); + originalGamesettings.setFactionTypeName(i,faction); + displayedGamesettings.setNetworkPlayerGameStatus(i,status); + originalGamesettings.setNetworkPlayerGameStatus(i,status); + displayedGamesettings.setNetworkPlayerName(i,networkPlayerName); + originalGamesettings.setNetworkPlayerName(i,networkPlayerName); + + } + setupUIFromGameSettings(&displayedGamesettings, errorOnMissingData); } + else { + // do nothing + setupUIFromGameSettings(&displayedGamesettings, errorOnMissingData); + } + broadCastGameSettingsToHeadlessServer(needToBroadcastServerSettings); } // check if we are joining an in progress game @@ -3477,7 +3594,26 @@ void MenuStateConnectedGame::update() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); launchingNewGame = true; - program->setState(new Game(program, clientInterface->getGameSettings(),false)); + + GameSettings gameSettings = *clientInterface->getGameSettings(); + // complete game settings with local stuff + if(gameSettings.getScenario()!="") + { + string scenario = gameSettings.getScenario(); + listBoxScenario.setSelectedItem(formatString(scenario)); + string file = Scenario::getScenarioPath(dirList, scenario); + + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, &scenarioInfo, isTutorial); + + gameSettings.setScenarioDir(Scenario::getScenarioPath(dirList, scenarioInfo.name)); + + gameSettings.setDefaultResources(scenarioInfo.defaultResources); + gameSettings.setDefaultUnits(scenarioInfo.defaultUnits); + gameSettings.setDefaultVictoryConditions(scenarioInfo.defaultVictoryConditions); + } + + program->setState(new Game(program, &gameSettings,false)); return; } } @@ -3490,12 +3626,11 @@ void MenuStateConnectedGame::update() { // check for need to switch music on again if(clientInterface != NULL) { - GameSettings *gameSettings = clientInterface->getGameSettingsPtr(); int currentConnectionCount=0; for(int i=0; i < GameConstants::maxPlayers; ++i) { - if(gameSettings->getFactionControl(i)==ctNetwork && - gameSettings->getNetworkPlayerName(i) != "" && - gameSettings->getNetworkPlayerName(i) != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) + if(displayedGamesettings.getFactionControl(i)==ctNetwork && + displayedGamesettings.getNetworkPlayerName(i) != "" && + displayedGamesettings.getNetworkPlayerName(i) != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { currentConnectionCount++; } @@ -3828,13 +3963,14 @@ bool MenuStateConnectedGame::loadMapInfo(string file, MapInfo *mapInfo, bool loa Lang &lang= Lang::getInstance(); if(MapPreview::loadMapInfo(file, mapInfo, lang.getString("MaxPlayers"),lang.getString("Size"),true) == true) { for(int i = 0; i < GameConstants::maxPlayers; ++i) { - labelPlayers[i].setVisible(i+1 <= mapInfo->players); - labelPlayerNames[i].setVisible(i+1 <= mapInfo->players); - listBoxControls[i].setVisible(i+1 <= mapInfo->players); - listBoxRMultiplier[i].setVisible(i+1 <= mapInfo->players); - listBoxFactions[i].setVisible(i+1 <= mapInfo->players); - listBoxTeams[i].setVisible(i+1 <= mapInfo->players); - labelNetStatus[i].setVisible(i+1 <= mapInfo->players); + bool visible=i+1 <= mapInfo->players; + labelPlayers[i].setVisible(visible); + labelPlayerNames[i].setVisible(visible); + listBoxControls[i].setVisible(visible); + listBoxRMultiplier[i].setVisible(visible); + listBoxFactions[i].setVisible(visible); + listBoxTeams[i].setVisible(visible); + labelNetStatus[i].setVisible(visible); } // Not painting properly so this is on hold @@ -4401,6 +4537,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, throw megaglest_runtime_error("gameSettings == NULL"); } + checkBoxScenario.setValue((gameSettings->getScenario() != "")); if(checkBoxScenario.getValue() == true) { int originalFOWValue = listBoxFogOfWar.getSelectedItemIndex(); @@ -4428,6 +4565,9 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, listBoxFogOfWar.setSelectedItemIndex(0); } + checkBoxAllowTeamUnitSharing.setValue(scenarioInfo.allowTeamUnitSharing); + checkBoxAllowTeamResourceSharing.setValue(scenarioInfo.allowTeamResourceSharing); + if(originalFOWValue != listBoxFogOfWar.getSelectedItemIndex()) { cleanupMapPreviewTexture(); } @@ -4441,8 +4581,8 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, //listBoxMap.setItems(formattedPlayerSortedMaps[gameSettings.getMapFilterIndex()]); //printf("A gameSettings->getTileset() [%s]\n",gameSettings->getTileset().c_str()); - if(getMissingTilesetFromFTPServerInProgress == false && - gameSettings->getTileset() != "") { + if ( getMissingTilesetFromFTPServerInProgress == false + && gameSettings->getTileset() != "") { // tileset tilesets = tilesetFiles; std::for_each(tilesets.begin(), tilesets.end(), FormatString()); @@ -4602,6 +4742,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, loadFactions(gameSettings,false); } + if(getMissingMapFromFTPServerInProgress == false && gameSettings->getMap() != "") { // map @@ -4655,9 +4796,13 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] listBoxMap.getSelectedItemIndex() = %d, mapFiles.size() = " MG_SIZE_T_SPECIFIER ", maps.size() = " MG_SIZE_T_SPECIFIER ", getCurrentMapFile() [%s] mapFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,listBoxMap.getSelectedItemIndex(),mapFiles.size(),maps.size(),getCurrentMapFile().c_str(),mapFile.c_str()); - if(!missingMap && mapFile!=listBoxMap.getSelectedItem()){ - console.addLine("Headless server does not have map, switching to next one"); - printf("Headless server doesn't have map '%s'. Setting map '%s' instead.\n",listBoxMap.getSelectedItem().c_str(),mapFile.c_str()); + if( isHeadlessAdmin() && !missingMap && mapFile!=listBoxMap.getSelectedItem()){ + //console.addLine("Headless server does not have map, switching to next one"); + if(isfirstSwitchingMapMessage){ + isfirstSwitchingMapMessage=false; + }else{ + console.addLine(Lang::getInstance().getString("HeadlessServerDoesNotHaveMap","",true)); + } } listBoxMap.setItems(maps); @@ -4714,6 +4859,8 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, checkBoxAllowTeamResourceSharing.setValue(false); } + checkBoxAllowNativeLanguageTechtree.setValue(gameSettings->getNetworkAllowNativeLanguageTechtree()); + // Control for(int i=0; igetFactionControl(i),errorOnMissingData); listBoxRMultiplier[slot].setSelectedItemIndex(gameSettings->getResourceMultiplierIndex(i),errorOnMissingData); - listBoxTeams[slot].setSelectedItemIndex(gameSettings->getTeam(i),errorOnMissingData); listBoxFactions[slot].setSelectedItem(formatString(gameSettings->getFactionTypeName(i)),false); + if( gameSettings->getFactionControl(i) == ctNetwork || gameSettings->getFactionControl(i) == ctNetworkUnassigned) { labelNetStatus[slot].setText(gameSettings->getNetworkPlayerName(i)); @@ -4821,13 +4968,12 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, labelPlayerNames[slot].setText(gameSettings->getNetworkPlayerName(i)); } } - - settingsReceivedFromServer=true; - initialSettingsReceivedFromServer=true; - - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time(NULL); } + settingsReceivedFromServer=true; + initialSettingsReceivedFromServer=true; + + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); } if(enableFactionTexturePreview == true) { @@ -4845,7 +4991,6 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings, } } - checkBoxAllowNativeLanguageTechtree.setValue(gameSettings->getNetworkAllowNativeLanguageTechtree()); } void MenuStateConnectedGame::initFactionPreview(const GameSettings *gameSettings) { @@ -4956,6 +5101,7 @@ void MenuStateConnectedGame::RestoreLastGameSettings() { needToBroadcastServerSettings=true; broadcastServerSettingsDelayTimer=time(NULL); + noReceiveTimer=time(NULL); } @@ -4968,11 +5114,12 @@ int MenuStateConnectedGame::setupMapList(string scenario) { string scenarioDir = Scenario::getScenarioDir(dirList, scenario); vector pathList = config.getPathListForType(ptMaps,scenarioDir); vector allMaps = MapPreview::findAllValidMaps(pathList,scenarioDir,false,true,&invalidMapList); - + // sort map list non case sensitive + std::sort(allMaps.begin(),allMaps.end(),compareNonCaseSensitive); if(scenario != "") { vector allMaps2 = MapPreview::findAllValidMaps(config.getPathListForType(ptMaps,""),"",false,true,&invalidMapList); copy(allMaps2.begin(), allMaps2.end(), std::inserter(allMaps, allMaps.begin())); - std::sort(allMaps.begin(),allMaps.end()); + std::sort(allMaps.begin(),allMaps.end(),compareNonCaseSensitive); } if (allMaps.empty()) { diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index d0fca6cca..54ccbd0f4 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -63,6 +63,7 @@ private: GraphicLabel labelMapInfo; GraphicLabel labelStatus; GraphicLabel labelInfo; + GraphicLabel labelWaitingForPlayers; GraphicButton buttonRestoreLastSettings; //GraphicLabel labelPathFinderType; @@ -89,7 +90,6 @@ private: GraphicListBox listBoxPlayerStatus; GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; - int nonAdminPlayerStatusX; GraphicLabel labelAllowObservers; GraphicCheckBox checkBoxAllowObservers; @@ -238,9 +238,18 @@ private: time_t broadcastServerSettingsDelayTimer; int lastGameSettingsReceivedCount; + time_t noReceiveTimer; + bool launchingNewGame; + bool isfirstSwitchingMapMessage; std::auto_ptr techTree; + GameSettings originalGamesettings; + bool validOriginalGameSettings; + GameSettings displayedGamesettings; + bool validDisplayedGamesettings; + + public: MenuStateConnectedGame(Program *program, MainMenu *mainMenu, JoinMenu joinMenuInfo=jmSimple, bool openNetworkSlots= false); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 5a22c621a..3cad62003 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -143,7 +143,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, this->dirList = Config::getInstance().getPathListForType(ptScenarios); mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox"); - mainMessageBox.init(lang.getString("Ok")); + mainMessageBox.init(lang.getString("Ok"),500,300); mainMessageBox.setEnabled(false); mainMessageBoxState=0; @@ -172,6 +172,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, needToSetChangedGameSettings = false; needToRepublishToMasterserver = false; needToBroadcastServerSettings = false; + lastGameSettingsreceivedCount = -1; showMasterserverError = false; tMasterserverErrorElapsed = 0; masterServererErrorToShow = "---"; @@ -193,16 +194,33 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, int xoffset=10; //create - int buttonx=200; + int buttonx=170; int buttony=180; + + // player status + listBoxPlayerStatus.registerGraphicComponent(containerName,"listBoxPlayerStatus"); + listBoxPlayerStatus.init(buttonx, buttony, 150); + vector playerStatuses; + playerStatuses.push_back(lang.getString("PlayerStatusSetup")); + playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.getString("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + listBoxPlayerStatus.setSelectedItemIndex(2,true); + listBoxPlayerStatus.setTextColor(Vec3f(0.0f,1.0f,0.0f)); + listBoxPlayerStatus.setLighted(false); + listBoxPlayerStatus.setVisible(true); + buttonx+=180; + buttonReturn.registerGraphicComponent(containerName,"buttonReturn"); buttonReturn.init(buttonx, buttony, 125); + buttonx+=130; buttonRestoreLastSettings.registerGraphicComponent(containerName,"buttonRestoreLastSettings"); - buttonRestoreLastSettings.init(buttonx+130, buttony, 220); + buttonRestoreLastSettings.init(buttonx, buttony, 220); + buttonx+=225; buttonPlayNow.registerGraphicComponent(containerName,"buttonPlayNow"); - buttonPlayNow.init(buttonx+130+225, buttony, 125); + buttonPlayNow.init(buttonx, buttony, 125); labelLocalGameVersion.registerGraphicComponent(containerName,"labelLocalGameVersion"); labelLocalGameVersion.init(10, networkHeadPos+labelOffset); @@ -356,19 +374,6 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, checkBoxAllowNativeLanguageTechtree.init(xoffset+650, mapHeadPos-70); checkBoxAllowNativeLanguageTechtree.setValue(false); - // player status - listBoxPlayerStatus.registerGraphicComponent(containerName,"listBoxPlayerStatus"); - listBoxPlayerStatus.init(810, buttony, 150); - vector playerStatuses; - playerStatuses.push_back(lang.getString("PlayerStatusSetup")); - playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); - playerStatuses.push_back(lang.getString("PlayerStatusReady")); - listBoxPlayerStatus.setItems(playerStatuses); - listBoxPlayerStatus.setSelectedItemIndex(2,true); - listBoxPlayerStatus.setTextColor(Vec3f(0.0f,1.0f,0.0f)); - listBoxPlayerStatus.setLighted(false); - listBoxPlayerStatus.setVisible(true); - // Network Scenario int scenarioX=810; int scenarioY=140; @@ -542,6 +547,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, listBoxTeams[i].registerGraphicComponent(containerName,"listBoxTeams" + intToStr(i)); listBoxTeams[i].init(xoffset+650, setupPos-30-i*rowHeight, 60); + listBoxTeams[i].setLighted(true); labelNetStatus[i].registerGraphicComponent(containerName,"labelNetStatus" + intToStr(i)); labelNetStatus[i].init(xoffset+715, setupPos-30-i*rowHeight, 60); @@ -733,7 +739,7 @@ void MenuStateCustomGame::reloadUI() { Config &config = Config::getInstance(); console.resetFonts(); - mainMessageBox.init(lang.getString("Ok")); + mainMessageBox.init(lang.getString("Ok"),500,300); if(EndsWith(glestVersionString, "-dev") == false){ @@ -2192,8 +2198,15 @@ void MenuStateCustomGame::render() { if(listBoxControls[i].getSelectedItemIndex()!=ctClosed){ renderer.renderListBox(&listBoxRMultiplier[i]); - renderer.renderListBox(&listBoxFactions[i]); + + int teamnumber=listBoxTeams[i].getSelectedItemIndex(); + Vec3f teamcolor=Vec3f(1.0f,1.0f,1.0f); + if(teamnumber>=0 && teamnumber<8){ + teamcolor=crcPlayerTextureCache[teamnumber]->getPixmap()->getPixel3f(0, 0); + } + listBoxTeams[i].setTextColor(teamcolor); + renderer.renderListBox(&listBoxTeams[i]); renderer.renderLabel(&labelNetStatus[i]); } @@ -2287,7 +2300,7 @@ void MenuStateCustomGame::render() { renderer.renderChatManager(&chatManager); } } - renderer.renderConsole(&console,showFullConsole,true); + renderer.renderConsole(&console,showFullConsole?consoleFull:consoleStoredAndNormal); } catch(const std::exception &ex) { char szBuf[8096]=""; @@ -2439,7 +2452,10 @@ void MenuStateCustomGame::update() { if(this->autoloadScenarioName != "") { listBoxScenario.setSelectedItem(formatString(this->autoloadScenarioName),false); - + lastSetChangedGameSettings = time(NULL); + if(serverInterface != NULL){ + lastGameSettingsreceivedCount=serverInterface->getGameSettingsUpdateCount(); + } if(listBoxScenario.getSelectedItem() != formatString(this->autoloadScenarioName)) { mainMessageBoxState=1; showMessageBox( "Could not find scenario name: " + formatString(this->autoloadScenarioName), "Scenario Missing", false); @@ -2489,7 +2505,7 @@ void MenuStateCustomGame::update() { publishText = lang.getString("PublishDisabled"); } - masterServererErrorToShow += publishText; + masterServererErrorToShow += "\n\n"+ publishText; showMasterserverError=false; mainMessageBoxState=1; showMessageBox( masterServererErrorToShow, lang.getString("ErrorFromMasterserver"), false); @@ -2845,7 +2861,15 @@ void MenuStateCustomGame::update() { if(needToPublishDelayed == false || headlessServerMode == true) { bool broadCastSettings = (difftime((long int)time(NULL),lastSetChangedGameSettings) >= BROADCAST_SETTINGS_SECONDS); - //printf("broadCastSettings = %d\n",broadCastSettings); + if(headlessServerMode==true){ + // publish settings directly when we receive them + ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + if(lastGameSettingsreceivedCountgetGameSettingsUpdateCount()){ + needToBroadcastServerSettings=true; + lastSetChangedGameSettings = time(NULL); + lastGameSettingsreceivedCount=serverInterface->getGameSettingsUpdateCount(); + } + } if(broadCastSettings == true) { needToBroadcastServerSettings=true; @@ -3081,8 +3105,7 @@ void MenuStateCustomGame::publishToMasterserver() { publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); //game info: - publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game"; - publishToServerInfo["serverTitle"] = labelGameName.getText(); + publishToServerInfo["serverTitle"] = gameSettings.getGameName(); //ip is automatically set //game setup info: @@ -3342,7 +3365,7 @@ void MenuStateCustomGame::simpleTaskForClients(BaseThread *callingThread) { } ServerInterface *serverInterface= NetworkManager::getInstance().getServerInterface(false); if(serverInterface != NULL) { - + lastGameSettingsreceivedCount++; if(this->headlessServerMode == false || (serverInterface->getGameSettingsUpdateCount() <= lastMasterServerSettingsUpdateCount)) { GameSettings gameSettings; loadGameSettings(&gameSettings); @@ -3422,6 +3445,8 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force setupUIFromGameSettings(*settings); } + gameSettings->setGameName(labelGameName.getText()); + // Test flags values //gameSettings->setFlagTypes1(ft1_show_map_resources); // @@ -3704,7 +3729,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,factionFiles[listBoxFactions[i].getSelectedItemIndex()].c_str()); gameSettings->setFactionTypeName(slotIndex, factionFiles[listBoxFactions[i].getSelectedItemIndex()]); - gameSettings->setNetworkPlayerName(slotIndex, "Closed"); + gameSettings->setNetworkPlayerName(slotIndex, GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); gameSettings->setNetworkPlayerUUID(slotIndex,""); gameSettings->setNetworkPlayerPlatform(slotIndex,""); @@ -3969,6 +3994,8 @@ void MenuStateCustomGame::setupUIFromGameSettings(const GameSettings &gameSettin else { listBoxFogOfWar.setSelectedItemIndex(0); } + checkBoxAllowTeamUnitSharing.setValue(scenarioInfo.allowTeamUnitSharing); + checkBoxAllowTeamResourceSharing.setValue(scenarioInfo.allowTeamResourceSharing); } setupMapList(gameSettings.getScenario()); setupTechList(gameSettings.getScenario(),false); @@ -4666,6 +4693,9 @@ void MenuStateCustomGame::processScenario() { listBoxFogOfWar.setSelectedItemIndex(0); } + checkBoxAllowTeamUnitSharing.setValue(scenarioInfo.allowTeamUnitSharing); + checkBoxAllowTeamResourceSharing.setValue(scenarioInfo.allowTeamResourceSharing); + setupTechList(scenarioInfo.name, false); listBoxTechTree.setSelectedItem(formatString(scenarioInfo.techTreeName)); reloadFactions(false,scenarioInfo.name); @@ -4836,6 +4866,8 @@ void MenuStateCustomGame::SetupUIForScenarios() { } listBoxFogOfWar.setEditable(false); checkBoxAllowObservers.setEditable(false); + checkBoxAllowTeamUnitSharing.setEditable(false); + checkBoxAllowTeamResourceSharing.setEditable(false); //listBoxPathFinderType.setEditable(false); checkBoxEnableSwitchTeamMode.setEditable(false); listBoxAISwitchTeamAcceptPercent.setEditable(false); @@ -4856,6 +4888,8 @@ void MenuStateCustomGame::SetupUIForScenarios() { } listBoxFogOfWar.setEditable(true); checkBoxAllowObservers.setEditable(true); + checkBoxAllowTeamUnitSharing.setEditable(true); + checkBoxAllowTeamResourceSharing.setEditable(true); //listBoxPathFinderType.setEditable(true); checkBoxEnableSwitchTeamMode.setEditable(true); listBoxAISwitchTeamAcceptPercent.setEditable(true); @@ -4887,11 +4921,12 @@ int MenuStateCustomGame::setupMapList(string scenario) { string scenarioDir = Scenario::getScenarioDir(dirList, scenario); vector pathList = config.getPathListForType(ptMaps,scenarioDir); vector allMaps = MapPreview::findAllValidMaps(pathList,scenarioDir,false,true,&invalidMapList); - + // sort map list non case sensitive + std::sort(allMaps.begin(),allMaps.end(),compareNonCaseSensitive); if(scenario != "") { vector allMaps2 = MapPreview::findAllValidMaps(config.getPathListForType(ptMaps,""),"",false,true,&invalidMapList); copy(allMaps2.begin(), allMaps2.end(), std::inserter(allMaps, allMaps.begin())); - std::sort(allMaps.begin(),allMaps.end()); + std::sort(allMaps.begin(),allMaps.end(),compareNonCaseSensitive); } if (allMaps.empty()) { diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index b2eb42648..54b6f4db6 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -220,6 +220,8 @@ private: string gameUUID; + int lastGameSettingsreceivedCount; + public: MenuStateCustomGame(Program *program, MainMenu *mainMenu , bool openNetworkSlots= false, ParentMenuState parentMenuState=pNewGame, diff --git a/source/glest_game/menu/menu_state_graphic_info.cpp b/source/glest_game/menu/menu_state_graphic_info.cpp index 2e7200942..41e2a9d40 100644 --- a/source/glest_game/menu/menu_state_graphic_info.cpp +++ b/source/glest_game/menu/menu_state_graphic_info.cpp @@ -141,7 +141,7 @@ void MenuStateGraphicInfo::render(){ renderer.renderLabel(&labelInternalInfo); renderer.renderLabel(&labelMoreInfo); - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); } void MenuStateGraphicInfo::keyDown(SDL_KeyboardEvent key) { diff --git a/source/glest_game/menu/menu_state_keysetup.cpp b/source/glest_game/menu/menu_state_keysetup.cpp index e420fdd4c..817b74a7c 100644 --- a/source/glest_game/menu/menu_state_keysetup.cpp +++ b/source/glest_game/menu/menu_state_keysetup.cpp @@ -445,7 +445,7 @@ void MenuStateKeysetup::render(){ renderer.renderScrollBar(&keyScrollBar); } - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/menu_state_load_game.cpp b/source/glest_game/menu/menu_state_load_game.cpp index 08492d947..f871e5ba4 100644 --- a/source/glest_game/menu/menu_state_load_game.cpp +++ b/source/glest_game/menu/menu_state_load_game.cpp @@ -85,8 +85,14 @@ MenuStateLoadGame::MenuStateLoadGame(Program *program, MainMenu *mainMenu): infoHeaderLabel.setFont3D(CoreData::getInstance().getMenuFontBig3D()); infoHeaderLabel.setText(lang.getString("SavegameInfo")); + versionWarningLabel.registerGraphicComponent(containerName,"versionWarningLabel"); + versionWarningLabel.init(550, 350); + versionWarningLabel.setText(""); + versionWarningLabel.setTextColor(Vec3f(1.0f,0.5f,0.5f)); + + infoTextLabel.registerGraphicComponent(containerName,"infoTextLabel"); - infoTextLabel.init(550, 350); + infoTextLabel.init(550, 310); infoTextLabel.setText(""); abortButton.registerGraphicComponent(containerName,"abortButton"); @@ -337,25 +343,26 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){ if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false) { char szBuf[8096]=""; snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str()); - infoTextLabel.setText(szBuf); + versionWarningLabel.setText(szBuf); } else { - XmlNode *gameNode = rootNode->getChild("Game"); - GameSettings newGameSettings; - newGameSettings.loadGame(gameNode); - - char szBuf[8096]=""; - snprintf(szBuf,8096,lang.getString("LoadSavedGameInfo").c_str(), - newGameSettings.getMap().c_str(), - newGameSettings.getTileset().c_str(), - newGameSettings.getTech().c_str(), - newGameSettings.getScenario().c_str(), - newGameSettings.getFactionCount(), - (newGameSettings.getThisFactionIndex() >= 0 && - newGameSettings.getThisFactionIndex() < newGameSettings.getFactionCount() ? - newGameSettings.getFactionTypeName(newGameSettings.getThisFactionIndex()).c_str() : "")); - infoTextLabel.setText(szBuf); + versionWarningLabel.setText(""); } + XmlNode *gameNode = rootNode->getChild("Game"); + GameSettings newGameSettings; + newGameSettings.loadGame(gameNode); + + char szBuf[8096]=""; + snprintf(szBuf,8096,lang.getString("LoadSavedGameInfo").c_str(), + newGameSettings.getMap().c_str(), + newGameSettings.getTileset().c_str(), + newGameSettings.getTech().c_str(), + newGameSettings.getScenario().c_str(), + newGameSettings.getFactionCount(), + (newGameSettings.getThisFactionIndex() >= 0 && + newGameSettings.getThisFactionIndex() < newGameSettings.getFactionCount() ? + newGameSettings.getFactionTypeName(newGameSettings.getThisFactionIndex()).c_str() : "")); + infoTextLabel.setText(szBuf); } catch(const megaglest_runtime_error &ex) { char szBuf[8096]=""; @@ -401,6 +408,8 @@ void MenuStateLoadGame::render() { renderer.renderLabel(&savedGamesLabel); renderer.renderLabel(&infoHeaderLabel); renderer.renderLabel(&infoTextLabel); + if(versionWarningLabel.getText()!="") + renderer.renderLabel(&versionWarningLabel); renderer.renderButton(&abortButton); renderer.renderButton(&deleteButton); @@ -434,7 +443,7 @@ void MenuStateLoadGame::render() { renderer.renderMessageBox(&mainMessageBox); } - renderer.renderConsole(&console,false,false); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/menu_state_load_game.h b/source/glest_game/menu/menu_state_load_game.h index 84e0d16ff..eeeb146ea 100644 --- a/source/glest_game/menu/menu_state_load_game.h +++ b/source/glest_game/menu/menu_state_load_game.h @@ -41,6 +41,7 @@ private: GraphicLabel savedGamesLabel; GraphicLabel infoHeaderLabel; GraphicLabel infoTextLabel; + GraphicLabel versionWarningLabel; GraphicLine lines[2]; diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index c6e1da1db..839eda39f 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -790,7 +790,7 @@ void MenuStateMasterserver::render(){ ircClient->getHasJoinedChannel() == true) { renderer.renderChatManager(&chatManager); } - renderer.renderConsole(&consoleIRC,false,true,21); + renderer.renderConsole(&consoleIRC,consoleStoredOnly,21); } if(program != NULL) program->renderProgramMsgBox(); @@ -857,7 +857,7 @@ void MenuStateMasterserver::update() { button->setFont(CoreData::getInstance().getDisplayFontSmall()); button->setFont3D(CoreData::getInstance().getDisplayFontSmall3D()); button->setText(nickList[i]); - if(strncmp(&nickList[i][0],"MG_",3) != 0) { + if(strncmp(&nickList[i][0],"MG_",3) != 0 || &nickList[i][0] == currentIrcNick) { button->setEnabled(false); button->setEditable(false); button->setCustomTexture(CoreData::getInstance().getCustomTexture()); diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp index 040c0c5ac..9182216ed 100644 --- a/source/glest_game/menu/menu_state_mods.cpp +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -2386,7 +2386,7 @@ void MenuStateMods::render() { } safeMutexFTPProgress.ReleaseLock(); - renderer.renderConsole(&console,showFullConsole,true,3); + renderer.renderConsole(&console,consoleNormal,3); if(mainMessageBox.getEnabled()) { renderer.renderMessageBox(&mainMessageBox); diff --git a/source/glest_game/menu/menu_state_new_game.cpp b/source/glest_game/menu/menu_state_new_game.cpp index af934419f..c509c88fa 100644 --- a/source/glest_game/menu/menu_state_new_game.cpp +++ b/source/glest_game/menu/menu_state_new_game.cpp @@ -137,7 +137,7 @@ void MenuStateNewGame::render(){ renderer.renderButton(&buttonTutorial); renderer.renderButton(&buttonReturn); - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/menu_state_options.cpp b/source/glest_game/menu/menu_state_options.cpp index f591e7a7c..6ba51bf06 100644 --- a/source/glest_game/menu/menu_state_options.cpp +++ b/source/glest_game/menu/menu_state_options.cpp @@ -227,6 +227,49 @@ MenuStateOptions::MenuStateOptions(Program *program, MainMenu *mainMenu, Program currentLine-=lineOffset; + labelHealthBars.registerGraphicComponent(containerName,"labelHealthBars"); + labelHealthBars.init(currentLabelStart ,currentLine); + labelHealthBars.setText(lang.getString("Healthbar")); + + listBoxHealthBars.registerGraphicComponent(containerName,"lisBoxtHealthBars"); + listBoxHealthBars.init(currentColumnStart ,currentLine, 300 ); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsFactionDefault")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsOff")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsAlways")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsIfNeeded")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsSelected")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsSelectedOrNeeded")); + + int hpMode=config.getInt("HealthBarMode","0"); + int hpIndex=0; + switch (hpMode) { + case hbvUndefined: + hpIndex = 0; + break; + case hbvOff: + hpIndex = 1; + break; + case hbvAlways: + hpIndex = 2; + break; + case hbvIfNeeded: + hpIndex = 3; + break; + case hbvSelected: + hpIndex = 4; + break; + case hbvSelected | hbvIfNeeded: + hpIndex = 5; + break; + default: + hpIndex = 0; + break; + } + + listBoxHealthBars.setSelectedItemIndex(hpIndex); + + currentLine-=lineOffset; + labelChatStaysActive.registerGraphicComponent(containerName,"labelChatStaysActive"); labelChatStaysActive.init(currentLabelStart ,currentLine); labelChatStaysActive.setText(lang.getString("ChatStaysActive")); @@ -274,7 +317,7 @@ MenuStateOptions::MenuStateOptions(Program *program, MainMenu *mainMenu, Program buttonReturn.setText(lang.getString("Return")); // Transifex related UI - currentLine-=lineOffset*4; + currentLine-=lineOffset*3; labelCustomTranslation.registerGraphicComponent(containerName,"labelCustomTranslation"); labelCustomTranslation.init(currentLabelStart ,currentLine); labelCustomTranslation.setText(lang.getString("CustomTranslation")); @@ -368,6 +411,7 @@ void MenuStateOptions::reloadUI() { buttonKeyboardSetup.setText(lang.getString("Keyboardsetup")); labelVisibleHud.setText(lang.getString("VisibleHUD")); + labelHealthBars.setText(lang.getString("HealthBars")); labelChatStaysActive.setText(lang.getString("ChatStaysActive")); labelTimeDisplay.setText(lang.getString("TimeDisplay")); @@ -922,6 +966,7 @@ void MenuStateOptions::mouseClick(int x, int y, MouseButton mouseButton){ checkBoxMouseMoveScrollsWorld.mouseClick(x, y); listCameraMoveSpeed.mouseClick(x, y); checkBoxVisibleHud.mouseClick(x, y); + listBoxHealthBars.mouseClick(x, y); checkBoxChatStaysActive.mouseClick(x, y); checkBoxTimeDisplay.mouseClick(x, y); checkBoxLuaDisableSecuritySandbox.mouseClick(x, y); @@ -952,6 +997,7 @@ void MenuStateOptions::mouseMove(int x, int y, const MouseState *ms){ checkBoxDisableScreenshotConsoleText.mouseMove(x, y); checkBoxMouseMoveScrollsWorld.mouseMove(x, y); listCameraMoveSpeed.mouseMove(x, y); + listBoxHealthBars.mouseMove(x, y); checkBoxVisibleHud.mouseMove(x, y); checkBoxChatStaysActive.mouseMove(x, y); checkBoxTimeDisplay.mouseMove(x, y); @@ -1039,6 +1085,8 @@ void MenuStateOptions::render(){ renderer.renderListBox(&listCameraMoveSpeed); renderer.renderLabel(&labelVisibleHud); + renderer.renderLabel(&labelHealthBars); + renderer.renderListBox(&listBoxHealthBars); renderer.renderLabel(&labelChatStaysActive); renderer.renderLabel(&labelTimeDisplay); @@ -1051,7 +1099,7 @@ void MenuStateOptions::render(){ } - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } @@ -1077,6 +1125,34 @@ void MenuStateOptions::saveConfig(){ config.setBool("DisableScreenshotConsoleText", !checkBoxDisableScreenshotConsoleText.getValue()); config.setBool("MouseMoveScrollsWorld", checkBoxMouseMoveScrollsWorld.getValue()); config.setString("CameraMoveSpeed", listCameraMoveSpeed.getSelectedItem()); + + int hpIndex=listBoxHealthBars.getSelectedItemIndex(); + int hpMode=hbvUndefined; + switch (hpIndex) { + case 0: + hpMode = hbvUndefined; + break; + case 1: + hpMode = hbvOff; + break; + case 2: + hpMode = hbvAlways; + break; + case 3: + hpMode = hbvIfNeeded; + break; + case 4: + hpMode = hbvSelected; + break; + case 5: + hpMode = hbvSelected | hbvIfNeeded; + break; + default: + hpMode = hbvUndefined; + break; + } + + config.setInt("HealthBarMode",hpMode ); config.setBool("VisibleHud", checkBoxVisibleHud.getValue()); config.setBool("ChatStaysActive", checkBoxChatStaysActive.getValue()); config.setBool("TimeDisplay", checkBoxTimeDisplay.getValue()); diff --git a/source/glest_game/menu/menu_state_options.h b/source/glest_game/menu/menu_state_options.h index 8a1e6d571..9996fba76 100644 --- a/source/glest_game/menu/menu_state_options.h +++ b/source/glest_game/menu/menu_state_options.h @@ -63,6 +63,9 @@ private: GraphicLabel labelVisibleHud; GraphicCheckBox checkBoxVisibleHud; + GraphicLabel labelHealthBars; + GraphicListBox listBoxHealthBars; + GraphicLabel labelTimeDisplay; GraphicCheckBox checkBoxTimeDisplay; GraphicLabel labelChatStaysActive; diff --git a/source/glest_game/menu/menu_state_options_graphics.cpp b/source/glest_game/menu/menu_state_options_graphics.cpp index 3aac17d79..d9aebef35 100644 --- a/source/glest_game/menu/menu_state_options_graphics.cpp +++ b/source/glest_game/menu/menu_state_options_graphics.cpp @@ -167,6 +167,21 @@ MenuStateOptionsGraphics::MenuStateOptionsGraphics(Program *program, MainMenu *m listBoxFilter.setSelectedItem(config.getString("Filter")); currentLine-=lineOffset; + //FilterMaxAnisotropy + labelFilterMaxAnisotropy.registerGraphicComponent(containerName,"labelFilterMaxAnisotropy"); + labelFilterMaxAnisotropy.init(currentLabelStart, currentLine); + labelFilterMaxAnisotropy.setText(lang.getString("FilterMaxAnisotropy")); + + listBoxFilterMaxAnisotropy.registerGraphicComponent(containerName,"listBoxFilterMaxAnisotropy"); + listBoxFilterMaxAnisotropy.init(currentColumnStart, currentLine, 200); + listBoxFilterMaxAnisotropy.pushBackItem("1"); + listBoxFilterMaxAnisotropy.pushBackItem("2"); + listBoxFilterMaxAnisotropy.pushBackItem("4"); + listBoxFilterMaxAnisotropy.pushBackItem("8"); + listBoxFilterMaxAnisotropy.pushBackItem("16"); + listBoxFilterMaxAnisotropy.setSelectedItem(config.getString("FilterMaxAnisotropy","1")); + currentLine-=lineOffset; + //selectionType labelSelectionType.registerGraphicComponent(containerName,"labelSelectionType"); labelSelectionType.init(currentLabelStart, currentLine); @@ -404,6 +419,15 @@ void MenuStateOptionsGraphics::reloadUI() { listboxData.push_back("Trilinear"); listBoxFilter.setItems(listboxData); + labelFilterMaxAnisotropy.setText(lang.getString("FilterMaxAnisotropy")); + listboxData.clear(); + listboxData.push_back("1"); + listboxData.push_back("2"); + listboxData.push_back("4"); + listboxData.push_back("8"); + listboxData.push_back("16"); + listBoxFilterMaxAnisotropy.setItems(listboxData); + listboxData.clear(); for (float f=0.0;f<2.1f;f=f+0.1f) { listboxData.push_back(floatToStr(f)); @@ -591,6 +615,14 @@ void MenuStateOptionsGraphics::mouseClick(int x, int y, MouseButton mouseButton) if(selectedMode == NULL) { throw megaglest_runtime_error("selectedMode == NULL"); } + +#if defined(__APPLE__) + mainMessageBoxState=1; + mainMessageBox.init(lang.getString("Ok"),lang.getString("Cancel")); + screenModeChangedTimer= time(NULL); + + showMessageBox(lang.getString("RestartNeeded"), lang.getString("ResolutionChanged"), false); +#else WindowGl *window = this->program->getWindow(); window->ChangeVideoMode(true, selectedMode->width, @@ -609,8 +641,9 @@ void MenuStateOptionsGraphics::mouseClick(int x, int y, MouseButton mouseButton) mainMessageBoxState=1; mainMessageBox.init(lang.getString("Ok"),lang.getString("Cancel")); screenModeChangedTimer= time(NULL); - //showMessageBox(lang.getString("RestartNeeded"), lang.getString("ResolutionChanged"), false); + showMessageBox(lang.getString("ResolutionChanged"), lang.getString("Notice"), false); +#endif //No saveConfig() here! this is done by the messageBox return; } @@ -687,6 +720,7 @@ void MenuStateOptionsGraphics::mouseClick(int x, int y, MouseButton mouseButton) listBoxShadowTextureSize.mouseClick(x, y); listBoxShadowIntensity.mouseClick(x, y); listBoxFilter.mouseClick(x, y); + listBoxFilterMaxAnisotropy.mouseClick(x, y); if(listBoxGammaCorrection.mouseClick(x, y)){ float gammaValue=strToFloat(listBoxGammaCorrection.getSelectedItem()); if(gammaValue!=0.0){ @@ -724,6 +758,7 @@ void MenuStateOptionsGraphics::mouseMove(int x, int y, const MouseState *ms){ buttonAutoConfig.mouseMove(x, y); buttonVideoInfo.mouseMove(x, y); listBoxFilter.mouseMove(x, y); + listBoxFilterMaxAnisotropy.mouseMove(x, y); listBoxGammaCorrection.mouseMove(x, y); listBoxShadowIntensity.mouseMove(x, y); listBoxSelectionType.mouseMove(x, y); @@ -800,6 +835,7 @@ void MenuStateOptionsGraphics::render(){ renderer.renderCheckBox(&checkBoxMapPreview); renderer.renderListBox(&listBoxLights); renderer.renderListBox(&listBoxFilter); + renderer.renderListBox(&listBoxFilterMaxAnisotropy); renderer.renderListBox(&listBoxGammaCorrection); renderer.renderListBox(&listBoxShadowIntensity); renderer.renderLabel(&labelShadows); @@ -811,6 +847,7 @@ void MenuStateOptionsGraphics::render(){ renderer.renderLabel(&labelMapPreview); renderer.renderLabel(&labelLights); renderer.renderLabel(&labelFilter); + renderer.renderLabel(&labelFilterMaxAnisotropy); renderer.renderLabel(&labelGammaCorrection); renderer.renderLabel(&labelShadowIntensity); renderer.renderLabel(&labelScreenModes); @@ -836,7 +873,7 @@ void MenuStateOptionsGraphics::render(){ renderer.renderCheckBox(&checkBoxVideos); } - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } @@ -864,6 +901,7 @@ void MenuStateOptionsGraphics::saveConfig(){ config.setBool("Windowed", checkBoxFullscreenWindowed.getValue()); config.setString("Filter", listBoxFilter.getSelectedItem()); + config.setInt("FilterMaxAnisotropy", strToInt(listBoxFilterMaxAnisotropy.getSelectedItem())); config.setFloat("GammaValue", strToFloat(listBoxGammaCorrection.getSelectedItem())); config.setFloat("ShadowIntensity", strToFloat(listBoxShadowIntensity.getSelectedItem())); config.setBool("Textures3D", checkBoxTextures3D.getValue()); diff --git a/source/glest_game/menu/menu_state_options_graphics.h b/source/glest_game/menu/menu_state_options_graphics.h index 48d701e08..75203ac6a 100644 --- a/source/glest_game/menu/menu_state_options_graphics.h +++ b/source/glest_game/menu/menu_state_options_graphics.h @@ -39,6 +39,9 @@ private: GraphicListBox listBoxShadows; GraphicLabel labelFilter; GraphicListBox listBoxFilter; + GraphicLabel labelFilterMaxAnisotropy; + GraphicListBox listBoxFilterMaxAnisotropy; + GraphicLabel labelTextures3D; GraphicCheckBox checkBoxTextures3D; GraphicLabel labelLights; diff --git a/source/glest_game/menu/menu_state_options_network.cpp b/source/glest_game/menu/menu_state_options_network.cpp index b6cd38e97..1e2bc53a1 100644 --- a/source/glest_game/menu/menu_state_options_network.cpp +++ b/source/glest_game/menu/menu_state_options_network.cpp @@ -499,7 +499,7 @@ void MenuStateOptionsNetwork::render(){ } - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/menu_state_options_sound.cpp b/source/glest_game/menu/menu_state_options_sound.cpp index 15e1ab8af..e20ced4a7 100644 --- a/source/glest_game/menu/menu_state_options_sound.cpp +++ b/source/glest_game/menu/menu_state_options_sound.cpp @@ -410,7 +410,7 @@ void MenuStateOptionsSound::render(){ } - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/menu_state_root.cpp b/source/glest_game/menu/menu_state_root.cpp index d1083d7f8..5fc5c139e 100644 --- a/source/glest_game/menu/menu_state_root.cpp +++ b/source/glest_game/menu/menu_state_root.cpp @@ -25,6 +25,7 @@ #include "network_message.h" #include "socket.h" #include "auto_test.h" +#include #include "leak_dumper.h" @@ -34,10 +35,16 @@ namespace Glest{ namespace Game{ // class MenuStateRoot // ===================================================== +bool MenuStateRoot::gameUpdateChecked = false; + MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu): - MenuState(program, mainMenu, "root") + MenuState(program, mainMenu, "root"), updatesHttpServerThread(NULL) { containerName = "MainMenu"; + + ftpClientThread = NULL; + lastDownloadProgress = 0; + Lang &lang= Lang::getInstance(); int yPos=440; @@ -87,6 +94,10 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu): errorMessageBox.init(lang.getString("Ok")); errorMessageBox.setEnabled(false); + ftpMessageBox.registerGraphicComponent(containerName,"ftpMessageBox"); + ftpMessageBox.init(lang.getString("Yes"), lang.getString("No")); + ftpMessageBox.setEnabled(false); + //PopupMenu popupMenu; std::vector menuItems; menuItems.push_back("1"); @@ -101,6 +112,57 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu): GraphicComponent::applyAllCustomProperties(containerName); } +MenuStateRoot::~MenuStateRoot() { + if(updatesHttpServerThread != NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + updatesHttpServerThread->setSimpleTaskInterfaceValid(false); + updatesHttpServerThread->signalQuit(); + updatesHttpServerThread->setThreadOwnerValid(false); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + if( updatesHttpServerThread->canShutdown(true) == true && + updatesHttpServerThread->shutdownAndWait() == true) { + delete updatesHttpServerThread; + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + updatesHttpServerThread = NULL; + } + + if(ftpClientThread != NULL) { + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if(ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } + else { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s %d] Error cannot shutdown ftpClientThread\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); + + //publishToMasterserverThread->cleanup(); + } + ftpClientThread = NULL; + +// ftpClientThread->signalQuit(); +// ftpClientThread->setCallBackObject(NULL); +// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +// if( ftpClientThread->shutdownAndWait() == true) { +// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +// delete ftpClientThread; +// } +// ftpClientThread = NULL; +// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + +} + void MenuStateRoot::reloadUI() { Lang &lang= Lang::getInstance(); @@ -122,6 +184,8 @@ void MenuStateRoot::reloadUI() { mainMessageBox.init(lang.getString("Yes"), lang.getString("No")); errorMessageBox.init(lang.getString("Ok")); + ftpMessageBox.init(lang.getString("Yes"), lang.getString("No")); + console.resetFonts(); GraphicComponent::reloadFontsForRegisterGraphicComponents(containerName); @@ -163,6 +227,28 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){ errorMessageBox.setEnabled(false); } } + + else if(ftpMessageBox.getEnabled()) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + int button= 0; + if(ftpMessageBox.mouseClick(x, y, button)) { + ftpMessageBox.setEnabled(false); + if(button == 0) { + startFTPClientIfRequired(); + + lastDownloadProgress = 0; + printf("Adding ftpFileName [%s] ftpFileURL [%s]\n",ftpFileName.c_str(),ftpFileURL.c_str()); + if(ftpClientThread != NULL) ftpClientThread->addTempFileToRequests(ftpFileName,ftpFileURL); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),mutexOwnerId); + if(ftpClientThread != NULL && ftpClientThread->getProgressMutex() != NULL) ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList[ftpFileName] = pair(0,""); + safeMutexFTPProgress.ReleaseLock(); + } + } + } else if(mainMessageBox.getEnabled() == false && buttonNewGame.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); mainMenu->setState(new MenuStateNewGame(program, mainMenu)); @@ -196,6 +282,201 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){ } } +void MenuStateRoot::startFTPClientIfRequired() { + if(ftpClientThread == NULL) { + // Setup File Transfer thread + Config &config = Config::getInstance(); + + vector tilesetFiles; + vector tilesetFilesUserData; + + vector techTreeFiles; + vector techTreeFilesUserData; + + + findDirs(config.getPathListForType(ptTilesets), tilesetFiles); + findDirs(config.getPathListForType(ptTechs), techTreeFiles); + + vector mapPathList = config.getPathListForType(ptMaps); + std::pair mapsPath; + if(mapPathList.empty() == false) { + mapsPath.first = mapPathList[0]; + } + if(mapPathList.size() > 1) { + mapsPath.second = mapPathList[1]; + } + std::pair tilesetsPath; + vector tilesetsList = Config::getInstance().getPathListForType(ptTilesets); + if(tilesetsList.empty() == false) { + tilesetsPath.first = tilesetsList[0]; + if(tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair techtreesPath; + vector techtreesList = Config::getInstance().getPathListForType(ptTechs); + if(techtreesList.empty() == false) { + techtreesPath.first = techtreesList[0]; + if(techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + std::pair scenariosPath; + vector scenariosList = Config::getInstance().getPathListForType(ptScenarios); + if(scenariosList.empty() == false) { + scenariosPath.first = scenariosList[0]; + if(scenariosList.size() > 1) { + scenariosPath.second = scenariosList[1]; + } + } + + string fileArchiveExtension = config.getString("FileArchiveExtension",""); + string fileArchiveExtractCommand = config.getString("FileArchiveExtractCommand",""); + string fileArchiveExtractCommandParameters = config.getString("FileArchiveExtractCommandParameters",""); + int32 fileArchiveExtractCommandSuccessResult = config.getInt("FileArchiveExtractCommandSuccessResult","0"); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + console.setOnlyChatMessagesInStoredLines(false); + + // Get path to temp files + string tempFilePath = "temp/"; + if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath; + } + else { + string userData = config.getString("UserData_Root",""); + if(userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str()); + + ftpClientThread = new FTPClientThread(-1,"", + mapsPath,tilesetsPath,techtreesPath,scenariosPath, + this,fileArchiveExtension,fileArchiveExtractCommand, + fileArchiveExtractCommandParameters, + fileArchiveExtractCommandSuccessResult, + tempFilePath); + ftpClientThread->start(); + + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + } +} + +void MenuStateRoot::FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result,void *userdata) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + Lang &lang= Lang::getInstance(); + if(type == ftp_cct_DownloadProgress) { + FTPClientCallbackInterface::FtpProgressStats *stats = (FTPClientCallbackInterface::FtpProgressStats *)userdata; + if(stats != NULL) { + int fileProgress = 0; + if(stats->download_total > 0) { + fileProgress = ((stats->download_now / stats->download_total) * 100.0); + } + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),mutexOwnerId); + if(ftpClientThread != NULL && ftpClientThread->getProgressMutex() != NULL) ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + pair lastProgress = fileFTPProgressList[itemName]; + fileFTPProgressList[itemName] = pair(fileProgress,stats->currentFilename); + safeMutexFTPProgress.ReleaseLock(); + + if(itemName != "" && (lastDownloadProgress < fileProgress && fileProgress % 25 == 0)) { + lastDownloadProgress = fileProgress; + + char szBuf[8096]=""; + snprintf(szBuf,8096,"Downloaded %d%% of file: %s",fileProgress,itemName.c_str()); + console.addLine(szBuf); + } + } + } + else if(type == ftp_cct_ExtractProgress) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP extract Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); + printf("Got FTP extract Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); + + if(userdata == NULL) { + char szBuf[8096]=""; + snprintf(szBuf,8096,lang.getString("DataMissingExtractDownloadMod").c_str(),itemName.c_str()); + //printf("%s\n",szBuf); + console.addLine(szBuf,true); + } + else { + char *szBuf = (char *)userdata; + //printf("%s\n",szBuf); + console.addLine(szBuf); + } + } + else if(type == ftp_cct_TempFile) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),mutexOwnerId); + if(ftpClientThread != NULL && ftpClientThread->getProgressMutex() != NULL) ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("### downloaded TEMP file [%s] result = %d\n",itemName.c_str(),result.first); + + if(result.first == ftp_crt_SUCCESS) { + // Get path to temp files + string tempFilePath = "temp/"; + if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath; + } + else { + Config &config = Config::getInstance(); + string userData = config.getString("UserData_Root",""); + if(userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str()); + + // Delete the downloaded archive + if(fileExists(tempFilePath + itemName)) { + removeFile(tempFilePath + itemName); + } + + bool result = upgradeFilesInTemp(); + if(result == false) { + string binaryName = Properties::getApplicationPath() + extractFileFromDirectoryPath(PlatformExceptionHandler::application_binary); + string binaryNameOld = Properties::getApplicationPath() + extractFileFromDirectoryPath(PlatformExceptionHandler::application_binary) + "__REMOVE"; + bool resultRename = renameFile(binaryName,binaryNameOld); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename); + printf("#1 Rename: [%s] to [%s] result = %d errno = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename, errno); + + //result = upgradeFilesInTemp(); + binaryName = Properties::getApplicationPath() + extractFileFromDirectoryPath(PlatformExceptionHandler::application_binary); + binaryNameOld = tempFilePath + extractFileFromDirectoryPath(PlatformExceptionHandler::application_binary); + resultRename = renameFile(binaryNameOld, binaryName); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename); + printf("#2 Rename: [%s] to [%s] result = %d errno = %d\n",binaryNameOld.c_str(),binaryName.c_str(),resultRename, errno); + } + + console.addLine("Successfully updated, please restart!",true); + } + else { + curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW); + + char szBuf[8096]=""; + snprintf(szBuf,8096,"FAILED to download the updates: [%s] using CURL version [%s] [%s]",itemName.c_str(),curlVersion->version,result.second.c_str()); + console.addLine(szBuf,true); + showErrorMessageBox(szBuf, "ERROR", false); + } + } +} + + void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){ popupMenu.mouseMove(x, y); buttonNewGame.mouseMove(x, y); @@ -210,6 +491,9 @@ void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){ if (errorMessageBox.getEnabled()) { errorMessageBox.mouseMove(x, y); } + if (ftpMessageBox.getEnabled()) { + ftpMessageBox.mouseMove(x, y); + } } bool MenuStateRoot::isMasterserverMode() const { @@ -279,7 +563,7 @@ void MenuStateRoot::render() { renderer.renderButton(&buttonExit); renderer.renderLabel(&labelVersion); - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); renderer.renderPopupMenu(&popupMenu); @@ -290,6 +574,9 @@ void MenuStateRoot::render() { if(errorMessageBox.getEnabled()) { renderer.renderMessageBox(&errorMessageBox); } + if(ftpMessageBox.getEnabled()) { + renderer.renderMessageBox(&ftpMessageBox); + } if(program != NULL) program->renderProgramMsgBox(); } @@ -304,9 +591,109 @@ void MenuStateRoot::update() { } return; } + + if(gameUpdateChecked == false) { + gameUpdateChecked = true; + + string updateCheckURL = Config::getInstance().getString("UpdateCheckURL",""); + if(updateCheckURL != "") { + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + updatesHttpServerThread = new SimpleTaskThread(this,1,200); + updatesHttpServerThread->setUniqueID(mutexOwnerId); + updatesHttpServerThread->start(); + } + } + console.update(); } +void MenuStateRoot::simpleTask(BaseThread *callingThread,void *userdata) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutexThreadOwner(callingThread->getMutexThreadOwnerValid(),mutexOwnerId); + if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + return; + } + + callingThread->getMutexThreadOwnerValid()->setOwnerId(mutexOwnerId); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + + string updateCheckURL = Config::getInstance().getString("UpdateCheckURL",""); + if(updateCheckURL != "") { + + string baseURL = updateCheckURL; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] About to call first http url, base [%s]..\n",__FILE__,__FUNCTION__,__LINE__,baseURL.c_str()); + + CURL *handle = SystemFlags::initHTTP(); + CURLcode curlResult = CURLE_OK; + string updateMetaData = SystemFlags::getHTTP(baseURL,handle,-1,&curlResult); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("techsMetaData [%s] curlResult = %d\n",updateMetaData.c_str(),curlResult); + + if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + return; + } + + if(curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] curlError [%s]..\n",__FILE__,__FUNCTION__,__LINE__,curlError.c_str()); + + char szMsg[8096]=""; + snprintf(szMsg,8096,"An error was detected while checking for new updates\n%s",curlError.c_str()); + showErrorMessageBox(szMsg, "ERROR", false); + } + + if(curlResult == CURLE_OK || + (curlResult != CURLE_COULDNT_RESOLVE_HOST && + curlResult != CURLE_COULDNT_CONNECT)) { + + Properties props; + props.loadFromText(updateMetaData); + + int compareResult = compareMajorMinorVersion(glestVersionString, props.getString("LatestGameVersion","")); + if(compareResult==0) { + if(glestVersionString != props.getString("LatestGameVersion","")) { + compareResult = -1; + } + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("compareResult = %d local [%s] remote [%s]\n",compareResult,glestVersionString.c_str(),props.getString("LatestGameVersion","").c_str()); + + if(compareResult < 0) { + + string downloadBinaryKey = "LatestGameBinaryUpdateArchiveURL-" + getPlatformTypeNameString() + getPlatformArchTypeNameString(); + if(props.hasString(downloadBinaryKey)) { + ftpFileName = extractFileFromDirectoryPath(props.getString(downloadBinaryKey)); + ftpFileURL = props.getString(downloadBinaryKey); + } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Checking update key downloadBinaryKey [%s] ftpFileURL [%s]\n",downloadBinaryKey.c_str(),ftpFileURL.c_str()); + + if(props.getBool("AllowUpdateDownloads","false") == false || ftpFileURL == "") { + char szMsg[8096]=""; + snprintf(szMsg,8096,"A new update was detected: %s\nUpdate Date: %s\nPlease visit megaglest.org for details!", + props.getString("LatestGameVersion","?").c_str(), + props.getString("LatestGameVersionReleaseDate","?").c_str()); + showFTPMessageBox(szMsg, "Update", false, true); + } + else { + char szMsg[8096]=""; + snprintf(szMsg,8096,"A new update was detected: %s\nUpdate Date: %s\nDownload update now?", + props.getString("LatestGameVersion","?").c_str(), + props.getString("LatestGameVersionReleaseDate","?").c_str()); + showFTPMessageBox(szMsg, "Update", false, false); + } + } + } + SystemFlags::cleanupHTTP(&handle); + } +} + void MenuStateRoot::keyDown(SDL_KeyboardEvent key) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym); @@ -344,34 +731,58 @@ void MenuStateRoot::keyDown(SDL_KeyboardEvent key) { } -void MenuStateRoot::showMessageBox(const string &text, const string &header, bool toggle){ - if(!toggle){ +void MenuStateRoot::showMessageBox(const string &text, const string &header, bool toggle) { + if(toggle == false) { mainMessageBox.setEnabled(false); } - if(!mainMessageBox.getEnabled()){ + if(mainMessageBox.getEnabled() == false) { mainMessageBox.setText(text); mainMessageBox.setHeader(header); mainMessageBox.setEnabled(true); } - else{ + else { mainMessageBox.setEnabled(false); } } -void MenuStateRoot::showErrorMessageBox(const string &text, const string &header, bool toggle){ - if(!toggle){ +void MenuStateRoot::showErrorMessageBox(const string &text, const string &header, bool toggle) { + if(toggle == false) { errorMessageBox.setEnabled(false); } - if(!errorMessageBox.getEnabled()){ + if(errorMessageBox.getEnabled() == false) { errorMessageBox.setText(text); errorMessageBox.setHeader(header); errorMessageBox.setEnabled(true); } - else{ + else { errorMessageBox.setEnabled(false); } } +void MenuStateRoot::showFTPMessageBox(const string &text, const string &header, bool toggle, bool okOnly) { + if(toggle == false) { + ftpMessageBox.setEnabled(false); + } + + Lang &lang= Lang::getInstance(); + if(okOnly) { + ftpMessageBox.init(lang.getString("Ok")); + } + else { + ftpMessageBox.init(lang.getString("Yes"), lang.getString("No")); + } + + if(ftpMessageBox.getEnabled() == false) { + ftpMessageBox.setText(text); + ftpMessageBox.setHeader(header); + ftpMessageBox.setEnabled(true); + } + else { + ftpMessageBox.setEnabled(false); + } +} + + }}//end namespace diff --git a/source/glest_game/menu/menu_state_root.h b/source/glest_game/menu/menu_state_root.h index 23aa073aa..71811fa43 100644 --- a/source/glest_game/menu/menu_state_root.h +++ b/source/glest_game/menu/menu_state_root.h @@ -13,6 +13,9 @@ #define _GLEST_GAME_MENUSTATEROOT_H_ #include "main_menu.h" +#include "simple_threads.h" +#include "miniftpclient.h" + #include "leak_dumper.h" namespace Glest{ namespace Game{ @@ -24,7 +27,7 @@ namespace Glest{ namespace Game{ class GraphicMessageBox; class PopupMenu; -class MenuStateRoot: public MenuState { +class MenuStateRoot: public MenuState, public SimpleTaskCallbackInterface, public FTPClientCallbackInterface { private: GraphicButton buttonNewGame; GraphicButton buttonLoadGame; @@ -36,20 +39,36 @@ private: GraphicMessageBox mainMessageBox; GraphicMessageBox errorMessageBox; + GraphicMessageBox ftpMessageBox; PopupMenu popupMenu; + static bool gameUpdateChecked; + SimpleTaskThread *updatesHttpServerThread; + FTPClientThread *ftpClientThread; + std::map > fileFTPProgressList; + string ftpFileName; + string ftpFileURL; + int lastDownloadProgress; + + virtual void simpleTask(BaseThread *callingThread,void *userdata); + void startFTPClientIfRequired(); + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result,void *userdata); + public: MenuStateRoot(Program *program, MainMenu *mainMenu); + virtual ~MenuStateRoot(); void mouseClick(int x, int y, MouseButton mouseButton); void mouseMove(int x, int y, const MouseState *mouseState); void render(); void update(); virtual void keyDown(SDL_KeyboardEvent key); - void showMessageBox(const string &text, const string &header, bool toggle); + void showMessageBox(const string &text, const string &header, bool toggle); void showErrorMessageBox(const string &text, const string &header, bool toggle); + void showFTPMessageBox(const string &text, const string &header, bool toggle, bool okOnly); virtual bool isMasterserverMode() const; virtual void reloadUI(); diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index 0a7e4aace..fd20a609a 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -301,7 +301,7 @@ void MenuStateScenario::render(){ renderer.renderButton(&buttonReturn); renderer.renderButton(&buttonPlayNow); } - renderer.renderConsole(&console,false,true); + renderer.renderConsole(&console); if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/server_line.cpp b/source/glest_game/menu/server_line.cpp index b494ade8b..7b34c8171 100644 --- a/source/glest_game/menu/server_line.cpp +++ b/source/glest_game/menu/server_line.cpp @@ -49,6 +49,8 @@ ServerLine::ServerLine(MasterServerInfo *mServerInfo, int lineIndex, int baseY, //general info: //i+= 10; glestVersionLabel.init(i, baseY - lineOffset); + glestVersionLabel.setRenderBackground(true); + glestVersionLabel.setMaxEditRenderWidth(960); // use background for whole line glestVersionLabel.setTextColor(color); glestVersionLabel.setText(masterServerInfo.getGlestVersion()); glestVersionLabel.setFont(CoreData::getInstance().getDisplayFontSmall()); @@ -152,6 +154,7 @@ ServerLine::ServerLine(MasterServerInfo *mServerInfo, int lineIndex, int baseY, i+= 130; selectButton.init(i, baseY - lineOffset, 30); selectButton.setText(">"); + selectButton.setAlwaysLighted(true); //printf("glestVersionString [%s] masterServerInfo->getGlestVersion() [%s]\n",glestVersionString.c_str(),masterServerInfo->getGlestVersion().c_str()); compatible= checkVersionComptability(glestVersionString, masterServerInfo.getGlestVersion()); @@ -218,20 +221,6 @@ bool ServerLine::buttonMouseMove(int x, int y){ void ServerLine::render(){ Renderer &renderer= Renderer::getInstance(); - - bool joinEnabled= (masterServerInfo.getNetworkSlots() > masterServerInfo.getConnectedClients()); - if(joinEnabled == true){ - if(compatible){ - selectButton.setEnabled(true); - selectButton.setVisible(true); - renderer.renderButton(&selectButton); - } - } - else{ - selectButton.setEnabled(false); - selectButton.setVisible(false); - } - //general info: renderer.renderLabel(&glestVersionLabel); renderer.renderLabel(&platformLabel); @@ -264,6 +253,18 @@ void ServerLine::render(){ } renderer.renderLabel(&status); + bool joinEnabled= (masterServerInfo.getNetworkSlots() > masterServerInfo.getConnectedClients()); + if(joinEnabled == true){ + if(compatible){ + selectButton.setEnabled(true); + selectButton.setVisible(true); + renderer.renderButton(&selectButton); + } + } + else{ + selectButton.setEnabled(false); + selectButton.setVisible(false); + } } void ServerLine::setY(int y){ diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index f73236049..1a18a3a38 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -250,6 +250,11 @@ void ConnectionSlotThread::execute() { //bool socketHasReadData = Socket::hasDataToRead(socket->getSocketId()); bool socketHasReadData = Socket::hasDataToReadWithWait(socketId,150000); + if(getQuitStatus() == true) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + break; + } + ConnectionSlotEvent eventCopy; eventCopy.eventType = eReceiveSocketData; eventCopy.connectionSlot = this->slotInterface->getSlot(slotIndex,true); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index d8f3414a7..96bb9c5df 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -2866,7 +2866,7 @@ std::map ServerInterface::publishToMasterserver() { publishToServerInfo["glestVersion"] = glestVersionString; publishToServerInfo["platform"] = getPlatformNameString() + "-" + getGITRevisionString(); publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); - publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game"; + publishToServerInfo["serverTitle"] = this->getGameSettings()->getGameName(); publishToServerInfo["tech"] = this->getGameSettings()->getTech(); publishToServerInfo["map"] = this->getGameSettings()->getMap(); publishToServerInfo["tileset"] = this->getGameSettings()->getTileset(); diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index aad40ae41..14bf5f299 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -673,6 +673,19 @@ bool Faction::canUnitsPathfind() { return result; } +void Faction::setLockedUnitForFaction(const UnitType *ut, bool lock) { + if (lock) { + lockedUnits.insert(ut); + } else { + std::set::iterator it; + it=lockedUnits.find(ut); + if(it!=lockedUnits.end()) { + lockedUnits.erase(it); + } + } + +} + void Faction::signalWorkerThread(int frameIndex) { if(workerThread != NULL) { workerThread->signalPathfinder(frameIndex); @@ -718,9 +731,13 @@ void Faction::init( store[index].init(rt, 0); this->world->initTeamResource(rt,this->teamIndex,0); - this->updateUnitTypeWithResourceCostCache(rt); } } + //initialize cache + for(int index = 0; index < techTree->getResourceTypeCount(); ++index) { + const ResourceType *rt = techTree->getResourceType(index); + this->updateUnitTypeWithResourceCostCache(rt); + } texture= Renderer::getInstance().newTexture2D(rsGame); string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey); @@ -913,6 +930,10 @@ bool Faction::reqsOk(const RequirableType *rt) const { return false; } } + + if(producedUnitType != NULL && isUnitLocked(producedUnitType)) { + return false; + } } return true; @@ -1203,7 +1224,7 @@ void Faction::applyCostsOnInterval(const ResourceType *rtApply) { //decrease unit hp if(scriptManager->getPlayerModifiers(this->index)->getConsumeEnabled() == true) { - bool decHpResult = unit->decHp(unit->getType()->getMaxHp() / 3); + bool decHpResult = unit->decHp(unit->getType()->getTotalMaxHp(unit->getTotalUpgrade()) / 3); if(decHpResult) { unit->setCauseOfDeath(ucodStarvedResource); world->getStats()->die(unit->getFactionIndex(),unit->getType()->getCountUnitDeathInStats()); @@ -1261,14 +1282,29 @@ bool Faction::isAlly(const Faction *faction) { // ================== misc ================== void Faction::incResourceAmount(const ResourceType *rt, int amount) { - for(int i=0; i < (int)resources.size(); ++i) { - Resource *r= &resources[i]; - if(r->getType()==rt) { - r->setAmount(r->getAmount()+amount); - if(r->getType()->getClass() != rcStatic && r->getAmount()>getStoreAmount(rt)) { - r->setAmount(getStoreAmount(rt)); + if (world != NULL && world->getGame() != NULL + && world->getGame()->isFlagType1BitEnabled( + ft1_allow_shared_team_resources) == true) { + for(int i=0; i < (int)resources.size(); ++i) { + Resource *r= &resources[i]; + if(r->getType()==rt) { + r->setAmount(r->getAmount()+amount); + if(r->getType()->getClass() != rcStatic && (getResource(rt,false)->getAmount()+amount)>getStoreAmount(rt,false)) { + r->setAmount(getStoreAmount(rt,false)-(getResource(rt,false)->getAmount()-r->getAmount())); + } + return; + } + } + } else { + for(int i=0; i < (int)resources.size(); ++i) { + Resource *r= &resources[i]; + if(r->getType()==rt) { + r->setAmount(r->getAmount()+amount); + if(r->getType()->getClass() != rcStatic && r->getAmount()>getStoreAmount(rt)) { + r->setAmount(getStoreAmount(rt)); + } + return; } - return; } } assert(false); @@ -1318,7 +1354,7 @@ void Faction::removeUnit(Unit *unit){ //assert(false); } -void Faction::addStore(const UnitType *unitType, bool replaceStorage) { +void Faction::addStore(const UnitType *unitType) { assert(unitType != NULL); for(int newUnitStoredResourceIndex = 0; newUnitStoredResourceIndex < unitType->getStoredResourceCount(); @@ -1331,12 +1367,7 @@ void Faction::addStore(const UnitType *unitType, bool replaceStorage) { Resource *storedResource= &store[currentStoredResourceIndex]; if(storedResource->getType() == newUnitStoredResource->getType()) { - if(replaceStorage == true) { - storedResource->setAmount(newUnitStoredResource->getAmount()); - } - else { - storedResource->setAmount(storedResource->getAmount() + newUnitStoredResource->getAmount()); - } + storedResource->setAmount(storedResource->getAmount() + newUnitStoredResource->getAmount()); } } } @@ -1357,11 +1388,23 @@ void Faction::removeStore(const UnitType *unitType){ } void Faction::limitResourcesToStore() { - for(int i=0; i < (int)resources.size(); ++i) { - Resource *r= &resources[i]; - Resource *s= &store[i]; - if(r->getType()->getClass() != rcStatic && r->getAmount()>s->getAmount()) { - r->setAmount(s->getAmount()); + if (world != NULL && world->getGame() != NULL + && world->getGame()->isFlagType1BitEnabled( + ft1_allow_shared_team_resources) == true) { + for(int i=0; i < (int)resources.size(); ++i) { + Resource *r= &resources[i]; + const ResourceType *rt= r->getType(); + if(rt->getClass() != rcStatic && (getResource(rt,false)->getAmount())>getStoreAmount(rt,false)) { + r->setAmount(getStoreAmount(rt,false)-(getResource(rt,false)->getAmount()-r->getAmount())); + } + } + } else { + for(int i=0; i < (int)resources.size(); ++i) { + Resource *r= &resources[i]; + Resource *s= &store[i]; + if(r->getType()->getClass() != rcStatic && r->getAmount()>s->getAmount()) { + r->setAmount(s->getAmount()); + } } } } @@ -2250,6 +2293,13 @@ void Faction::saveGame(XmlNode *rootNode) { factionNode->addAttribute("currentSwitchTeamVoteFactionIndex",intToStr(currentSwitchTeamVoteFactionIndex), mapTagReplacements); factionNode->addAttribute("allowSharedTeamUnits",intToStr(allowSharedTeamUnits), mapTagReplacements); + for(std::set::iterator iterMap = lockedUnits.begin(); + iterMap != lockedUnits.end(); ++iterMap) { + XmlNode *lockedUnitsListNode = factionNode->addChild("lockedUnitList"); + const UnitType *ut=*iterMap; + + lockedUnitsListNode->addAttribute("value",ut->getName(false), mapTagReplacements); + } for(std::map::iterator iterMap = unitsMovingList.begin(); iterMap != unitsMovingList.end(); ++iterMap) { @@ -2342,6 +2392,14 @@ void Faction::loadGame(const XmlNode *rootNode, int factionIndex,GameSettings *s random.setLastNumber(factionNode->getAttribute("random")->getIntValue()); + vector lockedUnitsListNodeList = factionNode->getChildList("lockedUnitList"); + for(unsigned int i = 0; i < lockedUnitsListNodeList.size(); ++i) { + XmlNode *lockedUnitsListNode = lockedUnitsListNodeList[i]; + + string unitName = lockedUnitsListNode->getAttribute("value")->getValue(); + lockedUnits.insert(getType()->getUnitType(unitName)); + } + vector unitsMovingListNodeList = factionNode->getChildList("unitsMovingList"); for(unsigned int i = 0; i < unitsMovingListNodeList.size(); ++i) { XmlNode *unitsMovingListNode = unitsMovingListNodeList[i]; diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 79db2a9a0..946ac31b3 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -174,6 +174,8 @@ private: std::map unitsMovingList; std::map unitsPathfindingList; + std::set lockedUnits; + TechTree *techTree; const XmlNode *loadWorldNode; @@ -244,6 +246,9 @@ public: void clearUnitsPathfinding(); bool canUnitsPathfind(); + void setLockedUnitForFaction(const UnitType *ut, bool lock); + bool isUnitLocked(const UnitType *ut) const { return lockedUnits.find(ut)!=lockedUnits.end(); } + void init( FactionType *factionType, ControlType control, TechTree *techTree, Game *game, int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, @@ -324,7 +329,7 @@ public: Unit *findUnit(int id) const; void addUnit(Unit *unit); void removeUnit(Unit *unit); - void addStore(const UnitType *unitType, bool replaceStorage); + void addStore(const UnitType *unitType); void removeStore(const UnitType *unitType); //resources diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp index 4bafffb73..29b565b00 100644 --- a/source/glest_game/type_instances/object.cpp +++ b/source/glest_game/type_instances/object.cpp @@ -113,6 +113,7 @@ void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleType for(ObjectParticleSystemTypes::const_iterator it= particleTypes->begin(); it != particleTypes->end(); ++it){ UnitParticleSystem *ups= new UnitParticleSystem(200); ups->setParticleOwner(this); + ups->setParticleType((*it)); (*it)->setValues(ups); ups->setPos(this->pos); ups->setRotation(this->rotation); diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 8353d8802..bce185dc2 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -36,7 +36,7 @@ using namespace Shared::Util; namespace Glest{ namespace Game{ const int CHANGE_COMMAND_SPEED = 325; -const int MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED = 160; +const uint32 MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED = 160; //Mutex Unit::mutexDeletedUnits; //map Unit::deletedUnits; @@ -323,6 +323,9 @@ void UnitAttackBoostEffect::setSource(const Unit *unit) { void UnitAttackBoostEffect::applyLoadedAttackBoostParticles(UnitParticleSystemType *upstPtr,const XmlNode *node, Unit* unit) { if (upstPtr != NULL) { bool showUnitParticles = Config::getInstance().getBool("UnitParticles","true"); + if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + showUnitParticles = false; + } if (showUnitParticles == true) { upst = new UnitParticleSystemType(); *upst = *upstPtr; @@ -331,10 +334,12 @@ void UnitAttackBoostEffect::applyLoadedAttackBoostParticles(UnitParticleSystemTy ups = new UnitParticleSystem(200); //ups->loadGame(node2); ups->setParticleOwner(unit); + ups->setParticleType(upst); + upst->setValues(ups); - ups->setPos(unit->getCurrVector()); + ups->setPos(unit->getCurrVectorForParticlesystems()); ups->setRotation(unit->getRotation()); - ups->setUnitModel(unit->getCurrentModelPtr()); + unit->setMeshPosInParticleSystem(ups); if (unit->getFaction()->getTexture()) { ups->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0)); } @@ -576,6 +581,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, this->lastHarvestResourceTarget.first = Vec2i(0); this->morphFieldsBlocked=false; //this->lastBadHarvestListPurge = 0; + this->oldTotalSight = 0; level= NULL; loadType= NULL; @@ -1048,7 +1054,7 @@ float Unit::getEpRatio() const { throw megaglest_runtime_error(szBuf); } - if(type->getMaxHp() == 0) { + if(type->getTotalMaxHp(&totalUpgrade) == 0) { return 0.f; } else { @@ -1291,12 +1297,16 @@ void Unit::setCurrSkill(const SkillType *currSkill) { unitParticleSystems.empty() == true) { //printf("START - particle system type\n"); - for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); it != currSkill->unitParticleSystemTypes.end(); ++it) { + /* + for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); + it != currSkill->unitParticleSystemTypes.end(); ++it) { if((*it)->getStartTime() == 0.0) { //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); UnitParticleSystem *ups = new UnitParticleSystem(200); ups->setParticleOwner(this); + ups->setParticleType((*it)); + (*it)->setValues(ups); ups->setPos(getCurrVector()); ups->setRotation(getRotation()); @@ -1313,6 +1323,8 @@ void Unit::setCurrSkill(const SkillType *currSkill) { queuedUnitParticleSystemTypes.push_back(*it); } } + */ + checkCustomizedUnitParticleListTriggers(currSkill->unitParticleSystemTypes,true); } progress2= 0; if(this->currSkill != currSkill) { @@ -1354,7 +1366,7 @@ void Unit::setTarget(const Unit *unit){ //ser field and vector targetField= unit->getCurrField(); - targetVec= unit->getCurrVector(); + targetVec= unit->getCurrVectorAsTarget(); targetRef= unit; } @@ -1384,10 +1396,10 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) { logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); } -void Unit::refreshPos() { +void Unit::refreshPos(bool forceRefresh) { // Attempt to improve performance - this->exploreCells(); - calculateFogOfWarRadius(); + this->exploreCells(forceRefresh); + calculateFogOfWarRadius(forceRefresh); } FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { @@ -1396,7 +1408,7 @@ FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { } //iterate through all cells - int sightRange= this->getType()->getSight(); + int sightRange= this->getType()->getTotalSight(this->getTotalUpgrade()); int radius = sightRange + World::indirectSightRange; PosCircularIterator pci(map, this->getPosNotThreadSafe(), radius); FowAlphaCellsLookupItem result; @@ -1428,9 +1440,9 @@ FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { return result; } -void Unit::calculateFogOfWarRadius() { +void Unit::calculateFogOfWarRadius(bool forceRefresh) { if(game->getWorld()->getFogOfWar() == true) { - if(this->pos != this->cachedFowPos) { + if(forceRefresh || this->pos != this->cachedFowPos) { cachedFow = getFogOfWarRadius(false); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); @@ -1590,7 +1602,16 @@ bool Unit::checkModelStateInfoForNewHpValue() { return result; } -Vec3f Unit::getCurrVector() const{ +Vec3f Unit::getCurrVectorForParticlesystems() const{ + if(getFaction()->getType()->isFlatParticlePositions()){ + return getCurrVectorFlat(); + } + else { + return getCurrMidHeightVector(); + } +} + +Vec3f Unit::getCurrMidHeightVector() const{ if(type == NULL) { char szBuf[8096]=""; snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); @@ -1605,6 +1626,36 @@ Vec3f Unit::getCurrVector() const{ return result; } +Vec3f Unit::getCurrVectorAsTarget() const{ + if(type == NULL) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + Vec3f result = getCurrVectorFlat() + Vec3f(0.f, type->getTargetHeight() / 2.f, 0.f); + result.x = truncateDecimal(result.x,6); + result.y = truncateDecimal(result.y,6); + result.z = truncateDecimal(result.z,6); + + return result; +} + +Vec3f Unit::getCurrBurnVector() const{ + if(type == NULL) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + Vec3f result = getCurrVectorFlat() + Vec3f(0.f, type->getBurnHeight() / 2.f, 0.f); + result.x = truncateDecimal(result.x,6); + result.y = truncateDecimal(result.y,6); + result.z = truncateDecimal(result.z,6); + + return result; +} + Vec3f Unit::getCurrVectorFlat() const{ return getVectorFlat(lastPos, pos); } @@ -1948,7 +1999,7 @@ void Unit::born(const CommandType *ct) { throw megaglest_runtime_error(szBuf); } - faction->addStore(type,false); + faction->addStore(type); faction->applyStaticProduction(type,ct); setCurrSkill(scStop); @@ -2372,13 +2423,11 @@ void Unit::updateAttackBoostProgress(const Game* game) { attackBoost->radius); if(debugBoost) printf("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER " attackBoost: %s\n",__LINE__,candidates.size(),attackBoost->getDesc(false).c_str()); - for (unsigned int i = 0; i < candidates.size(); ++i) { Unit *affectedUnit = candidates[i]; if (attackBoost->isAffected(this, affectedUnit) == true) { if (affectedUnit->applyAttackBoost(attackBoost, this) == true) { currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit->getId()); - //printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); } } @@ -2396,12 +2445,14 @@ void Unit::updateAttackBoostProgress(const Game* game) { currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleOwner(this); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleType(currentAttackBoostOriginatorEffect.currentAppliedEffect->upst); + currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues( currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos( - getCurrVector()); + getCurrVectorForParticlesystems()); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation()); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); if (getFaction()->getTexture()) { currentAttackBoostOriginatorEffect. @@ -2507,12 +2558,14 @@ void Unit::updateAttackBoostProgress(const Game* game) { currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleOwner(this); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleType(currentAttackBoostOriginatorEffect.currentAppliedEffect->upst); + currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues( currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos( - getCurrVector()); + getCurrVectorForParticlesystems()); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation()); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); if (getFaction()->getTexture()) { currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setFactionColor( @@ -2572,6 +2625,12 @@ bool Unit::update() { //speed int speed= currSkill->getTotalSpeed(&totalUpgrade); + if( oldTotalSight != getType()->getTotalSight(this->getTotalUpgrade())){ + oldTotalSight= getType()->getTotalSight(this->getTotalUpgrade()); + // refresh FogOfWar and so on, because sight ha changed since last update + refreshPos(true); + } + if(changedActiveCommand) { if(changedActiveCommandFrame - lastChangedActiveCommandFrame >= MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) { //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); @@ -2588,6 +2647,9 @@ bool Unit::update() { this->lastAnimProgress= this->animProgress; const Game *game = Renderer::getInstance().getGame(); + if(animProgress==0){ + AnimCycleStarts(); + } progress = getUpdatedProgress(progress, GameConstants::updateFps, speed, diagonalFactor, heightFactor); @@ -2686,28 +2748,28 @@ bool Unit::update() { } if (this->fire != NULL) { - this->fire->setPos(getCurrVector()); + this->fire->setPos(getCurrBurnVector()); } for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setPos(getCurrVector()); + (*it)->setPos(getCurrVectorForParticlesystems()); (*it)->setRotation(getRotation()); - (*it)->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(*it); } } for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) { if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setPos(getCurrVector()); + (*it)->setPos(getCurrVectorForParticlesystems()); (*it)->setRotation(getRotation()); - (*it)->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(*it); } } for(UnitParticleSystems::iterator it= smokeParticleSystems.begin(); it != smokeParticleSystems.end(); ++it) { if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setPos(getCurrVector()); + (*it)->setPos(getCurrMidHeightVector()); (*it)->setRotation(getRotation()); - (*it)->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(*it); } } @@ -2717,9 +2779,9 @@ bool Unit::update() { if(effect != NULL && effect->ups != NULL) { bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(effect->ups,rsGame); if(particleValid == true) { - effect->ups->setPos(getCurrVector()); + effect->ups->setPos(getCurrVectorForParticlesystems()); effect->ups->setRotation(getRotation()); - effect->ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(effect->ups); } //printf("i = %d particleValid = %d\n",i,particleValid); @@ -2732,9 +2794,9 @@ bool Unit::update() { if(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != NULL) { bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups,rsGame); if(particleValid == true) { - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos(getCurrVector()); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos(getCurrVectorForParticlesystems()); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation()); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); } } } @@ -2786,10 +2848,12 @@ void Unit::updateTimedParticles() { UnitParticleSystem *ups = new UnitParticleSystem(200); ups->setParticleOwner(this); + ups->setParticleType(pst); + pst->setValues(ups); - ups->setPos(getCurrVector()); + ups->setPos(getCurrVectorForParticlesystems()); ups->setRotation(getRotation()); - ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(ups); if(getFaction()->getTexture()) { ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); @@ -2879,7 +2943,7 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) { int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); //printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); - totalUpgrade.apply(&boost->boostUpgrade, this); + totalUpgrade.apply(source->getId(),&boost->boostUpgrade, this); checkItemInVault(&this->hp,this->hp); //hp += boost->boostUpgrade.getMaxHp(); @@ -2927,10 +2991,12 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) { effect->ups = new UnitParticleSystem(200); effect->ups->setParticleOwner(this); + effect->ups->setParticleType(effect->upst); + effect->upst->setValues(effect->ups); - effect->ups->setPos(getCurrVector()); + effect->ups->setPos(getCurrVectorForParticlesystems()); effect->ups->setRotation(getRotation()); - effect->ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(effect->ups); if(getFaction()->getTexture()) { effect->ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); } @@ -2997,7 +3063,7 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) { int originalHp = hp; int prevMaxHp = totalUpgrade.getMaxHp(); int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); - totalUpgrade.deapply(&boost->boostUpgrade, this); + totalUpgrade.deapply(source->getId(),&boost->boostUpgrade, this->getId()); checkItemInVault(&this->hp,this->hp); int original_hp = this->hp; @@ -3144,11 +3210,11 @@ void Unit::tick() { } //regenerate hp else { - if(type->getHpRegeneration() >= 0) { + if(type->getTotalMaxHpRegeneration(&totalUpgrade) >= 0) { if( currSkill->getClass() != scBeBuilt){ checkItemInVault(&this->hp,this->hp); int original_hp = this->hp; - this->hp += type->getHpRegeneration(); + this->hp += type->getTotalMaxHpRegeneration(&totalUpgrade); if(this->hp > type->getTotalMaxHp(&totalUpgrade)) { this->hp = type->getTotalMaxHp(&totalUpgrade); } @@ -3165,7 +3231,7 @@ void Unit::tick() { } // If we have negative regeneration then check if the unit should die else { - bool decHpResult = decHp(-type->getHpRegeneration()); + bool decHpResult = decHp(-type->getTotalMaxHpRegeneration(&totalUpgrade)); if(decHpResult) { this->setCauseOfDeath(ucodStarvedRegeneration); @@ -3566,7 +3632,7 @@ bool Unit::morph(const MorphCommandType *mct) { } map->clearUnitCells(this, pos, false); - if(map->isFreeCellsOrHasUnit(pos, morphUnitType->getSize(), morphUnitField, this,morphUnitType)) { + if(map->canMorph(pos,this,morphUnitType)) { map->clearUnitCells(this, pos, true); faction->deApplyStaticCosts(type,mct); @@ -3606,7 +3672,10 @@ bool Unit::morph(const MorphCommandType *mct) { map->putUnitCells(this, this->pos); this->faction->applyDiscount(morphUnitType, mct->getDiscount()); - this->faction->addStore(this->type,mct->getReplaceStorage()); + // add new storage + this->faction->addStore(this->type); + // remove former storage + this->faction->removeStore(this->preMorph_type); this->faction->applyStaticProduction(morphUnitType,mct); this->level= NULL; @@ -3668,6 +3737,11 @@ float Unit::computeHeight(const Vec2i &pos) const { return height; } +void Unit::AnimCycleStarts(){ + // we need to queue timed particles if progress starts + queueTimedParticles(currSkill->unitParticleSystemTypes); +} + void Unit::updateTarget(){ Unit *target= targetRef.getUnit(); if(target!=NULL){ @@ -3681,7 +3755,7 @@ void Unit::updateTarget(){ #else targetRotation= radToDeg(atan2(relPosf.x, relPosf.y)); #endif - targetVec= target->getCurrVector(); + targetVec= target->getCurrVectorAsTarget(); } } @@ -3977,8 +4051,171 @@ void Unit::stopDamageParticles(bool force) { checkCustomizedParticleTriggers(force); } +void Unit::checkCustomizedUnitParticleListTriggers(const UnitParticleSystemTypes &unitParticleSystemTypesList, + bool applySkillChangeParticles) { + if(showUnitParticles == true) { + vector systemTypesInUse; + + if(unitParticleSystems.empty() == false) { + for(int index = (int)unitParticleSystems.size() - 1; index >= 0; index--) { + UnitParticleSystem *ps = unitParticleSystems[index]; + if(ps != NULL) { + if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { + + bool stopParticle = false; + if((ps->getParticleType() != NULL && + ps->getParticleType()->getMinmaxEnabled())) { + + if(ps->getParticleType() != NULL) { + if(ps->getParticleType()->getMinmaxIsPercent() == false) { + if(hp < ps->getParticleType()->getMinHp() || hp > ps->getParticleType()->getMaxHp()) { + stopParticle = true; + + //printf("STOP Particle line: %d\n",__LINE__); + } + } + else { + int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if(hpPercent < ps->getParticleType()->getMinHp() || hpPercent > ps->getParticleType()->getMaxHp()) { + stopParticle = true; + + //printf("STOP Particle line: %d\n",__LINE__); + } + } + } + + if(stopParticle == true) { + ps->fade(); + unitParticleSystems.erase(unitParticleSystems.begin() + index); + } + } + + if(ps->getParticleType() != NULL && stopParticle == false) { + systemTypesInUse.push_back(ps->getParticleType()); + } + } + } + } + } + + //printf("Check Particle start line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypesList.size()); + + if(unitParticleSystemTypesList.empty() == false) { + + //for(unsigned int index = 0; index < unitParticleSystemTypesList.size(); ++index) { + for(UnitParticleSystemTypes::const_iterator iterParticleType = unitParticleSystemTypesList.begin(); + iterParticleType != unitParticleSystemTypesList.end(); ++iterParticleType) { + UnitParticleSystemType *pst = *iterParticleType; + + vector::iterator iterFind = std::find(systemTypesInUse.begin(),systemTypesInUse.end(),pst); + + //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind == systemTypesInUse.end())); + + bool showParticle = applySkillChangeParticles; + if(pst->getMinmaxEnabled() == true) { + + //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind != systemTypesInUse.end())); + + showParticle = false; + if(iterFind == systemTypesInUse.end()) { + if(pst->getMinmaxIsPercent() == false) { + if(hp >= pst->getMinHp() && hp <= pst->getMaxHp()) { + showParticle = true; + + //printf("START Particle line: %d\n",__LINE__); + } + } + else { + int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if(hpPercent >= pst->getMinHp() && hpPercent <= pst->getMaxHp()) { + showParticle = true; + + //printf("START Particle line: %d\n",__LINE__); + } + } + } + } + if(showParticle == true){ + if(pst->getStartTime() == 0.0) { + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType(pst); + + pst->setValues(ups); + ups->setPos(getCurrVectorForParticlesystems()); + ups->setRotation(getRotation()); + setMeshPosInParticleSystem(ups); + if(getFaction()->getTexture()) { + ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); + } + unitParticleSystems.push_back(ups); + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + else { + // do nothing, timed particles are handled below in queueTimedParticles() + } + } + } + } + } +} + +void Unit::queueTimedParticles(const UnitParticleSystemTypes &unitParticleSystemTypesList){ + if(showUnitParticles == true) { + for(UnitParticleSystemTypes::const_iterator iterParticleType = unitParticleSystemTypesList.begin(); + iterParticleType != unitParticleSystemTypesList.end(); ++iterParticleType) { + UnitParticleSystemType *pst = *iterParticleType; + if(pst->getMinmaxEnabled() == false) { + if(pst->getStartTime() != 0.0) { + queuedUnitParticleSystemTypes.push_back(pst); + } + } + } + } +} + +void Unit::setMeshPosInParticleSystem(UnitParticleSystem *ups){ + if(ups->getMeshName()!=""){ + string meshName=ups->getMeshName(); + Model *model= getCurrentModelPtr(); + model->updateInterpolationVertices(getAnimProgressAsFloat(), isAlive() && !isAnimProgressBound()); + + bool foundMesh=false; + for(unsigned int i=0; igetMeshCount() ; i++){ + //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); + if(model->getMesh(i)->getName()==meshName){ + const InterpolationData *data=model->getMesh(i)->getInterpolationData(); + const Vec3f *verticepos=data->getVertices(); + ups->setMeshPos(Vec3f(verticepos->x,verticepos->y,verticepos->z)); + foundMesh=true; + break; + } + } + if( foundMesh == false ) { + string meshesFound=""; + for(unsigned i=0; igetMeshCount() ; i++){ + meshesFound+= model->getMesh(i)->getName()+", "; + } + + string errorString = "Warning: Particle system is trying to find mesh'"+meshName+"', but just found:\n'"+meshesFound+"' in file:\n'"+model->getFileName()+"'\n"; + //throw megaglest_runtime_error(errorString); + printf("%s",errorString.c_str()); + } + } +} + +void Unit::checkCustomizedUnitParticleTriggers() { + if(currSkill != NULL) { + checkCustomizedUnitParticleListTriggers(currSkill->unitParticleSystemTypes,false); + } +} + void Unit::checkCustomizedParticleTriggers(bool force) { - // Now check if we have special hp triggered particles + // + // Now check if we have special pre-exisitng hp triggered particles and + // end those that should no longer display + // + // end s particles if(damageParticleSystems.empty() == false) { for(int i = (int)damageParticleSystems.size()-1; i >= 0; --i) { UnitParticleSystem *ps = damageParticleSystems[i]; @@ -4028,7 +4265,9 @@ void Unit::checkCustomizedParticleTriggers(bool force) { } } - // Now check if we have special hp triggered particles + // + // Now check if we have new special hp triggered particles to display + // //start additional particles if(showUnitParticles && type->damageParticleSystemTypes.empty() == false && @@ -4057,10 +4296,12 @@ void Unit::checkCustomizedParticleTriggers(bool force) { UnitParticleSystem *ups = new UnitParticleSystem(200); ups->setParticleOwner(this); + ups->setParticleType(pst); + pst->setValues(ups); - ups->setPos(getCurrVector()); + ups->setPos(getCurrVectorForParticlesystems()); ups->setRotation(getRotation()); - ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(ups); if(getFaction()->getTexture()) { ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); } @@ -4071,10 +4312,12 @@ void Unit::checkCustomizedParticleTriggers(bool force) { } } } + + checkCustomizedUnitParticleTriggers(); } void Unit::startDamageParticles() { - if(hp < type->getMaxHp() / 2 && hp > 0 && alive == true) { + if(hp < type->getTotalMaxHp(&totalUpgrade) / 2 && hp > 0 && alive == true) { //start additional particles if( showUnitParticles && type->damageParticleSystemTypes.empty() == false ) { @@ -4084,10 +4327,12 @@ void Unit::startDamageParticles() { if(pst->getMinmaxEnabled() == false && damageParticleSystemsInUse.find(i) == damageParticleSystemsInUse.end()) { UnitParticleSystem *ups = new UnitParticleSystem(200); ups->setParticleOwner(this); + ups->setParticleType(pst); + pst->setValues(ups); - ups->setPos(getCurrVector()); + ups->setPos(getCurrVectorForParticlesystems()); ups->setRotation(getRotation()); - ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(ups); if(getFaction()->getTexture()) { ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); } @@ -4104,7 +4349,7 @@ void Unit::startDamageParticles() { fps->setParticleOwner(this); const Game *game = Renderer::getInstance().getGame(); fps->setSpeed(2.5f / game->getWorld()->getUpdateFps(this->getFactionIndex())); - fps->setPos(getCurrVector()); + fps->setPos(getCurrBurnVector()); fps->setRadius(type->getSize()/3.f); fps->setTexture(CoreData::getInstance().getFireTexture()); fps->setParticleSize(type->getSize()/3.f); @@ -4118,9 +4363,9 @@ void Unit::startDamageParticles() { ups->setParticleOwner(this); ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f)); - ups->setPos(getCurrVector()); + ups->setPos(getCurrBurnVector()); ups->setRotation(getRotation()); - ups->setUnitModel(getCurrentModelPtr()); + setMeshPosInParticleSystem(ups); ups->setBlendMode(ups->strToBlendMode("black")); ups->setOffset(Vec3f(0,2,0)); ups->setDirection(Vec3f(0,1,-0.2f)); @@ -4144,11 +4389,6 @@ void Unit::startDamageParticles() { checkCustomizedParticleTriggers(false); } -//void Unit::setTargetVec(const Vec3f &targetVec) { -// this->targetVec= targetVec; -// logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -//} - void Unit::setMeetingPos(const Vec2i &meetingPos) { this->meetingPos= meetingPos; map->clampPos(this->meetingPos); @@ -4177,10 +4417,10 @@ uint32 Unit::getFrameCount() const { return frameCount; } -void Unit::exploreCells() { +void Unit::exploreCells(bool forceRefresh) { if(this->isOperative() == true) { const Vec2i &newPos = this->getCenteredPos(); - int sightRange = this->getType()->getSight(); + int sightRange = this->getType()->getTotalSight(this->getTotalUpgrade()); int teamIndex = this->getTeam(); if(game == NULL) { @@ -4191,7 +4431,8 @@ void Unit::exploreCells() { } // Try the local unit exploration cache - if(cacheExploredCellsKey.first == newPos && + if( !forceRefresh && + cacheExploredCellsKey.first == newPos && cacheExploredCellsKey.second == sightRange) { game->getWorld()->exploreCells(teamIndex, cacheExploredCells); } @@ -5076,7 +5317,8 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction * //result->fire->setTexture(CoreData::getInstance().getFireTexture()); result->fireParticleSystems.push_back(result->fire); - //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); + //printf("Load MAIN fire particle result->fire = %p\n",result->fire); + Renderer::getInstance().addToDeferredParticleSystemList(make_pair(result->fire, rsGame)); } @@ -5201,16 +5443,20 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction * for(int i = 0; i < (int)unitParticleSystemNodeList.size(); ++i) { XmlNode *node = unitParticleSystemNodeList[i]; - FireParticleSystem *ups = new FireParticleSystem(); - ups->loadGame(node); - //ups->setTexture(CoreData::getInstance().getFireTexture()); - result->fireParticleSystems.push_back(ups); + if(result->fire == NULL || linkFireIndex != i) { + FireParticleSystem *ups = new FireParticleSystem(); + ups->setParticleOwner(result); + ups->loadGame(node); + //ups->setTexture(CoreData::getInstance().getFireTexture()); + result->fireParticleSystems.push_back(ups); - if(linkFireIndex >= 0 && linkFireIndex == i) { - result->fire = ups; + //printf("Load fire particle i = %d linkFireIndex = %d result->fire = %p ups = %p\n",i,linkFireIndex,result->fire,ups); + + if(result->fire == NULL && linkFireIndex >= 0 && linkFireIndex == i) { + result->fire = ups; + } + Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); } - //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); } } diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index bbbfa12da..05a169b14 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -370,6 +370,7 @@ private: int32 kills; int32 enemyKills; bool morphFieldsBlocked; + int oldTotalSight; UnitReference targetRef; @@ -519,7 +520,7 @@ public: const FowAlphaCellsLookupItem & getCachedFow() const { return cachedFow; } FowAlphaCellsLookupItem getFogOfWarRadius(bool useCache) const; - void calculateFogOfWarRadius(); + void calculateFogOfWarRadius(bool forceRefresh=false); //queries Command *getCurrrentCommandThreadSafe(); @@ -626,7 +627,7 @@ public: inline void setLoadType(const ResourceType *loadType) {this->loadType= loadType;} inline void setProgress2(int progress2) {this->progress2= progress2;} void setPos(const Vec2i &pos,bool clearPathFinder=false); - void refreshPos(); + void refreshPos(bool forceRefresh=false); void setTargetPos(const Vec2i &targetPos); void setTarget(const Unit *unit); //void setTargetVec(const Vec3f &targetVec); @@ -637,7 +638,10 @@ public: //render related const Model *getCurrentModel(); Model *getCurrentModelPtr(); - Vec3f getCurrVector() const; + Vec3f getCurrMidHeightVector() const; + Vec3f getCurrVectorForParticlesystems() const; + Vec3f getCurrVectorAsTarget() const; + Vec3f getCurrBurnVector() const; Vec3f getCurrVectorFlat() const; Vec3f getVectorFlat(const Vec2i &lastPosValue, const Vec2i &curPosValue) const; @@ -708,7 +712,7 @@ public: inline string getCurrentUnitTitle() const {return currentUnitTitle;} void setCurrentUnitTitle(string value) { currentUnitTitle = value;} - void exploreCells(); + void exploreCells(bool forceRefresh=false); inline bool getInBailOutAttempt() const { return inBailOutAttempt; } inline void setInBailOutAttempt(bool value) { inBailOutAttempt = value; } @@ -785,6 +789,7 @@ public: inline void setUsePathfinderExtendedMaxNodes(bool value) { usePathfinderExtendedMaxNodes = value; } void updateTimedParticles(); + void setMeshPosInParticleSystem(UnitParticleSystem *ups); virtual string getUniquePickName() const; void saveGame(XmlNode *rootNode); @@ -813,6 +818,7 @@ private: float computeHeight(const Vec2i &pos) const; void calculateXZRotation(); + void AnimCycleStarts(); void updateTarget(); void clearCommands(); void deleteQueuedCommand(Command *command); @@ -821,7 +827,13 @@ private: void startDamageParticles(); uint32 getFrameCount() const; + void checkCustomizedParticleTriggers(bool force); + void checkCustomizedUnitParticleTriggers(); + void checkCustomizedUnitParticleListTriggers(const UnitParticleSystemTypes &unitParticleSystemTypesList, + bool applySkillChangeParticles); + void queueTimedParticles(const UnitParticleSystemTypes &unitParticleSystemTypesList); + bool checkModelStateInfoForNewHpValue(); void checkUnitLevel(); diff --git a/source/glest_game/types/command_type.cpp b/source/glest_game/types/command_type.cpp index 7e966dc0d..1c5f58cd9 100644 --- a/source/glest_game/types/command_type.cpp +++ b/source/glest_game/types/command_type.cpp @@ -852,7 +852,6 @@ MorphCommandType::MorphCommandType(){ morphUnit=NULL; discount=0; ignoreResourceRequirements = false; - replaceStorage = false; } void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const { @@ -882,11 +881,6 @@ void MorphCommandType::load(int id, const XmlNode *n, const string &dir, //printf("ignoreResourceRequirements = %d\n",ignoreResourceRequirements); } - replaceStorage = false; - if(n->hasChild("replace-storage") == true) { - replaceStorage = n->getChild("replace-storage")->getAttribute("value")->getBoolValue(); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } diff --git a/source/glest_game/types/command_type.h b/source/glest_game/types/command_type.h index fc4bbae3b..913272c53 100644 --- a/source/glest_game/types/command_type.h +++ b/source/glest_game/types/command_type.h @@ -418,7 +418,6 @@ private: const UnitType* morphUnit; int discount; bool ignoreResourceRequirements; - bool replaceStorage; public: MorphCommandType(); @@ -437,7 +436,6 @@ public: const UnitType *getMorphUnit() const {return morphUnit;} int getDiscount() const {return discount;} bool getIgnoreResourceRequirements() const {return ignoreResourceRequirements;} - bool getReplaceStorage() const {return replaceStorage;} virtual bool usesPathfinder() const { return false; } }; diff --git a/source/glest_game/types/faction_type.cpp b/source/glest_game/types/faction_type.cpp index bd8ae23f4..7c826d225 100644 --- a/source/glest_game/types/faction_type.cpp +++ b/source/glest_game/types/faction_type.cpp @@ -16,6 +16,7 @@ #include "xml_parser.h" #include "tech_tree.h" #include "resource.h" +#include "renderer.h" #include "platform_util.h" #include "game_util.h" #include "conversion.h" @@ -34,6 +35,15 @@ FactionType::FactionType() { music = NULL; personalityType = fpt_Normal; isLinked = false; + healthbarheight= -100.0f; + healthbarthickness= 0.11f; + healthbarVisible=hbvUndefined; + healthbarBorderTextureEnabled=false; + healthbarBackgroundTextureEnabled=false; + healthbarLineBorder=true; + healthbarTexture=NULL; + healthbarBackgroundTexture=NULL; + flatParticlePositions=false; } //load a faction, given a directory @@ -272,6 +282,64 @@ void FactionType::load(const string &factionName, const TechTree *techTree, Chec loadedFileList[musicNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(path,musicNode->getAttribute("path")->getRestrictedValue())); } + if(factionNode->hasChild("flat-particle-positions")) { + const XmlNode *node= factionNode->getChild("flat-particle-positions"); + flatParticlePositions = node->getAttribute("value")->getBoolValue(); + } + + //healthbar + if(factionNode->hasChild("healthbar")) { + const XmlNode *healthbarNode= factionNode->getChild("healthbar"); + if(healthbarNode->hasChild("height")) { + healthbarheight= healthbarNode->getChild("height")->getAttribute("value")->getFloatValue(); + } + if(healthbarNode->hasChild("thickness")) { + healthbarthickness= healthbarNode->getChild("thickness")->getAttribute("value")->getFloatValue(0.f, 1.f); + } + if(healthbarNode->hasChild("visible")) { + string healthbarVisibleString=healthbarNode->getChild("visible")->getAttribute("value")->getValue(); + vector v=split(healthbarVisibleString,"|"); + for (int i = 0; i < (int)v.size(); ++i) { + string current=trim(v[i]); + if(current=="always") { + healthbarVisible=healthbarVisible|hbvAlways; + } else if(current=="selected") { + healthbarVisible=healthbarVisible|hbvSelected; + } else if(current=="ifNeeded") { + healthbarVisible=healthbarVisible|hbvIfNeeded; + } else if(current=="off") { + healthbarVisible=healthbarVisible|hbvOff; + } else { + throw megaglest_runtime_error("Unknown Healthbar Visible Option: " + current, validationMode); + } + } + } + if(healthbarNode->hasChild("borderTexture")) { + healthbarBorderTextureEnabled=healthbarNode->getChild("borderTexture")->getAttribute("enabled")->getBoolValue(); + if(healthbarBorderTextureEnabled && healthbarNode->getChild("borderTexture")->hasAttribute("path")) { + healthbarTexture= Renderer::getInstance().newTexture2D(rsGame); + if(healthbarTexture) { + healthbarTexture->load(healthbarNode->getChild("borderTexture")->getAttribute("path")->getRestrictedValue(currentPath)); + } + loadedFileList[healthbarNode->getChild("borderTexture")->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(path,healthbarNode->getChild("borderTexture")->getAttribute("path")->getRestrictedValue())); + } + } + if(healthbarNode->hasChild("backgroundTexture")) { + healthbarBackgroundTextureEnabled=healthbarNode->getChild("backgroundTexture")->getAttribute("enabled")->getBoolValue(); + if(healthbarBackgroundTextureEnabled && healthbarNode->getChild("backgroundTexture")->hasAttribute("path")) { + healthbarBackgroundTexture= Renderer::getInstance().newTexture2D(rsGame); + if(healthbarBackgroundTexture) { + healthbarBackgroundTexture->load(healthbarNode->getChild("backgroundTexture")->getAttribute("path")->getRestrictedValue(currentPath)); + } + loadedFileList[healthbarNode->getChild("backgroundTexture")->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(path,healthbarNode->getChild("backgroundTexture")->getAttribute("path")->getRestrictedValue())); + } + } + if(healthbarNode->hasChild("lineBorder")) { + healthbarLineBorder= healthbarNode->getChild("lineBorder")->getAttribute("enabled")->getBoolValue(); + } + + } + //read ai behavior if(factionNode->hasChild("ai-behavior") == true) { const XmlNode *aiNode= factionNode->getChild("ai-behavior"); @@ -967,56 +1035,5 @@ string FactionType::getName(bool translatedValue) const { return lang.getTechTreeString("FactionName_" + name,name.c_str()); } -void FactionType::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *factionTypeNode = rootNode->addChild("FactionType"); - -// string name; - factionTypeNode->addAttribute("name",name, mapTagReplacements); -// UnitTypes unitTypes; - for(unsigned int i = 0; i < unitTypes.size(); ++i) { - XmlNode *unitTypesNode = factionTypeNode->addChild("unitTypes"); - unitTypesNode->addAttribute("name",unitTypes[i].getName(false), mapTagReplacements); - } -// UpgradeTypes upgradeTypes; - for(unsigned int i = 0; i < upgradeTypes.size(); ++i) { - XmlNode *upgradeTypesNode = factionTypeNode->addChild("upgradeTypes"); - upgradeTypesNode->addAttribute("name",upgradeTypes[i].getName(false), mapTagReplacements); - } - -// StartingUnits startingUnits; - for(unsigned int i = 0; i < startingUnits.size(); ++i) { - XmlNode *startingUnitsNode = factionTypeNode->addChild("startingUnits"); - startingUnitsNode->addAttribute("name",startingUnits[i].first->getName(false), mapTagReplacements); - startingUnitsNode->addAttribute("count",intToStr(startingUnits[i].second), mapTagReplacements); - } - -// Resources startingResources; - for(unsigned int i = 0; i < startingResources.size(); ++i) { - startingResources[i].saveGame(factionTypeNode); - } - -// StrSound *music; -// FactionPersonalityType personalityType; - factionTypeNode->addAttribute("personalityType",intToStr(personalityType), mapTagReplacements); -// std::map > mapAIBehaviorUnitCategories; - for(std::map >::iterator iterMap = mapAIBehaviorUnitCategories.begin(); - iterMap != mapAIBehaviorUnitCategories.end(); ++iterMap) { - - std::vector &vct = iterMap->second; - for(unsigned int i = 0; i < vct.size(); ++i) { - PairPUnitTypeInt &item = vct[i]; - - XmlNode *mapAIBehaviorUnitCategoriesNode = factionTypeNode->addChild("mapAIBehaviorUnitCategories"); - mapAIBehaviorUnitCategoriesNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); - mapAIBehaviorUnitCategoriesNode->addAttribute("unitType",item.first->getName(false), mapTagReplacements); - mapAIBehaviorUnitCategoriesNode->addAttribute("count",intToStr(item.second), mapTagReplacements); - } - } -// std::vector vctAIBehaviorUpgrades; - //for(unsigned int i = 0; i < vctAIBehaviorUpgrades.size(); ++i) { - // vctAIBehaviorUpgrades[i]->saveGame(factionTypeNode); - //} -} }}//end namespace diff --git a/source/glest_game/types/faction_type.h b/source/glest_game/types/faction_type.h index 476415985..c965f0ce5 100644 --- a/source/glest_game/types/faction_type.h +++ b/source/glest_game/types/faction_type.h @@ -96,6 +96,16 @@ private: bool isLinked; + float healthbarheight; + float healthbarthickness; + int healthbarVisible; + bool healthbarBorderTextureEnabled; + bool healthbarBackgroundTextureEnabled; + bool healthbarLineBorder; + Texture2D *healthbarTexture; + Texture2D *healthbarBackgroundTexture; + bool flatParticlePositions; + public: //init FactionType(); @@ -120,6 +130,16 @@ public: int getStartingUnitCount() const {return (int)startingUnits.size();} const UnitType *getStartingUnit(int i) const {return startingUnits[i].first;} int getStartingUnitAmount(int i) const {return startingUnits[i].second;} + inline float getHealthbarHeight() const {return healthbarheight;} + inline float getHealthbarThickness() const {return healthbarthickness;} + inline int getHealthbarVisible() const {return healthbarVisible;} + inline bool isHealthbarBorderTextureEnabled() const {return healthbarBorderTextureEnabled;} + inline bool isHealthbarBackgroundTextureEnabled() const {return healthbarBackgroundTextureEnabled;} + inline bool isHealthbarLineBorder() const {return healthbarLineBorder;} + Texture2D *getHealthbarTexture() const {return healthbarTexture;} + Texture2D *getHealthbarBackgroundTexture() const {return healthbarBackgroundTexture;} + bool isFlatParticlePositions() const {return flatParticlePositions;} + const UnitType *getUnitType(const string &name) const; const UnitType *getUnitTypeById(int id) const; @@ -137,7 +157,6 @@ public: void deletePixels(); bool factionUsesResourceType(const ResourceType *rt) const; - void saveGame(XmlNode *rootNode); }; }}//end namespace diff --git a/source/glest_game/types/skill_type.cpp b/source/glest_game/types/skill_type.cpp index 90d3f7828..a313fc949 100644 --- a/source/glest_game/types/skill_type.cpp +++ b/source/glest_game/types/skill_type.cpp @@ -62,38 +62,25 @@ bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const { else { // All units are affected (including enemies) if(targetType == abtAll) { - destUnitMightApply = (boostUnitList.empty() && tags.empty()); - destUnitMightApply = isInUnitListOrTags(dest->getType()); + destUnitMightApply = (boostUnitList.empty() && tags.empty()) || isInUnitListOrTags(dest->getType());; } // Only same faction units are affected else if(targetType == abtFaction) { - //if(boostUnitList.empty() == true) { if(source->getFactionIndex() == dest->getFactionIndex()) { - //destUnitMightApply = true; - destUnitMightApply = (boostUnitList.empty() && tags.empty()); - destUnitMightApply = isInUnitListOrTags(dest->getType()); + destUnitMightApply = (boostUnitList.empty() && tags.empty()) || isInUnitListOrTags(dest->getType()); } - //} } // Only ally units are affected else if(targetType == abtAlly) { - //if(boostUnitList.empty() == true) { if(source->isAlly(dest) == true) { - //destUnitMightApply = true; - destUnitMightApply = (boostUnitList.empty() && tags.empty()); - destUnitMightApply = isInUnitListOrTags(dest->getType()); + destUnitMightApply = (boostUnitList.empty() && tags.empty()) || isInUnitListOrTags(dest->getType()); } - //} } // Only foe units are affected else if(targetType == abtFoe) { - //if(boostUnitList.empty() == true) { if(source->isAlly(dest) == false) { - //destUnitMightApply = true; - destUnitMightApply = (boostUnitList.empty() && tags.empty()); - destUnitMightApply = isInUnitListOrTags(dest->getType()); + destUnitMightApply = (boostUnitList.empty() && tags.empty()) || isInUnitListOrTags(dest->getType()); } - //} } else if(targetType == abtUnitTypes) { destUnitMightApply = isInUnitListOrTags(dest->getType()); @@ -533,9 +520,21 @@ void SkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode, unitParticleSystemType->setEndTime(particleNode->getAttribute("end-time")->getFloatValue()); } + if(particleNode->getChild(i)->hasAttribute("minHp") && particleNode->getChild(i)->hasAttribute("maxHp")) { + unitParticleSystemType->setMinmaxEnabled(true); + unitParticleSystemType->setMinHp(particleNode->getChild(i)->getAttribute("minHp")->getIntValue()); + unitParticleSystemType->setMaxHp(particleNode->getChild(i)->getAttribute("maxHp")->getIntValue()); + + if(particleNode->getChild(i)->hasAttribute("ispercentbased")) { + unitParticleSystemType->setMinmaxIsPercent(particleNode->getChild(i)->getAttribute("ispercentbased")->getBoolValue()); + } + } + loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue())); unitParticleSystemTypes.push_back(unitParticleSystemType); } + + //printf("Load skill particles line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypes.size()); } } @@ -655,7 +654,7 @@ Model *SkillType::getAnimation(float animProgress, const Unit *unit, const AnimationAttributes &attributes = animationAttributes[i]; if(attributes.fromHp != 0 || attributes.toHp != 0) { if(unit->getHp() >= attributes.fromHp && unit->getHp() <= attributes.toHp) { - modelIndex = i; + //modelIndex = i; foundSpecificAnimation = true; filteredAnimations.push_back(i); //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); @@ -669,7 +668,7 @@ Model *SkillType::getAnimation(float animProgress, const Unit *unit, for(unsigned int i = 0; i < animationAttributes.size(); ++i) { const AnimationAttributes &attributes = animationAttributes[i]; if(attributes.fromHp == 0 && attributes.toHp == 0) { - modelIndex = i; + //modelIndex = i; foundSpecificAnimation = true; filteredAnimations.push_back(i); //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); @@ -933,15 +932,17 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode, projectile= projectileNode->getAttribute("value")->getBoolValue(); if(projectile){ // create new projectile - ProjectileType *projectileType=new ProjectileType(); - projectileTypes.push_back(projectileType); - projectileType->setAttackStartTime(attackStartTime); - projectileType->setDamagePercentage(100); + ProjectileType *projectileType = new ProjectileType(); + //only add this projectile if there is an enabled particlesystem + //projectileTypes.push_back(projectileType); + projectileType->setAttackStartTime(attackStartTime); + projectileType->setDamagePercentage(100); //proj particle if(projectileNode->hasChild("particle")){ const XmlNode *particleNode= projectileNode->getChild("particle"); bool particleEnabled= particleNode->getAttribute("value")->getBoolValue(); - if(particleEnabled){ + if(particleEnabled) { + projectileTypes.push_back(projectileType); string path= particleNode->getAttribute("path")->getRestrictedValue(); ParticleSystemTypeProjectile* projectileParticleSystemType= new ParticleSystemTypeProjectile(); projectileParticleSystemType->load(particleNode, dir, currentPath + path, @@ -950,6 +951,12 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode, loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleNode->getAttribute("path")->getRestrictedValue())); projectileType->setProjectileParticleSystemType(projectileParticleSystemType); } + else { + delete projectileType; + } + } + else { + delete projectileType; } //proj sounds const XmlNode *soundNode= projectileNode->getChild("sound"); diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index 82129a6ac..9191eead7 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -88,6 +88,9 @@ UnitType::UnitType() : ProducibleType() { meetingPointImage = NULL; lightColor= Vec3f(0.f); light= false; + healthbarheight= -100.0f; + healthbarthickness=-1.0f; + healthbarVisible=hbvUndefined; multiSelect= false; commandable= true; armorType= NULL; @@ -138,6 +141,8 @@ UnitType::UnitType() : ProducibleType() { size=0; renderSize=0; height=0; + burnHeight=0; + targetHeight=0; addItemToVault(&(this->maxHp),this->maxHp); addItemToVault(&(this->hpRegeneration),this->hpRegeneration); @@ -232,6 +237,22 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree, height= parametersNode->getChild("height")->getAttribute("value")->getIntValue(); addItemToVault(&(this->height),this->height); + //targetHeight + if(parametersNode->hasChild("target-height")){ + targetHeight= parametersNode->getChild("target-height")->getAttribute("value")->getIntValue(); + addItemToVault(&(this->targetHeight),this->targetHeight); + } else { + targetHeight=height; + } + //burnHeight + if(parametersNode->hasChild("target-height")){ + burnHeight= parametersNode->getChild("burn-height")->getAttribute("value")->getIntValue(); + addItemToVault(&(this->burnHeight),this->burnHeight); + } else { + burnHeight=height; + } + + //maxHp //checkItemInVault(&(this->maxHp),this->maxHp); maxHp = parametersNode->getChild("max-hp")->getAttribute("value")->getIntValue(); @@ -446,6 +467,35 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree, } } + //healthbar + if(parametersNode->hasChild("healthbar")) { + const XmlNode *healthbarNode= parametersNode->getChild("healthbar"); + if(healthbarNode->hasChild("height")) { + healthbarheight= healthbarNode->getChild("height")->getAttribute("value")->getFloatValue(); + } + if(healthbarNode->hasChild("thickness")) { + healthbarthickness= healthbarNode->getChild("thickness")->getAttribute("value")->getFloatValue(0.f, 1.f); + } + if(healthbarNode->hasChild("visible")) { + string healthbarVisibleString=healthbarNode->getChild("visible")->getAttribute("value")->getValue(); + vector v=split(healthbarVisibleString,"|"); + for (int i = 0; i < (int)v.size(); ++i) { + string current=trim(v[i]); + if(current=="always") { + healthbarVisible=healthbarVisible|hbvAlways; + } else if(current=="selected") { + healthbarVisible=healthbarVisible|hbvSelected; + } else if(current=="ifNeeded") { + healthbarVisible=healthbarVisible|hbvIfNeeded; + } else if(current=="off") { + healthbarVisible=healthbarVisible|hbvOff; + } else { + throw megaglest_runtime_error("Unknown Healthbar Visible Option: " + current, validationMode); + } + } + } + } + //light const XmlNode *lightNode= parametersNode->getChild("light"); light= lightNode->getAttribute("enabled")->getBoolValue(); @@ -596,13 +646,13 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree, } } sortedItems.clear(); - hasDup = false; + //hasDup = false; // Lootable resources (resources given/lost on death) if(parametersNode->hasChild("resources-death")) { const XmlNode *deathResourcesNode= parametersNode->getChild("resources-death"); - for(size_t i=0; i < deathResourcesNode->getChildCount(); ++i){ + for(unsigned int i = 0; i < deathResourcesNode->getChildCount(); ++i){ const XmlNode *resourceNode= deathResourcesNode->getChild("resource", i); string name= resourceNode->getAttribute("name")->getRestrictedValue(); @@ -660,7 +710,7 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree, if(parametersNode->hasChild("tags")) { const XmlNode *tagsNode= parametersNode->getChild("tags"); - for(size_t i=0; i < tagsNode->getChildCount(); ++i){ + for(unsigned int i = 0; i < tagsNode->getChildCount(); ++i){ const XmlNode *resourceNode= tagsNode->getChild("tag", i); string tag= resourceNode->getAttribute("value")->getRestrictedValue(); tags.insert(tag); diff --git a/source/glest_game/types/unit_type.h b/source/glest_game/types/unit_type.h index 2bc37fb0b..564ed14b9 100644 --- a/source/glest_game/types/unit_type.h +++ b/source/glest_game/types/unit_type.h @@ -79,6 +79,15 @@ private: bool negativeAllowed; public: + LootableResource() { + type=NULL; + amountValue=0; + amountFactionPercent=0; + lossValue=0; + lossFactionPercent=0; + negativeAllowed=false; + } + const ResourceType* getResourceType() const {return type;} void setResourceType(const ResourceType *type) {this->type=type;} @@ -116,6 +125,14 @@ enum UnitClass { typedef vector DamageParticleSystemTypes; +enum HealthbarVisible { + hbvUndefined=0, + hbvOff=1, + hbvAlways=2, + hbvIfNeeded=4, + hbvSelected=8 +}; + enum UnitCountsInVictoryConditions { ucvcNotSet, ucvcTrue, @@ -170,12 +187,17 @@ private: const ArmorType *armorType; bool light; Vec3f lightColor; + float healthbarheight; + float healthbarthickness; + int healthbarVisible; bool multiSelect; bool commandable; int sight; int size; //size in cells int renderSize; //size to render in cells int height; + int burnHeight; + int targetHeight; float rotatedBuildPos; bool rotationAllowed; @@ -256,15 +278,20 @@ public: inline bool getLight() const {return light;} inline bool getRotationAllowed() const {return rotationAllowed;} inline Vec3f getLightColor() const {return lightColor;} + inline float getHealthbarHeight() const {return healthbarheight;} + inline float getHealthbarThickness() const {return healthbarthickness;} + inline int getHealthbarVisible() const {return healthbarVisible;} inline bool getMultiSelect() const {return multiSelect;} inline bool isCommandable() const {return commandable;} inline int getSight() const {return sight;} inline int getSize() const {return size;} inline int getRenderSize() const {return renderSize;} - int getHeight() const {return height;} - int getStoredResourceCount() const {return (int)storedResources.size();} + int getHeight() const {return height;} + int getBurnHeight() const {return burnHeight;} + int getTargetHeight() const {return targetHeight;} + int getStoredResourceCount() const {return (int)storedResources.size();} inline const Resource *getStoredResource(int i) const {return &storedResources[i];} - int getLootableResourceCount() const {return lootableResources.size();} + int getLootableResourceCount() const {return (int)lootableResources.size();} inline const LootableResource getLootableResource(int i) const {return lootableResources.at(i);} const set &getTags() const {return tags;} bool getCellMapCell(int x, int y, CardinalDir facing) const; diff --git a/source/glest_game/types/upgrade_type.cpp b/source/glest_game/types/upgrade_type.cpp index 78ad754a1..46a573900 100644 --- a/source/glest_game/types/upgrade_type.cpp +++ b/source/glest_game/types/upgrade_type.cpp @@ -42,6 +42,37 @@ namespace Glest{ namespace Game{ const string VALUE_PERCENT_MULTIPLIER_KEY_NAME = "value-percent-multiplier"; const string VALUE_REGEN_KEY_NAME = "regeneration"; +void UpgradeTypeBase::copyDataFrom(UpgradeTypeBase *source) { + upgradename = source->upgradename; + maxHp = source->maxHp; + maxHpIsMultiplier = source->maxHpIsMultiplier; + maxHpRegeneration = source->maxHpRegeneration; + sight = source->sight; + sightIsMultiplier = source->sightIsMultiplier; + maxEp = source->maxEp; + maxEpIsMultiplier = source->maxEpIsMultiplier; + maxEpRegeneration = source->maxEpRegeneration; + armor = source->armor; + armorIsMultiplier = source->armorIsMultiplier; + attackStrength = source->attackStrength; + attackStrengthIsMultiplier = source->attackStrengthIsMultiplier; + attackStrengthMultiplierValueList = source->attackStrengthMultiplierValueList; + attackRange = source->attackRange; + attackRangeIsMultiplier = source->attackRangeIsMultiplier; + attackRangeMultiplierValueList = source->attackRangeMultiplierValueList; + moveSpeed = source->moveSpeed; + moveSpeedIsMultiplier = source->moveSpeedIsMultiplier; + moveSpeedIsMultiplierValueList = source->moveSpeedIsMultiplierValueList; + prodSpeed = source->prodSpeed; + prodSpeedIsMultiplier = source->prodSpeedIsMultiplier; + prodSpeedProduceIsMultiplierValueList = source->prodSpeedProduceIsMultiplierValueList; + prodSpeedUpgradeIsMultiplierValueList = source->prodSpeedUpgradeIsMultiplierValueList; + prodSpeedMorphIsMultiplierValueList = source->prodSpeedMorphIsMultiplierValueList; + attackSpeed = source->attackSpeed; + attackSpeedIsMultiplier = source->attackSpeedIsMultiplier; + attackSpeedIsMultiplierValueList = source->attackSpeedIsMultiplierValueList; +} + void UpgradeTypeBase::load(const XmlNode *upgradeNode, string upgradename) { this->upgradename = upgradename; //values @@ -273,119 +304,142 @@ string UpgradeTypeBase::getDesc(bool translatedValue) const{ string str=""; string indent="->"; - //int i; Lang &lang= Lang::getInstance(); - if(maxHp != 0) { + if(getMaxHp() != 0) { + str += indent+lang.getString("Hp",(translatedValue == true ? "" : "english")) + " +" + intToStr(maxHp); if(maxHpIsMultiplier) { - str += indent+lang.getString("Hp",(translatedValue == true ? "" : "english")) + " *" + intToStr(maxHp); + str += "%"; } - else { - str += indent+lang.getString("Hp",(translatedValue == true ? "" : "english")) + " +" + intToStr(maxHp); - } - - if(maxHpRegeneration != 0) { - str += " [" + intToStr(maxHpRegeneration) + "]"; +// if(getMaxHpFromBoosts() != 0) { +// str += " +" + intToStr(getMaxHpFromBoosts()); +// } + if(getMaxHpRegeneration() != 0) { + str += " [" + intToStr(maxHpRegeneration); +// if(getMaxHpRegenerationFromBoosts() != 0) { +// str += " +" + intToStr(getMaxHpRegenerationFromBoosts()); +// } + str += "]"; } } - if(sight != 0) { + if(getSight() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("Sight",(translatedValue == true ? "" : "english")) + " +" + intToStr(sight); if(sightIsMultiplier) { - str+= indent+lang.getString("Sight",(translatedValue == true ? "" : "english")) + " *" + intToStr(sight); - } - else { - str+= indent+lang.getString("Sight",(translatedValue == true ? "" : "english")) + " +" + intToStr(sight); + str += "%"; } +// if(getSightFromBoosts() != 0) { +// str += " +" + intToStr(getSightFromBoosts()); +// } } - if(maxEp != 0) { + + if(getMaxEp() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("Ep",(translatedValue == true ? "" : "english")) + " +" + intToStr(maxEp); if(maxEpIsMultiplier) { - str+= indent+lang.getString("Ep",(translatedValue == true ? "" : "english")) + " *" + intToStr(maxEp); + str += "%"; } - else { - str+= indent+lang.getString("Ep",(translatedValue == true ? "" : "english")) + " +" + intToStr(maxEp); - } - if(maxEpRegeneration != 0) { - str += " [" + intToStr(maxEpRegeneration) + "]"; +// if(getMaxEpFromBoosts() != 0) { +// str += " +" + intToStr(getMaxEpFromBoosts()); +// } + + if(getMaxEpRegeneration() != 0) { + str += " [" + intToStr(maxEpRegeneration); +// if(getMaxEpRegenerationFromBoosts() != 0) { +// str += " +" + intToStr(getMaxEpRegenerationFromBoosts()); +// } + str += "]"; } } - if(attackStrength != 0) { + + if(getAttackStrength() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("AttackStrenght",(translatedValue == true ? "" : "english")) + " +" + intToStr(attackStrength); if(attackStrengthIsMultiplier) { - str+= indent+lang.getString("AttackStrenght",(translatedValue == true ? "" : "english")) + " *" + intToStr(attackStrength); - } - else { - str+= indent+lang.getString("AttackStrenght",(translatedValue == true ? "" : "english")) + " +" + intToStr(attackStrength); + str += "%"; } +// if(getAttackStrengthFromBoosts(NULL) != 0) { +// str += " +" + intToStr(getAttackStrengthFromBoosts(NULL)); +// } } - if(attackRange != 0) { + + if(getAttackRange() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("AttackDistance",(translatedValue == true ? "" : "english")) + " +" + intToStr(attackRange); if(attackRangeIsMultiplier) { - str+= indent+lang.getString("AttackDistance",(translatedValue == true ? "" : "english")) + " *" + intToStr(attackRange); - } - else { - str+= indent+lang.getString("AttackDistance",(translatedValue == true ? "" : "english")) + " +" + intToStr(attackRange); + str += "%"; } +// if(getAttackRangeFromBoosts(NULL) != 0) { +// str += " +" + intToStr(getAttackRangeFromBoosts(NULL)); +// } } - if(armor != 0) { + + if(getArmor() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("Armor",(translatedValue == true ? "" : "english")) + " +" + intToStr(armor); if(armorIsMultiplier) { - str+= indent+lang.getString("Armor",(translatedValue == true ? "" : "english")) + " *" + intToStr(armor); - } - else { - str+= indent+lang.getString("Armor",(translatedValue == true ? "" : "english")) + " +" + intToStr(armor); + str += "%"; } +// if(getArmorFromBoosts() != 0) { +// str += " +" + intToStr(getArmorFromBoosts()); +// } } - if(moveSpeed != 0) { + + if(getMoveSpeed() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("WalkSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(moveSpeed); if(moveSpeedIsMultiplier) { - str+= indent+lang.getString("WalkSpeed",(translatedValue == true ? "" : "english")) + " *" + intToStr(moveSpeed); - } - else { - str+= indent+lang.getString("WalkSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(moveSpeed); + str += "%"; } +// if(getMoveSpeedFromBoosts(NULL) != 0) { +// str += " +" + intToStr(getMoveSpeedFromBoosts(NULL)); +// } } - if(prodSpeed != 0) { + + if(getProdSpeed() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("ProductionSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(prodSpeed); if(prodSpeedIsMultiplier) { - str+= indent+lang.getString("ProductionSpeed",(translatedValue == true ? "" : "english")) + " *" + intToStr(prodSpeed); - } - else { - str+= indent+lang.getString("ProductionSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(prodSpeed); + str += "%"; } +// if(getProdSpeedFromBoosts(NULL) != 0) { +// str += " +" + intToStr(getProdSpeedFromBoosts(NULL)); +// } } - if(attackSpeed != 0) { + + if(getAttackSpeed() != 0) { if(str != "") { str += "\n"; } + str += indent+lang.getString("AttackSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(attackSpeed); if(attackSpeedIsMultiplier) { - str+= indent+lang.getString("AttackSpeed",(translatedValue == true ? "" : "english")) + " *" + intToStr(moveSpeed); - } - else { - str+= indent+lang.getString("AttackSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(moveSpeed); + str += "%"; } +// if(getAttackSpeedFromBoosts(NULL) != 0) { +// str += " +" + intToStr(getAttackSpeedFromBoosts(NULL)); +// } } if(str != "") { str += "\n"; @@ -394,6 +448,105 @@ string UpgradeTypeBase::getDesc(bool translatedValue) const{ return str; } +void UpgradeTypeBase::saveGameBoost(XmlNode *rootNode) const { + std::map mapTagReplacements; + XmlNode *upgradeTypeBaseNode = rootNode->addChild("UpgradeTypeBaseBoost"); + + upgradeTypeBaseNode->addAttribute("upgradename",upgradename, mapTagReplacements); + +// int maxHp; + upgradeTypeBaseNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); +// bool maxHpIsMultiplier; + upgradeTypeBaseNode->addAttribute("maxHpIsMultiplier",intToStr(maxHpIsMultiplier), mapTagReplacements); +// int maxHpRegeneration; + upgradeTypeBaseNode->addAttribute("maxHpRegeneration",intToStr(maxHpRegeneration), mapTagReplacements); +// //bool maxHpRegenerationIsMultiplier; +// +// int sight; + upgradeTypeBaseNode->addAttribute("sight",intToStr(sight), mapTagReplacements); +// bool sightIsMultiplier; + upgradeTypeBaseNode->addAttribute("sightIsMultiplier",intToStr(sightIsMultiplier), mapTagReplacements); +// int maxEp; + upgradeTypeBaseNode->addAttribute("maxEp",intToStr(maxEp), mapTagReplacements); +// bool maxEpIsMultiplier; + upgradeTypeBaseNode->addAttribute("maxEpIsMultiplier",intToStr(maxEpIsMultiplier), mapTagReplacements); +// int maxEpRegeneration; + upgradeTypeBaseNode->addAttribute("maxEpRegeneration",intToStr(maxEpRegeneration), mapTagReplacements); +// //bool maxEpRegenerationIsMultiplier; +// int armor; + upgradeTypeBaseNode->addAttribute("armor",intToStr(armor), mapTagReplacements); +// bool armorIsMultiplier; + upgradeTypeBaseNode->addAttribute("armorIsMultiplier",intToStr(armorIsMultiplier), mapTagReplacements); +// int attackStrength; + upgradeTypeBaseNode->addAttribute("attackStrength",intToStr(attackStrength), mapTagReplacements); +// bool attackStrengthIsMultiplier; + upgradeTypeBaseNode->addAttribute("attackStrengthIsMultiplier",intToStr(attackStrengthIsMultiplier), mapTagReplacements); +// std::map attackStrengthMultiplierValueList; + for(std::map::const_iterator iterMap = attackStrengthMultiplierValueList.begin(); + iterMap != attackStrengthMultiplierValueList.end(); ++iterMap) { + XmlNode *attackStrengthMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackStrengthMultiplierValueList"); + + attackStrengthMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + attackStrengthMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + } +// int attackRange; + upgradeTypeBaseNode->addAttribute("attackRange",intToStr(attackRange), mapTagReplacements); +// bool attackRangeIsMultiplier; + upgradeTypeBaseNode->addAttribute("attackRangeIsMultiplier",intToStr(attackRangeIsMultiplier), mapTagReplacements); +// std::map attackRangeMultiplierValueList; + for(std::map::const_iterator iterMap = attackRangeMultiplierValueList.begin(); + iterMap != attackRangeMultiplierValueList.end(); ++iterMap) { + XmlNode *attackRangeMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackRangeMultiplierValueList"); + + attackRangeMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + attackRangeMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + } + +// int moveSpeed; + upgradeTypeBaseNode->addAttribute("moveSpeed",intToStr(moveSpeed), mapTagReplacements); +// bool moveSpeedIsMultiplier; + upgradeTypeBaseNode->addAttribute("moveSpeedIsMultiplier",intToStr(moveSpeedIsMultiplier), mapTagReplacements); +// std::map moveSpeedIsMultiplierValueList; + for(std::map::const_iterator iterMap = moveSpeedIsMultiplierValueList.begin(); + iterMap != moveSpeedIsMultiplierValueList.end(); ++iterMap) { + XmlNode *moveSpeedIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("moveSpeedIsMultiplierValueList"); + + moveSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + moveSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + } + +// int prodSpeed; + upgradeTypeBaseNode->addAttribute("prodSpeed",intToStr(prodSpeed), mapTagReplacements); +// bool prodSpeedIsMultiplier; + upgradeTypeBaseNode->addAttribute("prodSpeedIsMultiplier",intToStr(prodSpeedIsMultiplier), mapTagReplacements); +// std::map prodSpeedProduceIsMultiplierValueList; + for(std::map::const_iterator iterMap = prodSpeedProduceIsMultiplierValueList.begin(); + iterMap != prodSpeedProduceIsMultiplierValueList.end(); ++iterMap) { + XmlNode *prodSpeedProduceIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedProduceIsMultiplierValueList"); + + prodSpeedProduceIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + prodSpeedProduceIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + } + +// std::map prodSpeedUpgradeIsMultiplierValueList; + for(std::map::const_iterator iterMap = prodSpeedUpgradeIsMultiplierValueList.begin(); + iterMap != prodSpeedUpgradeIsMultiplierValueList.end(); ++iterMap) { + XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedUpgradeIsMultiplierValueList"); + + prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + } + +// std::map prodSpeedMorphIsMultiplierValueList; + for(std::map::const_iterator iterMap = prodSpeedMorphIsMultiplierValueList.begin(); + iterMap != prodSpeedMorphIsMultiplierValueList.end(); ++iterMap) { + XmlNode *prodSpeedMorphIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedMorphIsMultiplierValueList"); + + prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + } +} + void UpgradeTypeBase::saveGame(XmlNode *rootNode) const { std::map mapTagReplacements; XmlNode *upgradeTypeBaseNode = rootNode->addChild("UpgradeTypeBase"); @@ -493,6 +646,106 @@ void UpgradeTypeBase::saveGame(XmlNode *rootNode) const { // } } +void UpgradeTypeBase::loadGameBoost(const XmlNode *rootNode) { + const XmlNode *upgradeTypeBaseNode = rootNode->getChild("UpgradeTypeBaseBoost"); + + //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); + + upgradename = upgradeTypeBaseNode->getAttribute("upgradename")->getValue(); + + // int maxHp; + maxHp = upgradeTypeBaseNode->getAttribute("maxHp")->getIntValue(); + // bool maxHpIsMultiplier; + maxHpIsMultiplier = (upgradeTypeBaseNode->getAttribute("maxHpIsMultiplier")->getIntValue() != 0); + // int maxHpRegeneration; + maxHpRegeneration = upgradeTypeBaseNode->getAttribute("maxHpRegeneration")->getIntValue(); + // //bool maxHpRegenerationIsMultiplier; + // + // int sight; + sight = upgradeTypeBaseNode->getAttribute("sight")->getIntValue(); + // bool sightIsMultiplier; + sightIsMultiplier = (upgradeTypeBaseNode->getAttribute("sightIsMultiplier")->getIntValue() != 0); + // int maxEp; + maxEp = upgradeTypeBaseNode->getAttribute("maxEp")->getIntValue(); + // bool maxEpIsMultiplier; + maxEpIsMultiplier = (upgradeTypeBaseNode->getAttribute("maxEpIsMultiplier")->getIntValue() != 0); + // int maxEpRegeneration; + maxEpRegeneration = upgradeTypeBaseNode->getAttribute("maxEpRegeneration")->getIntValue(); + // //bool maxEpRegenerationIsMultiplier; + // int armor; + armor = upgradeTypeBaseNode->getAttribute("armor")->getIntValue(); + // bool armorIsMultiplier; + armorIsMultiplier = (upgradeTypeBaseNode->getAttribute("armorIsMultiplier")->getIntValue() != 0); + // int attackStrength; + attackStrength = upgradeTypeBaseNode->getAttribute("attackStrength")->getIntValue(); + // bool attackStrengthIsMultiplier; + attackStrengthIsMultiplier = (upgradeTypeBaseNode->getAttribute("attackStrengthIsMultiplier")->getIntValue() != 0); + // std::map attackStrengthMultiplierValueList; + vector attackStrengthMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackStrengthMultiplierValueList"); + for(unsigned int i = 0; i < attackStrengthMultiplierValueNodeList.size(); ++i) { + XmlNode *node = attackStrengthMultiplierValueNodeList[i]; + + attackStrengthMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } + // int attackRange; + attackRange = upgradeTypeBaseNode->getAttribute("attackRange")->getIntValue(); + // bool attackRangeIsMultiplier; + attackRangeIsMultiplier = (upgradeTypeBaseNode->getAttribute("attackRangeIsMultiplier")->getIntValue() != 0); + // std::map attackRangeMultiplierValueList; + vector attackRangeMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackRangeMultiplierValueList"); + for(unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size(); ++i) { + XmlNode *node = attackRangeMultiplierValueNodeList[i]; + + attackRangeMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // int moveSpeed; + moveSpeed = upgradeTypeBaseNode->getAttribute("moveSpeed")->getIntValue(); + // bool moveSpeedIsMultiplier; + moveSpeedIsMultiplier = (upgradeTypeBaseNode->getAttribute("moveSpeedIsMultiplier")->getIntValue() != 0); + // std::map moveSpeedIsMultiplierValueList; + vector moveSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("moveSpeedIsMultiplierValueList"); + for(unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; + + moveSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // int prodSpeed; + prodSpeed = upgradeTypeBaseNode->getAttribute("prodSpeed")->getIntValue(); + // bool prodSpeedIsMultiplier; + prodSpeedIsMultiplier = (upgradeTypeBaseNode->getAttribute("prodSpeedIsMultiplier")->getIntValue() != 0); + // std::map prodSpeedProduceIsMultiplierValueList; + vector prodSpeedProduceIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedProduceIsMultiplierValueList"); + for(unsigned int i = 0; i < prodSpeedProduceIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; + + prodSpeedProduceIsMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // std::map prodSpeedUpgradeIsMultiplierValueList; + vector prodSpeedUpgradeIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedUpgradeIsMultiplierValueList"); + for(unsigned int i = 0; i < prodSpeedUpgradeIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; + + prodSpeedUpgradeIsMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // std::map prodSpeedMorphIsMultiplierValueList; + vector prodSpeedMorphIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedMorphIsMultiplierValueList"); + for(unsigned int i = 0; i < prodSpeedMorphIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; + + prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } +} + const UpgradeType * UpgradeTypeBase::loadGame(const XmlNode *rootNode, Faction *faction) { const XmlNode *upgradeTypeBaseNode = rootNode->getChild("UpgradeTypeBase"); @@ -781,7 +1034,7 @@ void UpgradeType::load(const string &dir, const TechTree *techTree, } sortedItems.clear(); - hasDup = false; + //hasDup = false; //effects -- get list of affected units const XmlNode *effectsNode= upgradeNode->getChild("effects"); @@ -892,9 +1145,13 @@ void TotalUpgrade::reset() { attackSpeed=0; attackSpeedIsMultiplier=false; + + boostUpgradeBase = NULL; + boostUpgradeSourceUnit = -1; + boostUpgradeDestUnit = -1; } -void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { +void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit, bool boostMode) { maxHpIsMultiplier = ut->getMaxHpIsMultiplier(); sightIsMultiplier = ut->getSightIsMultiplier(); maxEpIsMultiplier = ut->getMaxEpIsMultiplier(); @@ -907,45 +1164,120 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { if(ut->getMaxHpIsMultiplier() == true) { //printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - maxHp += ((double)unit->getHp() * ((double)ut->getMaxHp() / (double)100)); + int newValue = ((double)unit->getHp() * ((double)ut->getMaxHp() / (double)100)); + if(boostMode) { + maxHp = newValue; + } + else { + maxHp += newValue; + } if(ut->getMaxHpRegeneration() != 0) { - maxHpRegeneration += ((double)unit->getType()->getHpRegeneration() + ((double)max(maxHp,unit->getHp()) * ((double)ut->getMaxHpRegeneration() / (double)100))); + newValue = ((double)unit->getType()->getHpRegeneration() + ((double)max(maxHp,unit->getHp()) * ((double)ut->getMaxHpRegeneration() / (double)100))); + if(boostMode) { + maxHpRegeneration = newValue; + } + else { + maxHpRegeneration += newValue; + } } //printf("#1.1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); } else { //printf("#2 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - maxHp += ut->getMaxHp(); + int newValue = ut->getMaxHp(); + if(boostMode) { + maxHp = newValue; + } + else { + maxHp += newValue; + } + if(ut->getMaxHpRegeneration() != 0) { - maxHpRegeneration += ut->getMaxHpRegeneration(); + newValue = ut->getMaxHpRegeneration(); + if(boostMode) { + maxHpRegeneration = newValue; + } + else { + maxHpRegeneration += newValue; + } } } if(ut->getMaxEpIsMultiplier() == true) { - maxEp += ((double)unit->getEp() * ((double)ut->getMaxEp() / (double)100)); + int newValue = ((double)unit->getEp() * ((double)ut->getMaxEp() / (double)100)); + if(boostMode) { + maxEp = newValue; + } + else { + maxEp += newValue; + } + if(ut->getMaxEpRegeneration() != 0) { - maxEpRegeneration += ((double)unit->getType()->getEpRegeneration() + ((double)max(maxEp,unit->getEp()) * ((double)ut->getMaxEpRegeneration() / (double)100))); + newValue = ((double)unit->getType()->getEpRegeneration() + ((double)max(maxEp,unit->getEp()) * ((double)ut->getMaxEpRegeneration() / (double)100))); + if(boostMode) { + maxEpRegeneration = newValue; + } + else { + maxEpRegeneration += newValue; + } } } else { - maxEp += ut->getMaxEp(); + int newValue = ut->getMaxEp(); + if(boostMode) { + maxEp = newValue; + } + else { + maxEp += newValue; + } + if(ut->getMaxEpRegeneration() != 0) { - maxEpRegeneration += ut->getMaxEpRegeneration(); + newValue = ut->getMaxEpRegeneration(); + if(boostMode) { + maxEpRegeneration = newValue; + } + else { + maxEpRegeneration += newValue; + } } } if(ut->getSightIsMultiplier() == true) { - sight += ((double)unit->getType()->getSight() * ((double)ut->getSight() / (double)100)); + int newValue = ((double)unit->getType()->getSight() * ((double)ut->getSight() / (double)100)); + if(boostMode) { + sight = newValue; + } + else { + sight += newValue; + } } else { - sight += ut->getSight(); + int newValue = ut->getSight(); + if(boostMode) { + sight = newValue; + } + else { + sight += newValue; + } } if(ut->getArmorIsMultiplier() == true) { - armor += ((double)unit->getType()->getArmor() * ((double)ut->getArmor() / (double)100)); + int newValue = ((double)unit->getType()->getArmor() * ((double)ut->getArmor() / (double)100)); + if(boostMode) { + armor = newValue; + } + else { + armor += newValue; + } } else { - armor += ut->getArmor(); + int newValue = ut->getArmor(); + if(boostMode) { + armor = newValue; + } + else { + armor += newValue; + } } if(ut->getAttackStrengthIsMultiplier() == true) { @@ -953,12 +1285,24 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { const SkillType *skillType = unit->getType()->getSkillType(i); const AttackSkillType *ast = dynamic_cast(skillType); if(ast != NULL) { - attackStrengthMultiplierValueList[ast->getName()] += ((double)ast->getAttackStrength() * ((double)ut->getAttackStrength(NULL) / (double)100)); + int newValue = ((double)ast->getAttackStrength() * ((double)ut->getAttackStrength(NULL) / (double)100)); + if(boostMode) { + attackStrengthMultiplierValueList[ast->getName()] = newValue; + } + else { + attackStrengthMultiplierValueList[ast->getName()] += newValue; + } } } } else { - attackStrength += ut->getAttackStrength(NULL); + int newValue = ut->getAttackStrength(NULL); + if(boostMode) { + attackStrength = newValue; + } + else { + attackStrength += newValue; + } } if(ut->getAttackRangeIsMultiplier() == true) { @@ -966,31 +1310,49 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { const SkillType *skillType = unit->getType()->getSkillType(i); const AttackSkillType *ast = dynamic_cast(skillType); if(ast != NULL) { - attackRangeMultiplierValueList[ast->getName()] += ((double)ast->getAttackRange() * ((double)ut->getAttackRange(NULL) / (double)100)); + int newValue = ((double)ast->getAttackRange() * ((double)ut->getAttackRange(NULL) / (double)100)); + if(boostMode) { + attackRangeMultiplierValueList[ast->getName()] = newValue; + } + else { + attackRangeMultiplierValueList[ast->getName()] += newValue; + } } } } else { - attackRange += ut->getAttackRange(NULL); + int newValue = ut->getAttackRange(NULL); + if(boostMode) { + attackRange = newValue; + } + else { + attackRange += newValue; + } } if(ut->getMoveSpeedIsMultiplier() == true) { - //printf("BEFORE Applying moveSpeedIsMultiplier\n"); - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { const SkillType *skillType = unit->getType()->getSkillType(i); const MoveSkillType *mst = dynamic_cast(skillType); if(mst != NULL) { - moveSpeedIsMultiplierValueList[mst->getName()] += ((double)mst->getSpeed() * ((double)ut->getMoveSpeed(NULL) / (double)100)); - - //printf("Applying moveSpeedIsMultiplier for unit [%s - %d], mst->getSpeed() = %d ut->getMoveSpeed(NULL) = %d newmoveSpeed = %d for skill [%s]\n",unit->getType()->getName().c_str(),unit->getId(), mst->getSpeed(),ut->getMoveSpeed(NULL),moveSpeedIsMultiplierValueList[mst->getName()],mst->getName().c_str()); + int newValue = ((double)mst->getSpeed() * ((double)ut->getMoveSpeed(NULL) / (double)100)); + if(boostMode) { + moveSpeedIsMultiplierValueList[mst->getName()] = newValue; + } + else { + moveSpeedIsMultiplierValueList[mst->getName()] += newValue; + } } } - - //printf("AFTER Applying moveSpeedIsMultiplierd\n"); } else { - moveSpeed += ut->getMoveSpeed(NULL); + int newValue = ut->getMoveSpeed(NULL); + if(boostMode) { + moveSpeed = newValue; + } + else { + moveSpeed += newValue; + } } if(ut->getProdSpeedIsMultiplier() == true) { @@ -998,20 +1360,44 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { const SkillType *skillType = unit->getType()->getSkillType(i); const ProduceSkillType *pst = dynamic_cast(skillType); if(pst != NULL) { - prodSpeedProduceIsMultiplierValueList[pst->getName()] += ((double)pst->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); + int newValue = ((double)pst->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); + if(boostMode) { + prodSpeedProduceIsMultiplierValueList[pst->getName()] = newValue; + } + else { + prodSpeedProduceIsMultiplierValueList[pst->getName()] += newValue; + } } const UpgradeSkillType *ust = dynamic_cast(skillType); if(ust != NULL) { - prodSpeedUpgradeIsMultiplierValueList[ust->getName()] += ((double)ust->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); + int newValue = ((double)ust->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); + if(boostMode) { + prodSpeedUpgradeIsMultiplierValueList[ust->getName()] = newValue; + } + else { + prodSpeedUpgradeIsMultiplierValueList[ust->getName()] += newValue; + } } const MorphSkillType *mst = dynamic_cast(skillType); if(mst != NULL) { - prodSpeedMorphIsMultiplierValueList[mst->getName()] += ((double)mst->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); + int newValue = ((double)mst->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); + if(boostMode) { + prodSpeedMorphIsMultiplierValueList[mst->getName()] = newValue; + } + else { + prodSpeedMorphIsMultiplierValueList[mst->getName()] += newValue; + } } } } else { - prodSpeed += ut->getProdSpeed(NULL); + int newValue = ut->getProdSpeed(NULL); + if(boostMode) { + prodSpeed = newValue; + } + else { + prodSpeed += newValue; + } } if(ut->getAttackSpeedIsMultiplier() == true) { @@ -1019,169 +1405,196 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { const SkillType *skillType = unit->getType()->getSkillType(i); const AttackSkillType *ast = dynamic_cast(skillType); if(ast != NULL) { - attackSpeedIsMultiplierValueList[ast->getName()] += ((double)ast->getSpeed() * ((double)ut->getAttackSpeed(NULL) / (double)100)); + int newValue = ((double)ast->getSpeed() * ((double)ut->getAttackSpeed(NULL) / (double)100)); + if(boostMode) { + attackSpeedIsMultiplierValueList[ast->getName()] = newValue; + } + else { + attackSpeedIsMultiplierValueList[ast->getName()] += newValue; + } } } } else { - attackSpeed += ut->getAttackSpeed(NULL); + int newValue = ut->getAttackSpeed(NULL); + if(boostMode) { + attackSpeed = newValue; + } + else { + attackSpeed += newValue; + } } } -void TotalUpgrade::apply(const UpgradeTypeBase *ut, const Unit *unit) { - sum(ut, unit); +void TotalUpgrade::apply(int sourceUnitId, const UpgradeTypeBase *ut, const Unit *unit) { + //sum(ut, unit); + + //printf("====> About to apply boost: %s\nTo unit: %d\n\n",ut->toString().c_str(),unit->getId()); + TotalUpgrade *boostUpgrade = new TotalUpgrade(); + boostUpgrade->copyDataFrom(this); + boostUpgrade->boostUpgradeBase = ut; + boostUpgrade->boostUpgradeSourceUnit = sourceUnitId; + boostUpgrade->boostUpgradeDestUnit = unit->getId(); + + boostUpgrade->sum(ut,unit, true); + boostUpgrades.push_back(boostUpgrade); } -void TotalUpgrade::deapply(const UpgradeTypeBase *ut,const Unit *unit) { - maxHpIsMultiplier = ut->getMaxHpIsMultiplier(); - sightIsMultiplier = ut->getSightIsMultiplier(); - maxEpIsMultiplier = ut->getMaxEpIsMultiplier(); - armorIsMultiplier = ut->getArmorIsMultiplier(); - attackStrengthIsMultiplier = ut->getAttackStrengthIsMultiplier(); - attackRangeIsMultiplier = ut->getAttackRangeIsMultiplier(); - moveSpeedIsMultiplier = ut->getMoveSpeedIsMultiplier(); - prodSpeedIsMultiplier = ut->getProdSpeedIsMultiplier(); +void TotalUpgrade::deapply(int sourceUnitId, const UpgradeTypeBase *ut,int destUnitId) { + //printf("<****** About to de-apply boost: %s\nTo unit: %d\n\n",ut->toString().c_str(),destUnitId); - if(ut->getMaxHpIsMultiplier() == true) { - //printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - maxHp -= ((double)unit->getHp() * ((double)ut->getMaxHp() / (double)100)); + bool removedBoost = false; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + if(boost->boostUpgradeSourceUnit == sourceUnitId && + boost->boostUpgradeBase->getUpgradeName() == ut->getUpgradeName() && + boost->boostUpgradeDestUnit == destUnitId) { - if(ut->getMaxHpRegeneration() != 0) { - maxHpRegeneration -= ((double)unit->getType()->getHpRegeneration() + ((double)max(maxHp,unit->getHp()) * ((double)ut->getMaxHpRegeneration() / (double)100))); - } - //printf("#1.1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - } - else { - maxHp -= ut->getMaxHp(); - if(ut->getMaxHpRegeneration() != 0) { - maxHpRegeneration -= ut->getMaxHpRegeneration(); + boostUpgrades.erase(boostUpgrades.begin() + index); + delete boost; + removedBoost = true; + + //printf("de-apply boost FOUND!\n"); + break; } } - enforceMinimumValue(0,maxHp); - enforceMinimumValue(0,maxHpRegeneration); - - if(ut->getMaxEpIsMultiplier() == true) { - maxEp -= ((double)unit->getEp() * ((double)ut->getMaxEp() / (double)100)); - if(ut->getMaxEpRegeneration() != 0) { - maxEpRegeneration -= ((double)unit->getType()->getEpRegeneration() + ((double)max(maxEp,unit->getEp()) * ((double)ut->getMaxEpRegeneration() / (double)100))); + if(removedBoost == false) { + printf("\n\n!!!!!! de-apply boost NOT FOUND for sourceUnitId = %d, destUnitId = %d\n%s\n\nCurrent Boosts:\n", + sourceUnitId,destUnitId,ut->toString().c_str()); + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + printf("\nBoost #%u\n%s\n",index,boost->toString().c_str()); } } - else { - maxEp -= ut->getMaxEp(); - if(ut->getMaxEpRegeneration() != 0) { - maxEpRegeneration -= ut->getMaxEpRegeneration(); - } - } - enforceMinimumValue(0,maxEp); - enforceMinimumValue(0,maxEpRegeneration); +} - if(ut->getSightIsMultiplier() == true) { - sight -= ((double)unit->getType()->getSight() * ((double)ut->getSight() / (double)100)); +int TotalUpgrade::getMaxHp() const { + return maxHp + getMaxHpFromBoosts(); +} +int TotalUpgrade::getMaxHpFromBoosts() const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxHp(); } - else { - sight -= ut->getSight(); + return result; +} +int TotalUpgrade::getMaxHpRegeneration() const { + return maxHpRegeneration + getMaxHpRegenerationFromBoosts(); +} +int TotalUpgrade::getMaxHpRegenerationFromBoosts() const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxHpRegeneration(); } - enforceMinimumValue(0,sight); + return result; +} +int TotalUpgrade::getSight() const { + return sight + getSightFromBoosts(); +} +int TotalUpgrade::getSightFromBoosts() const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getSight(); + } + return result; +} +int TotalUpgrade::getMaxEp() const { + return maxEp + getMaxEpFromBoosts(); +} +int TotalUpgrade::getMaxEpFromBoosts() const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxEp(); + } + return result; +} - if(ut->getArmorIsMultiplier() == true) { - armor -= ((double)unit->getType()->getArmor() * ((double)ut->getArmor() / (double)100)); +int TotalUpgrade::getMaxEpRegeneration() const { + return maxEpRegeneration + getMaxEpRegenerationFromBoosts(); +} +int TotalUpgrade::getMaxEpRegenerationFromBoosts() const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxEpRegeneration(); } - else { - armor -= ut->getArmor(); - } - enforceMinimumValue(0,armor); + return result; +} - if(ut->getAttackStrengthIsMultiplier() == true) { - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { - const SkillType *skillType = unit->getType()->getSkillType(i); - const AttackSkillType *ast = dynamic_cast(skillType); - if(ast != NULL) { - attackStrengthMultiplierValueList[ast->getName()] -= ((double)ast->getAttackStrength() * ((double)ut->getAttackStrength(NULL) / (double)100)); - enforceMinimumValue(0,attackStrengthMultiplierValueList[ast->getName()]); - } - } - } - else { - attackStrength -= ut->getAttackStrength(NULL); - enforceMinimumValue(0,attackStrength); +int TotalUpgrade::getArmor() const { + return armor + getArmorFromBoosts(); +} +int TotalUpgrade::getArmorFromBoosts() const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getArmor(); } + return result; +} +int TotalUpgrade::getAttackStrength(const AttackSkillType *st) const { + return UpgradeTypeBase::getAttackStrength(st) + getAttackStrengthFromBoosts(st); +} +int TotalUpgrade::getAttackStrengthFromBoosts(const AttackSkillType *st) const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getAttackStrength(st); + } + return result; +} - if(ut->getAttackRangeIsMultiplier() == true) { - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { - const SkillType *skillType = unit->getType()->getSkillType(i); - const AttackSkillType *ast = dynamic_cast(skillType); - if(ast != NULL) { - attackRangeMultiplierValueList[ast->getName()] -= ((double)ast->getAttackRange() * ((double)ut->getAttackRange(NULL) / (double)100)); - enforceMinimumValue(0,attackRangeMultiplierValueList[ast->getName()]); - } - } - } - else { - attackRange -= ut->getAttackRange(NULL); - enforceMinimumValue(0,attackRange); +int TotalUpgrade::getAttackRange(const AttackSkillType *st) const { + return UpgradeTypeBase::getAttackRange(st) + getAttackRangeFromBoosts(st); +} +int TotalUpgrade::getAttackRangeFromBoosts(const AttackSkillType *st) const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getAttackRange(st); } + return result; +} - if(ut->getMoveSpeedIsMultiplier() == true) { - //printf("BEFORE Applying moveSpeedIsMultiplier, moveSpeed = %d, ut->getMoveSpeed() = %d\n",moveSpeed,ut->getMoveSpeed()); +int TotalUpgrade::getMoveSpeed(const MoveSkillType *st) const { + return UpgradeTypeBase::getMoveSpeed(st) + getMoveSpeedFromBoosts(st); +} +int TotalUpgrade::getMoveSpeedFromBoosts(const MoveSkillType *st) const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMoveSpeed(st); + } + return result; +} - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { - const SkillType *skillType = unit->getType()->getSkillType(i); - const MoveSkillType *mst = dynamic_cast(skillType); - if(mst != NULL) { - moveSpeedIsMultiplierValueList[mst->getName()] -= ((double)mst->getSpeed() * ((double)ut->getMoveSpeed(NULL) / (double)100)); - enforceMinimumValue(0,moveSpeedIsMultiplierValueList[mst->getName()]); - } - } +int TotalUpgrade::getProdSpeed(const SkillType *st) const { + return UpgradeTypeBase::getProdSpeed(st) + getProdSpeedFromBoosts(st); +} +int TotalUpgrade::getProdSpeedFromBoosts(const SkillType *st) const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getProdSpeed(st); + } + return result; +} - //printf("AFTER Applying moveSpeedIsMultiplier, moveSpeed = %d\n",moveSpeed); - } - else { - moveSpeed -= ut->getMoveSpeed(NULL); - enforceMinimumValue(0,moveSpeed); - } - - if(ut->getProdSpeedIsMultiplier() == true) { - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { - const SkillType *skillType = unit->getType()->getSkillType(i); - const ProduceSkillType *pst = dynamic_cast(skillType); - if(pst != NULL) { - prodSpeedProduceIsMultiplierValueList[pst->getName()] -= ((double)pst->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); - enforceMinimumValue(0,prodSpeedProduceIsMultiplierValueList[pst->getName()]); - } - const UpgradeSkillType *ust = dynamic_cast(skillType); - if(ust != NULL) { - prodSpeedUpgradeIsMultiplierValueList[ust->getName()] -= ((double)ust->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); - enforceMinimumValue(0,prodSpeedUpgradeIsMultiplierValueList[ust->getName()]); - } - const MorphSkillType *mst = dynamic_cast(skillType); - if(mst != NULL) { - prodSpeedMorphIsMultiplierValueList[mst->getName()] -= ((double)mst->getSpeed() * ((double)ut->getProdSpeed(NULL) / (double)100)); - enforceMinimumValue(0,prodSpeedMorphIsMultiplierValueList[mst->getName()]); - } - } - } - else { - prodSpeed -= ut->getProdSpeed(NULL); - enforceMinimumValue(0,prodSpeed); - } - - if(ut->getAttackSpeedIsMultiplier() == true) { - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { - const SkillType *skillType = unit->getType()->getSkillType(i); - const AttackSkillType *ast = dynamic_cast(skillType); - if(ast != NULL) { - attackSpeedIsMultiplierValueList[ast->getName()] -= ((double)ast->getSpeed() * ((double)ut->getAttackSpeed(NULL) / (double)100)); - enforceMinimumValue(0, attackSpeedIsMultiplierValueList[ast->getName()]); - } - } - - //printf("AFTER Applying moveSpeedIsMultiplier, moveSpeed = %d\n",moveSpeed); - } - else { - attackSpeed -= ut->getAttackSpeed(NULL); - enforceMinimumValue(0, attackSpeed); +int TotalUpgrade::getAttackSpeed(const AttackSkillType *st) const { + return UpgradeTypeBase::getAttackSpeed(st) + getAttackSpeedFromBoosts(st); +} +int TotalUpgrade::getAttackSpeedFromBoosts(const AttackSkillType *st) const { + int result = 0; + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getAttackSpeed(st); } + return result; } void TotalUpgrade::incLevel(const UnitType *ut) { @@ -1189,6 +1602,11 @@ void TotalUpgrade::incLevel(const UnitType *ut) { maxEp += ut->getMaxEp()*50/100; sight += ut->getSight()*20/100; armor += ut->getArmor()*50/100; + + for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + boost->copyDataFrom(this); + } } void TotalUpgrade::saveGame(XmlNode *rootNode) const { @@ -1296,6 +1714,18 @@ void TotalUpgrade::saveGame(XmlNode *rootNode) const { attackSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); attackSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); } + +// for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { +// TotalUpgrade *boost = boostUpgrades[index]; +// XmlNode *attackBoostListNode = upgradeTypeBaseNode->addChild("attackBoostList"); +// attackBoostListNode->addAttribute("unitId",intToStr(boost->boostUpgradeUnit->getId()), mapTagReplacements); +// +// std::map mapTagReplacements; +// if(boost != NULL) { +// boost->saveGameBoost(attackBoostListNode); +// boost->boostUpgradeBase->saveGameBoost(attackBoostListNode); +// } +// } } void TotalUpgrade::loadGame(const XmlNode *rootNode) { @@ -1395,15 +1825,50 @@ void TotalUpgrade::loadGame(const XmlNode *rootNode) { node->getAttribute("value")->getIntValue(); } - attackSpeed = upgradeTypeBaseNode->getAttribute("attackSpeed")->getIntValue(); - attackSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("attackSpeedIsMultiplier")->getIntValue() != 0; - vector attackSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackSpeedIsMultiplierValueList"); - for(unsigned int i = 0; i < attackSpeedIsMultiplierValueNodeList.size(); ++i) { - XmlNode *node = attackSpeedIsMultiplierValueNodeList[i]; + if(upgradeTypeBaseNode->hasAttribute("attackSpeed")){ + attackSpeed = upgradeTypeBaseNode->getAttribute("attackSpeed")->getIntValue(); + attackSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("attackSpeedIsMultiplier")->getIntValue() != 0; + vector attackSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackSpeedIsMultiplierValueList"); + for(unsigned int i = 0; i < attackSpeedIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = attackSpeedIsMultiplierValueNodeList[i]; - attackSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = - node->getAttribute("value")->getIntValue(); + attackSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = + node->getAttribute("value")->getIntValue(); + } } + +// vector boostNodeList = upgradeTypeBaseNode->getChildList("attackBoostList"); +// for(unsigned int index = 0; index < boostNodeList.size(); ++index) { +// XmlNode *boostNode = boostNodeList[index]; +// +// //for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { +// // TotalUpgrade *boost = boostUpgrades[index]; +// // XmlNode *attackBoostListNode = upgradeTypeBaseNode->addChild("attackBoostList"); +// +//// std::map mapTagReplacements; +//// if(boost != NULL) { +//// boost->saveGame(attackBoostListNode); +//// } +// int unitId = boostNode->getAttribute("unitId")->getIntValue(); +// const Unit *unit = world->findUnitById(unitId); +// +// TotalUpgrade *boostUpgrade = new TotalUpgrade(); +// //boostUpgrade->copyDataFrom(this); +// boostUpgrade->loadGameBoost(boostNode); +// boostUpgrade->loadGameBoost(boostNode); +// +// boostUpgrade->boostUpgradeBase = ut; +// boostUpgrade->boostUpgradeUnit = unit; +// +// //boostUpgrade->sum(ut,unit); +// boostUpgrades.push_back(boostUpgrade); +// +// //boost->saveGameBoost(attackBoostListNode); +// //boost->boostUpgradeBase->saveGameBoost(attackBoostListNode); +// +// //apply(const UpgradeTypeBase *ut, unit); +// } + } diff --git a/source/glest_game/types/upgrade_type.h b/source/glest_game/types/upgrade_type.h index 5db3218db..c55a51103 100644 --- a/source/glest_game/types/upgrade_type.h +++ b/source/glest_game/types/upgrade_type.h @@ -97,6 +97,26 @@ protected: bool attackSpeedIsMultiplier; std::map attackSpeedIsMultiplierValueList; +protected: + + virtual int getAttackStrength() const { return attackStrength; } + virtual int getAttackRange() const { return attackRange; } + virtual int getMoveSpeed() const { return moveSpeed; } + virtual int getProdSpeed() const { return prodSpeed; } + virtual int getAttackSpeed() const { return attackSpeed; } + + virtual int getMaxHpFromBoosts() const { return 0; } + virtual int getMaxHpRegenerationFromBoosts() const { return 0; } + virtual int getSightFromBoosts() const { return 0; } + virtual int getMaxEpFromBoosts() const { return 0; } + virtual int getMaxEpRegenerationFromBoosts() const { return 0; } + virtual int getArmorFromBoosts() const { return 0; }; + virtual int getAttackStrengthFromBoosts(const AttackSkillType *st) const { return 0; } + virtual int getAttackRangeFromBoosts(const AttackSkillType *st) const { return 0; } + virtual int getMoveSpeedFromBoosts(const MoveSkillType *st) const { return 0; } + virtual int getProdSpeedFromBoosts(const SkillType *st) const { return 0; } + virtual int getAttackSpeedFromBoosts(const AttackSkillType *st) const { return 0; } + public: /** * Creates an UpgradeTypeBase with values such that there are no stat changes. @@ -120,35 +140,35 @@ public: moveSpeedIsMultiplier = false; prodSpeed = 0; prodSpeedIsMultiplier = false; + attackSpeed = 0; + attackSpeedIsMultiplier = false; } virtual ~UpgradeTypeBase() {} - int getMaxHp() const {return maxHp;} - bool getMaxHpIsMultiplier() const {return maxHpIsMultiplier;} - int getMaxHpRegeneration() const {return maxHpRegeneration;} - //bool getMaxHpRegenerationIsMultiplier() const {return maxHpRegenerationIsMultiplier;} + virtual void copyDataFrom(UpgradeTypeBase *source); - int getSight() const {return sight;} - bool getSightIsMultiplier() const {return sightIsMultiplier;} + virtual string getUpgradeName() const { return upgradename; } + virtual int getMaxHp() const {return maxHp;} + virtual int getMaxHpRegeneration() const {return maxHpRegeneration;} + virtual int getSight() const {return sight;} + virtual int getMaxEp() const {return maxEp;} + virtual int getMaxEpRegeneration() const {return maxEpRegeneration;} + virtual int getArmor() const {return armor;} + virtual int getAttackStrength(const AttackSkillType *st) const; + virtual int getAttackRange(const AttackSkillType *st) const; + virtual int getMoveSpeed(const MoveSkillType *st) const; + virtual int getProdSpeed(const SkillType *st) const; + virtual int getAttackSpeed(const AttackSkillType *st) const; - int getMaxEp() const {return maxEp;} - bool getMaxEpIsMultiplier() const {return maxEpIsMultiplier;} - int getMaxEpRegeneration() const {return maxEpRegeneration;} - //bool getMaxEpRegenerationIsMultiplier() const {return maxEpRegenerationIsMultiplier;} - - int getArmor() const {return armor;} - bool getArmorIsMultiplier() const {return armorIsMultiplier;} - - int getAttackStrength(const AttackSkillType *st) const; - bool getAttackStrengthIsMultiplier() const {return attackStrengthIsMultiplier;} - int getAttackRange(const AttackSkillType *st) const; - bool getAttackRangeIsMultiplier() const {return attackRangeIsMultiplier;} - int getMoveSpeed(const MoveSkillType *st) const; - bool getMoveSpeedIsMultiplier() const {return moveSpeedIsMultiplier;} - int getProdSpeed(const SkillType *st) const; - bool getProdSpeedIsMultiplier() const {return prodSpeedIsMultiplier;} - int getAttackSpeed(const AttackSkillType *st) const; - bool getAttackSpeedIsMultiplier() const {return attackSpeedIsMultiplier;} + virtual bool getAttackStrengthIsMultiplier() const {return attackStrengthIsMultiplier;} + virtual bool getMaxHpIsMultiplier() const {return maxHpIsMultiplier;} + virtual bool getSightIsMultiplier() const {return sightIsMultiplier;} + virtual bool getMaxEpIsMultiplier() const {return maxEpIsMultiplier;} + virtual bool getArmorIsMultiplier() const {return armorIsMultiplier;} + virtual bool getAttackRangeIsMultiplier() const {return attackRangeIsMultiplier;} + virtual bool getMoveSpeedIsMultiplier() const {return moveSpeedIsMultiplier;} + virtual bool getProdSpeedIsMultiplier() const {return prodSpeedIsMultiplier;} + virtual bool getAttackSpeedIsMultiplier() const {return attackSpeedIsMultiplier;} /** * Loads the upgrade values (stat boosts and whether or not the boosts use a multiplier) from an @@ -157,7 +177,7 @@ public: * @param upgradename Unique identifier for the upgrade. */ - void load(const XmlNode *upgradeNode, string upgradename); + virtual void load(const XmlNode *upgradeNode, string upgradename); /** * Creates a string representation of the upgrade. All stat boosts are detailed on their own line @@ -165,39 +185,39 @@ public: * @param translatedValue If true, the description is translated. Otherwise the description uses * names as they appear in the XMLs. */ - virtual string getDesc(bool translatedValue) const; + virtual string getDesc(bool translatedValue) const; /** * Returns a string representation of this object. Lists all the value that the object stores. * For debugging purposes, only. */ - std::string toString() const { + virtual std::string toString() const { std::string result = ""; - result += "upgradename =" + upgradename; - result += "maxHp = " + intToStr(maxHp); - result += "maxHpIsMultiplier = " + intToStr(maxHpIsMultiplier); - result += "maxHpRegeneration = " + intToStr(maxHpRegeneration); + result += "upgradename =" + getUpgradeName(); + result += "maxHp = " + intToStr(getMaxHp()); + result += "maxHpIsMultiplier = " + intToStr(getMaxHpIsMultiplier()); + result += "maxHpRegeneration = " + intToStr(getMaxHpRegeneration()); //result += "maxHpRegenerationIsMultiplier = " + intToStr(maxHpRegenerationIsMultiplier); - result += " sight = " + intToStr(sight); - result += "sightIsMultiplier = " + intToStr(sightIsMultiplier); + result += " sight = " + intToStr(getSight()); + result += "sightIsMultiplier = " + intToStr(getSightIsMultiplier()); - result += " maxEp = " + intToStr(maxEp); - result += " maxEpIsMultiplier = " + intToStr(maxEpIsMultiplier); - result += " maxEpRegeneration = " + intToStr(maxEpRegeneration); + result += " maxEp = " + intToStr(getMaxEp()); + result += " maxEpIsMultiplier = " + intToStr(getMaxEpIsMultiplier()); + result += " maxEpRegeneration = " + intToStr(getMaxEpRegeneration()); //result += "maxEpRegenerationIsMultiplier = " + intToStr(maxEpRegenerationIsMultiplier); - result += " armor = " + intToStr(armor); - result += " armorIsMultiplier = " + intToStr(armorIsMultiplier); - result += " attackStrength = " + intToStr(attackStrength); - result += " attackStrengthIsMultiplier = " + intToStr(attackStrengthIsMultiplier); - result += " attackRange = " + intToStr(attackRange); - result += " attackRangeIsMultiplier = " + intToStr(attackRangeIsMultiplier); - result += " moveSpeed = " + intToStr(moveSpeed); - result += " moveSpeedIsMultiplier = " + intToStr(moveSpeedIsMultiplier); - result += " prodSpeed = " + intToStr(prodSpeed); - result += " prodSpeedIsMultiplier = " + intToStr(prodSpeedIsMultiplier); + result += " armor = " + intToStr(getArmor()); + result += " armorIsMultiplier = " + intToStr(getArmorIsMultiplier()); + result += " attackStrength = " + intToStr(getAttackStrength()); + result += " attackStrengthIsMultiplier = " + intToStr(getAttackStrengthIsMultiplier()); + result += " attackRange = " + intToStr(getAttackRange()); + result += " attackRangeIsMultiplier = " + intToStr(getAttackRangeIsMultiplier()); + result += " moveSpeed = " + intToStr(getMoveSpeed()); + result += " moveSpeedIsMultiplier = " + intToStr(getMoveSpeedIsMultiplier()); + result += " prodSpeed = " + intToStr(getProdSpeed()); + result += " prodSpeedIsMultiplier = " + intToStr(getProdSpeedIsMultiplier()); return result; } @@ -205,46 +225,48 @@ public: // TODO: It's not clear if these save game methods are being used, currently. I think // attack boosts might use the few lines that aren't commented out. virtual void saveGame(XmlNode *rootNode) const; + virtual void saveGameBoost(XmlNode *rootNode) const; static const UpgradeType * loadGame(const XmlNode *rootNode, Faction *faction); + void loadGameBoost(const XmlNode *rootNode); /** * Generates a checksum value for the upgrade. */ - Checksum getCRC() { + virtual Checksum getCRC() { Checksum crcForUpgradeType; - crcForUpgradeType.addString(upgradename); - crcForUpgradeType.addInt(maxHp); - crcForUpgradeType.addInt(maxHpIsMultiplier); - crcForUpgradeType.addInt(maxHpRegeneration); + crcForUpgradeType.addString(getUpgradeName()); + crcForUpgradeType.addInt(getMaxHp()); + crcForUpgradeType.addInt(getMaxHpIsMultiplier()); + crcForUpgradeType.addInt(getMaxHpRegeneration()); - crcForUpgradeType.addInt(sight); - crcForUpgradeType.addInt(sightIsMultiplier); + crcForUpgradeType.addInt(getSight()); + crcForUpgradeType.addInt(getSightIsMultiplier()); - crcForUpgradeType.addInt(maxEp); - crcForUpgradeType.addInt(maxEpIsMultiplier); - crcForUpgradeType.addInt(maxEpRegeneration); + crcForUpgradeType.addInt(getMaxEp()); + crcForUpgradeType.addInt(getMaxEpIsMultiplier()); + crcForUpgradeType.addInt(getMaxEpRegeneration()); - crcForUpgradeType.addInt(armor); - crcForUpgradeType.addInt(armorIsMultiplier); + crcForUpgradeType.addInt(getArmor()); + crcForUpgradeType.addInt(getArmorIsMultiplier()); - crcForUpgradeType.addInt(attackStrength); - crcForUpgradeType.addInt(attackStrengthIsMultiplier); + crcForUpgradeType.addInt(getAttackStrength()); + crcForUpgradeType.addInt(getAttackStrengthIsMultiplier()); //std::map attackStrengthMultiplierValueList; crcForUpgradeType.addInt64((int64)attackStrengthMultiplierValueList.size()); - crcForUpgradeType.addInt(attackRange); - crcForUpgradeType.addInt(attackRangeIsMultiplier); + crcForUpgradeType.addInt(getAttackRange()); + crcForUpgradeType.addInt(getAttackRangeIsMultiplier()); //std::map attackRangeMultiplierValueList; crcForUpgradeType.addInt64((int64)attackRangeMultiplierValueList.size()); - crcForUpgradeType.addInt(moveSpeed); - crcForUpgradeType.addInt(moveSpeedIsMultiplier); + crcForUpgradeType.addInt(getMoveSpeed()); + crcForUpgradeType.addInt(getMoveSpeedIsMultiplier()); //std::map moveSpeedIsMultiplierValueList; crcForUpgradeType.addInt64((int64)moveSpeedIsMultiplierValueList.size()); - crcForUpgradeType.addInt(prodSpeed); - crcForUpgradeType.addInt(prodSpeedIsMultiplier); + crcForUpgradeType.addInt(getProdSpeed()); + crcForUpgradeType.addInt(getProdSpeedIsMultiplier()); //std::map prodSpeedProduceIsMultiplierValueList; crcForUpgradeType.addInt64((int64)prodSpeedProduceIsMultiplierValueList.size()); //std::map prodSpeedUpgradeIsMultiplierValueList; @@ -252,8 +274,8 @@ public: //std::map prodSpeedMorphIsMultiplierValueList; crcForUpgradeType.addInt64((int64)prodSpeedMorphIsMultiplierValueList.size()); - crcForUpgradeType.addInt(attackSpeed); - crcForUpgradeType.addInt(attackSpeedIsMultiplier); + crcForUpgradeType.addInt(getAttackSpeed()); + crcForUpgradeType.addInt(getAttackSpeedIsMultiplier()); return crcForUpgradeType; } @@ -326,6 +348,15 @@ public: * upgrades to a unit with the effects stacking. */ class TotalUpgrade: public UpgradeTypeBase { + +private: + + // List of boosts + const UpgradeTypeBase *boostUpgradeBase; + int boostUpgradeSourceUnit; + int boostUpgradeDestUnit; + std::vector boostUpgrades; + public: TotalUpgrade(); virtual ~TotalUpgrade() {} @@ -342,7 +373,7 @@ public: * @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier, * the stats raise by an amount relative to the unit's base stats). */ - void sum(const UpgradeTypeBase *ut, const Unit *unit); + void sum(const UpgradeTypeBase *ut, const Unit *unit, bool boostMode=false); /** * Increases the level of the unit. Doing so results in their HP, EP, and armour going up by @@ -355,7 +386,7 @@ public: /** * Applies the upgrade. Just a delegate to TotalUpgrade::sum. */ - void apply(const UpgradeTypeBase *ut, const Unit *unit); + void apply(int sourceUnitId, const UpgradeTypeBase *ut, const Unit *unit); /** * Removes the effect of an upgrade to a specific unit. Using this after applying the upgrade @@ -369,7 +400,31 @@ public: * @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier, * the stats were raise by an amount relative to the unit's base stats). */ - void deapply(const UpgradeTypeBase *ut, const Unit *unit); + void deapply(int sourceUnitId, const UpgradeTypeBase *ut,int destUnitId); + + virtual int getMaxHp() const; + virtual int getMaxHpRegeneration() const; + virtual int getSight() const; + virtual int getMaxEp() const; + virtual int getMaxEpRegeneration() const; + virtual int getArmor() const; + virtual int getAttackStrength(const AttackSkillType *st) const; + virtual int getAttackRange(const AttackSkillType *st) const; + virtual int getMoveSpeed(const MoveSkillType *st) const; + virtual int getProdSpeed(const SkillType *st) const; + virtual int getAttackSpeed(const AttackSkillType *st) const; + + virtual int getMaxHpFromBoosts() const; + virtual int getMaxHpRegenerationFromBoosts() const; + virtual int getSightFromBoosts() const; + virtual int getMaxEpFromBoosts() const; + virtual int getMaxEpRegenerationFromBoosts() const; + virtual int getArmorFromBoosts() const; + virtual int getAttackStrengthFromBoosts(const AttackSkillType *st) const; + virtual int getAttackRangeFromBoosts(const AttackSkillType *st) const; + virtual int getMoveSpeedFromBoosts(const MoveSkillType *st) const; + virtual int getProdSpeedFromBoosts(const SkillType *st) const; + virtual int getAttackSpeedFromBoosts(const AttackSkillType *st) const; /** * Creates the XML for the save game file. Essentially just stores everything about its state. diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 4c276bfbc..965c2a661 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -170,11 +170,25 @@ bool SurfaceCell::decAmount(int value) { return object->getResource()->decAmount(value); } void SurfaceCell::setExplored(int teamIndex, bool explored) { + if(teamIndex < 0 || teamIndex >= GameConstants::maxPlayers + GameConstants::specialFactions) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"Invalid value for teamIndex [%d]",teamIndex); + printf("%s\n",szBuf); + throw megaglest_runtime_error(szBuf); + } + this->explored[teamIndex]= explored; //printf("Setting explored to %d for teamIndex %d\n",explored,teamIndex); } void SurfaceCell::setVisible(int teamIndex, bool visible) { + if(teamIndex < 0 || teamIndex >= GameConstants::maxPlayers + GameConstants::specialFactions) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"Invalid value for teamIndex [%d]",teamIndex); + printf("%s\n",szBuf); + throw megaglest_runtime_error(szBuf); + } + this->visible[teamIndex]= visible; } @@ -477,7 +491,7 @@ Checksum Map::load(const string &path, TechTree *techTree, Tileset *tileset) { objNumber = ::Shared::PlatformByteOrder::fromCommonEndian(objNumber); SurfaceCell *sc= getSurfaceCell(toSurfCoords(Vec2i(i, j))); - if(objNumber == 0) { + if(objNumber <= 0) { sc->setObject(NULL); } else if(objNumber <= Tileset::objCount) { @@ -803,13 +817,7 @@ bool Map::isFreeCells(const Vec2i & pos, int size, Field field) const { } bool Map::isFreeCellsOrHasUnit(const Vec2i &pos, int size, Field field, - const Unit *unit, const UnitType *munit,bool allowNullUnit) const { - if(unit == NULL && allowNullUnit == false) { - throw megaglest_runtime_error("unit == NULL"); - } - if(munit == NULL && allowNullUnit == false) { - throw megaglest_runtime_error("munit == NULL"); - } + const Unit *unit) const { for(int i = pos.x; i < pos.x + size; ++i) { for(int j = pos.y; j < pos.y + size; ++j) { if(isFreeCellOrHasUnit(Vec2i(i,j), field, unit) == false) { @@ -831,6 +839,34 @@ bool Map::isAproxFreeCells(const Vec2i &pos, int size, Field field, int teamInde return true; } +bool Map::canMorph(const Vec2i &pos,const Unit *currentUnit,const UnitType *targetUnitType ) const{ + Field field=targetUnitType->getField(); + const UnitType *ut=targetUnitType; + CardinalDir facing=currentUnit->getModelFacing(); + + if (ut->hasCellMap() && isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + for (int y=0; y < ut->getSize(); ++y) { + for (int x=0; x < ut->getSize(); ++x) { + Vec2i cellPos = pos + Vec2i(x, y); + if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + if (ut->getCellMapCell(x, y, facing)) { + if (isFreeCellOrHasUnit(cellPos, field, currentUnit) == false) { + return false; + } + } + } + else { + return false; + } + } + } + return true; + } + else { + return isFreeCellsOrHasUnit(pos, ut->getSize(), field,currentUnit); + } +} + bool Map::canOccupy(const Vec2i &pos, Field field, const UnitType *ut, CardinalDir facing) { if (ut->hasCellMap() && isInside(pos) && isInsideSurface(toSurfCoords(pos))) { for (int y=0; y < ut->getSize(); ++y) { diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index 9e650c0ac..18e9415dd 100644 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -327,9 +327,9 @@ public: bool isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const; bool isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const; bool isFreeCells(const Vec2i &pos, int size, Field field) const; - bool isFreeCellsOrHasUnit(const Vec2i &pos, int size, Field field, const Unit *unit, const UnitType *munit, bool allowNullUnit=false) const; + bool isFreeCellsOrHasUnit(const Vec2i &pos, int size, Field field, const Unit *unit) const; bool isAproxFreeCells(const Vec2i &pos, int size, Field field, int teamIndex) const; - + bool canMorph(const Vec2i &pos,const Unit *currentUnit,const UnitType *targetUnitType ) const; bool canOccupy(const Vec2i &pos, Field field, const UnitType *ut, CardinalDir facing); //unit placement diff --git a/source/glest_game/world/scenario.cpp b/source/glest_game/world/scenario.cpp index 63f19e6ea..922d97c1f 100644 --- a/source/glest_game/world/scenario.cpp +++ b/source/glest_game/world/scenario.cpp @@ -392,6 +392,22 @@ void Scenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo, bool is scenarioInfo->fogOfWar_exploredFlag = false; } + if(scenarioNode->hasChild("shared-team-units") == true) { + scenarioInfo->allowTeamUnitSharing=scenarioNode->getChild("shared-team-units")->getAttribute("value")->getBoolValue(); + //printf("\nallowTeamUnitSharing is set to [%s]\n",scenarioInfo->allowTeamUnitSharing); + } + else { + scenarioInfo->allowTeamUnitSharing = false; + } + + if(scenarioNode->hasChild("shared-team-resources") == true) { + scenarioInfo->allowTeamResourceSharing=scenarioNode->getChild("shared-team-resources")->getAttribute("value")->getBoolValue(); + //printf("\nallowTeamResourceSharing is set to [%s]\n",scenarioInfo->allowTeamResourceSharing); + } + else { + scenarioInfo->allowTeamResourceSharing = false; + } + scenarioInfo->file = file; scenarioInfo->name = extractFileFromDirectoryPath(file); scenarioInfo->name = cutLastExt(scenarioInfo->name); @@ -480,6 +496,8 @@ void Scenario::loadGameSettings(const vector &dirList, const ScenarioInfo *scenarioInfo, GameSettings *gameSettings, string scenarioDescription) { int factionCount= 0; + int AIPlayerCount=0; + Lang &lang= Lang::getInstance(); if(gameSettings->getGameUUID() == "") { gameSettings->setGameUUID(getUUIDAsString()); @@ -501,15 +519,21 @@ void Scenario::loadGameSettings(const vector &dirList, if(ct == ctHuman) { gameSettings->setThisFactionIndex(factionCount); - if(gameSettings->getNetworkPlayerName(i) == "") { - gameSettings->setNetworkPlayerName(i,Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str())); + if(gameSettings->getNetworkPlayerName(factionCount) == "") { + gameSettings->setNetworkPlayerName(factionCount,Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str())); } - gameSettings->setNetworkPlayerUUID(i,Config::getInstance().getString("PlayerId","")); - gameSettings->setNetworkPlayerPlatform(i,getPlatformNameString()); + gameSettings->setNetworkPlayerUUID(factionCount,Config::getInstance().getString("PlayerId","")); + gameSettings->setNetworkPlayerPlatform(factionCount,getPlatformNameString()); } - else { - if(gameSettings->getNetworkPlayerName(i) == "") { - gameSettings->setNetworkPlayerName(i,controllerTypeToStr(ct)); + else if(ct == ctNetwork || ct == ctNetworkUnassigned){ + if(gameSettings->getNetworkPlayerName(factionCount) == "") { + gameSettings->setNetworkPlayerName(factionCount,controllerTypeToStr(ct)); + } + } + else {//this is a CPU player + AIPlayerCount++; + if(gameSettings->getNetworkPlayerName(factionCount) == "") { + gameSettings->setNetworkPlayerName(factionCount,lang.getString("AI") + intToStr(AIPlayerCount)); } } gameSettings->setFactionControl(factionCount, ct); @@ -533,6 +557,24 @@ void Scenario::loadGameSettings(const vector &dirList, gameSettings->setFlagTypes1(valueFlags1); } + if(scenarioInfo->allowTeamUnitSharing == true) { + valueFlags1 |= ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } + else { + valueFlags1 &= ~ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } + + if(scenarioInfo->allowTeamResourceSharing == true) { + valueFlags1 |= ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + else { + valueFlags1 &= ~ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + gameSettings->setPathFinderType(static_cast(Config::getInstance().getInt("ScenarioPathFinderType",intToStr(pfBasic).c_str()))); } diff --git a/source/glest_game/world/scenario.h b/source/glest_game/world/scenario.h index 7184274c0..549cb62c9 100644 --- a/source/glest_game/world/scenario.h +++ b/source/glest_game/world/scenario.h @@ -68,6 +68,9 @@ public: fogOfWar = false; fogOfWar_exploredFlag = false; + allowTeamUnitSharing = false; + allowTeamResourceSharing = false; + file = ""; name = ""; namei18n = ""; @@ -91,6 +94,9 @@ public: bool fogOfWar; bool fogOfWar_exploredFlag; + bool allowTeamUnitSharing; + bool allowTeamResourceSharing; + string file; string name; string namei18n; diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 1b9b24a09..1243e2227 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -134,7 +134,7 @@ bool UnitUpdater::updateUnit(Unit *unit) { if(soundStartTime >= unit->getLastAnimProgressAsFloat() && soundStartTime < unit->getAnimProgressAsFloat()) { if(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) || (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { - soundRenderer.playFx((*it)->getSoundContainer()->getRandSound(), unit->getCurrVector(), gameCamera->getPos()); + soundRenderer.playFx((*it)->getSoundContainer()->getRandSound(), unit->getCurrMidHeightVector(), gameCamera->getPos()); } } } @@ -171,7 +171,7 @@ bool UnitUpdater::updateUnit(Unit *unit) { bool cameraAffected=(!cameraViewAffected) || unit->getVisible(); if(visibility && cameraAffected && enabled) { - game->getGameCameraPtr()->shake( currSkill->getShakeDuration(), currSkill->getShakeIntensity(),cameraDistanceAffected,unit->getCurrVector()); + game->getGameCameraPtr()->shake( currSkill->getShakeDuration(), currSkill->getShakeIntensity(),cameraDistanceAffected,unit->getCurrMidHeightVector()); } } } @@ -291,7 +291,7 @@ bool UnitUpdater::updateUnit(Unit *unit) { if(Config::getInstance().getBool("DisableWaterSounds","false") == false) { soundRenderer.playFx( CoreData::getInstance().getWaterSound(), - unit->getCurrVector(), + unit->getCurrMidHeightVector(), gameCamera->getPos() ); @@ -1123,7 +1123,7 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) { (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { SoundRenderer::getInstance().playFx( bct->getStartSound(), - unit->getCurrVector(), + unit->getCurrMidHeightVector(), gameCamera->getPos()); } @@ -1215,7 +1215,7 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) { (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { SoundRenderer::getInstance().playFx( bct->getBuiltSound(), - unit->getCurrVector(), + unit->getCurrMidHeightVector(), gameCamera->getPos()); } } @@ -2434,7 +2434,7 @@ void UnitUpdater::updateMorph(Unit *unit, int frameIndex) { if(unit->getCurrSkill()->getClass()!=scMorph){ //if not morphing, check space - if(map->isFreeCellsOrHasUnit(unit->getPos(), mct->getMorphUnit()->getSize(), mct->getMorphUnit()->getField(), unit, mct->getMorphUnit())){ + if(map->canMorph(unit->getPos(),unit,mct->getMorphUnit())){ unit->setCurrSkill(mct->getMorphSkillType()); // block space for morphing units ( block space before and after morph ! ) map->putUnitCells(unit, unit->getPos()); @@ -2665,7 +2665,7 @@ void UnitUpdater::startAttackParticleSystem(Unit *unit, float lastAnimProgress, ParticleSystemTypeSplash *pstSplash= ast->getSplashParticleType(); bool hasProjectile = !ast->projectileTypes.empty(); - Vec3f startPos= unit->getCurrVector(); + Vec3f startPos= unit->getCurrVectorForParticlesystems(); Vec3f endPos= unit->getTargetVec(); //make particle system @@ -2755,12 +2755,12 @@ bool UnitUpdater::searchForResource(Unit *unit, const HarvestCommandType *hct) { } bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr, bool evalMode){ - int range= unit->getType()->getSight(); + int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); return unitOnRange(unit, range, rangedPtr, NULL,evalMode); } bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast, bool evalMode) { - int range= unit->getType()->getSight(); + int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); return unitOnRange(unit, range, rangedPtr, ast, evalMode); } @@ -3089,7 +3089,7 @@ vector UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillT try { - int range = unit->getType()->getSight(); + int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); if(ast != NULL) { range = ast->getTotalAttackRange(unit->getTotalUpgrade()); @@ -3159,7 +3159,7 @@ vector UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillT } -void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector &units) { +void UnitUpdater::findUnitsForCell(Cell *cell, vector &units) { //all fields if(cell != NULL) { for(int k = 0; k < fieldCount; k++) { @@ -3169,7 +3169,21 @@ void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector &u Unit *cellUnit = cell->getUnit(f); if(cellUnit != NULL && cellUnit->isAlive()) { - units.push_back(cellUnit); + // check if unit already is in list + bool found = false; + //printf("---- search for cellUnit=%d\n",cellUnit->getId()); + for (unsigned int i = 0; i < units.size(); ++i) { + Unit *unitInList = units[i]; + //printf("compare unitInList=%d cellUnit=%d\n",unitInList->getId(),cellUnit->getId()); + if (unitInList->getId() == cellUnit->getId()){ + found=true; + break; + } + } + if(found==false){ + //printf(">>> adding cellUnit=%d\n",cellUnit->getId()); + units.push_back(cellUnit); + } } } } @@ -3195,7 +3209,7 @@ vector UnitUpdater::findUnitsInRange(const Unit *unit, int radius) { if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ #endif Cell *cell = map->getCell(i,j); - findUnitsForCell(cell,unit,units); + findUnitsForCell(cell,units); } } } @@ -3311,7 +3325,7 @@ void ParticleDamager::update(ParticleSystem *particleSystem) { projSound= ast->getProjSound(); } if(particleSystem->getVisible() && projSound != NULL) { - SoundRenderer::getInstance().playFx(projSound, attacker->getCurrVector(), gameCamera->getPos()); + SoundRenderer::getInstance().playFx(projSound, attacker->getCurrMidHeightVector(), gameCamera->getPos()); } //check for spawnattack diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index fae218b8b..6063a48c3 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -129,7 +129,6 @@ public: vector enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast); void findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector &enemies, bool attackersOnly) const; - void findUnitsForCell(Cell *cell, const Unit *unit,vector &units); vector findUnitsInRange(const Unit *unit, int radius); string getUnitRangeCellsLookupItemCacheStats(); @@ -159,6 +158,8 @@ private: void SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, const CommandType *commandType, int originalValue,int newValue); + void findUnitsForCell(Cell *cell, vector &units); + }; // ===================================================== diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index f17997699..1ae088faf 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -418,6 +418,11 @@ void World::init(Game *game, bool createUnits, bool initFactions){ //initExplorationState(); ... was only for !fog-of-war, now handled in initCells() computeFow(); + if(getFrameCount()>1){ + // this is needed for games that are loaded to "switch the light on". + // otherwise the FowTexture is completely black like in the beginning of a game. + minimap.updateFowTex(1.f); + } if(gotError == true) { throw megaglest_runtime_error(sErrBuf,!skipStackTrace); @@ -1335,6 +1340,11 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po if(scriptManager) { scriptManager->onUnitCreated(unit); } + if(game->getPaused()==true){ + // new units added in pause mode might change the Fow. ( Scenarios do this ) + computeFow(); + minimap.updateFowTex(1.f); + } } else { delete unit; @@ -1702,6 +1712,9 @@ void World::clearCaches() { void World::togglePauseGame(bool pauseStatus,bool forceAllowPauseStateChange) { game->setPaused(pauseStatus, forceAllowPauseStateChange, false, false); + // ensures that the Fow is really up to date when the game switches to pause mode. ( mainly for scenarios ) + computeFow(); + minimap.updateFowTex(1.f); } void World::addConsoleText(const string &text) { @@ -2244,7 +2257,11 @@ void World::initUnits() { placeUnitAtLocation(map.getStartLocation(startLocationIndex), generationArea, unit, true); } } - + } + // the following is done here in an extra loop and not in the loop above, because shared resources games + // need to load all factions first, before calculating limitResourcesToStore() + for(int i = 0; i < getFactionCount(); ++i) { + Faction *f= factions[i]; // Ensure Starting Resource Amount are adjusted to max store levels f->limitResourcesToStore(); } @@ -2678,7 +2695,6 @@ const Resource *World::getResourceForTeam(const ResourceType *rt, int teamIndex) Faction *faction = factions[index]; if(faction != NULL && faction->getTeam() == teamIndex) { - const Resource *factionResource = faction->getResource(rt,true); if(factionResource != NULL && factionResource->getType() != NULL) { @@ -2709,7 +2725,23 @@ int World::getStoreAmountForTeam(const ResourceType *rt, int teamIndex) const { return teamStoreAmount; } -bool World::showResourceTypeForFaction(const ResourceType *rt, const Faction *faction,bool localFactionOnly) const { +bool World::showResourceTypeForTeam(const ResourceType *rt, int teamIndex) const { + //if any unit produces the resource + bool showResource = false; + for(int index = 0; showResource == false && index < (int)factions.size(); ++index) { + const Faction *teamFaction = factions[index]; + if(teamFaction != NULL && teamFaction->getTeam() == teamIndex) { + + if(teamFaction->hasUnitTypeWithResourceCostInCache(rt) == true) { + showResource = true; + } + } + } + return showResource; +} + + +bool World::showResourceTypeForFaction(const ResourceType *rt, const Faction *faction) const { //if any unit produces the resource bool showResource = false; for(int factionUnitTypeIndex = 0; @@ -2722,21 +2754,6 @@ bool World::showResourceTypeForFaction(const ResourceType *rt, const Faction *fa break; } } - if(localFactionOnly == false && showResource == false && - (game->isFlagType1BitEnabled(ft1_allow_shared_team_units) == true || - game->isFlagType1BitEnabled(ft1_allow_shared_team_resources) == true)) { - - for(int index = 0; showResource == false && index < (int)factions.size(); ++index) { - const Faction *teamFaction = factions[index]; - if(teamFaction != NULL && teamFaction->getTeam() == faction->getTeam()) { - - if(teamFaction->hasUnitTypeWithResourceCostInCache(rt) == true) { - showResource = true; - } - } - } - } - return showResource; } diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index 268fe0c27..8e8fd5664 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -326,7 +326,9 @@ public: void initTeamResource(const ResourceType *rt,int teamIndex, int value); const Resource * getResourceForTeam(const ResourceType *rt, int teamIndex); int getStoreAmountForTeam(const ResourceType *rt, int teamIndex) const; - bool showResourceTypeForFaction(const ResourceType *rt, const Faction *faction,bool localFactionOnly) const; + bool showResourceTypeForFaction(const ResourceType *rt, const Faction *faction) const; + bool showResourceTypeForTeam(const ResourceType *rt, int teamIndex) const; + private: diff --git a/source/glest_map_editor/main.cpp b/source/glest_map_editor/main.cpp index 9b2dc57cf..e9c9b7c70 100644 --- a/source/glest_map_editor/main.cpp +++ b/source/glest_map_editor/main.cpp @@ -138,12 +138,12 @@ END_EVENT_TABLE() void MainWindow::init(string fname) { #if wxCHECK_VERSION(2, 9, 3) - glCanvas->setCurrentGLContext(); + //glCanvas->setCurrentGLContext(); //printf("setcurrent #1\n"); #elif wxCHECK_VERSION(2, 9, 1) #else - glCanvas->SetCurrent(); + //glCanvas->SetCurrent(); //printf("setcurrent #2\n"); #endif @@ -638,11 +638,17 @@ void MainWindow::onPaint(wxPaintEvent &event) { return; } -#if wxCHECK_VERSION(2, 9, 3) +//#if wxCHECK_VERSION(2, 9, 3) -#elif wxCHECK_VERSION(2, 9, 1) +//#elif wxCHECK_VERSION(2, 9, 1) +// glCanvas->setCurrentGLContext(); +//#endif + + //static bool contextSet = false; + //if(contextSet == false) { + // contextSet = true; glCanvas->setCurrentGLContext(); -#endif + //} if(lastPaintEvent.getMillis() < 30) { sleep(1); @@ -1579,6 +1585,10 @@ bool App::OnInit() { SystemFlags::VERBOSE_MODE_ENABLED = false; SystemFlags::ENABLE_THREADED_LOGGING = false; +#if defined(wxMAJOR_VERSION) && defined(wxMINOR_VERSION) && defined(wxRELEASE_NUMBER) && defined(wxSUBRELEASE_NUMBER) + printf("Using wxWidgets version [%d.%d.%d.%d]\n",wxMAJOR_VERSION,wxMINOR_VERSION,wxRELEASE_NUMBER,wxSUBRELEASE_NUMBER); +#endif + string fileparam; if(argc==2){ if(argv[1][0]=='-') { // any flag gives help and exits program. diff --git a/source/shared_lib/include/graphics/particle.h b/source/shared_lib/include/graphics/particle.h index 786078881..1b1b0c102 100644 --- a/source/shared_lib/include/graphics/particle.h +++ b/source/shared_lib/include/graphics/particle.h @@ -58,6 +58,7 @@ public: public: Particle() { + speedUpRelative = 0; size = 0; energy = 0; } @@ -93,6 +94,20 @@ public: virtual void logParticleInfo(string info)= 0; }; + +class ParticleSystemTypeInterface { +public: + + ParticleSystemTypeInterface() {}; + virtual ~ParticleSystemTypeInterface() {}; + + virtual bool getMinmaxEnabled() const = 0; + virtual int getMinHp() const = 0; + virtual int getMaxHp() const = 0; + virtual bool getMinmaxIsPercent() const = 0; + +}; + // ===================================================== // class ParticleSystem // ===================================================== @@ -344,12 +359,15 @@ private: float startTime; float endTime; + ParticleSystemTypeInterface *particleSystemType; + public: enum Shape{ sLinear, // generated in a sphere, flying in direction sSpherical, // generated in a sphere, flying away from center sConical, // generated in a cone at angle from direction }; + bool relative; bool relativeDirection; bool fixed; @@ -359,6 +377,7 @@ public: float gravity; float rotation; const Model *unitModel; + Vec3f meshPos; string meshName; bool isVisibleAtNight; bool isVisibleAtDay; @@ -376,6 +395,13 @@ public: virtual ParticleSystemType getParticleSystemType() const { return pst_UnitParticleSystem;} + ParticleSystemTypeInterface * getParticleType() const { + return particleSystemType; + } + void setParticleType(ParticleSystemTypeInterface *type) { + particleSystemType = type; + } + //virtual virtual void initParticle(Particle *p, int particleIndex); virtual void updateParticle(Particle *p); @@ -400,7 +426,8 @@ public: void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;} void setGravity(float gravity) {this->gravity= gravity;} void setRotation(float rotation); - const void setUnitModel(const Model* unitModel) {this->unitModel= unitModel;} + void setMeshPos(Vec3f meshPos) {this->meshPos=meshPos;} + string getMeshName() {return meshName;} void setMeshName(string meshName) {this->meshName= meshName;} void setRelative(bool relative) {this->relative= relative;} void setRelativeDirection(bool relativeDirection) {this->relativeDirection= relativeDirection;} diff --git a/source/shared_lib/include/util/properties.h b/source/shared_lib/include/util/properties.h index 8aa3b272f..038facfee 100644 --- a/source/shared_lib/include/util/properties.h +++ b/source/shared_lib/include/util/properties.h @@ -54,6 +54,9 @@ private: static string scenarioPath; static string tutorialPath; +protected: + void processTextLine(bool is_utf8_language, char *lineBuffer); + public: static void setApplicationPath(string value) { applicationPath=value; } static string getApplicationPath() { return applicationPath; } @@ -72,6 +75,8 @@ public: static string getTutorialPath() { return tutorialPath; } void clear(); + + void loadFromText(const string &text); void load(const string &path,bool clearCurrentProperties=true); void save(const string &path); diff --git a/source/shared_lib/include/util/util.h b/source/shared_lib/include/util/util.h index 1ba171b45..eb7a44047 100644 --- a/source/shared_lib/include/util/util.h +++ b/source/shared_lib/include/util/util.h @@ -13,6 +13,7 @@ #define _SHARED_UTIL_UTIL_H_ #include +#include #include #include #include "thread.h" @@ -226,7 +227,9 @@ string cutLastFile(const string &s); string cutLastExt(const string &s); string ext(const string &s); string replaceBy(const string &s, char c1, char c2); +vector split(string s,string d); string toLower(const string &s); +bool compareNonCaseSensitive(const string a, const string b); void copyStringToBuffer(char *buffer, int bufferSize, const string& s); //numeric fcs @@ -237,6 +240,9 @@ float saturate(float value); int round(float f); //misc +int compareMajorMinorVersion(string versionA,string versionB); +int getMajor(string version); +int getMinor(string version); bool checkVersionComptability(string clientVersionString, string serverVersionString); template diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c index 80585525b..f2964a4bc 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c @@ -164,13 +164,13 @@ int ftpStat(const char* path, ftpPathInfo_S *info) pw = getpwuid(fileInfo.st_uid); if(pw) - strncpy(info->user, pw->pw_name, sizeof(info->user)); + strncpy(info->user, pw->pw_name, sizeof(info->user)-1); else snprintf(info->user, 20,"%04d", fileInfo.st_uid); gr = getgrgid(fileInfo.st_gid); if(gr) - strncpy(info->group, gr->gr_name, sizeof(info->group)); + strncpy(info->group, gr->gr_name, sizeof(info->group)-1); else snprintf(info->group, 20,"%04d", fileInfo.st_gid); diff --git a/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp b/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp index c3c41f0e9..981bff660 100644 --- a/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp @@ -64,6 +64,9 @@ void ParticleRendererGl::renderManager(ParticleManager *pm, ModelRenderer *mr){ pm->render(this, mr); rendering= false; + // blend mode back to normal + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //pop state glPopClientAttrib(); glPopAttrib(); diff --git a/source/shared_lib/sources/graphics/model.cpp b/source/shared_lib/sources/graphics/model.cpp index e3bf3cfb6..57ff5fc37 100644 --- a/source/shared_lib/sources/graphics/model.cpp +++ b/source/shared_lib/sources/graphics/model.cpp @@ -1099,7 +1099,7 @@ Model::Model() { } Model::~Model() { - delete [] meshes; + if(meshes) delete [] meshes; meshes = NULL; } @@ -2068,6 +2068,10 @@ void BaseColorPickEntity::beginPicking() { glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_NORMALIZE); + // all off, but we want depth test + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //glPushAttrib(GL_TEXTURE_2D | GL_LIGHTING | GL_BLEND | GL_MULTISAMPLE | GL_DITHER); //glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT | GL_NORMALIZE | GL_BLEND | GL_POLYGON_OFFSET_FILL); } diff --git a/source/shared_lib/sources/graphics/particle.cpp b/source/shared_lib/sources/graphics/particle.cpp index 9e69bcd3c..5c67d53aa 100644 --- a/source/shared_lib/sources/graphics/particle.cpp +++ b/source/shared_lib/sources/graphics/particle.cpp @@ -126,6 +126,9 @@ ParticleSystem::ParticleSystem(int particleCount) { emissionRate= 15.0f; emissionState= 1.0f; // initialized with 1 because we must have at least one particle in the beginning! speed= 1.0f; + speedUpRelative = 0; + speedUpConstant = 0; + teamcolorNoEnergy= false; teamcolorEnergy= false; alternations= 0; @@ -1009,6 +1012,8 @@ Vec3f UnitParticleSystem::lightColor=Vec3f(1.0f,1.0f,1.0f); UnitParticleSystem::UnitParticleSystem(int particleCount) : GameParticleSystem(particleCount), parent(NULL) { + + particleSystemType = NULL; radius= 0.5f; speed= 0.01f; windSpeed= Vec3f(0.0f); @@ -1049,6 +1054,7 @@ UnitParticleSystem::UnitParticleSystem(int particleCount) : endTime = 1; unitModel=NULL; meshName=""; + meshPos=Vec3f(0,0,0); radiusBasedStartenergy = false; } @@ -1177,36 +1183,17 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){ p->pos.z = truncateDecimal(p->pos.z,6); } - else {// rotate it according to rotation + else { Vec3f combinedOffset=Vec3f(offset); - if(meshName!="" && unitModel!=NULL){ - //printf("meshName set unitModel given\n"); - bool foundMesh=false; - for(unsigned int i=0; igetMeshCount() ; i++){ - //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); - if(unitModel->getMesh(i)->getName()==meshName){ - const InterpolationData *data=unitModel->getMesh(i)->getInterpolationData(); - const Vec3f *verticepos=data->getVertices(); - //printf("verticepos %f %f %f\n",verticepos->x,verticepos->y,verticepos->z); - combinedOffset.x+=verticepos->x; - combinedOffset.y+=verticepos->y; - combinedOffset.z+=verticepos->z; - foundMesh=true; - break; - } - } - if( foundMesh == false ) { - string meshesFound=""; - for(unsigned i=0; igetMeshCount() ; i++){ - meshesFound+= unitModel->getMesh(i)->getName()+", "; - } - - string errorString = "Warning: Particle system is trying to find mesh'"+meshName+"', but just found:\n'"+meshesFound+"' in file:\n'"+unitModel->getFileName()+"'\n"; - //throw megaglest_runtime_error(errorString); - printf("%s",errorString.c_str()); + if(meshName!=""){ + combinedOffset.x+=meshPos.x; + combinedOffset.y+=meshPos.y; + combinedOffset.z+=meshPos.z; + if(meshPos.x==0 && meshPos.y==0 && meshPos.z==0) { + printf("meshPosFail\n"); } } - + // rotate it according to rotation #ifdef USE_STREFLOP p->pos= Vec3f(pos.x+x+combinedOffset.z*streflop::sinf(static_cast(rad))+combinedOffset.x*streflop::cosf(static_cast(rad)), pos.y+random.randRange(-radius/2, radius/2)+combinedOffset.y, pos.z+y+(combinedOffset.z*streflop::cosf(static_cast(rad))-combinedOffset.x*streflop::sinf(static_cast(rad)))); #else @@ -1283,17 +1270,18 @@ void UnitParticleSystem::updateParticle(Particle *p){ if(alternations > 0){ int interval= (maxParticleEnergy / alternations); float moduloValue= (float)((int)(static_cast (p->energy)) % interval); + float floatInterval=static_cast (interval); - if(moduloValue < interval / 2){ - energyRatio= (interval - moduloValue) / interval; + if(moduloValue < floatInterval / 2.0f){ + energyRatio= (floatInterval - moduloValue) / floatInterval; } else{ - energyRatio= moduloValue / interval; + energyRatio= moduloValue / floatInterval; } energyRatio= clamp(energyRatio, 0.f, 1.f); } else{ - energyRatio= clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); + energyRatio= clamp(static_cast (p->energy) / static_cast (maxParticleEnergy), 0.f, 1.f); } energyRatio = truncateDecimal(energyRatio,6); @@ -1391,9 +1379,13 @@ void UnitParticleSystem::saveGame(XmlNode *rootNode) { unitParticleSystemNode->addAttribute("cRotation",cRotation.getString(), mapTagReplacements); // Vec3f fixedAddition; unitParticleSystemNode->addAttribute("fixedAddition",fixedAddition.getString(), mapTagReplacements); -// Vec3f oldPosition; +// Vec3f oldPosition; unitParticleSystemNode->addAttribute("oldPosition",oldPosition.getString(), mapTagReplacements); -// bool energyUp; +// Vec3f meshPos; + unitParticleSystemNode->addAttribute("meshPos",meshPos.getString(), mapTagReplacements); +// string meshName; + unitParticleSystemNode->addAttribute("meshName",meshName, mapTagReplacements); +// bool energyUp; unitParticleSystemNode->addAttribute("energyUp",intToStr(energyUp), mapTagReplacements); // float startTime; unitParticleSystemNode->addAttribute("startTime",floatToStr(startTime,6), mapTagReplacements); @@ -1403,7 +1395,7 @@ void UnitParticleSystem::saveGame(XmlNode *rootNode) { unitParticleSystemNode->addAttribute("relative",intToStr(relative), mapTagReplacements); // bool relativeDirection; unitParticleSystemNode->addAttribute("relativeDirection",intToStr(relativeDirection), mapTagReplacements); -// bool fixed; +// bool fixed; unitParticleSystemNode->addAttribute("fixed",intToStr(fixed), mapTagReplacements); // Shape shape; unitParticleSystemNode->addAttribute("shape",intToStr(shape), mapTagReplacements); @@ -1450,11 +1442,19 @@ void UnitParticleSystem::loadGame(const XmlNode *rootNode) { // Vec3f windSpeed; windSpeed = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("windSpeed")->getValue()); // Vec3f cRotation; - windSpeed = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("cRotation")->getValue()); + cRotation = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("cRotation")->getValue()); // Vec3f fixedAddition; fixedAddition = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("fixedAddition")->getValue()); // Vec3f oldPosition; oldPosition = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("oldPosition")->getValue()); + // Vec3f meshPos; + if(unitParticleSystemNode->hasAttribute("meshPos")){ + meshPos = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("meshPos")->getValue()); + } + // Vec3f meshName; + if(unitParticleSystemNode->hasAttribute("meshName")){ + meshName = unitParticleSystemNode->getAttribute("meshName")->getValue(); + } // bool energyUp; energyUp = unitParticleSystemNode->getAttribute("energyUp")->getIntValue() != 0; // float startTime; @@ -2435,7 +2435,7 @@ void ParticleManager::update(int renderFps){ vector cleanupParticleSystemsList; for(unsigned int i= 0; i < particleSystems.size(); i++){ ParticleSystem *ps= particleSystems[i]; - if(ps != NULL && validateParticleSystemStillExists(ps) == true) { + if(ps != NULL) { currentParticleCount+= ps->getAliveParticleCount(); bool showParticle= true; diff --git a/source/shared_lib/sources/libircclient/build/doc/doxygen.png b/source/shared_lib/sources/libircclient/build/doc/doxygen.png index f0a274bba..70db2c477 100644 Binary files a/source/shared_lib/sources/libircclient/build/doc/doxygen.png and b/source/shared_lib/sources/libircclient/build/doc/doxygen.png differ diff --git a/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/doxygen.png b/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/doxygen.png index f0a274bba..70db2c477 100644 Binary files a/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/doxygen.png and b/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/doxygen.png differ diff --git a/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png b/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png index bb19cb1c4..5e9447bb6 100644 Binary files a/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png and b/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png differ diff --git a/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png b/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png index 4bfd3d4bc..9048d5410 100644 Binary files a/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png and b/source/shared_lib/sources/libircclient/build/source/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png differ diff --git a/source/shared_lib/sources/libircclient/build/source/libircclient/doc/html/doxygen.png b/source/shared_lib/sources/libircclient/build/source/libircclient/doc/html/doxygen.png index f0a274bba..70db2c477 100644 Binary files a/source/shared_lib/sources/libircclient/build/source/libircclient/doc/html/doxygen.png and b/source/shared_lib/sources/libircclient/build/source/libircclient/doc/html/doxygen.png differ diff --git a/source/shared_lib/sources/libircclient/cocoa/doc/html/doxygen.png b/source/shared_lib/sources/libircclient/cocoa/doc/html/doxygen.png index f0a274bba..70db2c477 100644 Binary files a/source/shared_lib/sources/libircclient/cocoa/doc/html/doxygen.png and b/source/shared_lib/sources/libircclient/cocoa/doc/html/doxygen.png differ diff --git a/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png b/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png index bb19cb1c4..5e9447bb6 100644 Binary files a/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png and b/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_channel.png differ diff --git a/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png b/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png index 4bfd3d4bc..9048d5410 100644 Binary files a/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png and b/source/shared_lib/sources/libircclient/cocoa/doc/html/interface_i_r_c_client_session.png differ diff --git a/source/shared_lib/sources/libircclient/doc/html/doxygen.png b/source/shared_lib/sources/libircclient/doc/html/doxygen.png index f0a274bba..70db2c477 100644 Binary files a/source/shared_lib/sources/libircclient/doc/html/doxygen.png and b/source/shared_lib/sources/libircclient/doc/html/doxygen.png differ diff --git a/source/shared_lib/sources/map/map_preview.cpp b/source/shared_lib/sources/map/map_preview.cpp index cc9fd7824..e3c1208d1 100644 --- a/source/shared_lib/sources/map/map_preview.cpp +++ b/source/shared_lib/sources/map/map_preview.cpp @@ -992,9 +992,9 @@ void MapPreview::sinRandomize(int strenght) { float sinV1 = random.randRange(5.f, 40.f); float sinV2 = random.randRange(5.f, 40.f); float ah = static_cast(10 + random.randRange(-2, 2)); - float bh = static_cast((maxHeight - minHeight) / random.randRange(2, 3)); + float bh = static_cast((maxHeight - minHeight)) / static_cast(random.randRange(2, 3)); float av = static_cast(10 + random.randRange(-2, 2)); - float bv = static_cast((maxHeight - minHeight) / random.randRange(2, 3)); + float bv = static_cast((maxHeight - minHeight)) / static_cast(random.randRange(2, 3)); for (int i = 0; i < w; ++i) { for (int j = 0; j < h; ++j) { diff --git a/source/shared_lib/sources/miniz/miniz.c b/source/shared_lib/sources/miniz/miniz.c index e3fba2423..2b787fbf9 100644 --- a/source/shared_lib/sources/miniz/miniz.c +++ b/source/shared_lib/sources/miniz/miniz.c @@ -1,33 +1,54 @@ -/* miniz.c v1.14 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing +/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing See "unlicense" statement at the end of this file. - Rich Geldreich , last updated May 20, 2012 + Rich Geldreich , last updated Oct. 13, 2013 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). * Change History + 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!): + - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug + would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place() + (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag). + - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size + - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries. + Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice). + - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes + - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed + - Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6. + - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti + - Merged MZ_FORCEINLINE fix from hdeanclark + - Fix include before config #ifdef, thanks emil.brink + - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can + set it to 1 for real-time compression). + - Merged in some compiler fixes from paulharris's github repro. + - Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3. + - Added example6.c, which dumps an image of the mandelbrot set to a PNG file. + - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more. + - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled + - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include (thanks fermtect). 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit. - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files. - Eliminated a bunch of warnings when compiling with GCC 32-bit/64. - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly - "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning). - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64. - Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test. - Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives. - Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.) - Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself). + - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files. + - Eliminated a bunch of warnings when compiling with GCC 32-bit/64. + - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly + "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning). + - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64. + - Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test. + - Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives. + - Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.) + - Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself). 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's. level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson for the feedback/bug report. 5/28/11 v1.11 - Added statement from unlicense.org 5/27/11 v1.10 - Substantial compressor optimizations: - Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a - Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). - Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. - Refactored the compression code for better readability and maintainability. - Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large - drop in throughput on some files). + - Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a + - Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). + - Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. + - Refactored the compression code for better readability and maintainability. + - Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large + drop in throughput on some files). 5/15/11 v1.09 - Initial stable release. * Low-level Deflate/Inflate implementation notes: @@ -129,6 +150,10 @@ #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 #define MINIZ_LITTLE_ENDIAN 1 #define MINIZ_HAS_64BIT_REGISTERS 1 + + * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz + uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files + (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes). */ #ifndef MINIZ_HEADER_INCLUDED @@ -136,10 +161,6 @@ #include -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) -#include -#endif - // Defines to completely disable specific portions of miniz.c: // If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. @@ -147,7 +168,8 @@ //#define MINIZ_NO_STDIO // If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or -// get/set file times. +// get/set file times, and the C run-time funcs that get/set times won't be called. +// The current downside is the times written to your archives will be from 1979. //#define MINIZ_NO_TIME // Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. @@ -168,6 +190,15 @@ // functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. //#define MINIZ_NO_MALLOC +#if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) + // TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux + #define MINIZ_NO_TIME +#endif + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) + #include +#endif + #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) // MINIZ_X86_OR_X64_CPU is only used to help set the below macros. #define MINIZ_X86_OR_X64_CPU 1 @@ -222,11 +253,11 @@ typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); typedef void (*mz_free_func)(void *opaque, void *address); typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); -#define MZ_VERSION "9.1.14" -#define MZ_VERNUM 0x91E0 +#define MZ_VERSION "9.1.15" +#define MZ_VERNUM 0x91F0 #define MZ_VER_MAJOR 9 #define MZ_VER_MINOR 1 -#define MZ_VER_REVISION 14 +#define MZ_VER_REVISION 15 #define MZ_VER_SUBREVISION 0 // Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). @@ -447,7 +478,7 @@ typedef int mz_bool; #define MZ_FALSE (0) #define MZ_TRUE (1) -// Works around MSVC's spammy "warning C4127: conditional expression is constant" message. +// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message. #ifdef _MSC_VER #define MZ_MACRO_END while (0, 0) #else @@ -501,7 +532,7 @@ typedef enum MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 } mz_zip_mode; -typedef struct +typedef struct mz_zip_archive_tag { mz_uint64 m_archive_size; mz_uint64 m_central_directory_file_ofs; @@ -760,6 +791,7 @@ enum // TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. // TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. // TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. +// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). enum { TDEFL_WRITE_ZLIB_HEADER = 0x01000, @@ -791,10 +823,13 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void // On entry: // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. // The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. +// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL +// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). // On return: // Function returns a pointer to the compressed data, or NULL on failure. // *pLen_out will be set to the size of the PNG image file. // The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip); void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); // Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. @@ -928,9 +963,9 @@ typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; #ifdef _MSC_VER #define MZ_FORCEINLINE __forceinline #elif defined(__GNUC__) - #define MZ_FORCEINLINE __attribute__((__always_inline__)) + #define MZ_FORCEINLINE inline __attribute__((__always_inline__)) #else - #define MZ_FORCEINLINE + #define MZ_FORCEINLINE inline #endif #ifdef __cplusplus @@ -1470,7 +1505,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } r->m_table_sizes[2] = 19; } - for ( ; ; ) + for ( ; (int)r->m_type >= 0; r->m_type--) { int tree_next, tree_cur; tinfl_huff_table *pTable; mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); @@ -1513,13 +1548,6 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex } TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); } - - if(r->m_type == 0) { - break; - } - else { - r->m_type--; - } } for ( ; ; ) { @@ -2770,22 +2798,26 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int // Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at // http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. -void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +// This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip) { + // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. + static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; if (!pComp) return NULL; MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } // write dummy header for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); // compress image data - tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, TDEFL_DEFAULT_MAX_PROBES | TDEFL_WRITE_ZLIB_HEADER); - for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + y * bpl, bpl, TDEFL_NO_FLUSH); } + tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); } if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } // write real header *pLen_out = out_buf.m_size-41; { + static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06}; mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, - 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,"\0\0\04\02\06"[num_chans],0,0,0,0,0,0,0, + 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0, (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); memcpy(out_buf.m_pBuf, pnghdr, 41); @@ -2796,6 +2828,11 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, // compute final size of file, grab compressed data buffer and return *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; } +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +{ + // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) + return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE); +} #ifdef _MSC_VER #pragma warning (pop) @@ -2811,7 +2848,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #include #include - #if defined(_MSC_VER) + #if defined(_MSC_VER) || defined(__MINGW64__) static FILE *mz_fopen(const char *pFilename, const char *pMode) { FILE* pFile = NULL; @@ -2825,18 +2862,6 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, return NULL; return pFile; } - #else - static FILE *mz_fopen(const char *pFilename, const char *pMode) - { - return fopen(pFilename, pMode); - } - static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) - { - return freopen(pPath, pMode, pStream); - } - #endif // #if defined(_MSC_VER) - - #if defined(_MSC_VER) || defined(__MINGW64__) #ifndef MINIZ_NO_TIME #include #endif @@ -2857,7 +2882,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #include #endif #define MZ_FILE FILE - #define MZ_FOPEN mz_fopen + #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite @@ -2866,14 +2891,14 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #define MZ_FILE_STAT_STRUCT _stat #define MZ_FILE_STAT _stat #define MZ_FFLUSH fflush - #define MZ_FREOPEN mz_freopen + #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove #elif defined(__TINYC__) #ifndef MINIZ_NO_TIME - #include + #include #endif #define MZ_FILE FILE - #define MZ_FOPEN mz_fopen + #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite @@ -2882,14 +2907,30 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #define MZ_FILE_STAT_STRUCT stat #define MZ_FILE_STAT stat #define MZ_FFLUSH fflush - #define MZ_FREOPEN mz_freopen + #define MZ_FREOPEN(f, m, s) freopen(f, m, s) + #define MZ_DELETE_FILE remove + #elif defined(__GNUC__) && _LARGEFILE64_SOURCE + #ifndef MINIZ_NO_TIME + #include + #endif + #define MZ_FILE FILE + #define MZ_FOPEN(f, m) fopen64(f, m) + #define MZ_FCLOSE fclose + #define MZ_FREAD fread + #define MZ_FWRITE fwrite + #define MZ_FTELL64 ftello64 + #define MZ_FSEEK64 fseeko64 + #define MZ_FILE_STAT_STRUCT stat64 + #define MZ_FILE_STAT stat64 + #define MZ_FFLUSH fflush + #define MZ_FREOPEN(p, m, s) freopen64(p, m, s) #define MZ_DELETE_FILE remove #else #ifndef MINIZ_NO_TIME #include #endif #define MZ_FILE FILE - #define MZ_FOPEN mz_fopen + #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite @@ -2898,7 +2939,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #define MZ_FILE_STAT_STRUCT stat #define MZ_FILE_STAT stat #define MZ_FFLUSH fflush - #define MZ_FREOPEN mz_freopen + #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove #endif // #ifdef _MSC_VER #endif // #ifdef MINIZ_NO_STDIO @@ -3021,23 +3062,23 @@ static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *p #ifdef MINIZ_NO_TIME (void)pFilename; *pDOS_date = *pDOS_time = 0; #else - struct MZ_FILE_STAT_STRUCT file_stat; if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE; + struct MZ_FILE_STAT_STRUCT file_stat; + // On Linux with x86 glibc, this call will fail on large files (>= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. + if (MZ_FILE_STAT(pFilename, &file_stat) != 0) + return MZ_FALSE; mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date); #endif // #ifdef MINIZ_NO_TIME return MZ_TRUE; } +#ifndef MINIZ_NO_TIME static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time) { -#ifndef MINIZ_NO_TIME struct utimbuf t; t.actime = access_time; t.modtime = modified_time; return !utime(pFilename, &t); -#else - (void)pFilename, (void)access_time, (void)modified_time; - return MZ_TRUE; -#endif // #ifndef MINIZ_NO_TIME } -#endif +#endif // #ifndef MINIZ_NO_TIME +#endif // #ifndef MINIZ_NO_STDIO static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags) { @@ -3131,6 +3172,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 fl mz_int64 cur_file_ofs; const mz_uint8 *p; mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32; + mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) return MZ_FALSE; @@ -3177,11 +3219,18 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 fl if (pZip->m_total_files) { mz_uint i, n; + // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices. if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) || - (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) || - (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) + (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) return MZ_FALSE; + + if (sort_central_dir) + { + if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) + return MZ_FALSE; + } + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size) return MZ_FALSE; @@ -3193,7 +3242,8 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 fl if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) return MZ_FALSE; MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; + if (sort_central_dir) + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF)) @@ -3209,7 +3259,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 fl } } - if ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) + if (sort_central_dir) mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); return MZ_TRUE; @@ -3245,7 +3295,11 @@ mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t si pZip->m_archive_size = size; pZip->m_pRead = mz_zip_mem_read_func; pZip->m_pIO_opaque = pZip; +#ifdef __cplusplus + pZip->m_pState->m_pMem = const_cast(pMem); +#else pZip->m_pState->m_pMem = (void *)pMem; +#endif pZip->m_pState->m_mem_size = size; if (!mz_zip_reader_read_central_dir(pZip, flags)) { @@ -3271,8 +3325,9 @@ mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_ MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb"); if (!pFile) return MZ_FALSE; - if (MZ_FSEEK64(pFile, 0, SEEK_END)) { - MZ_FCLOSE(pFile); + if (MZ_FSEEK64(pFile, 0, SEEK_END)) + { + MZ_FCLOSE(pFile); return MZ_FALSE; } file_size = MZ_FTELL64(pFile); @@ -3318,16 +3373,12 @@ mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index) { - mz_uint filename_len, internal_attr, external_attr; + mz_uint filename_len, external_attr; const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); if (!p) return MZ_FALSE; - internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); - external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); - if ((!internal_attr) && ((external_attr & 0x10) != 0)) - return MZ_TRUE; - + // First see if the filename ends with a '/' character. filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); if (filename_len) { @@ -3335,6 +3386,13 @@ mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_ind return MZ_TRUE; } + // Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. + // Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. + // FIXME: Remove this check? Is it necessary - we already check the filename. + external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + if ((external_attr & 0x10) != 0) + return MZ_TRUE; + return MZ_FALSE; } @@ -3442,7 +3500,7 @@ int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const cha mz_uint file_index; size_t name_len, comment_len; if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) return -1; - if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_p)) + if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) return mz_zip_reader_locate_file_binary_search(pZip, pName); name_len = strlen(pName); if (name_len > 0xFFFF) return -1; comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1; @@ -3492,9 +3550,15 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; + // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes) if (!file_stat.m_comp_size) return MZ_TRUE; + // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers). + // I'm torn how to handle this case - should it fail instead? + if (mz_zip_reader_is_file_a_directory(pZip, file_index)) + return MZ_TRUE; + // Encryption and patch files are not supported. if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE; @@ -3545,7 +3609,7 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file pRead_buf = (mz_uint8 *)pUser_read_buf; read_buf_size = user_read_buf_size; read_buf_avail = 0; - comp_remaining = file_stat.m_uncomp_size; + comp_remaining = file_stat.m_comp_size; } else { @@ -3672,9 +3736,15 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_ind if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; + // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes) if (!file_stat.m_comp_size) return MZ_TRUE; + // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers). + // I'm torn how to handle this case - should it fail instead? + if (mz_zip_reader_is_file_a_directory(pZip, file_index)) + return MZ_TRUE; + // Encryption and patch files are not supported. if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE; @@ -4192,7 +4262,7 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name { mz_uint16 method = 0, dos_time = 0, dos_date = 0; mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; - mz_uint64 local_dir_header_ofs = 0, cur_archive_file_ofs = 0, comp_size = 0; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; tdefl_compressor *pComp = NULL; @@ -4207,9 +4277,6 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION)) return MZ_FALSE; - local_dir_header_ofs = pZip->m_archive_size; - cur_archive_file_ofs = pZip->m_archive_size; - pState = pZip->m_pState; if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) @@ -4346,7 +4413,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, { mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; - mz_uint64 local_dir_header_ofs = 0, cur_archive_file_ofs = 0, uncomp_size = 0, comp_size = 0; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; MZ_FILE *pSrc_file = NULL; @@ -4362,9 +4429,6 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; - local_dir_header_ofs = pZip->m_archive_size; - cur_archive_file_ofs = pZip->m_archive_size; - archive_name_size = strlen(pArchive_name); if (archive_name_size > 0xFFFF) return MZ_FALSE; @@ -4394,9 +4458,10 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, if (uncomp_size <= 3) level = 0; - if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) { - MZ_FCLOSE(pSrc_file); - return MZ_FALSE; + if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) + { + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; } local_dir_header_ofs += num_alignment_padding_bytes; if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } @@ -4607,7 +4672,7 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive * return MZ_FALSE; } - //cur_src_file_ofs += n; + cur_src_file_ofs += n; cur_dst_file_ofs += n; } pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); @@ -4632,7 +4697,7 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive * if (pState->m_central_dir.m_size > 0xFFFFFFFF) return MZ_FALSE; - n = (mz_uint32)pState->m_central_dir.m_size; + n = (mz_uint32)orig_central_dir_size; if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) { mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); diff --git a/source/shared_lib/sources/platform/common/base_thread.cpp b/source/shared_lib/sources/platform/common/base_thread.cpp index 656d643b1..42261bfd4 100644 --- a/source/shared_lib/sources/platform/common/base_thread.cpp +++ b/source/shared_lib/sources/platform/common/base_thread.cpp @@ -327,10 +327,11 @@ bool BaseThread::shutdownAndWait(BaseThread *pThread) { bool BaseThread::shutdownAndWait() { bool ret = true; BaseThread *pThread = this; - string uniqueID = (pThread != NULL ? pThread->getUniqueID() : "?"); + //string uniqueID = (pThread != NULL ? pThread->getUniqueID() : "?"); + string uniqueID = pThread->getUniqueID(); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - if(pThread != NULL) { + //if(pThread != NULL) { if(pThread->getRunningStatus() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); @@ -354,7 +355,7 @@ bool BaseThread::shutdownAndWait() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); sleep(0); } - } + //} if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); return ret; } diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index dbc6428e9..ffcc25ccd 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -619,7 +619,7 @@ void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck) { //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str()); if((path[x] == '/' || path[x] == '\\') && x != (int)pos) { - string origLoop = path; + //string origLoop = path; path.erase(x,(int)pos-x); //printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str()); @@ -2455,7 +2455,7 @@ void ValueCheckerVault::checkItemInVault(const void *ptr,int value) const { } string getUserHome() { - string home_folder = ""; + string home_folder; home_folder = safeCharPtrCopy(getenv("HOME"),8095); if(home_folder == "") { #if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED diff --git a/source/shared_lib/sources/platform/posix/ircclient.cpp b/source/shared_lib/sources/platform/posix/ircclient.cpp index 0b52b7efc..c3d3fc340 100644 --- a/source/shared_lib/sources/platform/posix/ircclient.cpp +++ b/source/shared_lib/sources/platform/posix/ircclient.cpp @@ -680,6 +680,7 @@ bool IRCThread::isConnected(bool mutexLockRequired) { safeMutex1.setMutex(&mutexIRCSession); } ret = (irc_is_connected(ircSession) != 0); + safeMutex1.ReleaseLock(); #endif } @@ -907,6 +908,7 @@ int IRCThread::irc_run_session(irc_session_t * session) { safeMutex.Lock(); if ( irc_process_select_descriptors (session, &in_set, &out_set) ) { + safeMutex.ReleaseLock(); return 3; } @@ -997,6 +999,7 @@ void IRCThread::connectToHost() { if(result != 1) { connectRequired = true; } + safeMutex1.ReleaseLock(); #endif } @@ -1004,9 +1007,12 @@ void IRCThread::connectToHost() { #if !defined(DISABLE_IRCCLIENT) MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); if(irc_connect(ircSession, argv[0].c_str(), IRC_SERVER_PORT, 0, this->nick.c_str(), this->username.c_str(), "megaglest")) { + safeMutex1.ReleaseLock(); + if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not connect: %s\n", irc_strerror (irc_errno(ircSession))); return; } + safeMutex1.ReleaseLock(); #endif } } @@ -1031,7 +1037,9 @@ void IRCThread::joinChannel() { lastNickListUpdate = time(NULL); irc_cmd_join(ircSession, ctx->getChannel().c_str(), 0); + safeMutex.ReleaseLock(); } + safeMutex.ReleaseLock(); #endif } } @@ -1050,7 +1058,9 @@ void IRCThread::leaveChannel() { IRCThread *ctx = (IRCThread *)irc_get_ctx(ircSession); if(ctx != NULL) { irc_cmd_part(ircSession,ctx->getChannel().c_str()); + safeMutex.ReleaseLock(); } + safeMutex.ReleaseLock(); #endif } } diff --git a/source/shared_lib/sources/platform/posix/miniftpclient.cpp b/source/shared_lib/sources/platform/posix/miniftpclient.cpp index adcd6acfd..d413aaa5e 100644 --- a/source/shared_lib/sources/platform/posix/miniftpclient.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpclient.cpp @@ -845,6 +845,8 @@ pair FTPClientThread::getFileInternalFromServer(p pair result = getFileFromServer(ftp_cct_File, fileName,remotePath, destFileSaveAs, "", ""); + //printf("Got file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first); + // Extract the archive if(result.first == ftp_crt_SUCCESS) { string ext = extractExtension(destFileSaveAs); @@ -897,10 +899,18 @@ pair FTPClientThread::getTempFileInternalFromServ destFileSaveAs += fileName.first; string remotePath = fileName.second; - fileName.second = ""; - pair result = getFileFromServer(ftp_cct_TempFile, - fileName,remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD); + //printf("First [%s] Second [%s]\n",fileName.first.c_str(),fileName.second.c_str()); + pair result; + if(StartsWith(remotePath,"http://")) { + result = getFileFromServer(ftp_cct_TempFile, fileName,remotePath, destFileSaveAs, "", ""); + } + else { + fileName.second = ""; + result = getFileFromServer(ftp_cct_TempFile,fileName,remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD); + } + + //printf("Got temp file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first); // Extract the archive if(result.first == ftp_crt_SUCCESS) { diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 514a58ea8..a5d4b9208 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -1818,9 +1818,9 @@ bool Socket::isConnected() { int err = peek(&tmp, peekDataBytes, false, &lastSocketError); //if(err <= 0 && err != PLATFORM_SOCKET_TRY_AGAIN) { //if(err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0) || - ((err == 0 || err == -1) && peekDataBytes == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { - + //if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0) || + // ((err == 0 || err == -1) && peekDataBytes == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { + if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0)) { //printf("IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,getLastSocketErrorFormattedText().c_str(),lastSocketError); if(SystemFlags::VERBOSE_MODE_ENABLED) SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET DISCONNECTED In [%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,getLastSocketErrorFormattedText().c_str(),lastSocketError); @@ -2634,10 +2634,10 @@ int UPNP_Tools::upnp_init(void *param) { } if(ServerSocket::cancelUpnpdiscoverThread == true) { - if(devlist != NULL) { - freeUPNPDevlist(devlist); - } - devlist = NULL; + //if(devlist != NULL) { + // freeUPNPDevlist(devlist); + //} + //devlist = NULL; return result; } @@ -2676,10 +2676,10 @@ int UPNP_Tools::upnp_init(void *param) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n"); if(ServerSocket::cancelUpnpdiscoverThread == true) { - if(devlist != NULL) { - freeUPNPDevlist(devlist); - } - devlist = NULL; + //if(devlist != NULL) { + // freeUPNPDevlist(devlist); + //} + //devlist = NULL; return result; } @@ -2695,10 +2695,10 @@ int UPNP_Tools::upnp_init(void *param) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP detection routine disabled by user.\n"); if(ServerSocket::cancelUpnpdiscoverThread == true) { - if(devlist != NULL) { - freeUPNPDevlist(devlist); - } - devlist = NULL; + //if(devlist != NULL) { + // freeUPNPDevlist(devlist); + //} + //devlist = NULL; return result; } diff --git a/source/shared_lib/sources/platform/sdl/platform_util.cpp b/source/shared_lib/sources/platform/sdl/platform_util.cpp index 69bd92a3a..de6185557 100644 --- a/source/shared_lib/sources/platform/sdl/platform_util.cpp +++ b/source/shared_lib/sources/platform/sdl/platform_util.cpp @@ -136,6 +136,7 @@ static int getFileAndLine(char *function, void *address, char *file, size_t flen #if __APPLE_CC__ //### TODO Will: still working this out int len = fread(buf,1,maxbufSize,f); + pclose(f); buf[len] = 0; fprintf(stderr,"< %s",buf); return -1; diff --git a/source/shared_lib/sources/util/properties.cpp b/source/shared_lib/sources/util/properties.cpp index 1e9096b11..aae62f7c8 100644 --- a/source/shared_lib/sources/util/properties.cpp +++ b/source/shared_lib/sources/util/properties.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "conversion.h" #include "util.h" @@ -31,7 +33,6 @@ #include "utf8.h" #include "font.h" #include "string_utils.h" - #include "leak_dumper.h" using namespace std; @@ -56,8 +57,6 @@ string Properties::tutorialPath = ""; void Properties::load(const string &path, bool clearCurrentProperties) { char lineBuffer[maxLine]=""; - string line, key, value, original_value; - size_t pos=0; this->path= path; bool is_utf8_language = valid_utf8_file(path.c_str()); @@ -88,80 +87,7 @@ void Properties::load(const string &path, bool clearCurrentProperties) { fileStream.getline(lineBuffer, maxLine); lineBuffer[maxLine-1]='\0'; - //printf("\n[%ls]\n",lineBuffer); - //printf("\n[%s]\n",&lineBuffer[0]); - - if(lineBuffer[0] != '\0') { - // If the file is NOT in UTF-8 format convert each line - if(is_utf8_language == false && Font::forceLegacyFonts == false) { - char *utfStr = ConvertToUTF8(&lineBuffer[0]); - - //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); - - memset(&lineBuffer[0],0,maxLine); - memcpy(&lineBuffer[0],&utfStr[0],strlen(utfStr)); - - delete [] utfStr; - } - else if(is_utf8_language == true && Font::forceLegacyFonts == true) { - char *asciiStr = ConvertFromUTF8(&lineBuffer[0]); - - //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); - - memset(&lineBuffer[0],0,maxLine); - memcpy(&lineBuffer[0],&asciiStr[0],strlen(asciiStr)); - - delete [] asciiStr; - } - } - - //process line if it it not a comment - if(lineBuffer[0] != ';' && lineBuffer[0] != '#') { - //wstring wstr = lineBuffer; - //line.assign(wstr.begin(),wstr.end()); - - // gracefully handle win32 \r\n line endings - size_t len= strlen(lineBuffer); - if(len > 0 && lineBuffer[len-1] == '\r') { - lineBuffer[len-1]= 0; - } - - line= lineBuffer; - pos= line.find('='); - - if(pos != string::npos){ - key= line.substr(0, pos); - value= line.substr(pos+1); - original_value = value; - - if(applyTagsToValue(value) == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s] original_value [%s]\n",key.c_str(),value.c_str(),original_value.c_str()); - } - - bool replaceExisting = false; - if(propertyMap.find(key) != propertyMap.end()) { - replaceExisting = true; - } - propertyMap[key] = original_value; - propertyMapTmp[key] = value; - - if(replaceExisting == false) { - propertyVector.push_back(PropertyPair(key, original_value)); - propertyVectorTmp.push_back(PropertyPair(key, value)); - } - else { - for(unsigned int i = 0; i < propertyVector.size(); ++i) { - PropertyPair ¤tPair = propertyVector[i]; - if(currentPair.first == key) { - currentPair.second = original_value; - - propertyVectorTmp[i].second = value; - break; - } - } - } - } - } + processTextLine(is_utf8_language,lineBuffer); } fileStream.close(); @@ -172,6 +98,108 @@ void Properties::load(const string &path, bool clearCurrentProperties) { #endif } +void Properties::loadFromText(const string &text) { + bool is_utf8_language = false; + + char lineBuffer[maxLine]=""; + + std::istringstream textStream(text); + while(textStream.eof() == false) { + //lineBuffer[0]='\0'; + std::string lineText; + getline(textStream, lineText); + if(lineText.length() > 0) { + memset(&lineBuffer[0],0,maxLine); + memcpy(&lineBuffer[0],&lineText[0],lineText.length()); + + //fileStream.getline(lineBuffer, maxLine); + //lineBuffer[maxLine-1]='\0'; + + processTextLine(is_utf8_language,&lineBuffer[0]); + } + } +} + +void Properties::processTextLine(bool is_utf8_language, char *lineBuffer) { + //printf("\n[%ls]\n",lineBuffer); + //printf("\n[%s]\n",&lineBuffer[0]); + + string line, key, value, original_value; + size_t pos=0; + + if(lineBuffer != NULL && lineBuffer[0] != '\0') { + // If the file is NOT in UTF-8 format convert each line + if(is_utf8_language == false && Font::forceLegacyFonts == false) { + char *utfStr = ConvertToUTF8(&lineBuffer[0]); + + //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); + + memset(&lineBuffer[0],0,maxLine); + memcpy(&lineBuffer[0],&utfStr[0],strlen(utfStr)); + + delete [] utfStr; + } + else if(is_utf8_language == true && Font::forceLegacyFonts == true) { + char *asciiStr = ConvertFromUTF8(&lineBuffer[0]); + + //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); + + memset(&lineBuffer[0],0,maxLine); + memcpy(&lineBuffer[0],&asciiStr[0],strlen(asciiStr)); + + delete [] asciiStr; + } + } + + //process line if it it not a comment + if(lineBuffer != NULL && lineBuffer[0] != ';' && lineBuffer[0] != '#') { + //wstring wstr = lineBuffer; + //line.assign(wstr.begin(),wstr.end()); + + // gracefully handle win32 \r\n line endings + size_t len= strlen(lineBuffer); + if(len > 0 && lineBuffer[len-1] == '\r') { + lineBuffer[len-1]= 0; + } + + line= lineBuffer; + pos= line.find('='); + + if(pos != string::npos){ + key= line.substr(0, pos); + value= line.substr(pos+1); + original_value = value; + + if(applyTagsToValue(value) == true) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s] original_value [%s]\n",key.c_str(),value.c_str(),original_value.c_str()); + } + + bool replaceExisting = false; + if(propertyMap.find(key) != propertyMap.end()) { + replaceExisting = true; + } + propertyMap[key] = original_value; + propertyMapTmp[key] = value; + + if(replaceExisting == false) { + propertyVector.push_back(PropertyPair(key, original_value)); + propertyVectorTmp.push_back(PropertyPair(key, value)); + } + else { + for(unsigned int i = 0; i < propertyVector.size(); ++i) { + PropertyPair ¤tPair = propertyVector[i]; + if(currentPair.first == key) { + currentPair.second = original_value; + + propertyVectorTmp[i].second = value; + break; + } + } + } + } + } +} + std::map Properties::getTagReplacementValues(std::map *mapExtraTagReplacementValues) { std::map mapTagReplacementValues; diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index e749937f4..0cbb76118 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -709,6 +709,22 @@ string replaceBy(const string &s, char c1, char c2){ return rs; } +vector split(string s,string d) { + vector results; + size_t lastOffset = 0; + + while(true) + { + size_t offset = s.find_first_of(d, lastOffset); + results.push_back(s.substr(lastOffset, offset - lastOffset)); + if (offset == string::npos) + break; + else + lastOffset = offset + d.size(); //skip the delimiter + } + return results; +} + string toLower(const string &s){ string rs= s; @@ -719,6 +735,10 @@ string toLower(const string &s){ return rs; } +bool compareNonCaseSensitive(const string a, const string b) { + return (toLower(a) < toLower(b)); +} + void copyStringToBuffer(char *buffer, int bufferSize, const string& s){ strncpy(buffer, s.c_str(), bufferSize-1); buffer[bufferSize-1]= '\0'; @@ -771,6 +791,67 @@ int round(float f){ } // ==================== misc ==================== +int compareMajorMinorVersion(string versionA,string versionB) { + int majorA = getMajor(versionA); + int minorA = getMinor(versionA); + int majorB = getMajor(versionB); + int minorB = getMinor(versionB); + + //printf("majorA:%d minorA:%d majorB:%d minorB:%d\n",majorA,minorA,majorB,minorB); + if(majorA < majorB) { + return -1; + } + else if(majorA == majorB) { + if(minorA < minorB) { + return -1; + } + else if(minorA == minorB) { + return 0; + } + else { + return 1; + } + } + else { + return 1; + } +} + +int getMajor(string version) { + vector parts = split(version.substr(1),"."); + + if(parts.size() > 1 && parts[0] != "" && IsNumeric(parts[0].c_str(),false)) { + return strToInt(parts[0]); + } + else { + return 0; + } +} + +int getMinor(string version) { + vector parts = split(version.substr(1),"."); + if(parts.size() > 1 && parts[1] != "") { + string resultStr=""; + for (int i = 0; i < (int)parts[1].length(); ++i) { + // just add leading numbers + if(IsNumeric((resultStr + parts[1][i]).c_str(),false) ) { + resultStr += parts[1][i]; + } + else { + break; + } + } + if(resultStr == "") { + return 0; + } + else { + return strToInt(resultStr); + } + } + else { + return 0; + } +} bool checkVersionComptability(string clientVersionString, string serverVersionString) { //SystemFlags::VERBOSE_MODE_ENABLED = true; diff --git a/source/shared_lib/sources/xml/xml_parser.cpp b/source/shared_lib/sources/xml/xml_parser.cpp index ca71d0bb9..47cfad3f8 100644 --- a/source/shared_lib/sources/xml/xml_parser.cpp +++ b/source/shared_lib/sources/xml/xml_parser.cpp @@ -705,15 +705,15 @@ XmlNode::XmlNode(xml_node<> *node, const std::map &mapTagReplacem if(node->type() == node_element && children.size() == 0) { string xmlText = node->value(); - bool debugReplace = false; +// bool debugReplace = false; // if(xmlText.find("{SCENARIOPATH}") != string::npos) { // printf("\n----------------------\n** XML!! WILL REPLACE [%s]\n",xmlText.c_str()); // debugReplace = true; // } Properties::applyTagsToValue(xmlText,&mapTagReplacementValues, skipUpdatePathClimbingParts); - if(debugReplace) { - printf("\n\n** XML!! REPLACED WITH [%s]\n===================\n",xmlText.c_str()); - } +// if(debugReplace) { +// printf("\n\n** XML!! REPLACED WITH [%s]\n===================\n",xmlText.c_str()); +// } text = xmlText; } } diff --git a/source/tests/shared_lib/streflop/streflop_test.cpp b/source/tests/shared_lib/streflop/streflop_test.cpp index 36327243d..e0404aaf4 100644 --- a/source/tests/shared_lib/streflop/streflop_test.cpp +++ b/source/tests/shared_lib/streflop/streflop_test.cpp @@ -35,7 +35,7 @@ using namespace Glest::Game; // const int64 PROGRESS_SPEED_MULTIPLIER = 100000; const float standardAirHeight = 5.0f; -const float FLOAT_TOLERANCE = 1e-10; +const float FLOAT_TOLERANCE = 1e-10f; class StreflopTest : public CppUnit::TestFixture { // Register the suite of tests for this fixture diff --git a/source/tools/convert_faction_xml2html/media/datatables/back_disabled.jpg b/source/tools/convert_faction_xml2html/media/datatables/back_disabled.jpg index 1e73a546e..7764bbec2 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/back_disabled.jpg and b/source/tools/convert_faction_xml2html/media/datatables/back_disabled.jpg differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/back_enabled.jpg b/source/tools/convert_faction_xml2html/media/datatables/back_enabled.jpg index a6d764c79..bbac1a8ff 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/back_enabled.jpg and b/source/tools/convert_faction_xml2html/media/datatables/back_enabled.jpg differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/forward_disabled.jpg b/source/tools/convert_faction_xml2html/media/datatables/forward_disabled.jpg index 28a9dc53f..9162da015 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/forward_disabled.jpg and b/source/tools/convert_faction_xml2html/media/datatables/forward_disabled.jpg differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/forward_enabled.jpg b/source/tools/convert_faction_xml2html/media/datatables/forward_enabled.jpg index 598c075f1..cf95c110d 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/forward_enabled.jpg and b/source/tools/convert_faction_xml2html/media/datatables/forward_enabled.jpg differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/sort_asc.png b/source/tools/convert_faction_xml2html/media/datatables/sort_asc.png index a56d0e219..ae7f01bd6 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/sort_asc.png and b/source/tools/convert_faction_xml2html/media/datatables/sort_asc.png differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/sort_asc_disabled.png b/source/tools/convert_faction_xml2html/media/datatables/sort_asc_disabled.png index b7e621ef1..7caebdab2 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/sort_asc_disabled.png and b/source/tools/convert_faction_xml2html/media/datatables/sort_asc_disabled.png differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/sort_desc.png b/source/tools/convert_faction_xml2html/media/datatables/sort_desc.png index 90b295159..c2402ddac 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/sort_desc.png and b/source/tools/convert_faction_xml2html/media/datatables/sort_desc.png differ diff --git a/source/tools/convert_faction_xml2html/media/datatables/sort_desc_disabled.png b/source/tools/convert_faction_xml2html/media/datatables/sort_desc_disabled.png index 2409653dc..c71c18b13 100644 Binary files a/source/tools/convert_faction_xml2html/media/datatables/sort_desc_disabled.png and b/source/tools/convert_faction_xml2html/media/datatables/sort_desc_disabled.png differ diff --git a/source/tools/glexemel/g3d_logo.png b/source/tools/glexemel/g3d_logo.png index fdf474f34..70852fe84 100644 Binary files a/source/tools/glexemel/g3d_logo.png and b/source/tools/glexemel/g3d_logo.png differ