Merge remote-tracking branch 'origin/master' into galtgendo/sdl2
This commit is contained in:
commit
af307f9f17
236 changed files with 24193 additions and 2687 deletions
.gitignore.travis.ymlCMakeLists.txtCOPYINGHOWTO-NEW-RELEASEREADME.mdappveyor.yml
cmake/modules
cmake_uninstall.cmake.indebian
doc
gameheaders
metaserver
src
action
action_attack.cppaction_board.cppaction_build.cppaction_built.cppaction_defend.cppaction_explore.cppaction_follow.cppaction_move.cppaction_patrol.cppaction_repair.cppaction_resource.cppaction_train.cppaction_upgradeto.cppactions.cppcommand.cpp
ai
animation
editor
game
guichan
include
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -26,3 +26,5 @@ obj-*
|
|||
./stratagus.suo
|
||||
./tolua.cpp
|
||||
./tolua.cpp.rule
|
||||
build
|
||||
.vscode
|
||||
|
|
29
.travis.yml
29
.travis.yml
|
@ -1,8 +1,4 @@
|
|||
language: cpp
|
||||
# sudo: required
|
||||
# compiler:
|
||||
# - gcc
|
||||
# - clang
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
@ -20,11 +16,32 @@ before_script:
|
|||
- "if [ $TRAVIS_OS_NAME == osx ]; then brew install lua51 sdl; \
|
||||
git clone https://github.com/LuaDist/toluapp.git; \
|
||||
cd toluapp; mkdir build;
|
||||
cd build; cmake ..; make && sudo make install; \
|
||||
cd build; cmake ..; make; \
|
||||
export CMAKEARGS=\"-DTOLUA++_INCLUDE_DIR=$(pwd)/../include/ -DTOLUA++_LIBRARY=$(pwd)/libtoluapp.dylib -DTOLUA++_APP=$(pwd)/toluapp -DWITH_X11=OFF\";
|
||||
cd ..;
|
||||
cd ..;
|
||||
fi"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- cmake $CMAKEARGS ..
|
||||
script: make
|
||||
after_success:
|
||||
- "if [ $TRAVIS_REPO_SLUG == Wargus/stratagus -a \
|
||||
$TRAVIS_BRANCH == master -a \
|
||||
$TRAVIS_OS_NAME == osx -a \
|
||||
$TRAVIS_PULL_REQUEST == 'false' ]; then \
|
||||
git clone https://${GH_TOKEN}@github.com/Wargus/stratagus.wiki.git;
|
||||
mkdir -p stratagus.wiki/$TRAVIS_OS_NAME;
|
||||
cp $TRAVIS_BUILD_DIR/build/stratagus stratagus.wiki/$TRAVIS_OS_NAME/;
|
||||
rm -rf macdylibbundler; git clone https://github.com/auriamg/macdylibbundler;
|
||||
cd macdylibbundler; make; cd ..;
|
||||
macdylibbundler/dylibbundler -cd -of -b -x stratagus.wiki/$TRAVIS_OS_NAME/stratagus -d stratagus.wiki/libs/;
|
||||
cd stratagus.wiki/;
|
||||
git config --global user.email \"travis-ci@travis.org\";
|
||||
git config --global user.name \"Travis CI\";
|
||||
git add $TRAVIS_OS_NAME/stratagus;
|
||||
git add libs;
|
||||
git commit --amend -C HEAD;
|
||||
git push -fq origin master;
|
||||
cd ..;
|
||||
fi"
|
||||
|
|
|
@ -34,7 +34,7 @@ set(STRATAGUS_MAJOR_VERSION 2)
|
|||
# Stratagus minor version (maximum 99)
|
||||
set(STRATAGUS_MINOR_VERSION 4)
|
||||
# Stratagus patch level (maximum 99)
|
||||
set(STRATAGUS_PATCH_LEVEL 0)
|
||||
set(STRATAGUS_PATCH_LEVEL 2)
|
||||
# Stratagus patch level 2
|
||||
set(STRATAGUS_PATCH_LEVEL2 0)
|
||||
#########################
|
||||
|
@ -65,6 +65,7 @@ set(action_SRCS
|
|||
src/action/action_built.cpp
|
||||
src/action/action_defend.cpp
|
||||
src/action/action_die.cpp
|
||||
src/action/action_explore.cpp
|
||||
src/action/action_follow.cpp
|
||||
src/action/action_move.cpp
|
||||
src/action/action_patrol.cpp
|
||||
|
@ -675,7 +676,7 @@ endif()
|
|||
# Options for compiling
|
||||
|
||||
if(WIN32)
|
||||
option(ENABLE_STDIO_REDIRECT "Redirect Stratagus console output to files on Windows" OFF)
|
||||
option(ENABLE_STDIO_REDIRECT "Redirect Stratagus console output to files on Windows" ON)
|
||||
option(ENABLE_NSIS "Create Stratagus Window NSIS Installer" OFF)
|
||||
endif()
|
||||
|
||||
|
@ -759,6 +760,10 @@ if(WITH_MNG AND MNG_FOUND)
|
|||
add_definitions(-DUSE_MNG)
|
||||
include_directories(${MNG_INCLUDE_DIR})
|
||||
set(stratagus_LIBS ${stratagus_LIBS} ${MNG_LIBRARY})
|
||||
if (MSVC)
|
||||
include_directories(${JPEG_INCLUDE_DIR})
|
||||
set(stratagus_LIBS ${stratagus_LIBS} ${JPEG_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_OGGVORBIS AND OGGVORBIS_FOUND)
|
||||
|
@ -841,10 +846,14 @@ if(BEOS)
|
|||
set(stratagus_SRCS ${stratagus_SRCS} ${beos_SRCS})
|
||||
endif()
|
||||
|
||||
if(HAIKU)
|
||||
set(stratagus_LIBS ${stratagus_LIBS} -lnetwork)
|
||||
endif()
|
||||
|
||||
# Stratagus needs to have char by default signed
|
||||
# No idea how to tell this to other compilers
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char -std=gnu++0x -Werror")
|
||||
endif()
|
||||
if(CMAKE_COMPILER_IS_GNUC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsigned-char")
|
||||
|
@ -972,6 +981,8 @@ elseif(BSD)
|
|||
message("Platform: BSD")
|
||||
elseif(BEOS)
|
||||
message("Platform: BEOS")
|
||||
elseif(HAIKU)
|
||||
message("Platform: Haiku")
|
||||
elseif(LINUX)
|
||||
message("Platform: Linux")
|
||||
else()
|
||||
|
@ -1078,7 +1089,11 @@ add_custom_command(OUTPUT tolua.cpp
|
|||
VERBATIM
|
||||
)
|
||||
|
||||
add_executable(stratagus WIN32 ${stratagus_SRCS} ${stratagus_HDRS})
|
||||
if (ENABLE_STDIO_REDIRECT)
|
||||
add_executable(stratagus WIN32 ${stratagus_SRCS} ${stratagus_HDRS})
|
||||
else ()
|
||||
add_executable(stratagus ${stratagus_SRCS} ${stratagus_HDRS})
|
||||
endif ()
|
||||
target_link_libraries(stratagus ${stratagus_LIBS})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
@ -1149,7 +1164,9 @@ endif()
|
|||
|
||||
set(gameheaders_HDRS
|
||||
gameheaders/stratagus-game-installer.nsi
|
||||
gameheaders/stratagus-gameutils.h
|
||||
gameheaders/stratagus-game-launcher.h
|
||||
gameheaders/stratagus-tinyfiledialogs.h
|
||||
)
|
||||
source_group(gameheaders FILES ${gameheaders_HDRS})
|
||||
|
||||
|
@ -1212,6 +1229,14 @@ if(WIN32 AND ENABLE_NSIS AND MAKENSIS_FOUND)
|
|||
file(COPY ${GLIB_DLL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
file(COPY ${GTHREAD_DLL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
# also ship lua51.dll
|
||||
find_file(LUA_DLL lua51.dll HINTS ${CMAKE_PREFIX_PATH} PATH_SUFFIXES bin lib)
|
||||
file(COPY ${LUA_DLL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(MAKENSIS_FLAGS ${MAKENSIS_FLAGS} -DLUADLL=lua51.dll)
|
||||
# ship SDL.dll
|
||||
find_file(SDL_DLL SDL.dll HINTS ${CMAKE_PREFIX_PATH} PATH_SUFFIXES bin lib)
|
||||
file(COPY ${SDL_DLL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(MAKENSIS_FLAGS ${MAKENSIS_FLAGS} -DSDL=SDL.dll)
|
||||
add_custom_command(OUTPUT Stratagus-${STRATAGUS_VERSION}${MAKENSIS_SUFFIX}
|
||||
COMMAND ${MAKENSIS} ARGS ${MAKENSIS_FLAGS} -DVERSION=${STRATAGUS_VERSION} -DVIVERSION=${STRATAGUS_VERSION_FULL} ${CMAKE_CURRENT_SOURCE_DIR}/src/win32/stratagus.nsi
|
||||
DEPENDS src/win32/stratagus.nsi stratagus COPYING
|
||||
|
@ -1227,7 +1252,7 @@ install(TARGETS stratagus DESTINATION ${GAMEDIR})
|
|||
install(TARGETS png2stratagus DESTINATION ${BINDIR})
|
||||
|
||||
if(SQLITE_FOUND)
|
||||
install(TARGETS metaserver DESTINATION ${SBINDIR})
|
||||
install(TARGETS metaserver DESTINATION ${BINDIR} RENAME stratagus-metaserver)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DOC AND DOXYGEN_FOUND)
|
||||
|
@ -1255,3 +1280,14 @@ endif()
|
|||
########### clean files ###############
|
||||
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEAN_FILES}")
|
||||
|
||||
# uninstall target
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
|
47
COPYING
47
COPYING
|
@ -1,12 +1,12 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
|
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
|||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
|
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
|
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
|||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
|
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
|||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
|
@ -225,7 +225,7 @@ impose that choice.
|
|||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
|
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
|||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
|
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
|
@ -290,8 +290,8 @@ to attach them to the start of each source file to most effectively
|
|||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
{description}
|
||||
Copyright (C) {year} {fullname}
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
@ -330,11 +329,11 @@ necessary. Here is a sample; alter the names:
|
|||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
{signature of Ty Coon}, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
|
|
@ -1,17 +1,4 @@
|
|||
Here is small HOWTO release new version of Stratagus
|
||||
|
||||
You need some linux machine (ideally ubuntu) with:
|
||||
git, debhelper, devscripts, cmake, make, nsis, upx, gnupg
|
||||
|
||||
For windows installers you need:
|
||||
cmake toolchain file (see example)
|
||||
windows gcc cross compiler: g++-mingw-w64
|
||||
windows stratagus dependencies (from https://launchpad.net/~mingw-packages/+archive/ppa):
|
||||
libmikmod-mingw-w64-cross, libogg-mingw-w64-cross, libpng-mingw-w64-cross, libpthread-mingw-w64-cross, libsdl1.2-mingw-w64-cross,
|
||||
libtheora-mingw-w64-cross, libvorbis-mingw-w64-cross, lua5.1-mingw-w64-cross, tolua++-mingw-w64-cross, zlib-mingw-w64-cross
|
||||
|
||||
Download source code:
|
||||
git clone https://github.com/Wargus/stratagus && cd stratagus
|
||||
Here is small HOWTO release new version of Stratagus (and also Wargus/War1gus/Stargus/...)
|
||||
|
||||
Increase version in file:
|
||||
CMakeLists.txt
|
||||
|
@ -20,46 +7,31 @@ Update changelog in file:
|
|||
doc/changelog.html
|
||||
|
||||
Increase version and update changelog for debian:
|
||||
dch -i
|
||||
dch -vNEWVERSION
|
||||
dch -r
|
||||
|
||||
Commit changes to git and create tag:
|
||||
Update copyright information for Debian:
|
||||
debian/copyright
|
||||
|
||||
Update Copyright information in NSI installer:
|
||||
src/win32/stratagus.nsi
|
||||
|
||||
Tag the new release in https://github.com/Wargus/win32-stratagus-dependencies
|
||||
and wait for it to run through on the Appveyor CI. This will automatically
|
||||
cause a release with the tag name to be created, and the windows dependencies
|
||||
will be uploaded there.
|
||||
|
||||
Tag the new release here and wait for it to run through the CIs. Appveyor and
|
||||
Travis will upload new versions for Windows and OSX, and Launchpad will
|
||||
automatically build new debian packages:
|
||||
git commit -a -m "Release version <version>"
|
||||
git tag <version>
|
||||
git push --tags origin master
|
||||
|
||||
Create orig tarball + sign:
|
||||
git clean -idx
|
||||
tar czvf ../stratagus_<version>.orig.tar.gz
|
||||
gpg --armor --sign --detach-sig ../stratagus_*.orig.tar.gz
|
||||
For Wargus/War1gus/Stargus we have a release.rb script. Run it without any
|
||||
arguments, and it will tell you how to call it to start the release process
|
||||
for this particular project.
|
||||
|
||||
Create ubuntu release packages:
|
||||
(happens automatically on commit in launchpad)
|
||||
Tag the new release in Wargus/War1gus/Stargus/... these repositories should be
|
||||
set up to also use the appropriate release source from the Stratagus releases.
|
||||
|
||||
Create win32 installer + sign:
|
||||
rm -rf build && mkdir build && cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/path/to/win32/toolchain/file -DENABLE_STATIC=ON -DENABLE_NSIS=ON -DENABLE_UPX=ON -DENABLE_STRIP=ON ..
|
||||
make && mv Stratagus-*.exe ../../ && cd ..
|
||||
gpg --armor --sign --detach-sig ../Stratagus-*.exe
|
||||
|
||||
Create win64 installer + sign:
|
||||
rm -rf build && mkdir build && cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/path/to/win64/toolchain/file -DENABLE_STATIC=ON -DENABLE_NSIS=ON -DENABLE_STRIP=ON ..
|
||||
make && mv Stratagus-*-x86_64.exe ../../ && cd ..
|
||||
gpg --armor --sign --detach-sig ../Stratagus-*-x86_64.exe
|
||||
|
||||
Create new release on github, upload windows installers with signatures:
|
||||
via web interface on https://github.com/Wargus/stratagus/releases
|
||||
|
||||
Upload ubuntu dsc packages to stratagus PPA:
|
||||
dput ppa:stratagus/ppa ../stratagus_*ubuntu*_source.changes
|
||||
|
||||
Example of cmake win32 toolchain file for windows:
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
|
||||
SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
|
||||
SET(CMAKE_PREFIX_PATH /usr/i686-w64-mingw32)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
|
27
README.md
27
README.md
|
@ -1,4 +1,4 @@
|
|||
________________________________README_________________________________
|
||||
_______________________________________________________________________
|
||||
_________ __ __
|
||||
/ _____// |_____________ _/ |______ ____ __ __ ______
|
||||
\_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
|
@ -9,14 +9,37 @@
|
|||
T H E W A R B E G I N S
|
||||
Stratagus - A free fantasy real time strategy game engine
|
||||
|
||||
[](https://gitter.im/Wargus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Windows: <a href="https://ci.appveyor.com/project/timfel/stratagus"><img width="100" src="https://ci.appveyor.com/api/projects/status/github/Wargus/stratagus?branch=master&svg=true"></a>
|
||||
|
||||
Linux & OSX: [](https://travis-ci.org/Wargus/stratagus)
|
||||
|
||||
Nightly builds are available:
|
||||
For Mac OS X, Stratagus comes bundled in the app bundles for Wargus, Stargus, and War1gus:
|
||||
- Wargus: https://github.com/Wargus/stratagus/wiki/osx/Wargus.app.tar.gz
|
||||
- War1gus: https://github.com/Wargus/stratagus/wiki/osx/War1gus.app.tar.gz
|
||||
- Stargus: https://github.com/Wargus/stratagus/wiki/osx/Stargus.app.tar.gz
|
||||
|
||||
On Ubuntu/Debian, you probably want the deb packages:
|
||||
- https://launchpad.net/~stratagus/+archive/ubuntu/ppa
|
||||
- Note that the game packages you probably want are `wargus`, `war1gus`, and `stargus`
|
||||
|
||||
For Windows, you likely want the game installers:
|
||||
- Wargus: https://github.com/Wargus/wargus/releases
|
||||
- War1gus: https://github.com/Wargus/war1gus/releases
|
||||
- Stargus: https://github.com/Wargus/stargus/releases
|
||||
|
||||
If you do indeed need the Stratagus engine itself, nightly builds are available:
|
||||
- Windows Installer: https://github.com/Wargus/stratagus/releases/tag/master-builds
|
||||
- Ubuntu/Debian Packages: https://launchpad.net/~stratagus/+archive/ubuntu/ppa
|
||||
|
||||
Read 'doc/index.html' for general information and license information.
|
||||
Read 'doc/install.html' for Stratagus installation instructions.
|
||||
Read 'doc/changelog.html' for the Stratagus changelog.
|
||||
|
||||
The Mac and Windows builds are done on Appveyor and Travis. The Ubuntu packages
|
||||
are built on Launchpad:
|
||||
- https://code.launchpad.net/~stratagus/+recipe/stratagus-github
|
||||
- https://code.launchpad.net/~stratagus/+recipe/war1gus-github
|
||||
- https://code.launchpad.net/~stratagus/+recipe/stargus-github
|
||||
- https://code.launchpad.net/~stratagus/+recipe/wargus-github
|
||||
|
|
41
appveyor.yml
41
appveyor.yml
|
@ -1,24 +1,39 @@
|
|||
os: Visual Studio 2015
|
||||
shallow_clone: true
|
||||
configuration:
|
||||
- Release
|
||||
before_build:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- appveyor DownloadFile https://github.com/Wargus/stratagus/releases/download/2015-30-11/dependencies.zip
|
||||
- appveyor DownloadFile https://github.com/Wargus/win32-stratagus-dependencies/releases/download/master-builds/dependencies.zip
|
||||
- 7z x dependencies.zip
|
||||
- choco install nsis -pre
|
||||
- cmake -G "Visual Studio 14 2015" -DCMAKE_PREFIX_PATH="%cd%\\dependencies" -DENABLE_NSIS=ON ..
|
||||
- appveyor DownloadFile https://github.com/jimpark/unsis/releases/download/2.50.0/nsis-2.50.0-Unicode-setup.exe
|
||||
- nsis-2.50.0-Unicode-setup.exe /S /D=C:\Program Files (x86)\NSIS
|
||||
- cmake -G "Visual Studio 14 2015" -T v140_xp -DCMAKE_PREFIX_PATH="%cd%\\dependencies" -DENABLE_NSIS=ON -DENABLE_STDIO_REDIRECT=ON ..
|
||||
- cd ..
|
||||
after_build:
|
||||
- 7z a compiled-binaries.zip %cd%\build\stratagus.exe %cd%\build\dependencies\bin\*.dll
|
||||
artifacts:
|
||||
- path: build\Stratagus-*.exe
|
||||
- path: compiled-binaries.zip
|
||||
deploy:
|
||||
release: master-builds
|
||||
description: 'Automatic builds from the master branch'
|
||||
provider: GitHub
|
||||
auth_token:
|
||||
secure: NMy2KE3EpZTjverxNzEAoBnlV+7VLGvwy3e1WEIrliFy3R1oxuT+AgGUDcRwv9y/
|
||||
artifact: /.*exe/
|
||||
draft: false
|
||||
prerelease: true
|
||||
on:
|
||||
branch: master
|
||||
- provider: GitHub
|
||||
release: master-builds
|
||||
description: 'Automatic builds from the master branch'
|
||||
auth_token:
|
||||
secure: NMy2KE3EpZTjverxNzEAoBnlV+7VLGvwy3e1WEIrliFy3R1oxuT+AgGUDcRwv9y/
|
||||
artifact: /.*(exe|zip)/
|
||||
draft: false
|
||||
prerelease: true
|
||||
on:
|
||||
branch: master
|
||||
- provider: GitHub
|
||||
release: $(APPVEYOR_REPO_TAG_NAME)
|
||||
description: 'Release'
|
||||
auth_token:
|
||||
secure: NMy2KE3EpZTjverxNzEAoBnlV+7VLGvwy3e1WEIrliFy3R1oxuT+AgGUDcRwv9y/
|
||||
artifact: /.*(exe|zip)/
|
||||
draft: false
|
||||
prerelease: false
|
||||
on:
|
||||
appveyor_repo_tag: true
|
||||
|
|
|
@ -10,19 +10,33 @@
|
|||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
if(MNG_INCLUDE_DIR AND MNG_LIBRARY)
|
||||
if(MNG_INCLUDE_DIR AND MNG_LIBRARY AND ((NOT MSVC) OR (JPEG_INCLUDE_DIR AND JPEG_LIBRARY)))
|
||||
set(MNG_FOUND true)
|
||||
else()
|
||||
find_path(MNG_INCLUDE_DIR libmng.h)
|
||||
find_library(MNG_LIBRARY NAMES mng)
|
||||
if(MSVC)
|
||||
find_path(JPEG_INCLUDE_DIR jpeglib.h)
|
||||
find_library(JPEG_LIBRARY NAMES jpeg)
|
||||
endif()
|
||||
|
||||
if(MNG_INCLUDE_DIR AND MNG_LIBRARY)
|
||||
if(MNG_INCLUDE_DIR AND MNG_LIBRARY AND ((NOT MSVC) OR (JPEG_INCLUDE_DIR AND JPEG_LIBRARY)))
|
||||
set(MNG_FOUND true)
|
||||
message(STATUS "Found MNG: ${MNG_LIBRARY}")
|
||||
if (MSVC)
|
||||
message(STATUS "Found JPEG: ${JPEG_LIBRARY}")
|
||||
endif()
|
||||
else()
|
||||
set(MNG_FOUND false)
|
||||
if(MSVC AND (NOT (JPEG_INCLUDE_DIR AND JPEG_LIBRARY)))
|
||||
message(STATUS "Could not find JPEG")
|
||||
endif()
|
||||
message(STATUS "Could not find MNG")
|
||||
endif()
|
||||
|
||||
mark_as_advanced(MNG_INCLUDE_DIR MNG_LIBRARY)
|
||||
if(MSVC)
|
||||
mark_as_advanced(MNG_INCLUDE_DIR MNG_LIBRARY JPEG_INCLUDE_DIR JPEG_LIBRARY)
|
||||
else()
|
||||
mark_as_advanced(MNG_INCLUDE_DIR MNG_LIBRARY)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
if ( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES )
|
||||
# in cache already
|
||||
SET(Sqlite_FIND_QUIETLY TRUE)
|
||||
SET(SQLITE_FOUND)
|
||||
endif ( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES )
|
||||
|
||||
# use pkg-config to get the directories and then use these values
|
||||
|
|
21
cmake_uninstall.cmake.in
Normal file
21
cmake_uninstall.cmake.in
Normal file
|
@ -0,0 +1,21 @@
|
|||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
37
debian/changelog
vendored
37
debian/changelog
vendored
|
@ -1,3 +1,40 @@
|
|||
stratagus (2.4.2) xenial; urgency=medium
|
||||
* Force load progress to screen only every 500ms. On modern machines,
|
||||
loading was so fast that almost all time was spent in screen redraw
|
||||
rather than loading.
|
||||
* Add support for game launchers to have optional contrib files that are
|
||||
just ignored if they are not present
|
||||
* Reliability: Fall back to software and windowed rendering before
|
||||
giving up on startup. This fixes the trouble some people have when
|
||||
they enable OpenGL or an unsupported fullscreen resolution and now the
|
||||
game won't start. Otherwise, they have to know where the
|
||||
preferences.lua file is stored and either delete or edit it.
|
||||
* Commandline: -Z now takes a WIDTHxHEIGHT argument, too, to define the
|
||||
base resolution to scale up from.
|
||||
* Bugfix: Warping mouse coordinates in zoomed mode was not scaled correctly.
|
||||
* Metaserver: Implement simple UDP hole punching to allow connections through some NATs
|
||||
* Metaserver: Add CREATEGAME command
|
||||
* Metaserver: Allow access for non-registered users
|
||||
* Bugfix: Remove checksumming of lua files for now due to issues
|
||||
* Installation: Include tinyfiledialogs and make extraction of game
|
||||
data more consistent for games that want it by offering the
|
||||
functionality on first launch based on header defines in the game
|
||||
launchers.
|
||||
* Bugfix: Regenerating forest tiles should no longer set the wrong tile index
|
||||
* Graphics: Allow each game to ship its own shaders by searching in the game data path
|
||||
* Keybindings: Use Alt+/ and Alt+\ do change shaders globally
|
||||
|
||||
-- Tim Felgentreff <timfelgentreff@gmail.com> Sun, 11 Jun 2017 12:10:55 +0200
|
||||
|
||||
stratagus (2.4.1-0) unstable; urgency=low
|
||||
|
||||
* Add support for icon frames in engine
|
||||
* Add support for selecting and giving orders to multiple buildings
|
||||
* Add checksumming for loaded lua files, to avoid incompatible multiplayer clients
|
||||
* Update shader support to use pre-compiled shaders from libretro
|
||||
|
||||
-- Tim Felgentreff <timfelgentreff@gmail.com> Wed, 2 Dec 2015 12:41:01 +0100
|
||||
|
||||
stratagus (2.4.0-1) unstable; urgency=low
|
||||
|
||||
* Introduced OpenGL shaders for pixel scaling
|
||||
|
|
6
debian/control
vendored
6
debian/control
vendored
|
@ -4,8 +4,8 @@ Priority: optional
|
|||
Maintainer: cybermind <iddqd_mail@mail.ru>
|
||||
Build-Depends: debhelper (>= 7), cmake (>= 2.6), doxygen,
|
||||
imagemagick, sharutils, liblua5.1-dev | liblua5.1-0-dev, libtolua++5.1-dev,
|
||||
zlib1g-dev, libbz2-dev, libpng12-dev (>= 1.2.5), libmng-dev,
|
||||
libmikmod2-dev, libogg-dev, libvorbis-dev, libtheora-dev,
|
||||
zlib1g-dev, libbz2-dev, libpng12-dev (>= 1.2.5) | libpng-dev (>= 1.2.5),
|
||||
libmng-dev, libmikmod2-dev, libogg-dev, libvorbis-dev, libtheora-dev,
|
||||
libsdl1.2-dev (>> 1.2.2), libx11-dev, libsqlite3-dev,
|
||||
libgles1-sgx-img-dev | libglu1-mesa-dev | libglu-dev | libgles1-mesa-dev,
|
||||
libsdl-gles1.2-dev | libglu1-mesa-dev | libglu-dev, libfluidsynth-dev
|
||||
|
@ -16,7 +16,7 @@ Vcs-Git: https://github.com/Wargus/stratagus.git
|
|||
|
||||
Package: stratagus
|
||||
Architecture: any
|
||||
Suggests: wargus, war1gus, stargus, stratagus-data
|
||||
Recommends: wargus, war1gus, stargus, stratagus-data
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: Strategy Gaming Engine
|
||||
Stratagus is a free cross-platform real-time strategy gaming engine.
|
||||
|
|
4
debian/copyright
vendored
4
debian/copyright
vendored
|
@ -6,15 +6,17 @@ Copyright:
|
|||
© 2004 David Martínez Moreno <ender@debian.org>
|
||||
© 2010-2012 Pali Rohár <pali.rohar@gmail.com>
|
||||
© 2015 cybermind <iddqd_mail@mail.ru>
|
||||
© 2016-2018 Tim Felgentreff <timfelgentreff@gmail.com>
|
||||
License: GPL-2+
|
||||
|
||||
Files: *
|
||||
© 1998-2015 by The Stratagus Project, including:
|
||||
© 1998-2017 by The Stratagus Project, including:
|
||||
Jimmy Salmon <jsalmon3@users.sourceforge.net>
|
||||
Russel Smith <mr-russ@users.sourceforge.net>
|
||||
Nehal Mistry <nehalmistry@users.sourceforge.net>
|
||||
Pali Rohár <pali.rohar@gmail.com>
|
||||
cybermind <iddqd_mail@mail.ru>
|
||||
Tim Felgentreff <timfelgentreff@gmail.com>
|
||||
License: GPL-2+
|
||||
|
||||
License: GPL-2+
|
||||
|
|
2
debian/rules
vendored
2
debian/rules
vendored
|
@ -45,7 +45,7 @@ override_dh_auto_build:
|
|||
override_dh_install:
|
||||
dh_install
|
||||
dh_auto_install --builddirectory=obj-$(DEB_BUILD_GNU_TYPE)-dbg --destdir=debian/stratagus-dbg
|
||||
rm -f debian/stratagus-dbg/usr/bin/png2stratagus debian/stratagus-dbg/usr/sbin/metaserver
|
||||
rm -f debian/stratagus-dbg/usr/bin/png2stratagus
|
||||
convert src/win32/stratagus.ico debian/stratagus/usr/share/pixmaps/stratagus.png
|
||||
|
||||
override_dh_shlibdeps:
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>ChangeLog: Stratagus Version 2.3</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
@ -40,6 +40,73 @@
|
|||
|
||||
<ul>
|
||||
<p/>
|
||||
<p/><li>2.4.3 Released<p/></li>
|
||||
<ul>
|
||||
<li>
|
||||
Allow specifying colors, percentages, and border for the LifeBar.
|
||||
</li>
|
||||
</ul>
|
||||
</li><p/><li>2.4.2 Released<p/></li>
|
||||
<ul>
|
||||
<li>
|
||||
Force load progress to screen only every 500ms. On modern machines, loading
|
||||
was so fast that almost all time was spent in screen redraw rather than loading.
|
||||
</li>
|
||||
<li>
|
||||
Add support for game launchers to have optional contrib files that are just ignored if they are not present
|
||||
</li>
|
||||
<li>
|
||||
Add "make uninstall" target
|
||||
</li>
|
||||
<li>
|
||||
Reliability: Fall back to software and windowed rendering before
|
||||
giving up on startup. This fixes the trouble some people have when
|
||||
they enable OpenGL or an unsupported fullscreen resolution and now the
|
||||
game won't start. Otherwise, they have to know where the
|
||||
preferences.lua file is stored and either delete or edit it.
|
||||
</li>
|
||||
<li>
|
||||
Commandline: -Z now takes a WIDTHxHEIGHT argument, too, to define the
|
||||
base resolution to scale up from.
|
||||
</li>
|
||||
<li>
|
||||
Bugfix: Warping mouse coordinates in zoomed mode was not scaled correctly.
|
||||
</li>
|
||||
<li>
|
||||
Metaserver: Implement simple UDP hole punching to allow connections through some NATs
|
||||
</li>
|
||||
<li>
|
||||
Metaserver: Add CREATEGAME command
|
||||
</li>
|
||||
<li>
|
||||
Metaserver: Allow access for non-registered users
|
||||
</li>
|
||||
<li>
|
||||
Bugfix: Remove checksumming of lua files for now due to issues
|
||||
</li>
|
||||
<li>
|
||||
Installation: Include tinyfiledialogs and make extraction of game
|
||||
data more consistent for games that want it by offering the
|
||||
functionality on first launch based on header defines in the game
|
||||
launchers.
|
||||
</li>
|
||||
<li>
|
||||
Bugfix: Regenerating forest tiles should no longer set the wrong tile index
|
||||
</li>
|
||||
<li>
|
||||
Graphics: Allow each game to ship its own shaders by searching in the game data path
|
||||
</li>
|
||||
<li>
|
||||
Keybindings: Use Alt+/ and Alt+\ do change shaders globally
|
||||
</li>
|
||||
</ul>
|
||||
<p/><li>2.4.1 Released<p/></li>
|
||||
<ul>
|
||||
<li>Add support for icon frames in engine</li>
|
||||
<li>Add support for selecting and giving orders to multiple buildings</li>
|
||||
<li>Add checksumming for loaded lua files, to avoid incompatible multiplayer clients</li>
|
||||
<li>Update shader support to use pre-compiled shaders from libretro</li>
|
||||
</ul>
|
||||
<p/><li>2.4.0 Released<p/></li>
|
||||
<ul>
|
||||
<li>Introduced OpenGL shaders for pixel scaling</li>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Development for Stratagus</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>FAQ for Stratagus</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Palette Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus tileset graphic format</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
@ -57,7 +57,7 @@
|
|||
<ul>
|
||||
<li>Wargus - Warcraft II - <a href="https://launchpad.net/wargus">https://launchpad.net/wargus</a>
|
||||
<li>Doom Wars - <a href="http://stratagus.com/games/doom-wars">http://stratagus.com/games/doom-wars</a>
|
||||
<li>Wyrmsun - <a href="ttps://github.com/andrettin/wyrmsun">ttps://github.com/andrettin/wyrmsun</a><br>
|
||||
<li>Wyrmsun - <a href="https://github.com/andrettin/wyrmsun">https://github.com/andrettin/wyrmsun</a><br>
|
||||
(uses modified engine version : <a href="https://github.com/Andrettin/Wyrmgus">https://github.com/Andrettin/Wyrmgus</a>)</li>
|
||||
<li>War1gus - Warcraft I - <a href="https://launchpad.net/war1gus">https://launchpad.net/war1gus</a>
|
||||
<li>Stargus - Starcraft I - <a href="https://launchpad.net/stargus">https://launchpad.net/stargus</a>
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Installation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Media Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Artificial Intelligence(AI)</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Config</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Icon</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Index</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Magic</title>
|
||||
<meta name="Author" content="cleonard@go.ro">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: PUD conversion</title>
|
||||
</head>
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: PUD conversion</title>
|
||||
</head>
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Icon</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Save Game Files</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Icon</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Tileset</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: Triggers</title>
|
||||
<meta name="Keyword" content="ccl,tileset">
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: User Interface (UI)</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
@ -54,6 +54,7 @@
|
|||
<a href="#DefineUI">DefineUI</a>
|
||||
<a href="#DefineViewports">DefineViewports</a>
|
||||
<a href="#SetGameCursor">SetGameCursor</a>
|
||||
<a href="#Icon Frame">Icon Frame</a>
|
||||
<hr>
|
||||
<h2>Intro - Introduction to UI functions and variables</h2>
|
||||
|
||||
|
@ -231,7 +232,11 @@ Selected, Clicked, Disabled, or the Default setting. Possible tags:
|
|||
<dd>Display the text at this position (overrides the main position).
|
||||
</dd>
|
||||
<dt>Border = { Color = color, Size = size}</dt>
|
||||
<dd>Draw a border with the specified color and size.
|
||||
<dd>Draw a border with the specified color and size, with the border flashing
|
||||
</dd>
|
||||
</dl>
|
||||
<dt>Border = { SolidColor = color, Size = size}</dt>
|
||||
<dd>Draw a border with the specified color and size, without any flashing of the border
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
@ -913,6 +918,15 @@ Define panel content when an unit is selected.
|
|||
<dd>Height of the bar.</dd>
|
||||
<dt>Width = value</dt>
|
||||
<dd>width of the bar.</dd>
|
||||
<dt>Border = boolean</dt>
|
||||
<dd>if true then add a border to the bar. Default is true.</dd>
|
||||
<dt>Colors = list</dt>
|
||||
<dd>A list of {percentage, color-name} pairs. The default is equivalent
|
||||
to {{75, "dark-green"}, {50, "yellow"}, {25, "orange"}, {0,
|
||||
"red"}}. The last element must start with "0". The meaning of the
|
||||
number is the percentage above which the associated color takes
|
||||
effect.
|
||||
</dd>
|
||||
</dl></dd>
|
||||
<dt>"CompleteBar", {flag = value, ...}</dt>
|
||||
<dd>Draw a bar which represent the variable.
|
||||
|
@ -1261,6 +1275,16 @@ Set the game cursor.
|
|||
SetGameCursor("cursor-point")
|
||||
</pre>
|
||||
|
||||
<a name="Icon Frame"></a>
|
||||
<h3>Icon Frame</h3>
|
||||
Set a custom frame to be drawn around icons. Note that "IconsShift" has to be true.
|
||||
<h4>Example</h4>
|
||||
<pre>
|
||||
Preference.IconsShift = true
|
||||
Preference.IconFrameG = CGraphic:New("ui/" .. race .. "/icon_border.png", 62, 48)
|
||||
Preference.PressedIconFrameG = CGraphic:New("ui/" .. race .. "/icon_border.png", 62, 48)
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
(C) Copyright 2002-2015 by The <a href="https://launchpad.net/stratagus">Stratagus</a> Project under the <a href="../gpl.html">GNU General Public License</a>.<br>
|
||||
All trademarks and copyrights on this page are owned by their respective owners.<br>
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
----
|
||||
---- You should have received a copy of the GNU General Public License
|
||||
---- along with this program; if not, write to the Free Software
|
||||
---- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
---- 02111-1307, USA.
|
||||
---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
---- 02110-1301, USA.
|
||||
-->
|
||||
<title>Stratagus Configuration Language Description: UnitType</title>
|
||||
<meta name="Author" content="johns98@gmx.net">
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
T H E W A R B E G I N S
|
||||
Stratagus - A free fantasy real time strategy game engine
|
||||
|
||||
stratagus-game-launcher.h - Stratagus Game Launcher
|
||||
stratagus-game-launcher.h - Stratagus Game Launcher
|
||||
Copyright (C) 2010-2011 Pali Rohár <pali.rohar@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -24,7 +24,6 @@
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -41,8 +40,14 @@
|
|||
*
|
||||
* ::GAME_CD
|
||||
*
|
||||
* ::GAME_CD_FILE_PATTERNS
|
||||
*
|
||||
* ::GAME
|
||||
*
|
||||
* ::EXTRACTOR_TOOL
|
||||
*
|
||||
* ::EXTRACTOR_ARGS
|
||||
*
|
||||
* On Non Windows system you need to specify also paths:
|
||||
*
|
||||
* ::DATA_PATH
|
||||
|
@ -61,6 +66,9 @@
|
|||
* #define GAME_NAME "My Game Name"
|
||||
* #define GAME_CD "Original Game CD Name"
|
||||
* #define GAME "my_game"
|
||||
* #define GAME_CD_FILE_PATTERNS "*.WAR", "*.war"
|
||||
* #define EXTRACTOR_TOOL "gametool"
|
||||
* #define EXTRACTOR_ARGS "-v"
|
||||
*
|
||||
* #ifndef WIN32
|
||||
* #define DATA_PATH "/usr/share/games/stratagus/my_game"
|
||||
|
@ -83,11 +91,28 @@
|
|||
* Full name of data CD
|
||||
**/
|
||||
|
||||
/**
|
||||
* \def GAME_CD_FILE_PATTERNS
|
||||
* Comma-separated file patterns for the extraction wizard to help users select
|
||||
* the right folder.
|
||||
**/
|
||||
|
||||
/**
|
||||
* \def GAME
|
||||
* Short name of game (lower ascii chars without space)
|
||||
**/
|
||||
|
||||
/**
|
||||
* \def EXTRACTOR_TOOL
|
||||
* The name of the game data extractor tool. This code will append the
|
||||
* arguments, src, and destionation directories.
|
||||
**/
|
||||
|
||||
/**
|
||||
* \def EXTRACTOR_ARGS
|
||||
* The default arguments of the game data extractor tool.
|
||||
**/
|
||||
|
||||
/**
|
||||
* \def DATA_PATH
|
||||
* Path to game data directory
|
||||
|
@ -103,14 +128,6 @@
|
|||
* Path to stratagus executable binary
|
||||
**/
|
||||
|
||||
/**
|
||||
* \def TITLE_PNG
|
||||
* OPTIONAL: Path to title screen (for testing if data was extracted)
|
||||
**/
|
||||
#ifndef TITLE_PNG
|
||||
#define TITLE_PNG "%s\\graphics\\ui\\title.png"
|
||||
#endif
|
||||
|
||||
/* Fake definitions for Doxygen */
|
||||
#ifdef DOXYGEN
|
||||
#define GAME_NAME
|
||||
|
@ -121,56 +138,37 @@
|
|||
#define STRATAGUS_BIN
|
||||
#endif
|
||||
|
||||
#if ! defined (GAME_NAME) || ! defined (GAME_CD) || ! defined (GAME)
|
||||
#if ! defined (GAME_NAME) || ! defined (GAME_CD) || ! defined (GAME) || ! defined(EXTRACTOR_TOOL)
|
||||
#error You need to define all Game macros, see stratagus-game-launcher.h
|
||||
#endif
|
||||
|
||||
#if ( defined (_MSC_VER) || defined (_WIN32) || defined (_WIN64) ) && ! defined (WIN32)
|
||||
#define WIN32
|
||||
#ifndef GAME_SHOULD_EXTRACT_AGAIN
|
||||
#define GAME_SHOULD_EXTRACT_AGAIN false
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def TITLE_PNG
|
||||
* OPTIONAL: Path to title screen (for testing if data was extracted)
|
||||
**/
|
||||
#ifndef TITLE_PNG
|
||||
#ifdef WIN32
|
||||
#define TITLE_PNG "%s\\graphics\\ui\\title.png"
|
||||
#else
|
||||
#define TITLE_PNG "%s/graphics/ui/title.png"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#if ! defined (DATA_PATH) || ! defined (SCRIPTS_PATH) || ! defined (STRATAGUS_BIN)
|
||||
#error You need to define paths, see stratagus-game-launcher.h
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define WINVER 0x0501
|
||||
#include <windows.h>
|
||||
#include <wincon.h>
|
||||
#include <process.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <direct.h>
|
||||
#define inline __inline
|
||||
#define chdir _chdir
|
||||
#define getcwd _getcwd
|
||||
#define spawnvp _spawnvp
|
||||
#define stat _stat
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#ifndef NOGTK
|
||||
#include <gtk/gtk.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
#define REGKEY "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Stratagus (64 bit)"
|
||||
#elif defined (WIN32)
|
||||
|
@ -179,66 +177,284 @@
|
|||
|
||||
#define TITLE GAME_NAME
|
||||
#define STRATAGUS_NOT_FOUND "Stratagus is not installed.\nYou need Stratagus to run " GAME_NAME "!\nFirst install Stratagus from https://launchpad.net/stratagus"
|
||||
#define DATA_NOT_EXTRACTED GAME_NAME " data was not extracted yet.\nYou need extract data from original " GAME_CD " first!"
|
||||
#define NO_X_DISPLAY "Cannot open X Display"
|
||||
#define CONSOLE_MODE_NOT_ROOT "You must be root to run " GAME_NAME " in console framebuffer mode"
|
||||
#define DATA_NOT_EXTRACTED GAME_NAME " data was not extracted, is corrupted, or outdated.\nYou need to extract it from original " GAME_CD "."
|
||||
|
||||
#define BUFF_SIZE 1024
|
||||
#include "stratagus-gameutils.h"
|
||||
|
||||
static void SetUserDataPath(char* data_path) {
|
||||
#if defined(WIN32)
|
||||
strcpy(data_path, getenv("APPDATA"));
|
||||
#else
|
||||
strcpy(data_path, getenv("HOME"));
|
||||
#endif
|
||||
int datalen = strlen(data_path);
|
||||
#if defined(WIN32)
|
||||
strcat(data_path, "\\Stratagus\\");
|
||||
#elif defined(USE_MAC)
|
||||
strcat(data_path, "/Library/Stratagus/");
|
||||
#else
|
||||
strcat(data_path, "/.stratagus/");
|
||||
#endif
|
||||
strcat(data_path, "data." GAME_NAME);
|
||||
}
|
||||
|
||||
int check_version(char* tool_path, char* data_path) {
|
||||
char buf[4096] = {'\0'};
|
||||
sprintf(buf, "%s/extracted" , data_path);
|
||||
FILE *f = fopen(buf, "r");
|
||||
char dataversion[20] = {'\0'};
|
||||
char toolversion[20] = {'\0'};
|
||||
if (f) {
|
||||
fgets(dataversion, 20, f);
|
||||
fclose(f);
|
||||
} else {
|
||||
#ifdef CHECK_EXTRACTED_VERSION
|
||||
return 0; // No file means we have a problem
|
||||
#else
|
||||
return 1; // No file means we don't care
|
||||
#endif
|
||||
}
|
||||
#ifndef WIN32
|
||||
int ConsoleMode = 0;
|
||||
sprintf(buf, "%s -V", tool_path);
|
||||
FILE *pipe = popen(buf, "r");
|
||||
if (f) {
|
||||
fgets(toolversion, 20, pipe);
|
||||
pclose(pipe);
|
||||
}
|
||||
#else
|
||||
sprintf(buf, "%s -V", tool_path); // tool_path is already quoted
|
||||
HANDLE g_hChildStd_OUT_Rd = NULL;
|
||||
HANDLE g_hChildStd_OUT_Wr = NULL;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))
|
||||
return 1;
|
||||
if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
|
||||
return 1;
|
||||
PROCESS_INFORMATION piProcInfo;
|
||||
STARTUPINFO siStartInfo;
|
||||
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
|
||||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
|
||||
siStartInfo.cb = sizeof(STARTUPINFO);
|
||||
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
|
||||
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
|
||||
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
if (!CreateProcess(NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo))
|
||||
return 1;
|
||||
CloseHandle(piProcInfo.hProcess);
|
||||
CloseHandle(piProcInfo.hThread);
|
||||
ReadFile(g_hChildStd_OUT_Rd, toolversion, 20, NULL, NULL);
|
||||
#endif
|
||||
// strip whitespace
|
||||
for (size_t i=0, j=0; toolversion[j]=toolversion[i]; j+=!isspace(toolversion[i++]));
|
||||
for (size_t i=0, j=0; dataversion[j]=dataversion[i]; j+=!isspace(dataversion[i++]));
|
||||
if (strcmp(dataversion, toolversion) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void error(char * title, char * text) {
|
||||
|
||||
static void ExtractData(char* extractor_tool, char* destination, char* scripts_path, int force=0) {
|
||||
if (force == 0) {
|
||||
tinyfd_messageBox("Missing data",
|
||||
DATA_NOT_EXTRACTED " Please select the " GAME_CD, "ok", "question", 1);
|
||||
} else if (force == 1) {
|
||||
tinyfd_messageBox("", "Please select the " GAME_CD, "ok", "question", 1);
|
||||
} else if (force == 2) {
|
||||
// pass
|
||||
}
|
||||
#ifdef USE_MAC
|
||||
int patterncount = 0;
|
||||
char* filepatterns[] = { NULL };
|
||||
// file types as names not working at least on macOS sierra
|
||||
#else
|
||||
char* filepatterns[] = { GAME_CD_FILE_PATTERNS, NULL };
|
||||
int patterncount = 0;
|
||||
while (filepatterns[patterncount++] != NULL);
|
||||
#endif
|
||||
const char* datafile = tinyfd_openFileDialog(GAME_CD " location", "",
|
||||
patterncount - 1, filepatterns, NULL, 0);
|
||||
if (datafile == NULL) {
|
||||
exit(-1);
|
||||
}
|
||||
char srcfolder[1024] = {'\0'};
|
||||
strcpy(srcfolder, datafile);
|
||||
char* sourcepath = strdup(scripts_path);
|
||||
#ifdef WIN32
|
||||
MessageBox(NULL, text, title, MB_OK | MB_ICONERROR);
|
||||
#else
|
||||
#ifdef NOGTK
|
||||
{
|
||||
#else
|
||||
if ( ! ConsoleMode ) {
|
||||
GtkWidget * window = NULL;
|
||||
GtkWidget * dialog = NULL;
|
||||
|
||||
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", text);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), title);
|
||||
gtk_window_set_skip_pager_hint(GTK_WINDOW(dialog), 0);
|
||||
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), 0);
|
||||
gtk_label_set_selectable(GTK_LABEL(GTK_MESSAGE_DIALOG(dialog)->label), 0);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
} else {
|
||||
#endif
|
||||
fprintf(stderr, "%s -- Error: %s\n", title, text);
|
||||
if (sourcepath[0] == '"') {
|
||||
// if scripts_path is quoted, remove the quotes, i.e.,
|
||||
// copy all but the first until all but the last char.
|
||||
// sourcepath is already large enough because it used to contain the
|
||||
// entire scripts_path
|
||||
strncpy(sourcepath, scripts_path + 1, strlen(scripts_path) - 2);
|
||||
sourcepath[strlen(scripts_path) - 2] = '\0';
|
||||
}
|
||||
#endif
|
||||
exit(1);
|
||||
mkdir_p(destination);
|
||||
|
||||
parentdir(srcfolder);
|
||||
|
||||
struct stat st;
|
||||
if (stat(sourcepath, &st) != 0) {
|
||||
// deployment time path not found, try compile time path
|
||||
strcpy(sourcepath, SRC_PATH());
|
||||
parentdir(sourcepath);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (stat(sourcepath, &st) != 0) {
|
||||
// deployment time path might be same as extractor
|
||||
strcpy(sourcepath, extractor_tool);
|
||||
parentdir(sourcepath);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stat(sourcepath, &st) != 0) {
|
||||
// scripts not found, abort!
|
||||
tinyfd_messageBox("Error", "There was an error copying the data, could not discover contributed directory path.", "ok", "error", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (force != 2) {
|
||||
char contrib_src_path[BUFF_SIZE];
|
||||
char contrib_dest_path[BUFF_SIZE];
|
||||
int i = 0;
|
||||
int optional = 0;
|
||||
char* contrib_directories[] = CONTRIB_DIRECTORIES;
|
||||
while (contrib_directories[i] != NULL && contrib_directories[i + 1] != NULL) {
|
||||
if (!strcmp(contrib_directories[i], ":optional:")) {
|
||||
i += 1;
|
||||
optional = 1;
|
||||
} else {
|
||||
if (contrib_directories[i][0] != '/') {
|
||||
// absolute Unix paths are not appended to the source path
|
||||
strcpy(contrib_src_path, sourcepath);
|
||||
strcat(contrib_src_path, SLASH);
|
||||
strcat(contrib_src_path, contrib_directories[i]);
|
||||
} else {
|
||||
strcpy(contrib_src_path, contrib_directories[i]);
|
||||
}
|
||||
|
||||
if (stat(contrib_src_path, &st) != 0) {
|
||||
// contrib dir not found, abort!
|
||||
if (!optional) {
|
||||
tinyfd_messageBox(contrib_directories[i], "There was an error copying the data, could not discover contributed directory path.", "ok", "error", 1);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
strcpy(contrib_dest_path, destination);
|
||||
strcat(contrib_dest_path, SLASH);
|
||||
strcat(contrib_dest_path, contrib_directories[i + 1]);
|
||||
copy_dir(contrib_src_path, contrib_dest_path);
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char cmdbuf[4096] = {'\0'};
|
||||
#ifdef USE_MAC
|
||||
strcat(cmdbuf, "osascript -e \"tell application \\\"Terminal\\\"\n"
|
||||
" set w to do script \\\"");
|
||||
#elif defined(WIN32)
|
||||
strcat(cmdbuf, "/C \"");
|
||||
#else
|
||||
if (!isatty(1)) {
|
||||
strcat(cmdbuf, "xterm -e bash -c ");
|
||||
strcat(cmdbuf, " \"");
|
||||
}
|
||||
#endif
|
||||
strcat(cmdbuf, extractor_tool);
|
||||
strcat(cmdbuf, " " QUOTE);
|
||||
strcat(cmdbuf, srcfolder);
|
||||
strcat(cmdbuf, QUOTE " " QUOTE);
|
||||
strcat(cmdbuf, destination);
|
||||
strcat(cmdbuf, QUOTE);
|
||||
#ifdef USE_MAC
|
||||
strcat(cmdbuf, "; exit\\\"\n"
|
||||
" repeat\n"
|
||||
" delay 1\n"
|
||||
" if not busy of w then exit repeat\n"
|
||||
" end repeat\n"
|
||||
"end tell\"");
|
||||
#elif defined(WIN32)
|
||||
strcat(cmdbuf, "\"");
|
||||
#else
|
||||
if (!isatty(1)) {
|
||||
strcat(cmdbuf, "; echo 'Press RETURN to continue...'; read\"");
|
||||
}
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
DWORD exitcode = 0;
|
||||
SHELLEXECUTEINFO ShExecInfo = { 0 };
|
||||
char* toolpath = strdup(extractor_tool);
|
||||
if (PathRemoveFileSpec(toolpath)) {
|
||||
// remove the leading quote
|
||||
if (toolpath[0] == '"') memmove(toolpath, toolpath + 1, strlen(toolpath) + 1);
|
||||
} else {
|
||||
// nothing was removed, use current dir
|
||||
toolpath = NULL;
|
||||
}
|
||||
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
ShExecInfo.hwnd = NULL;
|
||||
ShExecInfo.lpVerb = NULL;
|
||||
ShExecInfo.lpFile = "cmd";
|
||||
ShExecInfo.lpParameters = cmdbuf;
|
||||
ShExecInfo.lpDirectory = toolpath;
|
||||
ShExecInfo.nShow = SW_SHOW;
|
||||
ShExecInfo.hInstApp = NULL;
|
||||
ShellExecuteEx(&ShExecInfo);
|
||||
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
|
||||
GetExitCodeProcess(ShExecInfo.hProcess, &exitcode);
|
||||
#else
|
||||
int exitcode = 0;
|
||||
exitcode = system(cmdbuf);
|
||||
#endif
|
||||
if (exitcode != 0) {
|
||||
char* extractortext = (char*)calloc(sizeof(char), strlen(cmdbuf) + 1024);
|
||||
sprintf(extractortext, "The following command was used to extract the data\n%s", cmdbuf);
|
||||
tinyfd_messageBox("Extraction failed!", extractortext, "ok", "error", 1);
|
||||
unlink(destination);
|
||||
} else if (GAME_SHOULD_EXTRACT_AGAIN) {
|
||||
ExtractData(extractor_tool, destination, scripts_path, 2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
#ifndef WIN32
|
||||
if ( ! XOpenDisplay(NULL) ) {
|
||||
ConsoleMode = 1;
|
||||
}
|
||||
if ( ConsoleMode ) {
|
||||
if ( getuid() != 0 ) {
|
||||
error(TITLE, CONSOLE_MODE_NOT_ROOT);
|
||||
}
|
||||
} else {
|
||||
#ifndef NOGTK
|
||||
gtk_init(&argc, &argv);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
struct stat st;
|
||||
int argccpy = argc;
|
||||
char data_path[BUFF_SIZE];
|
||||
char scripts_path[BUFF_SIZE];
|
||||
char stratagus_bin[BUFF_SIZE];
|
||||
char title_path[BUFF_SIZE];
|
||||
char extractor_path[BUFF_SIZE];
|
||||
|
||||
strcat(extractor_path, EXTRACTOR_TOOL);
|
||||
if (!detectPresence(extractor_path)) {
|
||||
// The extractor is in the same dir as we are
|
||||
if (strchr(argv[0], SLASH[0])) {
|
||||
strcpy(extractor_path, argv[0]);
|
||||
parentdir(extractor_path);
|
||||
strcat(extractor_path, SLASH EXTRACTOR_TOOL);
|
||||
#ifdef WIN32
|
||||
if (!strstr(extractor_path, ".exe")) {
|
||||
strcat(extractor_path, ".exe");
|
||||
}
|
||||
#endif
|
||||
// Once we have the path, we quote it by moving the memory one byte to the
|
||||
// right, and surrounding it with the quote character and finishing null
|
||||
// bytes. Then we add the arguments.
|
||||
extractor_path[strlen(extractor_path) + 1] = '\0';
|
||||
memmove(extractor_path + 1, extractor_path, strlen(extractor_path));
|
||||
extractor_path[0] = QUOTE[0];
|
||||
extractor_path[strlen(extractor_path) + 1] = '\0';
|
||||
extractor_path[strlen(extractor_path)] = QUOTE[0];
|
||||
}
|
||||
}
|
||||
strcat(extractor_path, " " EXTRACTOR_ARGS);
|
||||
|
||||
#ifdef WIN32
|
||||
char executable_path[BUFF_SIZE];
|
||||
|
@ -264,41 +480,102 @@ int main(int argc, char * argv[]) {
|
|||
if (data_path_length != 0 && data_path[data_path_length - 1] == '\\') {
|
||||
data_path[data_path_length - 1] = '\0';
|
||||
}
|
||||
sprintf(scripts_path, "\"%s\"", data_path);
|
||||
|
||||
char stratagus_path[BUFF_SIZE];
|
||||
DWORD stratagus_path_size = sizeof(stratagus_path);
|
||||
memset(stratagus_path, 0, stratagus_path_size);
|
||||
HKEY key;
|
||||
|
||||
if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS ) {
|
||||
if ( RegQueryValueEx(key, "InstallLocation", NULL, NULL, (LPBYTE) stratagus_path, &stratagus_path_size) == ERROR_SUCCESS ) {
|
||||
if ( stratagus_path_size == 0 || strlen(stratagus_path) == 0 ) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
// Try to use stratagus.exe from data (install) directory first
|
||||
sprintf(stratagus_bin, "%s\\stratagus.exe", data_path);
|
||||
if (stat(stratagus_bin, &st) != 0) {
|
||||
// If no local stratagus.exe is present, look for a globally installed version
|
||||
DWORD stratagus_path_size = sizeof(stratagus_path);
|
||||
memset(stratagus_path, 0, stratagus_path_size);
|
||||
HKEY key;
|
||||
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueEx(key, "InstallLocation", NULL, NULL, (LPBYTE)stratagus_path, &stratagus_path_size) == ERROR_SUCCESS) {
|
||||
if (stratagus_path_size == 0 || strlen(stratagus_path) == 0) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
if ( chdir(stratagus_path) != 0 ) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
if (chdir(stratagus_path) != 0) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
}
|
||||
sprintf(stratagus_bin, "%s\\stratagus.exe", stratagus_path);
|
||||
}
|
||||
sprintf(scripts_path, "\"%s\"", data_path);
|
||||
sprintf(stratagus_bin, "%s\\stratagus.exe", stratagus_path);
|
||||
#ifdef DATA_PATH
|
||||
// usually this isn't defined for windows builds. if it is, use it
|
||||
strcpy(data_path, DATA_PATH);
|
||||
#endif
|
||||
#else
|
||||
strcpy(data_path, DATA_PATH);
|
||||
strcpy(scripts_path, SCRIPTS_PATH);
|
||||
strcpy(stratagus_bin, STRATAGUS_BIN);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strcmp(argv[1], "--extract")) {
|
||||
// Force extraction and exit
|
||||
SetUserDataPath(data_path);
|
||||
ExtractData(extractor_path, data_path, scripts_path, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "--extract-no-gui")) {
|
||||
// Force extraction without ui and exit
|
||||
tinyfd_forceConsole = 1;
|
||||
SetUserDataPath(data_path);
|
||||
ExtractData(extractor_path, data_path, scripts_path, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( stat(stratagus_bin, &st) != 0 ) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
}
|
||||
if ( stat(data_path, &st) != 0 ) {
|
||||
error(TITLE, DATA_NOT_EXTRACTED);
|
||||
#ifdef WIN32
|
||||
_fullpath(stratagus_bin, argv[0], BUFF_SIZE);
|
||||
PathRemoveFileSpec(stratagus_bin);
|
||||
strcat(extractor_path, "\\stratagus.exe");
|
||||
if (stat(stratagus_bin, &st) != 0) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
}
|
||||
#else
|
||||
if (!detectPresence(stratagus_bin)) {
|
||||
realpath(argv[0], stratagus_bin);
|
||||
parentdir(stratagus_bin);
|
||||
if (strlen(stratagus_bin) > 0) {
|
||||
strcat(stratagus_bin, "/stratagus");
|
||||
} else {
|
||||
strcat(stratagus_bin, "./stratagus");
|
||||
}
|
||||
if ( stat(stratagus_bin, &st) != 0 ) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
sprintf(title_path, TITLE_PNG, data_path);
|
||||
if ( stat(title_path, &st) != 0 ) {
|
||||
SetUserDataPath(data_path);
|
||||
sprintf(title_path, TITLE_PNG, data_path);
|
||||
if ( stat(title_path, &st) != 0 ) {
|
||||
ExtractData(extractor_path, data_path, scripts_path);
|
||||
}
|
||||
if ( stat(title_path, &st) != 0 ) {
|
||||
error(TITLE, DATA_NOT_EXTRACTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_version(extractor_path, data_path)) {
|
||||
ExtractData(extractor_path, data_path, scripts_path);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
int data_path_len = strlen(data_path);
|
||||
_chdir(data_path);
|
||||
|
||||
for (int i = data_path_len - 1; i >= 0; --i) {
|
||||
data_path[i + 1] = data_path[i];
|
||||
|
@ -308,17 +585,6 @@ int main(int argc, char * argv[]) {
|
|||
data_path[data_path_len + 2] = 0;
|
||||
#endif
|
||||
|
||||
if ( stat(title_path, &st) != 0 ) {
|
||||
error(TITLE, DATA_NOT_EXTRACTED);
|
||||
}
|
||||
#ifndef WIN32
|
||||
if ( strcmp(data_path, scripts_path) != 0 ) {
|
||||
if ( chdir(data_path) != 0 ) {
|
||||
error(TITLE, DATA_NOT_EXTRACTED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
char** stratagus_argv;
|
||||
stratagus_argv = (char**) malloc((argc + 3) * sizeof (*stratagus_argv));
|
||||
|
@ -339,7 +605,7 @@ int main(int argc, char * argv[]) {
|
|||
#endif
|
||||
|
||||
stratagus_argv[1] = "-d";
|
||||
stratagus_argv[2] = scripts_path;
|
||||
stratagus_argv[2] = data_path;
|
||||
|
||||
for (int i = 3; i < argc + 2; ++i ) {
|
||||
stratagus_argv[i] = argv[i - 2];
|
||||
|
@ -347,20 +613,38 @@ int main(int argc, char * argv[]) {
|
|||
stratagus_argv[argc + 2] = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
errno = 0;
|
||||
int ret = spawnvp(_P_WAIT, stratagus_bin, stratagus_argv);
|
||||
#ifdef _MSC_VER
|
||||
free (stratagus_argv);
|
||||
#endif
|
||||
if ( errno == 0 ) {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
execvp(stratagus_bin, stratagus_argv);
|
||||
int ret = 0;
|
||||
int childpid = fork();
|
||||
if (childpid == 0) {
|
||||
execvp(stratagus_bin, stratagus_argv);
|
||||
if (strcmp(stratagus_bin, "stratagus") == 0) {
|
||||
realpath(argv[0], stratagus_bin);
|
||||
parentdir(stratagus_bin);
|
||||
strcat(stratagus_bin, "/stratagus");
|
||||
}
|
||||
execvp(stratagus_bin, stratagus_argv);
|
||||
exit(ENOENT);
|
||||
} else if (childpid > 0) {
|
||||
waitpid(childpid, &ret, 0);
|
||||
} else {
|
||||
ret = ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
return 1;
|
||||
if (ret == ENOENT) {
|
||||
error(TITLE, STRATAGUS_NOT_FOUND);
|
||||
} else if (ret != 0) {
|
||||
char message[8096] = {'\0'};
|
||||
snprintf(message, 8096,
|
||||
"Stratagus failed to load game data. "
|
||||
"If you just launched the game without any arguments, this may indicate a bug with the extraction process. "
|
||||
"Please report this on https://github.com/Wargus/stratagus/issues/new, "
|
||||
"and please give details, including: operating system, installation path, username, kind of source CD. "
|
||||
"A possible solution is to remove the hidden folder %s).", data_path);
|
||||
error(TITLE, message);
|
||||
unlink(title_path);
|
||||
unlink(data_path);
|
||||
}
|
||||
exit(ret);
|
||||
}
|
||||
|
|
191
gameheaders/stratagus-gameutils.h
Normal file
191
gameheaders/stratagus-gameutils.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
_________ __ __
|
||||
/ _____// |_____________ _/ |______ ____ __ __ ______
|
||||
\_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
/ \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
/_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
\/ \/ \//_____/ \/
|
||||
______________________ ______________________
|
||||
T H E W A R B E G I N S
|
||||
Stratagus - A free fantasy real time strategy game engine
|
||||
|
||||
stratagus-game-launcher.h - Stratagus Game Launcher
|
||||
Copyright (C) 2015-2016 The Stratagus Developers
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void error(const char* title, const char* text);
|
||||
void mkdir_p(const char* path);
|
||||
void copy_dir(const char* source_folder, const char* target_folder);
|
||||
|
||||
#if __APPLE__
|
||||
#define USE_MAC
|
||||
#endif
|
||||
|
||||
#if ( defined (_MSC_VER) || defined (_WIN32) || defined (_WIN64) ) && ! defined (WIN32)
|
||||
#define WIN32 1
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Shlwapi.h>
|
||||
#pragma comment(lib, "comdlg32.lib")
|
||||
#pragma comment(lib, "ole32.lib")
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#include <direct.h>
|
||||
//#define inline __inline
|
||||
#define chdir _chdir
|
||||
#define getcwd _getcwd
|
||||
#define spawnvp _spawnvp
|
||||
#define stat _stat
|
||||
#define strdup _strdup
|
||||
#define mkdir(f, m) _mkdir(f)
|
||||
// PathRemoveFileSpec on a drive (e.g. when extracting from CD) will leave the trailing \... remove that
|
||||
#define parentdir(x) PathRemoveFileSpec(x); if (x[strlen(x) - 1] == '\\') x[strlen(x) - 1] = '\0'
|
||||
#define execvp _execvp
|
||||
#define unlink(x) _unlink(x)
|
||||
#else
|
||||
#if defined(USE_MAC)
|
||||
#define parentdir(x) strcpy(x, dirname(x))
|
||||
#else
|
||||
#define parentdir(x) dirname(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <wincon.h>
|
||||
#include <process.h>
|
||||
#define QUOTE "\""
|
||||
#else
|
||||
#include <ftw.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/wait.h>
|
||||
#define QUOTE "'"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "stratagus-tinyfiledialogs.h"
|
||||
|
||||
#define BUFF_SIZE 4096
|
||||
char dst_root[BUFF_SIZE];
|
||||
char src_root[BUFF_SIZE];
|
||||
|
||||
void error(const char* title, const char* text) {
|
||||
tinyfd_messageBox(title, text, "ok", "error", 1);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void mkdir_p(const char* path) {
|
||||
int error = 0;
|
||||
printf("mkdir %s\n", path);
|
||||
if (mkdir(path, 0777)) {
|
||||
error = errno;
|
||||
if (error == ENOENT) {
|
||||
char *sep = strrchr((char*)path, '/');
|
||||
if (sep == NULL) {
|
||||
sep = strrchr((char*)path, SLASH[0]);
|
||||
}
|
||||
if (sep != NULL) {
|
||||
*sep = '\0';
|
||||
if (strlen(path) > 0) {
|
||||
// will be null if the we reach the first /
|
||||
mkdir_p(path);
|
||||
}
|
||||
*sep = '/';
|
||||
}
|
||||
} else if (error != EEXIST) {
|
||||
if (mkdir(path, 0777)) {
|
||||
printf("Error while trying to create '%s'\n", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#include <wchar.h>
|
||||
#include <string>
|
||||
void copy_dir(const char* source_folder, const char* target_folder)
|
||||
{
|
||||
wchar_t *wsource_folder = new wchar_t[strlen(source_folder) + 1];
|
||||
size_t convertedChars = 0;
|
||||
mbstowcs_s(&convertedChars, wsource_folder, strlen(source_folder) + 1, source_folder, _TRUNCATE);
|
||||
wchar_t *wtarget_folder = new wchar_t[strlen(target_folder) + 1];
|
||||
mbstowcs_s(&convertedChars, wtarget_folder, strlen(target_folder) + 1, target_folder, _TRUNCATE);
|
||||
WCHAR sf[MAX_PATH + 1];
|
||||
WCHAR tf[MAX_PATH + 1];
|
||||
wcscpy_s(sf, MAX_PATH, wsource_folder);
|
||||
char* ptarget = strdup(target_folder);
|
||||
parentdir(ptarget);
|
||||
mkdir_p(ptarget);
|
||||
wcscpy_s(tf, MAX_PATH, wtarget_folder);
|
||||
sf[lstrlenW(sf) + 1] = 0;
|
||||
tf[lstrlenW(tf) + 1] = 0;
|
||||
SHFILEOPSTRUCTW s = { 0 };
|
||||
s.wFunc = FO_COPY;
|
||||
s.pTo = tf;
|
||||
s.pFrom = sf;
|
||||
s.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI;
|
||||
SHFileOperationW(&s);
|
||||
}
|
||||
#else
|
||||
int copy_file(const char* src_path, const struct stat* sb, int typeflag) {
|
||||
char dst_path[BUFF_SIZE];
|
||||
printf("%s to %s\n", src_path, dst_root);
|
||||
strcpy(dst_path, dst_root);
|
||||
strcat(dst_path, src_path + strlen(src_root));
|
||||
switch(typeflag) {
|
||||
case FTW_D:
|
||||
mkdir_p(dst_path);
|
||||
break;
|
||||
case FTW_F:
|
||||
mkdir_p(parentdir(strdup(dst_path)));
|
||||
FILE* in = fopen(src_path, "rb");
|
||||
FILE* out = fopen(dst_path, "wb");
|
||||
char buf[4096];
|
||||
int c = 0;
|
||||
if (!in) {
|
||||
error("Extraction error", "Could not open source folder for reading.");
|
||||
}
|
||||
if (!out) {
|
||||
error("Extraction error", "Could not open data folder for writing.");
|
||||
}
|
||||
while (c = fread(buf, sizeof(char), 4096, in)) {
|
||||
fwrite(buf, sizeof(char), c, out);
|
||||
}
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void copy_dir(const char* src_path, const char* dst_path) {
|
||||
printf("Copying %s to %s\n", src_path, dst_path);
|
||||
mkdir_p(parentdir(strdup(dst_path)));
|
||||
strcpy(dst_root, dst_path);
|
||||
strcpy(src_root, src_path);
|
||||
ftw(src_path, copy_file, 20);
|
||||
}
|
||||
#endif
|
4491
gameheaders/stratagus-tinyfiledialogs.h
Normal file
4491
gameheaders/stratagus-tinyfiledialogs.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -329,6 +329,7 @@ static void ParseCreateGame(Session *session, char *buf)
|
|||
CreateGame(session, description, map, players, ip, port, password);
|
||||
|
||||
DebugPrint("%s created a game\n" _C_ session->UserData.Name);
|
||||
DBAddGame(session->Game->ID, description, map, players_int);
|
||||
Send(session, "CREATEGAME_OK\n");
|
||||
}
|
||||
|
||||
|
@ -399,13 +400,15 @@ static void ParseJoinGame(Session *session, char *buf)
|
|||
char *id;
|
||||
char *password;
|
||||
int ret;
|
||||
unsigned long udphost;
|
||||
int udpport;
|
||||
|
||||
if (Parse1or2Args(buf, &id, &password)) {
|
||||
Send(session, "ERR_BADPARAMETER\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = JoinGame(session, atoi(id), password);
|
||||
ret = JoinGame(session, atoi(id), password, &udphost, &udpport);
|
||||
if (ret == -1) {
|
||||
Send(session, "ERR_ALREADYINGAME\n");
|
||||
return;
|
||||
|
@ -422,10 +425,16 @@ static void ParseJoinGame(Session *session, char *buf)
|
|||
} else if (ret == -4) {
|
||||
Send(session, "ERR_GAMEFULL\n");
|
||||
return;
|
||||
} else if (ret == -5) {
|
||||
Send(session, "ERR_SERVERNOTREADY\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DebugPrint("%s joined game %d\n" _C_ session->UserData.Name _C_ atoi(id));
|
||||
Send(session, "JOINGAME_OK\n");
|
||||
char* reply = (char*)calloc(sizeof(char), strlen("JOINGAME_OK 255.255.255.255 66535\n") + 1);
|
||||
sprintf(reply, "JOINGAME_OK %d.%d.%d.%d %d\n", NIPQUAD(ntohl(UDPHost)), udpport);
|
||||
DebugPrint("%s joined game %d with %s\n" _C_ session->UserData.Name _C_ atoi(id) _C_ reply);
|
||||
Send(session, reply);
|
||||
free(reply);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -467,6 +476,30 @@ static void ParseEndGame(Session *session, char *buf)
|
|||
Send(session, "ENDGAME_OK\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Parse STATS
|
||||
*/
|
||||
static void ParseStats(Session *session, char *buf)
|
||||
{
|
||||
char *result;
|
||||
int start_time = 0;
|
||||
char resultbuf[20] = {'\0'};
|
||||
|
||||
while (*buf == ' ') ++buf;
|
||||
if (*buf) {
|
||||
Parse1Arg(buf, &result);
|
||||
start_time = atoi(result);
|
||||
}
|
||||
|
||||
DebugPrint("%s requested stats\n" _C_ session->UserData.Name);
|
||||
char* reply = (char*)calloc(sizeof(char), strlen("GAMES SINCE 12345678901234567890: 12345678901234567890\n") + 1);
|
||||
DBStats(resultbuf, start_time);
|
||||
sprintf(reply, "GAMES SINCE %d: %s\n", start_time, resultbuf);
|
||||
Send(session, reply);
|
||||
Send(session, "STATS_OK\n");
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse MSG
|
||||
*/
|
||||
|
@ -490,19 +523,19 @@ static void ParseBuffer(Session *session)
|
|||
buf = session->Buffer;
|
||||
if (!strncmp(buf, "PING", 4)) {
|
||||
ParsePing(session);
|
||||
} else if (!session->UserData.LoggedIn) {
|
||||
if (!strncmp(buf, "USER ", 5)) {
|
||||
ParseUser(session, buf + 5);
|
||||
} else if (!strncmp(buf, "REGISTER ", 9)) {
|
||||
ParseRegister(session, buf + 9);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown command: %s\n", session->Buffer);
|
||||
Send(session, "ERR_BADCOMMAND\n");
|
||||
}
|
||||
} else {
|
||||
if (!strncmp(buf, "USER ", 5) || !strncmp(buf, "REGISTER ", 9)) {
|
||||
Send(session, "ERR_ALREADYLOGGEDIN\n");
|
||||
} else if (!strncmp(buf, "CREATEGAME ", 11)) {
|
||||
if (!session->UserData.LoggedIn) {
|
||||
if (!strncmp(buf, "USER ", 5)) {
|
||||
ParseUser(session, buf + 5);
|
||||
} else if (!strncmp(buf, "REGISTER ", 9)) {
|
||||
ParseRegister(session, buf + 9);
|
||||
}
|
||||
} else {
|
||||
if (!strncmp(buf, "USER ", 5) || !strncmp(buf, "REGISTER ", 9)) {
|
||||
Send(session, "ERR_ALREADYLOGGEDIN\n");
|
||||
}
|
||||
}
|
||||
if (!strncmp(buf, "CREATEGAME ", 11)) {
|
||||
ParseCreateGame(session, buf + 11);
|
||||
} else if (!strcmp(buf, "CANCELGAME") || !strncmp(buf, "CANCELGAME ", 11)) {
|
||||
ParseCancelGame(session, buf + 10);
|
||||
|
@ -516,6 +549,8 @@ static void ParseBuffer(Session *session)
|
|||
ParsePartGame(session, buf + 8);
|
||||
} else if (!strncmp(buf, "ENDGAME ", 8)) {
|
||||
ParseEndGame(session, buf + 8);
|
||||
} else if (!strncmp(buf, "STATS ", 6)) {
|
||||
ParseStats(session, buf + 6);
|
||||
} else if (!strncmp(buf, "MSG ", 4)) {
|
||||
ParseMsg(session, buf + 4);
|
||||
} else {
|
||||
|
@ -556,6 +591,26 @@ int UpdateParser(void)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
if (strlen(UDPBuffer)) {
|
||||
// If this is a server, we'll note its external data. When clients join,
|
||||
// they'll receive this as part of the TCP response that they
|
||||
// successfully joined. This is a simplification of the full UDP hole
|
||||
// punching algorithm, which unneccessarily might go through the NAT
|
||||
// even for clients inside the same NAT. This will also not work if in
|
||||
// that case the NAT does not support hairpin translation. But we'll see
|
||||
// how common that is...
|
||||
char ip[128] = {'\0'};
|
||||
char port[128] = {'\0'};
|
||||
sscanf(UDPBuffer, "%s %s", (char*)&ip, (char*)&port);
|
||||
DebugPrint("Filling in UDP info for %s:%s\n" _C_ ip _C_ port);
|
||||
if (FillinUDPInfo(UDPHost, UDPPort, ip, port)) {
|
||||
fprintf(stderr, "Error filling in UDP info for %s:%s with %d.%d.%d.%d:%d",
|
||||
ip, port, NIPQUAD(ntohl(UDPHost)), UDPPort);
|
||||
}
|
||||
UDPBuffer[0] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,10 +59,11 @@ static sqlite3 *DB;
|
|||
|
||||
#define SQLCreateGamesTable \
|
||||
"CREATE TABLE games (" \
|
||||
"date INTEGER," \
|
||||
"id INTEGER PRIMARY KEY," \
|
||||
"date INTEGER," \
|
||||
"gamename TEXT," \
|
||||
"map_id INTEGER" \
|
||||
"mapname TEXT," \
|
||||
"slots INTEGER" \
|
||||
");"
|
||||
|
||||
#define SQLCreateGameDataTable \
|
||||
|
@ -112,8 +113,10 @@ static sqlite3 *DB;
|
|||
static int DBMaxIDCallback(void *password, int argc, char **argv, char **colname)
|
||||
{
|
||||
Assert(argc == 1);
|
||||
if (argv[0])
|
||||
GameID = atoi(argv[0]);
|
||||
if (argv[0]) {
|
||||
GameID = atoi(argv[0]) + 1;
|
||||
}
|
||||
fprintf(stderr, "Current max game id is %d\n", GameID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -141,15 +144,13 @@ int DBInit(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!doinit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
errmsg = NULL;
|
||||
if (sqlite3_exec(DB, SQLCreateTables, NULL, NULL, &errmsg) != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
return -1;
|
||||
if (doinit) {
|
||||
errmsg = NULL;
|
||||
if (sqlite3_exec(DB, SQLCreateTables, NULL, NULL, &errmsg) != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
errmsg = NULL;
|
||||
|
@ -259,3 +260,44 @@ int DBUpdateLoginDate(char *username)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DBAddGame(int id, char *description, char *mapname, int numplayers)
|
||||
{
|
||||
char buf[1024];
|
||||
int t;
|
||||
char *errmsg;
|
||||
|
||||
t = (int)time(0);
|
||||
sprintf(buf, "INSERT INTO games VALUES(%d, %d, '%s', '%s', %d);",
|
||||
id, t, description, mapname, numplayers);
|
||||
if (sqlite3_exec(DB, buf, NULL, NULL, &errmsg) != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DBStatsCallback(void *resultbuf, int argc, char **argv, char **colname)
|
||||
{
|
||||
Assert(argc == 1);
|
||||
strcpy((char *)resultbuf, argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DBStats(char* resultbuf, int start_time)
|
||||
{
|
||||
char buf[1024];
|
||||
int t;
|
||||
char *errmsg;
|
||||
|
||||
t = (int)time(0);
|
||||
sprintf(buf, "SELECT COUNT(id) FROM games WHERE date > %d;", start_time);
|
||||
if (sqlite3_exec(DB, buf, DBStatsCallback, resultbuf, &errmsg) != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ extern void DBQuit(void);
|
|||
extern int DBFindUser(char *username, char *password);
|
||||
extern int DBAddUser(char *username, char *password);
|
||||
extern int DBUpdateLoginDate(char *username);
|
||||
extern int DBAddGame(int id, char *description, char *mapname, int numplayers);
|
||||
extern int DBStats(char *results, int resultlen);
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ void CreateGame(Session *session, char *description, char *map,
|
|||
|
||||
strcpy(game->IP, ip);
|
||||
strcpy(game->Port, port);
|
||||
game->UDPHost = 0;
|
||||
game->UDPPort = 0;
|
||||
strcpy(game->Description, description);
|
||||
strcpy(game->Map, map);
|
||||
game->MaxSlots = atoi(players);
|
||||
|
@ -89,6 +91,9 @@ void CreateGame(Session *session, char *description, char *map,
|
|||
game->Prev = NULL;
|
||||
Games = game;
|
||||
|
||||
if (session->Game) {
|
||||
PartGame(session);
|
||||
}
|
||||
session->Game = game;
|
||||
}
|
||||
|
||||
|
@ -120,6 +125,7 @@ int CancelGame(Session *session)
|
|||
game->Sessions[i]->Game = NULL;
|
||||
}
|
||||
|
||||
session->Game = NULL;
|
||||
delete game;
|
||||
return 0;
|
||||
}
|
||||
|
@ -140,12 +146,12 @@ int StartGame(Session *session)
|
|||
/**
|
||||
** Join a game
|
||||
*/
|
||||
int JoinGame(Session *session, int id, char *password)
|
||||
int JoinGame(Session *session, int id, char *password, unsigned long *host, int *port)
|
||||
{
|
||||
GameData *game;
|
||||
|
||||
if (session->Game) {
|
||||
return -1; // Already in a game
|
||||
PartGame(session);
|
||||
}
|
||||
|
||||
game = Games;
|
||||
|
@ -167,6 +173,12 @@ int JoinGame(Session *session, int id, char *password)
|
|||
if (!game->OpenSlots) {
|
||||
return -4; // Game full
|
||||
}
|
||||
if (!(game->UDPHost && game->UDPPort)) {
|
||||
return -5; // Server not ready
|
||||
}
|
||||
|
||||
*host = game->UDPHost;
|
||||
*port = game->UDPPort;
|
||||
game->Sessions[game->NumSessions++] = session;
|
||||
session->Game = game;
|
||||
|
||||
|
@ -213,8 +225,9 @@ int PartGame(Session *session)
|
|||
|
||||
static int MatchGameType(Session *session, GameData *game)
|
||||
{
|
||||
return (!*game->GameName || !strcmp(session->UserData.GameName, game->GameName)) &&
|
||||
(!*game->Version || !strcmp(session->UserData.Version, game->Version));
|
||||
return (!session->UserData.LoggedIn) ||
|
||||
((!*game->GameName ||!strcmp(session->UserData.GameName, game->GameName)) &&
|
||||
(!*game->Version || !strcmp(session->UserData.Version, game->Version)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,3 +249,17 @@ void ListGames(Session *session)
|
|||
game = game->Next;
|
||||
}
|
||||
}
|
||||
|
||||
int FillinUDPInfo(unsigned long udphost, int udpport, char* ip, char* port) {
|
||||
GameData *game;
|
||||
for (game = Games; game; game = Games->Next) {
|
||||
if (!strcmp(game->IP, ip) && !strcmp(game->Port, port)) {
|
||||
if (!game->UDPHost && !game->UDPPort) {
|
||||
game->UDPHost = udphost;
|
||||
game->UDPPort = udpport;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,9 @@ public:
|
|||
int ID;
|
||||
int Started;
|
||||
|
||||
unsigned long UDPHost;
|
||||
int UDPPort;
|
||||
|
||||
GameData *Next;
|
||||
GameData *Prev;
|
||||
};
|
||||
|
@ -79,9 +82,10 @@ extern void CreateGame(Session *session, char *description, char *map,
|
|||
char *players, char *ip, char *port, char *password);
|
||||
extern int CancelGame(Session *session);
|
||||
extern int StartGame(Session *session);
|
||||
extern int JoinGame(Session *session, int id, char *password);
|
||||
extern int JoinGame(Session *session, int id, char *password, unsigned long *host, int *port);
|
||||
extern int PartGame(Session *session);
|
||||
extern void ListGames(Session *session);
|
||||
extern int FillinUDPInfo(unsigned long udphost, int udpport, char* ip, char* port);
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ int main(int argc, char **argv)
|
|||
//
|
||||
// Parse the command line.
|
||||
//
|
||||
while ((i = getopt(argc, argv, "aP:pm:i:d:")) != -1) {
|
||||
while ((i = getopt(argc, argv, "aP:pm:i:d:h")) != -1) {
|
||||
switch (i) {
|
||||
case 'a':
|
||||
EnableAssert = true;
|
||||
|
@ -250,6 +250,16 @@ int main(int argc, char **argv)
|
|||
printf("Missing argument for %c\n", optopt);
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
printf("Arguments:\n"
|
||||
"-a\tEnable asserts\n"
|
||||
"-P\tSet port\n"
|
||||
"-p\tEnable debug print\n"
|
||||
"-m\tMax connections\n"
|
||||
"-i\tIdle timeout\n"
|
||||
"-d\tPolling delay\n");
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
printf("Unrecognized option: -%c\n", optopt);
|
||||
break;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#endif
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "games.h"
|
||||
#include "netdriver.h"
|
||||
#include "net_lowlevel.h"
|
||||
|
||||
|
@ -92,9 +93,13 @@
|
|||
----------------------------------------------------------------------------*/
|
||||
|
||||
static Socket MasterSocket;
|
||||
static Socket HolePunchSocket;
|
||||
|
||||
SessionPool *Pool;
|
||||
ServerStruct Server;
|
||||
char UDPBuffer[16 /* GameData->IP */ + 6 /* GameData->Port */ + 1] = {'\0'};
|
||||
unsigned long UDPHost = 0;
|
||||
int UDPPort = 0;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
|
@ -120,6 +125,7 @@ void Send(Session *session, const char *msg)
|
|||
*/
|
||||
int ServerInit(int port)
|
||||
{
|
||||
int code = 0;
|
||||
Pool = NULL;
|
||||
|
||||
if (NetInit() == -1) {
|
||||
|
@ -127,35 +133,42 @@ int ServerInit(int port)
|
|||
}
|
||||
|
||||
if ((MasterSocket = NetOpenTCP(NULL, port)) == (Socket)-1) {
|
||||
fprintf(stderr, "NetOpenTCP failed\n");
|
||||
return -2;
|
||||
fprintf(stderr, "NetOpenTCP failed\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((HolePunchSocket = NetOpenUDP(INADDR_ANY, port)) == (Socket)-1) {
|
||||
fprintf(stderr, "NetOpenUDP failed\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (NetSetNonBlocking(MasterSocket) == -1) {
|
||||
fprintf(stderr, "NetSetNonBlocking failed\n");
|
||||
NetCloseTCP(MasterSocket);
|
||||
NetExit();
|
||||
return -3;
|
||||
fprintf(stderr, "NetSetNonBlocking TCP failed\n");
|
||||
code = -3;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (NetSetNonBlocking(HolePunchSocket) == -1) {
|
||||
fprintf(stderr, "NetSetNonBlocking UDP failed\n");
|
||||
code = -3;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (NetListenTCP(MasterSocket) == -1) {
|
||||
fprintf(stderr, "NetListenTCP failed\n");
|
||||
NetCloseTCP(MasterSocket);
|
||||
NetExit();
|
||||
return -4;
|
||||
fprintf(stderr, "NetListenTCP failed\n");
|
||||
code = -4;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(Pool = new SessionPool)) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
NetCloseTCP(MasterSocket);
|
||||
NetExit();
|
||||
return -5;
|
||||
code = -5;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(Pool->Sockets = new SocketSet)) {
|
||||
NetCloseTCP(MasterSocket);
|
||||
NetExit();
|
||||
return -6;
|
||||
code = -6;
|
||||
goto error;
|
||||
}
|
||||
|
||||
Pool->First = NULL;
|
||||
|
@ -163,6 +176,12 @@ int ServerInit(int port)
|
|||
Pool->Count = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
NetCloseTCP(MasterSocket);
|
||||
NetCloseUDP(HolePunchSocket);
|
||||
NetExit();
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,6 +229,7 @@ static int KillSession(Session *session)
|
|||
NetCloseTCP(session->Sock);
|
||||
Pool->Sockets->DelSocket(session->Sock);
|
||||
UNLINK(Pool->First, session, Pool->Last, Pool->Count);
|
||||
PartGame(session);
|
||||
delete session;
|
||||
return 0;
|
||||
}
|
||||
|
@ -248,6 +268,10 @@ static void AcceptConnections()
|
|||
LINK(Pool->First, new_session, Pool->Last, Pool->Count);
|
||||
Pool->Sockets->AddSocket(new_socket);
|
||||
}
|
||||
if (NetSocketReady(HolePunchSocket, 0)) {
|
||||
NetRecvUDP(HolePunchSocket, UDPBuffer, sizeof(UDPBuffer), &UDPHost, &UDPPort);
|
||||
DebugPrint("New UDP %s (%d %d)\n" _C_ UDPBuffer _C_ UDPHost _C_ UDPPort);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -133,8 +133,11 @@ public:
|
|||
SocketSet *Sockets;
|
||||
};
|
||||
|
||||
/// external reference to session tracking.
|
||||
/// external reference to session tracking.
|
||||
extern SessionPool *Pool;
|
||||
extern char UDPBuffer[16 /* GameData->IP */ + 6 /* GameData->Port */ + 1];
|
||||
extern unsigned long UDPHost;
|
||||
extern int UDPPort;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
|
|
|
@ -103,6 +103,8 @@ void AnimateActionAttack(CUnit &unit, COrder &order)
|
|||
order->SetGoal(&target);
|
||||
order->Range = attacker.Stats->Variables[ATTACKRANGE_INDEX].Max;
|
||||
order->MinRange = attacker.Type->MinAttackRange;
|
||||
if (attacker.Type->BoolFlag[SKIRMISHER_INDEX].value)
|
||||
order->SkirmishRange = order->Range;
|
||||
|
||||
return order;
|
||||
}
|
||||
|
@ -121,6 +123,9 @@ void AnimateActionAttack(CUnit &unit, COrder &order)
|
|||
} else {
|
||||
order->goalPos = dest;
|
||||
}
|
||||
if (attacker.Type->BoolFlag[SKIRMISHER_INDEX].value)
|
||||
order->SkirmishRange = attacker.Stats->Variables[ATTACKRANGE_INDEX].Max;
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
|
@ -131,6 +136,8 @@ void AnimateActionAttack(CUnit &unit, COrder &order)
|
|||
order->goalPos = dest;
|
||||
order->Range = attacker.Stats->Variables[ATTACKRANGE_INDEX].Max;
|
||||
order->MinRange = attacker.Type->MinAttackRange;
|
||||
if (attacker.Type->BoolFlag[SKIRMISHER_INDEX].value)
|
||||
order->SkirmishRange = order->Range;
|
||||
|
||||
return order;
|
||||
}
|
||||
|
@ -172,6 +179,8 @@ void AnimateActionAttack(CUnit &unit, COrder &order)
|
|||
} else if (!strcmp(value, "range")) {
|
||||
++j;
|
||||
this->Range = LuaToNumber(l, -1, j + 1);
|
||||
if (unit.Type->BoolFlag[SKIRMISHER_INDEX].value)
|
||||
this->SkirmishRange = this->Range;
|
||||
} else if (!strcmp(value, "tile")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
|
@ -226,12 +235,15 @@ void AnimateActionAttack(CUnit &unit, COrder &order)
|
|||
input.SetGoal(this->goalPos, tileSize);
|
||||
}
|
||||
|
||||
input.SetMinRange(this->MinRange);
|
||||
int distance = this->Range;
|
||||
if (GameSettings.Inside) {
|
||||
CheckObstaclesBetweenTiles(input.GetUnitPos(), this->HasGoal() ? this->GetGoal()->tilePos : this->goalPos, MapFieldRocks | MapFieldForest, &distance);
|
||||
}
|
||||
input.SetMaxRange(distance);
|
||||
if (!this->SkirmishRange || Distance(input.GetUnitPos(), input.GetGoalPos()) < this->SkirmishRange)
|
||||
input.SetMinRange(this->MinRange);
|
||||
else
|
||||
input.SetMinRange(std::max<int>(this->SkirmishRange, this->MinRange));
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Attack::OnAnimationAttack(CUnit &unit)
|
||||
|
@ -605,6 +617,11 @@ void COrder_Attack::AttackTarget(CUnit &unit)
|
|||
unit.Waiting = 0;
|
||||
}
|
||||
|
||||
if (this->State != ATTACK_TARGET && unit.CanStoreOrder(this) && AutoCast(unit)) {
|
||||
this->Finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this->State) {
|
||||
case 0: { // First entry
|
||||
// did Order change ?
|
||||
|
|
|
@ -296,5 +296,18 @@ static void EnterTransporter(CUnit &unit, COrder_Board &order)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Board::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
//@}
|
||||
|
|
|
@ -469,4 +469,19 @@ bool COrder_Build::BuildFromOutside(CUnit &unit) const
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Build::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "commands.h"
|
||||
#include "construct.h"
|
||||
#include "iolib.h"
|
||||
#include "luacallback.h"
|
||||
#include "map.h"
|
||||
#include "player.h"
|
||||
#include "script.h"
|
||||
|
@ -208,6 +209,12 @@ static void Finish(COrder_Built &order, CUnit &unit)
|
|||
AiWorkComplete(worker, unit);
|
||||
}
|
||||
|
||||
if (unit.Type->OnReady) {
|
||||
unit.Type->OnReady->pushPreamble();
|
||||
unit.Type->OnReady->pushInteger(UnitNumber(unit));
|
||||
unit.Type->OnReady->run();
|
||||
}
|
||||
|
||||
// FIXME: Vladi: this is just a hack to test wall fixing,
|
||||
// FIXME: also not sure if the right place...
|
||||
// FIXME: Johns: hardcoded unit-type wall / more races!
|
||||
|
@ -228,7 +235,7 @@ static void Finish(COrder_Built &order, CUnit &unit)
|
|||
CorrectWallDirections(unit);
|
||||
CorrectWallNeighBours(unit);
|
||||
} else {
|
||||
unit.Direction = (MyRand() >> 8) & 0xFF; // random heading
|
||||
unit.Direction = (SyncRand() >> 8) & 0xFF; // random heading
|
||||
}
|
||||
UnitUpdateHeading(unit);
|
||||
}
|
||||
|
@ -267,6 +274,11 @@ static void Finish(COrder_Built &order, CUnit &unit)
|
|||
|
||||
const int maxProgress = type.Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// Check if we should make some random noise
|
||||
if (unit.Frame == 0 && unit.Player == ThisPlayer && GameCycle % 150 == 0 && SyncRand(3) == 0) {
|
||||
PlayUnitSound(unit, VoiceBuilding, true);
|
||||
}
|
||||
|
||||
// Check if building ready. Note we can both build and repair.
|
||||
if (!unit.Anim.Unbreakable && this->ProgressCounter >= maxProgress) {
|
||||
Finish(*this, unit);
|
||||
|
|
|
@ -213,3 +213,18 @@ enum {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Defend::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
|
219
src/action/action_explore.cpp
Normal file
219
src/action/action_explore.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_explore.cpp - The explore action. */
|
||||
//
|
||||
// (c) Copyright 1998-2019 by Lutz Sammer, Jimmy Salmon and Talas
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
#include "action/action_explore.h"
|
||||
|
||||
#include "animation.h"
|
||||
#include "iolib.h"
|
||||
#include "map.h"
|
||||
#include "pathfinder.h"
|
||||
#include "script.h"
|
||||
#include "tile.h"
|
||||
#include "ui.h"
|
||||
#include "unit.h"
|
||||
#include "unittype.h"
|
||||
#include "video.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
static void GetExplorationTarget(const CUnit &unit, Vec2i &dest)
|
||||
{
|
||||
int triesLeft = Map.NoFogOfWar ? 0 : 3;
|
||||
CMapField *field;
|
||||
const CPlayer &player = *unit.Player;
|
||||
dest.x = SyncRand(Map.Info.MapWidth - 1) + 1;
|
||||
dest.y = SyncRand(Map.Info.MapHeight - 1) + 1;
|
||||
|
||||
while (triesLeft > 0) {
|
||||
field = Map.Field(dest);
|
||||
if (field && !field->playerInfo.IsExplored(player))
|
||||
return; // unexplored, go here!
|
||||
dest.x = SyncRand(Map.Info.MapWidth - 1) + 1;
|
||||
dest.y = SyncRand(Map.Info.MapHeight - 1) + 1;
|
||||
--triesLeft;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ COrder *COrder::NewActionExplore(const CUnit &unit)
|
||||
{
|
||||
Vec2i dest;
|
||||
GetExplorationTarget(unit, dest);
|
||||
Assert(Map.Info.IsPointOnMap(dest));
|
||||
|
||||
COrder_Explore *order = new COrder_Explore();
|
||||
|
||||
order->goalPos = dest;
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void COrder_Explore::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-explore\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
|
||||
if (this->WaitingCycle != 0) {
|
||||
file.printf(" \"waiting-cycle\", %d,", this->WaitingCycle);
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Explore::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (!strcmp(value, "waiting-cycle")) {
|
||||
++j;
|
||||
this->WaitingCycle = LuaToNumber(l, -1, j + 1);
|
||||
} else if (!strcmp(value, "range")) {
|
||||
++j;
|
||||
this->Range = LuaToNumber(l, -1, j + 1);
|
||||
} else if (!strcmp(value, "tile")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
CclGetPos(l, &this->goalPos.x , &this->goalPos.y);
|
||||
lua_pop(l, 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Explore::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ PixelPos COrder_Explore::Show(const CViewport &vp, const PixelPos &lastScreenPos) const
|
||||
{
|
||||
const PixelPos pos1 = vp.TilePosToScreen_Center(this->goalPos);
|
||||
|
||||
Video.DrawLineClip(ColorGreen, lastScreenPos, pos1);
|
||||
Video.FillCircleClip(ColorBlue, pos1, 2);
|
||||
return pos1;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Explore::UpdatePathFinderData(PathFinderInput &input)
|
||||
{
|
||||
input.SetMinRange(0);
|
||||
input.SetMaxRange(this->Range);
|
||||
const Vec2i tileSize(0, 0);
|
||||
input.SetGoal(this->goalPos, tileSize);
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void COrder_Explore::Execute(CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
if (!unit.Waiting) {
|
||||
unit.Waiting = 1;
|
||||
unit.WaitBackup = unit.Anim;
|
||||
}
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Still);
|
||||
unit.Wait--;
|
||||
return;
|
||||
}
|
||||
if (unit.Waiting) {
|
||||
unit.Anim = unit.WaitBackup;
|
||||
unit.Waiting = 0;
|
||||
}
|
||||
|
||||
switch (DoActionMove(unit)) {
|
||||
case PF_FAILED:
|
||||
this->WaitingCycle = 0;
|
||||
break;
|
||||
case PF_UNREACHABLE:
|
||||
// Increase range and try again
|
||||
this->WaitingCycle = 1;
|
||||
this->Range++;
|
||||
break;
|
||||
|
||||
case PF_REACHED:
|
||||
{
|
||||
this->WaitingCycle = 1;
|
||||
this->Range = 0;
|
||||
// pick a new place to explore
|
||||
GetExplorationTarget(unit, this->goalPos);
|
||||
}
|
||||
break;
|
||||
case PF_WAIT:
|
||||
{
|
||||
// Wait for a while then give up
|
||||
this->WaitingCycle++;
|
||||
if (this->WaitingCycle == 5) {
|
||||
this->WaitingCycle = 0;
|
||||
this->Range = 0;
|
||||
// pick a new place to explore
|
||||
GetExplorationTarget(unit, this->goalPos);
|
||||
|
||||
unit.pathFinderData->output.Cycles = 0; //moving counter
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // moving
|
||||
this->WaitingCycle = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
if (AutoAttack(unit) || AutoRepair(unit) || AutoCast(unit)) {
|
||||
this->Finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Explore::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
//@}
|
|
@ -317,4 +317,19 @@ enum {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Follow::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -170,13 +170,22 @@ int DoActionMove(CUnit &unit)
|
|||
}
|
||||
|
||||
if (unit.Type->UnitType == UnitTypeNaval) { // Boat (un)docking?
|
||||
const CMapField &mf_cur = *Map.Field(unit.Offset);
|
||||
const CMapField &mf_next = *Map.Field(unit.tilePos + posd);
|
||||
bool foundCoast = false;
|
||||
|
||||
if (mf_cur.WaterOnMap() && mf_next.CoastOnMap()) {
|
||||
PlayUnitSound(unit, VoiceDocking);
|
||||
} else if (mf_cur.CoastOnMap() && mf_next.WaterOnMap()) {
|
||||
PlayUnitSound(unit, VoiceDocking); // undocking
|
||||
for (int i = 0; i < unit.Type->TileWidth && !foundCoast; i++) {
|
||||
for (int j = 0; j < unit.Type->TileHeight && !foundCoast; j++) {
|
||||
const Vec2i offset(i, j);
|
||||
const CMapField &mf_next = *Map.Field(unit.tilePos + posd + offset);
|
||||
const CMapField &mf_cur = *Map.Field(unit.tilePos + offset);
|
||||
|
||||
if (mf_cur.CoastOnMap() || mf_next.CoastOnMap()) {
|
||||
foundCoast = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foundCoast) {
|
||||
// Should play, even if unit already speaking
|
||||
PlayUnitSound(unit, VoiceDocking, true);
|
||||
}
|
||||
}
|
||||
Vec2i pos = unit.tilePos + posd;
|
||||
|
@ -252,4 +261,19 @@ int DoActionMove(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Move::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -186,4 +186,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Patrol::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -319,5 +319,20 @@ static void AnimateActionRepair(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Repair::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
|
||||
//@}
|
||||
|
|
|
@ -167,6 +167,15 @@ static bool FindNearestReachableTerrainType(int movemask, int resmask, int range
|
|||
order->CurrentResource = harvester.CurrentResource;
|
||||
order->DoneHarvesting = true;
|
||||
|
||||
if (harvester.CurrentResource) {
|
||||
const ResourceInfo &resinfo = *harvester.Type->ResInfo[harvester.CurrentResource];
|
||||
if (resinfo.TerrainHarvester && harvester.ResourcesHeld < resinfo.ResourceCapacity) {
|
||||
// Need to finish harvesting first!
|
||||
delete order;
|
||||
return NewActionResource(harvester, harvester.tilePos);
|
||||
}
|
||||
}
|
||||
|
||||
if (depot == NULL) {
|
||||
depot = FindDeposit(harvester, 1000, harvester.CurrentResource);
|
||||
}
|
||||
|
@ -345,6 +354,11 @@ COrder_Resource::~COrder_Resource()
|
|||
}
|
||||
if (this->IsGatheringStarted() && unit.ResourcesHeld > 0) {
|
||||
// escape to Depot with what you have
|
||||
const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
|
||||
if (resinfo.TerrainHarvester && unit.ResourcesHeld < resinfo.ResourceCapacity) {
|
||||
// We don't have anything yet.
|
||||
return false;
|
||||
}
|
||||
this->DoneHarvesting = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -1355,4 +1369,19 @@ void COrder_Resource::Execute(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Get goal position
|
||||
*/
|
||||
/* virtual */ const Vec2i COrder_Resource::GetGoalPos() const
|
||||
{
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
if (goalPos != invalidPos) {
|
||||
return goalPos;
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
return this->GetGoal()->tilePos;
|
||||
}
|
||||
return invalidPos;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "ai.h"
|
||||
#include "animation.h"
|
||||
#include "iolib.h"
|
||||
#include "luacallback.h"
|
||||
#include "player.h"
|
||||
#include "sound.h"
|
||||
#include "translate.h"
|
||||
|
@ -217,14 +218,19 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
newUnit->TTL = GameCycle + unit.Type->DecayRate * 6 * CYCLES_PER_SECOND;
|
||||
}
|
||||
|
||||
|
||||
/* Auto Group Add */
|
||||
/* Remove this code from active status to allow buildings to be a group member
|
||||
without trained units becoming part of the group. Reactivate to enable units
|
||||
to be added to the group by uncommenting this code block
|
||||
|
||||
if (!unit.Player->AiEnabled && unit.GroupId) {
|
||||
int num = 0;
|
||||
while (!(unit.GroupId & (1 << num))) {
|
||||
++num;
|
||||
}
|
||||
AddToGroup(&newUnit, 1, num);
|
||||
}
|
||||
} */
|
||||
|
||||
DropOutOnSide(*newUnit, LookingW, &unit);
|
||||
player.Notify(NotifyGreen, newUnit->tilePos, _("New %s ready"), nType.Name.c_str());
|
||||
|
@ -234,6 +240,11 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
if (unit.Player->AiEnabled) {
|
||||
AiTrainingComplete(unit, *newUnit);
|
||||
}
|
||||
if (newUnit->Type->OnReady) {
|
||||
newUnit->Type->OnReady->pushPreamble();
|
||||
newUnit->Type->OnReady->pushInteger(UnitNumber(*newUnit));
|
||||
newUnit->Type->OnReady->run();
|
||||
}
|
||||
|
||||
if (unit.NewOrder && unit.NewOrder->HasGoal()
|
||||
&& unit.NewOrder->GetGoal()->Destroyed) {
|
||||
|
|
|
@ -136,7 +136,7 @@ static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
|
|||
unit.Variable[i].Enable = newstats.Variables[i].Enable;
|
||||
} else {
|
||||
unit.Variable[i].Value = newstats.Variables[i].Value;
|
||||
unit.Variable[i].Max = unit.Variable[i].Value;
|
||||
unit.Variable[i].Max = unit.Variable[i].Max;
|
||||
unit.Variable[i].Enable = newstats.Variables[i].Enable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "action/action_built.h"
|
||||
#include "action/action_defend.h"
|
||||
#include "action/action_die.h"
|
||||
#include "action/action_explore.h"
|
||||
#include "action/action_follow.h"
|
||||
#include "action/action_move.h"
|
||||
#include "action/action_patrol.h"
|
||||
|
@ -200,6 +201,8 @@ void CclParseOrder(lua_State *l, CUnit &unit, COrderPtr *orderPtr)
|
|||
*orderPtr = new COrder_Defend;
|
||||
} else if (!strcmp(actiontype, "action-die")) {
|
||||
*orderPtr = new COrder_Die;
|
||||
} else if (!strcmp(actiontype, "action-explore")) {
|
||||
*orderPtr = new COrder_Explore;
|
||||
} else if (!strcmp(actiontype, "action-follow")) {
|
||||
*orderPtr = new COrder_Follow;
|
||||
} else if (!strcmp(actiontype, "action-move")) {
|
||||
|
@ -397,6 +400,14 @@ static void HandleUnitAction(CUnit &unit)
|
|||
SelectedUnitChanged();
|
||||
}
|
||||
}
|
||||
if (unit.CurrentResource) {
|
||||
const ResourceInfo &resinfo = *unit.Type->ResInfo[unit.CurrentResource];
|
||||
if (resinfo.LoseResources && unit.Orders[0]->Action != UnitActionResource
|
||||
&& (!resinfo.TerrainHarvester || unit.ResourcesHeld < resinfo.ResourceCapacity)) {
|
||||
unit.CurrentResource = 0;
|
||||
unit.ResourcesHeld = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
unit.Orders[0]->Execute(unit);
|
||||
}
|
||||
|
|
|
@ -403,6 +403,19 @@ void CommandPatrolUnit(CUnit &unit, const Vec2i &pos, int flush)
|
|||
if (IsUnitValidForNetwork(unit) == false) {
|
||||
return ;
|
||||
}
|
||||
|
||||
const Vec2i invalidPos(-1, -1);
|
||||
|
||||
Vec2i startPos = unit.tilePos;
|
||||
COrderPtr *prevOrder = &unit.Orders.back();
|
||||
|
||||
if(*prevOrder != NULL) {
|
||||
Vec2i prevGoalPos = (*prevOrder)->GetGoalPos();
|
||||
if(prevGoalPos != invalidPos) {
|
||||
startPos = prevGoalPos;
|
||||
}
|
||||
}
|
||||
|
||||
COrderPtr *order;
|
||||
|
||||
if (!unit.CanMove()) {
|
||||
|
@ -414,7 +427,7 @@ void CommandPatrolUnit(CUnit &unit, const Vec2i &pos, int flush)
|
|||
return;
|
||||
}
|
||||
}
|
||||
*order = COrder::NewActionPatrol(unit.tilePos, pos);
|
||||
*order = COrder::NewActionPatrol(startPos, pos);
|
||||
|
||||
ClearSavedAction(unit);
|
||||
}
|
||||
|
@ -499,6 +512,33 @@ void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int fl
|
|||
ClearSavedAction(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
** Send a unit exploring
|
||||
**
|
||||
** @param unit pointer to unit.
|
||||
** @param flush if true, flush command queue.
|
||||
*/
|
||||
void CommandExplore(CUnit &unit, int flush)
|
||||
{
|
||||
if (IsUnitValidForNetwork(unit) == false) {
|
||||
return ;
|
||||
}
|
||||
COrderPtr *order;
|
||||
|
||||
if (!unit.CanMove()) {
|
||||
ClearNewAction(unit);
|
||||
order = &unit.NewOrder;
|
||||
} else {
|
||||
order = GetNextOrder(unit, flush);
|
||||
if (order == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
*order = COrder::NewActionExplore(unit);
|
||||
|
||||
ClearSavedAction(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
** Cancel the building construction, or kill a unit.
|
||||
**
|
||||
|
|
|
@ -268,7 +268,7 @@ bool HallPlaceFinder::IsAUsableMine(const CUnit &mine) const
|
|||
}
|
||||
// Town hall may not be near but we may be using it, check
|
||||
// for 2 buildings near it and assume it's been used
|
||||
if (unit.Type->Building && !unit.Type->GivesResource == resource) {
|
||||
if (unit.Type->Building && !(unit.Type->GivesResource == resource)) {
|
||||
++buildings;
|
||||
if (buildings == 2) {
|
||||
return false;
|
||||
|
|
|
@ -57,6 +57,64 @@
|
|||
#define AIATTACK_BUILDING 2
|
||||
#define AIATTACK_AGRESSIVE 3
|
||||
|
||||
class EnemyUnitFinder
|
||||
{
|
||||
public:
|
||||
EnemyUnitFinder(const CUnit &unit, CUnit **result_unit, int find_type) :
|
||||
//Wyrmgus end
|
||||
unit(unit),
|
||||
movemask(unit.Type->MovementMask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit)),
|
||||
attackrange(unit.Stats->Variables[ATTACKRANGE_INDEX].Max),
|
||||
find_type(find_type),
|
||||
result_unit(result_unit)
|
||||
{
|
||||
*result_unit = NULL;
|
||||
}
|
||||
VisitResult Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from);
|
||||
private:
|
||||
const CUnit &unit;
|
||||
unsigned int movemask;
|
||||
const int attackrange;
|
||||
const int find_type;
|
||||
CUnit **result_unit;
|
||||
};
|
||||
|
||||
VisitResult EnemyUnitFinder::Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from)
|
||||
{
|
||||
if (!CanMoveToMask(pos, movemask)) { // unreachable
|
||||
return VisitResult_DeadEnd;
|
||||
}
|
||||
|
||||
std::vector<CUnit *> table;
|
||||
Vec2i minpos = pos - Vec2i(attackrange, attackrange);
|
||||
Vec2i maxpos = pos + Vec2i(unit.Type->TileWidth - 1 + attackrange, unit.Type->TileHeight - 1 + attackrange);
|
||||
Select(minpos, maxpos, table, HasNotSamePlayerAs(Players[PlayerNumNeutral]));
|
||||
for (size_t i = 0; i != table.size(); ++i) {
|
||||
CUnit *dest = table[i];
|
||||
const CUnitType &dtype = *dest->Type;
|
||||
|
||||
if (
|
||||
!unit.IsEnemy(*dest) // a friend or neutral
|
||||
|| !CanTarget(*unit.Type, dtype)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't attack invulnerable units
|
||||
if (dtype.BoolFlag[INDESTRUCTIBLE_INDEX].value || dest->Variable[UNHOLYARMOR_INDEX].Value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((find_type != AIATTACK_BUILDING || dtype.BoolFlag[BUILDING_INDEX].value) && (find_type != AIATTACK_AGRESSIVE || dest->IsAgressive())) {
|
||||
*result_unit = dest;
|
||||
return VisitResult_Finished;
|
||||
} else if (*result_unit == NULL) { // if trying to search for buildings or aggressive units specifically, still put the first found unit (even if it doesn't fit those parameters) as the result unit, so that it can be returned if no unit with the specified parameters is found
|
||||
*result_unit = dest;
|
||||
}
|
||||
}
|
||||
return VisitResult_Ok;
|
||||
}
|
||||
|
||||
template <const int FIND_TYPE>
|
||||
class AiForceEnemyFinder
|
||||
{
|
||||
|
@ -84,21 +142,35 @@ public:
|
|||
}
|
||||
if (FIND_TYPE == AIATTACK_RANGE) {
|
||||
*enemy = AttackUnitsInReactRange(*unit);
|
||||
} else if (FIND_TYPE == AIATTACK_ALLMAP) {
|
||||
*enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
|
||||
} else if (FIND_TYPE == AIATTACK_BUILDING) {
|
||||
*enemy = AttackUnitsInDistance(*unit, MaxMapWidth, IsBuildingType());
|
||||
Assert(!*enemy);
|
||||
if (*enemy == NULL || !(*enemy)->Type->Building) {
|
||||
*enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
|
||||
}
|
||||
} else if (FIND_TYPE == AIATTACK_AGRESSIVE) {
|
||||
*enemy = AttackUnitsInDistance(*unit, MaxMapWidth, IsAggresiveUnit());
|
||||
Assert(!*enemy || (*enemy)->IsAgressive());
|
||||
if (*enemy == NULL) {
|
||||
*enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
|
||||
}
|
||||
} else {
|
||||
// Terrain traversal by Andrettin
|
||||
TerrainTraversal terrainTraversal;
|
||||
terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
|
||||
terrainTraversal.Init();
|
||||
terrainTraversal.PushUnitPosAndNeighboor(*unit);
|
||||
CUnit *result_unit = NULL;
|
||||
EnemyUnitFinder enemyUnitFinder(*unit, &result_unit, FIND_TYPE);
|
||||
terrainTraversal.Run(enemyUnitFinder);
|
||||
*enemy = result_unit;
|
||||
}
|
||||
// Previous attack finding code before we added TerrainTraversal for all
|
||||
// of these. Here for prosperity
|
||||
|
||||
// } else if (FIND_TYPE == AIATTACK_ALLMAP) {
|
||||
// *enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
|
||||
// } else if (FIND_TYPE == AIATTACK_BUILDING) {
|
||||
// *enemy = AttackUnitsInDistance(*unit, MaxMapWidth, IsBuildingType());
|
||||
// Assert(!*enemy);
|
||||
// if (*enemy == NULL || !(*enemy)->Type->Building) {
|
||||
// *enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
|
||||
// }
|
||||
// } else if (FIND_TYPE == AIATTACK_AGRESSIVE) {
|
||||
// *enemy = AttackUnitsInDistance(*unit, MaxMapWidth, IsAggresiveUnit());
|
||||
// Assert(!*enemy || (*enemy)->IsAgressive());
|
||||
// if (*enemy == NULL) {
|
||||
// *enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
|
||||
// }
|
||||
// }
|
||||
return *enemy == NULL;
|
||||
}
|
||||
private:
|
||||
|
@ -1083,6 +1155,12 @@ void AiForceManager::Update()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (force.Defending == false) {
|
||||
// force is no longer defending
|
||||
return;
|
||||
}
|
||||
|
||||
// Find idle units and order them to defend
|
||||
// Don't attack if there aren't our units near goal point
|
||||
std::vector<CUnit *> nearGoal;
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
target->tilePos = resPos;
|
||||
target->Place(resPos);
|
||||
if (flags & SU_Summoned) {
|
||||
target->Summoned = 1;
|
||||
target->Summoned = GameCycle + 1;
|
||||
}
|
||||
if ((flags & SU_JoinToAIForce) && unit.Player->AiEnabled) {
|
||||
int force = unit.Player->Ai->Force.GetForce(unit);
|
||||
|
|
|
@ -705,7 +705,6 @@ static void DrawTileIcons()
|
|||
} else {
|
||||
label.DrawCentered(x, y, "Filler");
|
||||
}
|
||||
y += 20;
|
||||
|
||||
int i = Editor.TileIndex;
|
||||
Assert(Editor.TileIndex != -1);
|
||||
|
@ -1301,7 +1300,7 @@ static void EditorCallbackKeyDown(unsigned key, unsigned keychar)
|
|||
const char *ptr = strchr(UiGroupKeys.c_str(), key);
|
||||
|
||||
if (ptr) {
|
||||
key = '0' + ptr - UiGroupKeys.c_str();
|
||||
key = ((int)'0') + ptr - UiGroupKeys.c_str();
|
||||
if (key > '9') {
|
||||
key = SDLK_BACKQUOTE;
|
||||
}
|
||||
|
@ -1502,7 +1501,6 @@ static bool EditorCallbackMouse_EditUnitArea(const PixelPos &screenPos)
|
|||
}
|
||||
|
||||
int i = Editor.UnitIndex;
|
||||
by = UI.ButtonPanel.Y + 24;
|
||||
for (size_t j = 0; j < UI.ButtonPanel.Buttons.size(); ++j) {
|
||||
const int x = UI.ButtonPanel.Buttons[j].X;
|
||||
const int y = UI.ButtonPanel.Buttons[j].Y;
|
||||
|
@ -2080,4 +2078,4 @@ void StartEditor(const char *filename)
|
|||
SetDefaultTextColors(nc, rc);
|
||||
}
|
||||
|
||||
//@}
|
||||
//@}
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
#include "unittype.h"
|
||||
|
||||
|
||||
/// Callback for changed tile (with direction mask)
|
||||
static void EditorChangeSurrounding(const Vec2i &pos, int d);
|
||||
/// Callback for changed tile (with locked position)
|
||||
static void EditorChangeSurrounding(const Vec2i &pos, const Vec2i &lock_pos);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
|
@ -92,9 +92,9 @@ static unsigned QuadFromTile(const Vec2i &pos)
|
|||
**
|
||||
** @param pos map tile coordinate.
|
||||
** @param tileIndex Tile type to edit.
|
||||
** @param d Fix direction flag 8 up, 4 down, 2 left, 1 right.
|
||||
** @param lock_pos map tile coordinate, that should not be changed in callback.
|
||||
*/
|
||||
void EditorChangeTile(const Vec2i &pos, int tileIndex, int d)
|
||||
void EditorChangeTile(const Vec2i &pos, int tileIndex, const Vec2i &lock_pos)
|
||||
{
|
||||
Assert(Map.Info.IsPointOnMap(pos));
|
||||
|
||||
|
@ -125,16 +125,16 @@ void EditorChangeTile(const Vec2i &pos, int tileIndex, int d)
|
|||
UI.Minimap.UpdateSeenXY(pos);
|
||||
UI.Minimap.UpdateXY(pos);
|
||||
|
||||
EditorChangeSurrounding(pos, d);
|
||||
EditorChangeSurrounding(pos, lock_pos);
|
||||
}
|
||||
|
||||
/**
|
||||
** Update surroundings for tile changes.
|
||||
**
|
||||
** @param pos Map tile position of change.
|
||||
** @param d Fix direction flag 8 up, 4 down, 2 left, 1 right.
|
||||
** @param lock_pos Original change position, that should not be altered.
|
||||
*/
|
||||
static void EditorChangeSurrounding(const Vec2i &pos, int d)
|
||||
static void EditorChangeSurrounding(const Vec2i &pos, const Vec2i &lock_pos)
|
||||
{
|
||||
// Special case 1) Walls.
|
||||
CMapField &mf = *Map.Field(pos);
|
||||
|
@ -148,55 +148,61 @@ static void EditorChangeSurrounding(const Vec2i &pos, int d)
|
|||
const unsigned int BH_QUAD_M = 0x0000FFFF; // Bottom half quad mask
|
||||
const unsigned int LH_QUAD_M = 0xFF00FF00; // Left half quad mask
|
||||
const unsigned int RH_QUAD_M = 0x00FF00FF; // Right half quad mask
|
||||
const unsigned int DIR_UP = 8; // Go up allowed
|
||||
const unsigned int DIR_DOWN = 4; // Go down allowed
|
||||
const unsigned int DIR_LEFT = 2; // Go left allowed
|
||||
const unsigned int DIR_RIGHT = 1; // Go right allowed
|
||||
|
||||
bool did_change = false; // if we changed any tiles
|
||||
|
||||
// How this works:
|
||||
// first get the quad of the neighbouring tile,
|
||||
// then check if the margin matches.
|
||||
// Otherwise, call EditorChangeTile again.
|
||||
if ((d & DIR_UP) && pos.y) {
|
||||
if (pos.y) {
|
||||
const Vec2i offset(0, -1);
|
||||
// Insert into the bottom the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & TH_QUAD_M) | ((quad >> 16) & BH_QUAD_M);
|
||||
if (u != q2) {
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & BH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, d & ~DIR_DOWN);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
if ((d & DIR_DOWN) && pos.y < Map.Info.MapHeight - 1) {
|
||||
if (pos.y < Map.Info.MapHeight - 1) {
|
||||
const Vec2i offset(0, 1);
|
||||
// Insert into the top the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & BH_QUAD_M) | ((quad << 16) & TH_QUAD_M);
|
||||
if (u != q2) {
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & TH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, d & ~DIR_UP);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
if ((d & DIR_LEFT) && pos.x) {
|
||||
if (pos.x) {
|
||||
const Vec2i offset(-1, 0);
|
||||
// Insert into the left the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & LH_QUAD_M) | ((quad >> 8) & RH_QUAD_M);
|
||||
if (u != q2) {
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & RH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, d & ~DIR_RIGHT);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
if ((d & DIR_RIGHT) && pos.x < Map.Info.MapWidth - 1) {
|
||||
if (pos.x < Map.Info.MapWidth - 1) {
|
||||
const Vec2i offset(1, 0);
|
||||
// Insert into the right the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & RH_QUAD_M) | ((quad << 8) & LH_QUAD_M);
|
||||
if (u != q2) {
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & LH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, d & ~DIR_LEFT);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (did_change) {
|
||||
EditorChangeSurrounding(pos, lock_pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,7 +212,7 @@ static void EditorChangeSurrounding(const Vec2i &pos, int d)
|
|||
*/
|
||||
void EditorTileChanged(const Vec2i &pos)
|
||||
{
|
||||
EditorChangeSurrounding(pos, 0x0F);
|
||||
EditorChangeSurrounding(pos, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,7 +241,7 @@ static void TileFill(const Vec2i &pos, int tile, int size)
|
|||
Vec2i itPos;
|
||||
for (itPos.x = ipos.x; itPos.x <= apos.x; ++itPos.x) {
|
||||
for (itPos.y = ipos.y; itPos.y <= apos.y; ++itPos.y) {
|
||||
EditorChangeTile(itPos, tile, 15);
|
||||
EditorChangeTile(itPos, tile, itPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -625,6 +625,7 @@ int SaveStratagusMap(const std::string &mapName, CMap &map, int writeTerrain)
|
|||
char *setupExtension = strstr(mapSetup, ".smp");
|
||||
if (!setupExtension) {
|
||||
fprintf(stderr, "%s: invalid Stratagus map filename\n", mapName.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
char previewName[PATH_MAX];
|
||||
|
@ -878,6 +879,14 @@ void CreateGame(const std::string &filename, CMap *map)
|
|||
|
||||
InitPlayers();
|
||||
|
||||
if (IsNetworkGame()) {
|
||||
// if is a network game, it is necessary to reinitialize the syncrand
|
||||
// variables before beginning to load the map, due to random map
|
||||
// generation
|
||||
SyncHash = 0;
|
||||
InitSyncRand();
|
||||
}
|
||||
|
||||
if (Map.Info.Filename.empty() && !filename.empty()) {
|
||||
const std::string path = LibraryFileName(filename.c_str());
|
||||
|
||||
|
@ -894,6 +903,15 @@ void CreateGame(const std::string &filename, CMap *map)
|
|||
}
|
||||
CreatePlayer(playertype);
|
||||
}
|
||||
if (!ThisPlayer && !IsNetworkGame()) {
|
||||
// In demo or kiosk mode, pick first empty slot
|
||||
for (int i = 0; i < PlayerMax; ++i) {
|
||||
if (Players[i].Type == PlayerNobody) {
|
||||
ThisPlayer = &Players[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename.empty()) {
|
||||
if (CurrentMapPath != filename) {
|
||||
|
@ -1068,6 +1086,11 @@ void CreateGame(const std::string &filename, CMap *map)
|
|||
} else {
|
||||
unit.Colors = &unit.Player->UnitColors;
|
||||
}
|
||||
if (unit.Type->OnReady) {
|
||||
unit.Type->OnReady->pushPreamble();
|
||||
unit.Type->OnReady->pushInteger(UnitNumber(unit));
|
||||
unit.Type->OnReady->run();
|
||||
}
|
||||
}
|
||||
|
||||
GameResult = GameNoResult;
|
||||
|
|
|
@ -850,6 +850,8 @@ static void DoNextReplay()
|
|||
SendCommandUnload(*unit, pos, dunit, flags);
|
||||
} else if (!strcmp(action, "build")) {
|
||||
SendCommandBuildBuilding(*unit, pos, *UnitTypeByIdent(val), flags);
|
||||
} else if (!strcmp(action, "explore")) {
|
||||
SendCommandExplore(*unit, flags);
|
||||
} else if (!strcmp(action, "dismiss")) {
|
||||
SendCommandDismiss(*unit);
|
||||
} else if (!strcmp(action, "resource-loc")) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -78,7 +78,7 @@ namespace gcn
|
|||
return 8;
|
||||
}
|
||||
|
||||
void DefaultFont::drawString(Graphics* graphics, const std::string& text, int x, int y)
|
||||
void DefaultFont::drawString(Graphics* graphics, const std::string& text, int x, int y, bool is_normal)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -129,8 +129,7 @@ namespace gcn
|
|||
mFont = font;
|
||||
}
|
||||
|
||||
void Graphics::drawText(const std::string& text, int x, int y,
|
||||
unsigned int alignment)
|
||||
void Graphics::drawText(const std::string& text, int x, int y, unsigned int alignment, bool is_normal)
|
||||
{
|
||||
if (mFont == NULL)
|
||||
{
|
||||
|
@ -141,13 +140,13 @@ namespace gcn
|
|||
switch (alignment)
|
||||
{
|
||||
case LEFT:
|
||||
mFont->drawString(this, text, x, y);
|
||||
mFont->drawString(this, text, x, y, is_normal);
|
||||
break;
|
||||
case CENTER:
|
||||
mFont->drawString(this, text, x - mFont->getWidth(text) / 2, y);
|
||||
mFont->drawString(this, text, x - mFont->getWidth(text) / 2, y, is_normal);
|
||||
break;
|
||||
case RIGHT:
|
||||
mFont->drawString(this, text, x - mFont->getWidth(text), y);
|
||||
mFont->drawString(this, text, x - mFont->getWidth(text), y, is_normal);
|
||||
break;
|
||||
default:
|
||||
assert(!"Unknown alignment.");
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -208,7 +208,7 @@ namespace gcn
|
|||
return mGlyph[glyph].width + mGlyphSpacing;
|
||||
}
|
||||
|
||||
void ImageFont::drawString(Graphics* graphics, const std::string& text, int x, int y)
|
||||
void ImageFont::drawString(Graphics* graphics, const std::string& text, int x, int y, bool is_normal)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -92,7 +92,7 @@ namespace gcn
|
|||
|
||||
// Inherited from Font
|
||||
|
||||
virtual void drawString(Graphics* graphics, const std::string& text, int x, int y);
|
||||
virtual void drawString(Graphics* graphics, const std::string& text, int x, int y, bool is_normal);
|
||||
|
||||
virtual int getWidth(const std::string& text) const;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -113,7 +113,7 @@ namespace gcn
|
|||
* @param x the x coordinate where to draw the string.
|
||||
* @param y the y coordinate where to draw the string.
|
||||
*/
|
||||
virtual void drawString(Graphics* graphics, const std::string& text, int x, int y) = 0;
|
||||
virtual void drawString(Graphics* graphics, const std::string& text, int x, int y, bool is_normal = true) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -247,8 +247,7 @@ namespace gcn
|
|||
* @param alignment Graphics::LEFT, Graphics::CENTER or Graphics::RIGHT.
|
||||
* @throws Exception when no Font is set.
|
||||
*/
|
||||
virtual void drawText(const std::string& text, int x, int y,
|
||||
unsigned int alignment = LEFT);
|
||||
virtual void drawText(const std::string& text, int x, int y, unsigned int alignment = LEFT, bool is_normal = true);
|
||||
/**
|
||||
* Alignments for text drawing.
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* Copyright (c) 2004, 2005 darkbits Js_./
|
||||
* Per Larsson a.k.a finalman _RqZ{a<^_aa
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
|
||||
* _Qhm`] _f "'c 1!5m
|
||||
* Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
|
||||
* .)j(] .d_/ '-( P . S
|
||||
|
@ -185,7 +185,7 @@ pqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); @endcode
|
|||
|
||||
virtual int getWidth(const std::string& text) const;
|
||||
|
||||
virtual void drawString(Graphics* graphics, const std::string& text, int x, int y);
|
||||
virtual void drawString(Graphics* graphics, const std::string& text, int x, int y, bool is_normal = true);
|
||||
|
||||
virtual int getHeight() const;
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ namespace gcn
|
|||
textX = getWidth() - 4;
|
||||
break;
|
||||
default:
|
||||
textX = 0;
|
||||
//textX = 0;
|
||||
//throw GCN_EXCEPTION("Unknown alignment.");
|
||||
assert(!"Unknown alignment.");
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class COrder_Attack : public COrder
|
|||
friend COrder *COrder::NewActionAttackGround(const CUnit &attacker, const Vec2i &dest);
|
||||
public:
|
||||
explicit COrder_Attack(bool ground) : COrder(ground ? UnitActionAttackGround : UnitActionAttack),
|
||||
State(0), MinRange(0), Range(0), goalPos(-1, -1) {}
|
||||
State(0), MinRange(0), Range(0), SkirmishRange(0), goalPos(-1, -1) {}
|
||||
|
||||
virtual COrder_Attack *Clone() const { return new COrder_Attack(*this); }
|
||||
|
||||
|
@ -68,6 +68,7 @@ private:
|
|||
int State;
|
||||
int MinRange;
|
||||
int Range;
|
||||
int SkirmishRange;
|
||||
Vec2i goalPos;
|
||||
};
|
||||
//@}
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
bool WaitForTransporter(CUnit &unit);
|
||||
int MoveToTransporter(CUnit &unit);
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
virtual void AiUnitKilled(CUnit &unit);
|
||||
|
||||
const CUnitType &GetUnitType() const { return *Type; }
|
||||
virtual const Vec2i GetGoalPos() const { return goalPos; }
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
|
||||
private:
|
||||
bool MoveToLocation(CUnit &unit);
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
unsigned int State;
|
||||
int Range;
|
||||
|
|
66
src/include/action/action_explore.h
Normal file
66
src/include/action/action_explore.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_explore.h - The actions headerfile. */
|
||||
//
|
||||
// (c) Copyright 1998-2019 by Lutz Sammer, Jimmy Salmon and Talas
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
#ifndef __ACTION_EXPLORE_H__
|
||||
#define __ACTION_EXPLORE_H__
|
||||
|
||||
#include "actions.h"
|
||||
|
||||
//@{
|
||||
|
||||
class COrder_Explore : public COrder
|
||||
{
|
||||
friend COrder *COrder::NewActionExplore(const CUnit &unit);
|
||||
public:
|
||||
COrder_Explore() : COrder(UnitActionExplore), WaitingCycle(0), Range(0)
|
||||
{
|
||||
goalPos.x = -1;
|
||||
goalPos.y = -1;
|
||||
}
|
||||
|
||||
virtual COrder_Explore *Clone() const { return new COrder_Explore(*this); }
|
||||
|
||||
virtual bool IsValid() const;
|
||||
|
||||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
unsigned int WaitingCycle; /// number of cycle pathfinder wait.
|
||||
int Range;
|
||||
Vec2i goalPos;
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
#endif // !__ACTION_EXPLORE_H__
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
unsigned int State;
|
||||
int Range;
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
|
||||
private:
|
||||
int Range;
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
|
||||
const Vec2i &GetWayPoint() const { return WayPoint; }
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
Vec2i WayPoint; /// position for patroling.
|
||||
unsigned int WaitingCycle; /// number of cycle pathfinder wait.
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
|
||||
const CUnitPtr &GetReparableTarget() const { return ReparableTarget; }
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
bool RepairUnit(const CUnit &unit, CUnit &goal);
|
||||
private:
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
bool IsGatheringStarted() const;
|
||||
bool IsGatheringFinished() const;
|
||||
bool IsGatheringWaiting() const;
|
||||
virtual const Vec2i GetGoalPos() const;
|
||||
private:
|
||||
int MoveToResource_Terrain(CUnit &unit);
|
||||
int MoveToResource_Unit(CUnit &unit);
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void Execute(CUnit &unit);
|
||||
virtual PixelPos Show(const CViewport &vp, const PixelPos &lastScreenPos) const;
|
||||
virtual void UpdatePathFinderData(PathFinderInput &input);
|
||||
virtual const Vec2i GetGoalPos() const { return goalPos; }
|
||||
|
||||
private:
|
||||
bool LeaveTransporter(CUnit &transporter);
|
||||
|
|
|
@ -70,6 +70,7 @@ enum UnitAction {
|
|||
UnitActionUnload, /// unit leaving transporter
|
||||
UnitActionPatrol, /// unit paroling area
|
||||
UnitActionBuild, /// unit builds building
|
||||
UnitActionExplore, /// unit explores map
|
||||
|
||||
UnitActionRepair, /// unit repairing
|
||||
UnitActionResource, /// unit harvesting resources
|
||||
|
@ -133,6 +134,7 @@ public:
|
|||
static COrder *NewActionBuilt(CUnit &builder, CUnit &unit);
|
||||
static COrder *NewActionDefend(CUnit &dest);
|
||||
static COrder *NewActionDie();
|
||||
static COrder *NewActionExplore(const CUnit &unit);
|
||||
static COrder *NewActionFollow(CUnit &dest);
|
||||
static COrder *NewActionMove(const Vec2i &pos);
|
||||
static COrder *NewActionPatrol(const Vec2i ¤tPos, const Vec2i &dest);
|
||||
|
|
|
@ -84,6 +84,8 @@ extern void CommandBoard(CUnit &unit, CUnit &dest, int flush);
|
|||
extern void CommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush);
|
||||
/// Prepare command build
|
||||
extern void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &, int flush);
|
||||
/// Prepare command explore
|
||||
extern void CommandExplore(CUnit &unit, int flush);
|
||||
/// Prepare command dismiss
|
||||
extern void CommandDismiss(CUnit &unit);
|
||||
/// Prepare command resource location
|
||||
|
@ -152,6 +154,8 @@ extern void SendCommandBoard(CUnit &unit, CUnit &dest, int flush);
|
|||
extern void SendCommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush);
|
||||
/// Send build building command
|
||||
extern void SendCommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int flush);
|
||||
/// Send explore command
|
||||
extern void SendCommandExplore(CUnit &unit, int flush);
|
||||
/// Send cancel building command
|
||||
extern void SendCommandDismiss(CUnit &unit);
|
||||
/// Send harvest location command
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
|
||||
virtual int getHeight() const { return Height(); }
|
||||
virtual int getWidth(const std::string &text) const { return Width(text); }
|
||||
virtual void drawString(gcn::Graphics *graphics, const std::string &text, int x, int y);
|
||||
virtual void drawString(gcn::Graphics *graphics, const std::string &text, int x, int y, bool is_normal = true);
|
||||
|
||||
void Load();
|
||||
void Reload() const;
|
||||
|
@ -207,7 +207,7 @@ public:
|
|||
int Draw(int x, int y, int number) const;
|
||||
/// Draw text/number clipped
|
||||
int DrawClip(int x, int y, const char *const text) const;
|
||||
int DrawClip(int x, int y, const std::string &text) const;
|
||||
int DrawClip(int x, int y, const std::string &text, bool is_normal = true) const;
|
||||
int DrawClip(int x, int y, int number) const;
|
||||
/// Draw reverse text/number unclipped
|
||||
int DrawReverse(int x, int y, const char *const text) const;
|
||||
|
|
|
@ -63,6 +63,7 @@ enum ButtonCmd {
|
|||
ButtonHarvest, /// order harvest
|
||||
ButtonBuild, /// order build
|
||||
ButtonPatrol, /// order patrol
|
||||
ButtonExplore, /// order explore
|
||||
ButtonAttackGround, /// order attack ground
|
||||
ButtonSpellCast, /// order cast spell
|
||||
ButtonUnload, /// order unload unit
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
int GetLastRecvState() { return lastRecvState; }
|
||||
int GetLogSize() { return events.size(); }
|
||||
CClientLog *GetLastMessage() { return events.back(); }
|
||||
int CreateGame(std::string desc, std::string map, std::string players);
|
||||
|
||||
private:
|
||||
CTCPSocket metaSocket; /// This is a TCP socket
|
||||
|
|
|
@ -462,7 +462,7 @@ public:
|
|||
static unsigned int Count; /// slot number generator.
|
||||
};
|
||||
|
||||
extern bool MissileInitMove(Missile &missile);
|
||||
extern bool MissileInitMove(Missile &missile, bool pointToPoint = false);
|
||||
extern bool PointToPointMissile(Missile &missile);
|
||||
extern void MissileHandlePierce(Missile &missile, const Vec2i &pos);
|
||||
extern bool MissileHandleBlocking(Missile &missile, const PixelPos &position);
|
||||
|
@ -627,9 +627,7 @@ extern void InitMissiles();
|
|||
/// Clean missiles
|
||||
extern void CleanMissiles();
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void FreeBurningBuildingFrames();
|
||||
#endif
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
# include <netdb.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <ifaddrs.h>
|
||||
# ifndef __BEOS__
|
||||
# include <net/if.h>
|
||||
# include <arpa/inet.h>
|
||||
|
|
|
@ -105,7 +105,7 @@ enum _ic_message_subtype_ {
|
|||
ICMConfig, /// Setup message configure clients
|
||||
|
||||
ICMEngineMismatch, /// Stratagus engine version doesn't match
|
||||
ICMProtocolMismatch, /// Network protocol version doesn't match
|
||||
ICMLuaFilesMismatch, /// Network protocol version doesn't match
|
||||
ICMEngineConfMismatch, /// UNUSED:Engine configuration isn't identical
|
||||
ICMMapUidMismatch, /// MAP UID doesn't match
|
||||
|
||||
|
@ -161,7 +161,7 @@ private:
|
|||
public:
|
||||
char PlyName[NetPlayerNameSize]; /// Name of player
|
||||
int32_t Stratagus; /// Stratagus engine version
|
||||
int32_t Version; /// Network protocol version
|
||||
uint32_t Version; /// Lua files version
|
||||
};
|
||||
|
||||
class CInitMessage_Config
|
||||
|
@ -194,10 +194,10 @@ public:
|
|||
int32_t Stratagus; /// Stratagus engine version
|
||||
};
|
||||
|
||||
class CInitMessage_ProtocolMismatch
|
||||
class CInitMessage_LuaFilesMismatch
|
||||
{
|
||||
public:
|
||||
CInitMessage_ProtocolMismatch();
|
||||
CInitMessage_LuaFilesMismatch();
|
||||
const CInitMessage_Header &GetHeader() const { return header; }
|
||||
const unsigned char *Serialize() const;
|
||||
void Deserialize(const unsigned char *p);
|
||||
|
@ -205,7 +205,7 @@ public:
|
|||
private:
|
||||
CInitMessage_Header header;
|
||||
public:
|
||||
int32_t Version; /// Network protocol version
|
||||
uint32_t Version; /// Lua files version
|
||||
};
|
||||
|
||||
class CInitMessage_Welcome
|
||||
|
@ -299,6 +299,7 @@ enum _message_type_ {
|
|||
MessageCommandBoard, /// Unit command board
|
||||
MessageCommandUnload, /// Unit command unload
|
||||
MessageCommandBuild, /// Unit command build building
|
||||
MessageCommandExplore, /// Unit command explore
|
||||
MessageCommandDismiss, /// Unit command dismiss unit
|
||||
MessageCommandResourceLoc, /// Unit command resource location
|
||||
MessageCommandResource, /// Unit command resource
|
||||
|
|
|
@ -80,7 +80,7 @@ enum _net_client_con_state_ {
|
|||
ccs_goahead, /// Server wants to start game
|
||||
ccs_started, /// Server has started game
|
||||
ccs_incompatibleengine, /// Incompatible engine version
|
||||
ccs_incompatiblenetwork /// Incompatible netowrk version
|
||||
ccs_incompatibleluafiles /// Incompatible lua files
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
//
|
||||
int HasDataToRead(int timeout);
|
||||
bool IsValid() const;
|
||||
int GetSocketAddresses(unsigned long *ips, int maxAddr);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
|
|
|
@ -373,9 +373,7 @@ extern void GraphicPlayerPixels(CPlayer &player, const CGraphic &sprite);
|
|||
/// Output debug information for players
|
||||
extern void DebugPlayers();
|
||||
|
||||
#ifdef DEBUG
|
||||
void FreePlayerColors();
|
||||
#endif
|
||||
|
||||
/// register ccl features
|
||||
extern void PlayerCclRegister();
|
||||
|
|
|
@ -2,8 +2,14 @@
|
|||
#define __SHADERS_H__
|
||||
#ifdef USE_OPENGL
|
||||
#define MAX_SHADERS 5
|
||||
extern unsigned ShaderIndex;
|
||||
extern void LoadShaders();
|
||||
// #define SHADERDEBUG // Uncomment for loading shaders from file
|
||||
#ifndef __APPLE__
|
||||
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebuffer;
|
||||
#else
|
||||
#define glBindFramebuffer glBindFramebufferEXT
|
||||
#endif
|
||||
extern GLuint fullscreenFramebuffer;
|
||||
extern bool LoadShaders(int direction, char* shadernameOut);
|
||||
extern bool LoadShaderExtensions();
|
||||
extern void SetupFramebuffer();
|
||||
extern void RenderFramebufferToScreen();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue