Compare commits

...

66 Commits

Author SHA1 Message Date
Romain Naour f8136fcbc5 CMake: add C4GROUP_TOOL_ONLY
When cross-compiling c4group should be build for the host
machine before building OpenClonk for the target.

Without C4GROUP_TOOL_ONLY option, we have to build OpenClonk
for the host.

C4GROUP_TOOL_ONLY allow to build only c4group tool for the
host.

Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
With this patch I can build OpenClonk with Buildroot.
2018-04-12 23:20:21 +02:00
Romain Naour 54d2ce7e07 CMake: use FIND_PROGRAM
While cross-compiling, it is easier to find a binary
from the patch using FIND_PROGRAM instead of using
a cmake file.

Try to find c4group native tool with FIND_PROGRAM and
fallback to the cmake file if c4group is not found.

Signed-off-by: Romain Naour <romain.naour@gmail.com>
2018-04-12 23:20:21 +02:00
Romain Naour 923d355c91 CMake: build libmisc and libc4script statically
As reported by [1], some distributions use shared libraries as
default preset in CMake.

Without explicitely linking statically libmisc and libc4script,
we have the following link issue:

[...]/host/bin/x86_64-linux-g++ --sysroot=[...]sysroot
-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os
-std=gnu++14 -Wall -Wextra -Wredundant-decls -Wendif-labels
-Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Winit-self
-Wsign-promo -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor
-Woverloaded-virtual  -DNDEBUG
-rdynamic CMakeFiles/c4group.dir/src/c4group/C4GroupMain.cpp.o
-o c4group
-Wl,-rpath,[...]/build/openclonk-7.0:
liblibmisc.so -lz -lpthread -lrt
liblibmisc.so : référence indéfinie vers « C4LangStringTable::Translate(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const »
liblibmisc.so : référence indéfinie vers « C4LangStringTable::system_string_table »

[1] https://github.com/openclonk/openclonk/pull/26

While at it, build libopenclonk statically since libopenclonk is not
installed by the CMake build system.

Signed-off-by: Romain Naour <romain.naour@gmail.com>
2018-04-12 23:19:14 +02:00
Nicolas Hake c1ee1bdac7 Fix the most horrible merge I've done yet 2018-03-21 13:34:13 +01:00
Nicolas Hake c291488034 Merge branch 'blake2-no-sse2' into stable-8 2018-03-21 13:03:39 +01:00
Maikel de Vries 5c6fadfb26 warn about deprecated use of base respawn rule 2018-03-16 18:25:33 +01:00
Maikel de Vries 4dc3fe5928 fix king of the hill graphics in editor mode 2018-03-16 18:25:27 +01:00
Maikel de Vries 168277abdb moving brick: fix movement graph saving
Did not test all corner cases but this improves the situation for sure.
2018-03-15 15:41:25 +01:00
Maikel de Vries a7e1f59369 flame: option to make eternal for editor mode 2018-03-15 15:41:17 +01:00
Maikel de Vries 90ea896814 correctly update active fire effect when NoBurnDecay changes 2018-03-15 15:41:08 +01:00
Maikel de Vries 7c0ae67289 do not show compensator burning battery in editor creation list 2018-03-15 15:40:58 +01:00
Maikel de Vries 07b0f51742 remove duplicate cloud effect object
The particle had the same graphics as the real Cloud object and the script does not seem to have any uses. Also unused for more than 4 years.
2018-03-15 15:40:46 +01:00
Maikel de Vries 0aba4f88fc make time object more editor friendly 2018-03-15 15:40:35 +01:00
Maikel de Vries a935a9d4ac fix meteor graphics 2018-03-15 15:40:27 +01:00
Maikel de Vries 97f87019b7 waterfall: implement editor interface 2018-03-15 15:40:17 +01:00
Maikel de Vries a85a3201d9 hide some more objects in editor creation list
The burned object may be creatable, but must then be moved such that the libraries parent folder remains invisble in the editor.
2018-03-15 15:40:04 +01:00
Maikel de Vries e0e570e9c9 fix DefCore Version entry for stone and wooden sign 2018-03-12 16:51:16 +01:00
Maikel de Vries 68d901b61c relaunch rule: fix scoreboard updating and scenario overloading 2018-03-12 15:05:50 +01:00
Maikel de Vries 2c4676d63c update version to 8.1 2018-03-05 17:47:43 +01:00
Armin Burgmeier d952012331 Install platforms/ folder in windows installer 2018-03-05 17:42:17 +01:00
Maikel de Vries 0f67b7bb70 treasure hunt: fix wrong dialogue translation of Dagobert to Scrooge 2018-03-05 17:37:08 +01:00
Maikel de Vries 2a59351edd add wooden sign object
Graphics made by Foaly.
2018-03-05 17:37:08 +01:00
Maikel de Vries 0c0c5df94d signpost and stone sign: clean up scripts and lessen code duplication 2018-03-05 17:37:08 +01:00
Maikel de Vries 84063e1917 c4script: some fixes for style guidelines and typos 2018-03-05 17:37:08 +01:00
Maikel de Vries b88e72c67a add stone sign object
Graphics made by Foaly.
2018-03-05 17:37:08 +01:00
Maikel de Vries 459b081033 fix guide post pictures and interaction icons 2018-03-05 17:37:08 +01:00
Maikel de Vries 44b377d637 prevent floor switch from making object stuck while moving 2018-03-05 17:37:08 +01:00
Maikel de Vries 2c43ac6bac item spawn: prevent pickung up two carry heavy objects 2018-03-05 17:37:08 +01:00
Maikel de Vries c2ac2bda42 item spawn: instantly pick carry heavy items 2018-03-05 17:37:07 +01:00
Nicolas Hake 0e45bb8ee9 Enable SSE2 for BLAKE2 library 2018-03-05 17:37:07 +01:00
Maikel de Vries 66f52a4097 keypad: save code hashed, so that they can't be read off in editor mode 2018-03-05 17:37:07 +01:00
Nicolas Hake 3e0ed99c83 Add BLAKE2 library and expose its a CS hash algorithm to script
The crypto "library" only consists of a single function at the
moment because that's all that users have asked for so far. It is
also highly experimental. We will make an attempt to keep the public
interface (i.e. the interface provided by Library_Crypto.c) stable,
but it might still change if necessary. The internal interface
(provided via the global _Crypto proplist) is not for public
consumption and will probably change at some point.
2018-03-05 17:37:07 +01:00
Nicolas Hake 49a1b5aaf7 Make cross-compiling work with GCC 6+
GCC6 doesn't like getting some of its default include search paths
passed with the -isystem flag, and the devs seem unlikely to change
whatever they did back to before they broke it. Work around CMake
not dealing with it well either by figuring out the paths at
configure time and telling CMake about them so it can avoid adding
them superfluously.
2018-03-05 17:37:07 +01:00
Maikel de Vries 0eeaf99266 fix dialogue image size for use as icon 2018-03-05 17:37:07 +01:00
Lukas Werling 03d05ff98f Add EvaluateOnAbort scenario flag for Tower of Despair
In Tower of Despair, the scenario saves per-room progress in the
player files. Players win individual rooms, but never the whole
scenario. Consequently, they currently have to give up to make sure
they don't lose their progress. This is not intuitive at all. With the
new flag enabled, players will be saved even if the scenario is aborted.
2018-03-05 17:37:07 +01:00
Maikel de Vries fabe8302eb add stalactites to hot ice as decoration (#1564) 2018-03-05 17:37:07 +01:00
Maikel de Vries 0f48bb2a86 stalactite: fix raindrop, allow placing in sky, fix stalagmite, clean up 2018-03-05 17:37:07 +01:00
Maikel de Vries 64c08e1510 add star icon 2018-03-05 17:37:07 +01:00
Lukas Werling 32df251d2e Fix editor keyboard input on FreeBSD (hopefully)
Assuming keyboard scancodes on FreeBSD are the same as on Linux.
2018-02-18 22:37:52 +01:00
Lukas Werling 2159895280 Fix IPv4 address serialization on FreeBSD (hopefully) 2018-02-18 22:37:52 +01:00
Lukas Werling 846ba60d46 Editor join: Serialize reference as INI
On FreeBSD, the binary serialization doesn't work for IPv4 addresses,
and we never serialize game references as binary anywhere else.
2018-02-18 22:37:52 +01:00
Lukas Werling e10d4b3bf5 Launch editor via argv[0] on Unix systems without /proc/self/exe (#1999) 2018-02-18 22:37:52 +01:00
Lukas Werling a091874546 Autodetect "/proc/self/exe"-equivalent on FreeBSD (#1999) 2018-02-18 22:37:52 +01:00
Lukas Werling cd1f540b1e Disable -Wformat-security in parts of C4AulCompiler (#1992, GH-64) 2018-02-18 22:37:52 +01:00
Kevin Zheng d57e0e08d2 Fix networking on FreeBSD (#1998) 2018-02-18 22:37:52 +01:00
Lukas Werling 1f20add428 Credits: Fix Kevin Zheng's name 2018-02-18 22:37:52 +01:00
Maikel de Vries 9af9e5d98f docs: removed obsolote Components entry and add IsEditor function 2018-02-15 13:04:22 +01:00
Maikel de Vries 39d55a6c3f floor switch: improve object detection and save switch mass 2018-02-15 13:04:12 +01:00
Lukas Werling ff44b26d4c Enable -Wformat-security for gcc and fix one warning (GH-64)
Fedora has -Werror=format-security enabled per default, so enabling and
fixing these warnings is a good idea.
2018-02-15 13:03:57 +01:00
Maikel de Vries 721d808df3 molten monarch: fix fire particles and fade out gravestones (#1560) 2018-02-15 13:02:05 +01:00
Maikel de Vries 22cd0d03d6 flammable library: burned object copies motion from inflamed object 2018-02-15 13:01:56 +01:00
Maikel de Vries c46b66002c fix some more structure vertices, also for asymmetric ones when flipped (#1979) 2018-02-15 13:01:42 +01:00
Lukas Werling 85d9c2c410 Set C4VERSIONEXTRA to FALSE 2018-02-04 16:39:08 +01:00
Lukas Werling 8f863d8905 Maze/Sandbox: Fix SprayCan include path 2018-02-04 16:37:47 +01:00
Lukas Werling 7a0c323099 Add KKenny to Credits for Miami Ice 2018-02-04 16:27:49 +01:00
Lukas Werling be31964c2e Fix Mac build error 2018-02-04 16:20:38 +01:00
Lukas Werling ce9245c55c Fix warnings in DirectExec crashing (#1990) 2018-02-04 12:35:33 +01:00
Maikel de Vries 92a7087bf7 sandbox: remove god mode objects on departure
This ensures that their too large graphics do not appear for the player, the only departure is when the clonk dies or is removed.
2018-02-04 12:35:32 +01:00
Maikel de Vries c7262aa317 sandbox: use spraycan and overload functionality 2018-02-04 12:35:32 +01:00
Maikel de Vries d3bc20f168 maze: fix warning for declaration of variables and move spray can to Decoration.ocd 2018-02-04 12:35:32 +01:00
Maikel de Vries 6ac777e705 remove strange pixel artefacts from signpost graphics 2018-02-04 12:35:32 +01:00
Maikel de Vries 6ec655cbce sandbox: add english translations and clean up scripts 2018-02-04 12:35:32 +01:00
Lukas Werling 7694ae5020 Fix Mortimer missing in Credits 2018-01-31 21:18:53 +01:00
Lukas Werling 78833d10ee Implement Credits.txt export from StartupAboutDlg
Pressing Ctrl+S while on the Credits screen will save everything to
Credits.txt in the current working directory. This is only meant for
developers modifying the credits; the shortcut isn't mentioned anywhere.
2018-01-31 21:09:30 +01:00
Lukas Werling 3b0b66909e Set C4VERSIONEXTRA to rc2 2018-01-31 17:54:19 +01:00
Lukas Werling 4262fd0c08 Remove folders from planet/ which aren't part of the release 2018-01-31 17:52:14 +01:00
470 changed files with 1813 additions and 16736 deletions

View File

@ -48,6 +48,7 @@ CMAKE_DEPENDENT_OPTION(USE_WIN32_WINDOWS "Use Microsoft Desktop App User Interfa
CMAKE_DEPENDENT_OPTION(USE_SDL_MAINLOOP "Use SDL to create windows etc. Qt editor." ON "NOT USE_COCOA AND NOT USE_WIN32_WINDOWS AND NOT HEADLESS_ONLY" OFF)
option(WITH_AUTOMATIC_UPDATE "Automatic updates are downloaded from the project website." OFF)
option(HEADLESS_ONLY "Only build headless parts. Somewhat reduces dependencies. (still needs libpng because that one's small and hard to remove.) Only tested with make/gcc/linux." OFF)
option(C4GROUP_TOOL_ONLY "Only build c4group binary." OFF)
set_property(GLOBAL PROPERTY USE_FOLDERS ${PROJECT_FOLDERS})
@ -158,7 +159,7 @@ endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wextra-tokens -Wpointer-arith -Wno-cast-align -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual")
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wredundant-decls -Wendif-labels -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Winit-self -Wsign-promo -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wredundant-decls -Wendif-labels -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Winit-self -Wsign-promo -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual -Wformat-security")
endif()
if(WIN32 AND MINGW)
@ -177,6 +178,12 @@ endif()
############################################################################
# Check for compiler quirks and features
############################################################################
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CROSSCOMPILING)
include(HandleGccCrossIncludePaths)
HANDLE_GCC_CROSS_INCLUDE_PATHS(CXX c++)
HANDLE_GCC_CROSS_INCLUDE_PATHS(C c)
endif()
include(CheckCXXSourceCompiles)
include(RequireCXXSourceCompiles)
include(CheckCXXSymbolExists)
@ -224,25 +231,30 @@ CHECK_CXX_SOURCE_COMPILES("#include <getopt.h>\nint main(int argc, char * argv[]
# Locate libraries
############################################################################
SET(JPEG_NAMES ${JPEG_NAMES} libjpeg jpeg-static)
if(NOT HEADLESS_ONLY)
if(NOT HEADLESS_ONLY AND NOT C4GROUP_TOOL_ONLY)
find_package(Freetype REQUIRED)
include_directories(
${FREETYPE_INCLUDE_DIRS})
link_directories(
${FREETYPE_LIBRARY_DIRS})
endif()
find_package(JPEG REQUIRED)
find_package(PNG REQUIRED)
# Needed for c4group
find_package(ZLIB REQUIRED)
include_directories(
${JPEG_INCLUDE_DIR}
${PNG_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR})
if(CMAKE_SYSTEM MATCHES "Windows")
message(STATUS "Using Win32 threading.")
else()
find_package("Threads" REQUIRED)
SET(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT} CACHE INTERNAL "libpthread available")
if (NOT C4GROUP_TOOL_ONLY)
find_package(JPEG REQUIRED)
find_package(PNG REQUIRED)
include_directories(
${JPEG_INCLUDE_DIR}
${PNG_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR})
if(CMAKE_SYSTEM MATCHES "Windows")
message(STATUS "Using Win32 threading.")
else()
find_package("Threads" REQUIRED)
SET(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT} CACHE INTERNAL "libpthread available")
endif()
endif()
# FINDLIB works the same as find_library, but also marks the resulting var as
@ -267,19 +279,20 @@ if(NOT HAVE_GETOPT_H)
set(GETOPT_LIBRARIES getopt)
endif()
# TinyXML
find_package(TinyXML)
if(NOT TinyXML_FOUND)
add_subdirectory(thirdparty/tinyxml)
set_property(TARGET tinyxml PROPERTY FOLDER "Third-party libraries")
set(TinyXML_INCLUDE_DIRS thirdparty/tinyxml)
set(TinyXML_LIBRARIES tinyxml)
set(TinyXML_FOUND TRUE)
if (NOT C4GROUP_TOOL_ONLY)
# TinyXML
find_package(TinyXML)
if(NOT TinyXML_FOUND)
add_subdirectory(thirdparty/tinyxml)
set_property(TARGET tinyxml PROPERTY FOLDER "Third-party libraries")
set(TinyXML_INCLUDE_DIRS thirdparty/tinyxml)
set(TinyXML_LIBRARIES tinyxml)
set(TinyXML_FOUND TRUE)
endif()
include_directories(SYSTEM ${TinyXML_INCLUDE_DIRS})
endif()
include_directories(SYSTEM ${TinyXML_INCLUDE_DIRS})
if(NOT HEADLESS_ONLY)
if(NOT HEADLESS_ONLY AND NOT C4GROUP_TOOL_ONLY)
find_package(OpenGL)
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
@ -291,13 +304,26 @@ if(NOT HEADLESS_ONLY)
CHECK_CXX_SOURCE_COMPILES("#include <GL/glew.h>\nvoid GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam) {}\nint main() { GLDEBUGPROCARB proc = &OpenGLDebugProc; }" GLDEBUGPROCARB_USERPARAM_IS_CONST)
endif()
if(UNIX AND NOT APPLE)
FINDLIB(X11_LIBRARIES X11)
if(NOT C4GROUP_TOOL_ONLY)
if(UNIX AND NOT APPLE)
FINDLIB(X11_LIBRARIES X11)
set(Backward_DIR thirdparty/backward-cpp)
find_package(Backward)
if(Backward_FOUND)
set(HAVE_BACKWARD 1)
set(Backward_DIR thirdparty/backward-cpp)
find_package(Backward)
if(Backward_FOUND)
set(HAVE_BACKWARD 1)
endif()
if(NOT DEFINED PROC_SELF_EXE)
macro(FIND_PROC_SELF_EXE path)
if(EXISTS ${path})
set(PROC_SELF_EXE ${path} CACHE FILEPATH "Path to /proc/self/exe (Linux) or equivalent")
endif()
endmacro()
FIND_PROC_SELF_EXE(/proc/self/exe) # Linux
FIND_PROC_SELF_EXE(/proc/curproc/file) # FreeBSD
FIND_PROC_SELF_EXE(/proc/curproc/exe) # NetBSD
endif()
endif()
endif()
@ -309,71 +335,75 @@ if (WIN32)
set(HAVE_DBGHELP ${DBGHELP_FOUND})
endif()
find_package(Upnp)
if(UPNP_FOUND)
include_directories(SYSTEM ${UPNP_INCLUDE_DIR})
endif()
if(NOT C4GROUP_TOOL_ONLY)
find_package(Upnp)
if(UPNP_FOUND)
include_directories(SYSTEM ${UPNP_INCLUDE_DIR})
endif()
find_package(Readline)
if(READLINE_FOUND)
include_directories(SYSTEM ${READLINE_INCLUDE_DIR})
endif()
SET(HAVE_LIBREADLINE ${READLINE_FOUND} CACHE INTERNAL "libreadline available")
find_package(Readline)
if(READLINE_FOUND)
include_directories(SYSTEM ${READLINE_INCLUDE_DIR})
endif()
SET(HAVE_LIBREADLINE ${READLINE_FOUND} CACHE INTERNAL "libreadline available")
find_package(GTK3 COMPONENTS gthread gio gobject glib OPTIONAL_COMPONENTS gtksourceview)
find_package(GTK3 COMPONENTS gthread gio gobject glib OPTIONAL_COMPONENTS gtksourceview)
# Select an audio library
find_package("Audio")
if(Audio_FOUND)
include_directories(${Audio_INCLUDE_DIRS})
endif()
# Select an audio library
find_package("Audio")
if(Audio_FOUND)
include_directories(${Audio_INCLUDE_DIRS})
endif()
# SDL
if(USE_SDL_MAINLOOP)
find_package(SDL2 REQUIRED)
else()
# for gamepads
find_package(SDL2)
endif()
set(HAVE_SDL ${SDL2_FOUND})
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
# SDL
if(USE_SDL_MAINLOOP)
find_package(SDL2 REQUIRED)
else()
# for gamepads
find_package(SDL2)
endif()
set(HAVE_SDL ${SDL2_FOUND})
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
# Qt5 for editor
find_path(Qt5DIR qt.pro PATHS ${CMAKE_ADDITIONAL_DEPS_PATH}/qt-5.5.0)
find_package(Qt5Widgets 5.4 PATHS ${Qt5DIR}/qtbase/lib/cmake/Qt5Widgets)
if(Qt5Widgets_FOUND)
SET(WITH_QT_EDITOR ${Qt5Widgets_FOUND} "Qt editor dialogues available")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
else()
message("Qt5Widgets not found. Building openclonk without editor.")
UNSET(WITH_QT_EDITOR)
# Qt5 for editor
find_path(Qt5DIR qt.pro PATHS ${CMAKE_ADDITIONAL_DEPS_PATH}/qt-5.5.0)
find_package(Qt5Widgets 5.4 PATHS ${Qt5DIR}/qtbase/lib/cmake/Qt5Widgets)
if(Qt5Widgets_FOUND)
SET(WITH_QT_EDITOR ${Qt5Widgets_FOUND} "Qt editor dialogues available")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
else()
message("Qt5Widgets not found. Building openclonk without editor.")
UNSET(WITH_QT_EDITOR)
endif()
endif()
############################################################################
# generated source files
############################################################################
find_program(GLIB_COMPILE_RESOURCES glib-compile-resources)
if(NOT C4GROUP_TOOL_ONLY)
find_program(GLIB_COMPILE_RESOURCES glib-compile-resources)
add_custom_command(
OUTPUT mape-resource.c
COMMAND
${GLIB_COMPILE_RESOURCES} "--internal" "--generate"
"--target" "mape-resource.c"
"--sourcedir" ${CMAKE_CURRENT_SOURCE_DIR}/src/res
"${CMAKE_CURRENT_SOURCE_DIR}/src/res/mape.xml"
MAIN_DEPENDENCY src/res/mape.xml
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocd.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocf.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocg.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocm.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocs.ico
VERBATIM
)
add_custom_command(
OUTPUT mape-resource.c
COMMAND
${GLIB_COMPILE_RESOURCES} "--internal" "--generate"
"--target" "mape-resource.c"
"--sourcedir" ${CMAKE_CURRENT_SOURCE_DIR}/src/res
"${CMAKE_CURRENT_SOURCE_DIR}/src/res/mape.xml"
MAIN_DEPENDENCY src/res/mape.xml
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocd.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocf.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocg.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocm.ico
${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocs.ico
VERBATIM
)
endif()
############################################################################
# Mac OS bundle setup
@ -973,7 +1003,7 @@ include_directories(SYSTEM
############################################################################
add_definitions(-DHAVE_CONFIG_H)
add_library(libmisc
add_library(libmisc STATIC
src/C4Include.cpp
src/c4group/C4Group.cpp
src/c4group/C4Group.h
@ -1038,7 +1068,7 @@ if(UNIX AND NOT APPLE)
target_link_libraries(libmisc rt)
endif()
add_library(libc4script
add_library(libc4script STATIC
src/C4Include.cpp
src/c4group/C4ComponentHost.cpp
src/c4group/C4ComponentHost.h
@ -1072,6 +1102,8 @@ src/script/C4PropList.h
src/script/C4Script.cpp
src/script/C4ScriptHost.cpp
src/script/C4ScriptHost.h
src/script/C4ScriptLibraries.cpp
src/script/C4ScriptLibraries.h
src/script/C4StringTable.cpp
src/script/C4StringTable.h
src/script/C4Value.cpp
@ -1081,10 +1113,11 @@ src/script/C4ValueArray.h
src/script/C4ValueMap.cpp
src/script/C4ValueMap.h
)
add_subdirectory(thirdparty/blake2)
set_property(TARGET blake2 PROPERTY FOLDER "Third-party libraries")
target_link_libraries(libc4script blake2 libmisc)
target_link_libraries(libc4script libmisc)
add_library(libopenclonk
add_library(libopenclonk STATIC
src/c4group/C4Extra.cpp
src/c4group/C4Extra.h
src/control/C4PlayerInfoConflicts.cpp
@ -1154,7 +1187,7 @@ target_link_libraries(c4script
${GETOPT_LIBRARIES}
)
if(NOT HEADLESS_ONLY)
if(NOT HEADLESS_ONLY AND NOT C4GROUP_TOOL_ONLY)
add_executable(openclonk WIN32 MACOSX_BUNDLE
${OC_SYSTEM_SOURCES}
${OC_GUI_SOURCES}
@ -1194,40 +1227,42 @@ if(NOT HEADLESS_ONLY)
endif()
endif()
add_executable(openclonk-server
${OC_SYSTEM_SOURCES}
${OC_CLONK_SOURCES}
src/platform/C4AppT.cpp
src/platform/C4StdInProc.cpp
src/platform/C4StdInProc.h
)
target_compile_definitions(openclonk-server PRIVATE "USE_CONSOLE")
if(NOT C4GROUP_TOOL_ONLY)
add_executable(openclonk-server
${OC_SYSTEM_SOURCES}
${OC_CLONK_SOURCES}
src/platform/C4AppT.cpp
src/platform/C4StdInProc.cpp
src/platform/C4StdInProc.h
)
target_compile_definitions(openclonk-server PRIVATE "USE_CONSOLE")
target_link_libraries(openclonk-server
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${EXECINFO_LIBRARY}
${SDL2_LIBRARIES}
${READLINE_LIBRARIES}
${Audio_LIBRARIES}
${GETOPT_LIBRARIES}
${TinyXML_LIBRARIES}
${DBGHELP_LIBRARIES}
libmisc
libc4script
libopenclonk
)
if(UPNP_FOUND)
target_link_libraries(openclonk-server ${UPNP_LIBRARIES})
endif()
if(USE_COCOA)
target_link_libraries(openclonk-server "-framework Cocoa")
endif()
if(HAVE_BACKWARD)
target_link_libraries(openclonk-server Backward::Backward)
target_link_libraries(openclonk-server
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${EXECINFO_LIBRARY}
${SDL2_LIBRARIES}
${READLINE_LIBRARIES}
${Audio_LIBRARIES}
${GETOPT_LIBRARIES}
${TinyXML_LIBRARIES}
${DBGHELP_LIBRARIES}
libmisc
libc4script
libopenclonk
)
if(UPNP_FOUND)
target_link_libraries(openclonk-server ${UPNP_LIBRARIES})
endif()
if(USE_COCOA)
target_link_libraries(openclonk-server "-framework Cocoa")
endif()
if(HAVE_BACKWARD)
target_link_libraries(openclonk-server Backward::Backward)
endif()
endif()
if(GTK3_FOUND AND GTK3_gtksourceview_FOUND AND NOT HEADLESS_ONLY)
if(GTK3_FOUND AND GTK3_gtksourceview_FOUND AND NOT HEADLESS_ONLY AND NOT C4GROUP_TOOL_ONLY)
add_executable(mape ${MAPE_BASE_SOURCES} ${MAPE_SOURCES})
target_compile_options(mape PRIVATE ${GTK3_COMPILE_DEFINITIONS} ${GTK3_gtksourceview_COMPILE_DEFINITIONS})
set_property(TARGET mape PROPERTY FOLDER "Utilities")
@ -1254,17 +1289,19 @@ target_link_libraries(c4group
libmisc
)
add_executable(netpuncher EXCLUDE_FROM_ALL
src/netpuncher/C4PuncherHash.h
src/netpuncher/main.cpp
)
if(NOT C4GROUP_TOOL_ONLY)
add_executable(netpuncher EXCLUDE_FROM_ALL
src/netpuncher/C4PuncherHash.h
src/netpuncher/main.cpp
)
target_link_libraries(netpuncher
libmisc
)
target_link_libraries(netpuncher
libmisc
)
if(WIN32)
target_link_libraries(libmisc iphlpapi ws2_32)
if(WIN32)
target_link_libraries(libmisc iphlpapi ws2_32)
endif()
endif()
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG>)
@ -1281,7 +1318,7 @@ if (APPLE AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
set(EXECUTABLE_NAME openclonk)
endif()
if(NOT HEADLESS_ONLY)
if(NOT HEADLESS_ONLY AND NOT C4GROUP_TOOL_ONLY)
set_target_properties(openclonk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Info.plist")
endif()
@ -1367,7 +1404,9 @@ endif()
############################################################################
# Miscellaneous
############################################################################
add_subdirectory(tests)
if(NOT C4GROUP_TOOL_ONLY)
add_subdirectory(tests)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
@ -1415,18 +1454,20 @@ IF(WITH_AUTOMATIC_UPDATE)
INSTALL(CODE "MESSAGE(SEND_ERROR \"Installation is only supported for WITH_AUTOMATIC_UPDATE disabled\")")
ENDIF()
# hack to build the data on install, see
# http://public.kitware.com/Bug/view.php?id=8438
add_custom_target(data)
set_property(TARGET data PROPERTY FOLDER "Setup")
install(
CODE
"execute_process(
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target data
)"
)
if(NOT C4GROUP_TOOL_ONLY)
# hack to build the data on install, see
# http://public.kitware.com/Bug/view.php?id=8438
add_custom_target(data)
set_property(TARGET data PROPERTY FOLDER "Setup")
install(
CODE
"execute_process(
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target data
)"
)
endif()
if (NOT APPLE)
if (NOT APPLE AND NOT C4GROUP_TOOL_ONLY)
install(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc32.png
DESTINATION share/icons/hicolor/32x32/apps
@ -1461,78 +1502,88 @@ ENDIF()
# When cross-compiling, import c4group from a native build
IF(CMAKE_CROSSCOMPILING)
SET(IMPORT_NATIVE_TOOLS "IMPORT_NATIVE_TOOLS-NOTFOUND" CACHE FILEPATH "Export file from a native build")
INCLUDE(${IMPORT_NATIVE_TOOLS})
SET(native_c4group native-c4group)
FIND_PROGRAM(C4GROUP_PATH NAMES c4group PATHS)
IF (NOT C4GROUP_PATH)
SET(IMPORT_NATIVE_TOOLS "IMPORT_NATIVE_TOOLS-NOTFOUND" CACHE FILEPATH "Export file from a native build")
INCLUDE(${IMPORT_NATIVE_TOOLS})
SET(native_c4group native-c4group)
ELSE()
SET(native_c4group ${C4GROUP_PATH})
ENDIF()
ELSE()
SET(native_c4group c4group)
ENDIF()
# NOTE: The scripts that does the autobuilds and ultimately the automated
# releases as well do keep their own list of group files around currently.
# So if you change anything here, change it in the release scripts as well.
# See openclonk-release-scripts.git/groupcontent.py
set(OC_C4GROUPS
Graphics.ocg
Material.ocg
Sound.ocg
System.ocg
Objects.ocd
Decoration.ocd
Arena.ocf
Parkour.ocf
Defense.ocf
Missions.ocf
Tutorials.ocf
Worlds.ocf
)
if(APPLE)
list(APPEND OC_C4GROUPS Music.ocg)
endif()
foreach(group ${OC_C4GROUPS})
if (APPLE)
if (CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(TARGET openclonk
POST_BUILD COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_pack_gamedata.sh"
"$<TARGET_FILE:${native_c4group}>"
"${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}"
# leave out third parameter here so the script can figure out Xcode-ish paths as usual
DEPENDS "${native_c4group}"
)
else()
add_custom_command(TARGET openclonk
POST_BUILD COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_pack_gamedata.sh"
"$<TARGET_FILE:${native_c4group}>"
"${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}"
"${CMAKE_CURRENT_BINARY_DIR}/openclonk.app/Contents/Resources"
DEPENDS "${native_c4group}"
)
endif()
else()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${group}
COMMAND "${native_c4group}" ARGS "${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}" -t "${CMAKE_CURRENT_BINARY_DIR}/${group}"
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}
DEPENDS "${native_c4group}"
VERBATIM
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${group} DESTINATION share/games/openclonk)
if(NOT C4GROUP_TOOL_ONLY)
# NOTE: The scripts that does the autobuilds and ultimately the automated
# releases as well do keep their own list of group files around currently.
# So if you change anything here, change it in the release scripts as well.
# See openclonk-release-scripts.git/groupcontent.py
set(OC_C4GROUPS
Graphics.ocg
Material.ocg
Sound.ocg
System.ocg
Objects.ocd
Decoration.ocd
Arena.ocf
Parkour.ocf
Defense.ocf
Missions.ocf
Tutorials.ocf
Worlds.ocf
)
if(APPLE)
list(APPEND OC_C4GROUPS Music.ocg)
endif()
endforeach()
foreach(group ${OC_C4GROUPS})
if (APPLE)
if (CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(TARGET openclonk
POST_BUILD COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_pack_gamedata.sh"
"$<TARGET_FILE:${native_c4group}>"
"${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}"
# leave out third parameter here so the script can figure out Xcode-ish paths as usual
DEPENDS "${native_c4group}"
)
else()
add_custom_command(TARGET openclonk
POST_BUILD COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_pack_gamedata.sh"
"$<TARGET_FILE:${native_c4group}>"
"${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}"
"${CMAKE_CURRENT_BINARY_DIR}/openclonk.app/Contents/Resources"
DEPENDS "${native_c4group}"
)
endif()
else()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${group}
COMMAND "${native_c4group}" ARGS "${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}" -t "${CMAKE_CURRENT_BINARY_DIR}/${group}"
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}
DEPENDS "${native_c4group}"
VERBATIM
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${group} DESTINATION share/games/openclonk)
endif()
endforeach()
endif()
if(NOT APPLE)
if(NOT HEADLESS_ONLY)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/planet/Music.ocg DESTINATION share/games/openclonk)
endif()
# group files (game data)
add_custom_target(groups DEPENDS ${OC_C4GROUPS})
set_property(TARGET groups PROPERTY FOLDER "Setup")
add_dependencies(data groups)
if(NOT C4GROUP_TOOL_ONLY)
# group files (game data)
add_custom_target(groups DEPENDS ${OC_C4GROUPS})
set_property(TARGET groups PROPERTY FOLDER "Setup")
add_dependencies(data groups)
endif()
# Install binaries
install(TARGETS c4group DESTINATION bin)
endif()
if(NOT HEADLESS_ONLY)
if(NOT HEADLESS_ONLY AND NOT C4GROUP_TOOL_ONLY)
if(NOT APPLE)
# Install new files
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/openclonk.desktop DESTINATION share/applications)
@ -1558,26 +1609,28 @@ endif()
# setup_openclonk.exe
############################################################################
find_program(MAKENSIS makensis PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS])
if(NOT C4GROUP_TOOL_ONLY)
find_program(MAKENSIS makensis PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS])
if(NOT HEADLESS_ONLY)
add_custom_command(
OUTPUT setup_openclonk.exe
COMMAND ${MAKENSIS} -NOCD -DSRCDIR=${CMAKE_CURRENT_SOURCE_DIR} -DPROGRAMFILES=$PROGRAMFILES "-DPRODUCT_NAME=${C4ENGINENAME}" "-DPRODUCT_COMPANY=${C4PROJECT}" "-DCLONK=$<TARGET_FILE_DIR:openclonk>\\$<TARGET_FILE_NAME:openclonk>" "-DC4GROUP=$<TARGET_FILE_DIR:c4group>\\$<TARGET_FILE_NAME:c4group>" ${CMAKE_CURRENT_SOURCE_DIR}/tools/install/oc.nsi "-XOutFile setup_openclonk.exe"
MAIN_DEPENDENCY
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/oc.nsi
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/header.bmp
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/inst.ico
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/uninst.ico
${OC_C4GROUPS} openclonk c4group
VERBATIM
)
if(NOT HEADLESS_ONLY)
add_custom_command(
OUTPUT setup_openclonk.exe
COMMAND ${MAKENSIS} -NOCD -DSRCDIR=${CMAKE_CURRENT_SOURCE_DIR} -DPROGRAMFILES=$PROGRAMFILES "-DPRODUCT_NAME=${C4ENGINENAME}" "-DPRODUCT_COMPANY=${C4PROJECT}" "-DCLONK=$<TARGET_FILE_DIR:openclonk>\\$<TARGET_FILE_NAME:openclonk>" "-DC4GROUP=$<TARGET_FILE_DIR:c4group>\\$<TARGET_FILE_NAME:c4group>" ${CMAKE_CURRENT_SOURCE_DIR}/tools/install/oc.nsi "-XOutFile setup_openclonk.exe"
MAIN_DEPENDENCY
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/oc.nsi
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/header.bmp
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/inst.ico
${CMAKE_CURRENT_SOURCE_DIR}/tools/install/uninst.ico
${OC_C4GROUPS} openclonk c4group
VERBATIM
)
add_custom_target(setup
DEPENDS setup_openclonk.exe groups
)
set_property(TARGET setup PROPERTY FOLDER "Setup")
add_custom_target(setup
DEPENDS setup_openclonk.exe groups
)
set_property(TARGET setup PROPERTY FOLDER "Setup")
endif()
endif()
############################################################################

View File

@ -1,15 +1,17 @@
<Engine and Tools>
Sven Eberhardt (Sven2)
Armin Burgmeier (Clonk-Karl)
Günther Brammer (Günther)
Nicolas Hake (Isilkor)
Armin Burgmeier (Clonk-Karl)
Lukas Werling (Luchs)
Martin Plicht (Mortimer)
Julius Michaelis (JCaesar)
Peter Wortmann (PeterW)
Julius Michaelis (Caesar)
<Scripting and Content>
Maikel de Vries (Maikel)
David Dormagen (Zapper)
Mark Haßelbusch (Marky)
Felix Wagner (Clonkonaut)
Bernhard Bonigl (Boni)
@ -26,11 +28,8 @@ Martin Strohmeier (K-Pone)
<Administration>
Tobias Zwick (Newton)
<Thanks to our package maintainers>
Benedict Etzel (B_E), Philipp Kern (pkern), Kevin Zheng and more
<Special Thanks to Contributors>
Martin Adam (Win), Florian Graier (Nachtfalter), Mark Haßelbusch (Marky), Merten Ehmig (pluto), Benjamin Herr (Loriel), Armin Schäfer, Pyrit, Philip Holzmann (Batman), Alexander Semeniuk (AlteredARMOR), Andriel, Peewee, Oliver Schneider (ker), Fabian Pietsch, Manuel Rieke (MrBeast), Felix Riese (Fungiform), Carl-Philip Hänsch (Carli), Sebastian Rühl, Gurkenglas and many more:
Luchs, Asmageddon, mizipzor, Tim Blume, Apfelclonk, Sven-Hendrik Haase, Lauri Niskanen (Ape), Daniel Theuke (ST-DDT), Russell, Stan, TomyLobo, Clonkine, Koronis, Johannes Nixdorf (mixi), grgecko, Dominik Bayerl, Misty de Meo, Lorenz Schwittmann, hasufell, Jan Heberer, dylanstrategie, Checkmaty, Faby
Also, big thanks to Matthes Bender and all those who contributed to previous Clonk titles for the passion they put into the game and for agreeing to make Clonk open source.
Contributors for OpenClonk 8.0: George Tokmaji (Fulgen), Martin Adam (Win), Merten Ehmig (pluto), Florian Graier (Nachtfalter), Philip Holzmann (Foaly), Dominik Bayerl (Kanibal), Linus Heckemann (sphalerite), Pyrit, Thomas Wiest (KKenny), Armin Schäfer, Tushar Maheshwari, jok, Tarte, Philip Kern (pkern), Arne Schauf (NativeException), Matthias Mailänder, marsmoon
Previous contributors: Tim Blume, Sven-Hendrik Haase, Carl-Philip Hänsch (Carli), Jan Heberer, Benjamin Herr (Loriel), Lauri Niskanen (Ape), Johannes Nixdorf (mixi), Misty de Meo, Fabian Pietsch, Manuel Rieke (MrBeast), Felix Riese (Fungiform), Sebastian Rühl, Oliver Schneider (ker), Lorenz Schwittmann, Alexander Semeniuk (AlteredARMOR), Daniel Theuke (ST-DDT), Andriel, Apfelclonk, Asmageddon, Checkmaty, Clonkine, dylanstrategie, Faby, grgecko, Gurkenglas, hasufell, Koronis, mizipzor, Peewee, Russell, Stan, TomyLobo
Also thanks to our Linux package maintainers Benedict Etzel (B_E), Linus Heckemann (sphalerite), Philip Kern (pkern), Matthias Mailänder, Julian Ospald (hasufell), Kevin Zheng, and more
Finally, a big thanks to Matthes Bender and all those who contributed to previous Clonk titles for the passion they put into the game and for agreeing to make Clonk open source.

View File

@ -23,8 +23,8 @@ SET(C4ENGINENAME "OpenClonk")
SET(C4ENGINENICK "openclonk")
SET(C4XVER1 8)
SET(C4XVER2 0)
SET(C4XVER2 1)
# Set this variable to any string for pre-release versions, like "alpha" or
# "rc1". Don't supply a value (FALSE) for release versions.
SET(C4VERSIONEXTRA "rc1")
SET(C4VERSIONEXTRA FALSE)

View File

@ -0,0 +1,37 @@
# OpenClonk, http://www.openclonk.org
#
# Copyright (c) 2018, The OpenClonk Team and contributors
#
# Distributed under the terms of the ISC license; see accompanying file
# "COPYING" for details.
#
# "Clonk" is a registered trademark of Matthes Bender, used with permission.
# See accompanying file "TRADEMARK" for details.
#
# To redistribute this file separately, substitute the full license texts
# for the above references.
# GCC6 doesn't work well with CMake while cross-compiling. See bugs:
# https://gitlab.kitware.com/cmake/cmake/issues/16291
# https://gitlab.kitware.com/cmake/cmake/issues/16919
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129
function(HANDLE_GCC_CROSS_INCLUDE_PATHS _lang _gcc_lang_flag)
set(_compiler "${CMAKE_${_lang}_COMPILER}")
set(_compile_flags "${CMAKE_${_lang}_FLAGS}")
separate_arguments(_compile_flags UNIX_COMMAND "${_compile_flags}")
execute_process(
COMMAND ${_compiler} ${_compile_flags} -v -E -x ${_gcc_lang_flag} /dev/null
OUTPUT_QUIET
ERROR_VARIABLE _compiler_output
)
if ("${_compiler_output}" MATCHES "#include <\\.\\.\\.> search starts here:\n *(.*)\nEnd of search list\\.")
string(REGEX REPLACE "[\n ]+" " " _search_list "${CMAKE_MATCH_1}")
separate_arguments(_search_list)
foreach(_directory ${_search_list})
get_filename_component(_fixed_component "${_directory}" REALPATH)
set(_resolved_list ${_resolved_list} "${_fixed_component}")
endforeach()
set(CMAKE_${_lang}_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_${_lang}_IMPLICIT_INCLUDE_DIRECTORIES} ${_resolved_list} PARENT_SCOPE)
endif()
endfunction()

View File

@ -118,3 +118,6 @@
/* Include OpenAL extensions (alext.h) for sound modifiers */
#cmakedefine HAVE_ALEXT 1
/* Path to /proc/self/exe (Linux) or equivalent */
#cmakedefine PROC_SELF_EXE "${PROC_SELF_EXE}"

View File

@ -60,11 +60,6 @@
<col>Integer</col>
<col>Weight of the object. Rock 10, clonk 50, hut 1000, castle 10000.</col>
</row>
<row>
<literal_col>Components</literal_col>
<col>ID list</col>
<col>Elements from which the object is composed. Uncompleted or half grown objects will only have the respective fraction of the components.</col>
</row>
<row>
<literal_col>SolidMask</literal_col>
<col>6 integers</col>

View File

@ -122,9 +122,14 @@
</row>
<row>
<col>FoWEnabled</col>
<col>Integer</col>
<col>Bool</col>
<col>0 or 1. If 0, FoW is disabled, and the whole landscape is visible. Default 1.</col>
</row>
<row>
<col>EvaluateOnAbort</col>
<col>Bool</col>
<col>If enabled, the game will be evaluated even when aborted by the player. This is intended for scenarios like Tower of Despair that save progress in players. Default false.</col>
</row>
</table>
</text>
<text>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>IsEditor</title>
<category>Global</category>
<version>8.0 OC</version>
<syntax><rtype>bool</rtype></syntax>
<desc>Returns whether the current game is an editor game.</desc>
<examples>
<example>
<code>public func InitializePlayer(int plr)
{
if (IsEditor())
<funclink>SetWealth</funclink>funclink>(plr, 10**4);
}</code>
<text>Gives the player a lot of wealth for testing purposes in editor mode.</text>
</example>
</examples>
</func>
<author>Maikel</author><date>2018-02</date>
</funcs>

View File

@ -468,14 +468,14 @@ func IsFirestoneSpot(int x, int y)
}
// ============= Themes =============
static const HotIce = new Global {
static const DefaultTheme = new Global
{
InitializeRound = func() { },
LavaMat = "^DuroLava",
IceMats = ["^Ice-ice", "^Ice-ice2"],
AltMatRatio = 50,
BackgroundMat = nil,
Sky = "Default",
PlayList = nil,
InitializeMusic = func()
{
@ -489,17 +489,31 @@ static const HotIce = new Global {
SetPlayList(this.PlayList, NO_OWNER, true);
SetGlobalSoundModifier(nil);
}
},
}
};
static const EciToh = new HotIce {
static const HotIce = new DefaultTheme
{
InitializeRound = func()
{
Stalactite->Place(10 + Random(3));
}
};
static const EciToh = new DefaultTheme
{
LavaMat = "DuroLava",
IceMats = ["Coal", "Rock-rock"],
AltMatRatio = 8,
BackgroundMat = "Tunnel",
InitializeRound = func()
{
Stalactite->Place(10 + Random(3));
}
};
static const MiamiIce = new HotIce {
static const MiamiIce = new DefaultTheme
{
IceMats = ["^BlackIce-black", "^BlackIce-black"],
Sky = "SkyMiami",
PlayList =
@ -526,6 +540,5 @@ static const MiamiIce = new HotIce {
o->SetClrModulation(HSL(time, 255, 100));
}
},
},
}
};

View File

@ -17,7 +17,7 @@ protected func Initialize()
// Objects fade after 7 seconds.
CreateObject(Rule_ObjectFade)->DoFadeTime(7 * 36);
CreateObject(Rule_KillLogs);
CreateObject(Rule_Gravestones);
CreateObject(Rule_Gravestones)->SetFadeOut(3 * 36);
GetRelaunchRule()->SetLastWeaponUse(false);
//make lava collapse
@ -101,7 +101,7 @@ global func FxDeathByFireTimer(object target, effect fx, int timer)
}
}
CreateParticle("Fire", PV_Random(55, 90), PV_Random(0, 40), PV_Random(-1, 1), PV_Random(0, 20), PV_Random(10, 40), fx.particles, 20);
CreateParticle("Fire", PV_Random(55, 95), PV_Random(0, 40), PV_Random(-1, 1), PV_Random(0, 20), PV_Random(10, 40), fx.particles, 20);
}
global func FxLavaBrickResetTimer(object target, effect, int timer)

View File

@ -35,9 +35,9 @@ protected func Initialize()
var waterfall;
waterfall = CreateWaterfall(130, 53, 2, "Water");
waterfall->SetDirection(4, 0, 3, 6);
waterfall->SetDirection(6, 3, 2, 3);
waterfall = CreateWaterfall(144, 50, 8, "Water");
waterfall->SetDirection(6, 0, 5, 6);
waterfall->SetDirection(9, 3, 3, 3);
CreateLiquidDrain(100, 315, 10);
CreateLiquidDrain(130, 315, 10);
CreateLiquidDrain(160, 315, 10);

View File

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 203 B

View File

@ -1,4 +1,9 @@
/* Spray can */
/**
Spray can
Let out the little artist in you!
@author Sven2
*/
local last_x, last_y, last_ldx, last_ldy;
local paint_col;
@ -6,13 +11,13 @@ local max_dist = 50;
static SprayCan_last_col;
protected func Construction()
public func Construction()
{
SetPaintCol(SprayCan_last_col++);
return true;
return;
}
func SetPaintCol(int idx)
public func SetPaintCol(int idx)
{
idx %= 5;
var tex_name = Format("Paint%s",["Red", "Green", "Teal", "Yellow", "White"][idx]);
@ -39,7 +44,7 @@ public func HoldingEnabled() { return true; }
public func ControlUseHolding(object clonk, int new_x, int new_y)
{
// Out of reach? Stop spraying.
if (Distance(0,0,new_x,new_y) > max_dist)
if (Distance(0, 0, new_x, new_y) > max_dist)
{
SetAction("Idle");
return true;
@ -49,16 +54,22 @@ public func ControlUseHolding(object clonk, int new_x, int new_y)
new_x += GetX(); new_y += GetY();
// (re-)start spraying
if (GetAction() != "Spraying") StartSpraying(clonk, new_x, new_y);
if (GetAction() != "Spraying")
StartSpraying(clonk, new_x, new_y);
// Spray paint if position moved
if (new_x==last_x && new_y == last_y) return true;
if (new_x == last_x && new_y == last_y)
return true;
var wdt = 2;
var dx=new_x-last_x, dy=new_y-last_y;
var d = Distance(dx,dy);
var ldx = dy*wdt/d, ldy = -dx*wdt/d;
if (!last_ldx && !last_ldy) { last_ldx=ldx; last_ldy=ldy; }
DrawMaterialQuad(paint_col, last_x-last_ldx,last_y-last_ldy, last_x+last_ldx,last_y+last_ldy, new_x+ldx,new_y+ldy, new_x-ldx,new_y-ldy, DMQ_Bridge);
var dx = new_x - last_x, dy = new_y - last_y;
var d = Distance(dx, dy);
var ldx = dy * wdt / d, ldy = -dx *wdt / d;
if (!last_ldx && !last_ldy)
{
last_ldx = ldx;
last_ldy = ldy;
}
DrawMaterialQuad(paint_col, last_x - last_ldx, last_y - last_ldy, last_x + last_ldx, last_y + last_ldy, new_x + ldx, new_y + ldy, new_x - ldx, new_y - ldy, DMQ_Bridge);
last_x = new_x; last_y = new_y;
last_ldx = ldx; last_ldy = ldy;
return true;
@ -80,14 +91,25 @@ private func StartSpraying(object clonk, int x, int y)
{
// Go into spray mode and place an initial blob
last_x = x; last_y = y;
last_ldx=last_ldy=0;
last_ldx = last_ldy = 0;
var r = Random(90), wdt = 2;
var ldx = Sin(r, wdt), ldy = Cos(r, wdt);
DrawMaterialQuad(paint_col, x-ldx,y-ldy, x-ldy,y+ldx, x+ldx,y+ldy, x+ldy,y-ldx, DMQ_Bridge);
DrawMaterialQuad(paint_col, x - ldx, y - ldy, x - ldy, y + ldx, x + ldx, y + ldy, x + ldy, y - ldx, DMQ_Bridge);
SetAction("Spraying");
return true;
}
public func Definition(def)
{
SetProperty("PictureTransformation", Trans_Rotate(-30, 0, 1, 1), def);
}
/*-- Properties --*/
local Collectible = true;
local Name = "$Name$";
local Description = "$Description$";
local ActMap = {
Spraying = {
@ -96,15 +118,7 @@ local ActMap = {
Length = 1,
Delay = 1,
Name = "Spraying",
Sound = "SprayCan::SprayCan",
Sound = "Objects::SprayCan",
NextAction = "Spraying",
}
};
func Definition(def) {
SetProperty("PictureTransformation",Trans_Rotate(-30,0,1,1),def);
}
local Collectible = 1;
local Name = "$Name$";
local Description = "$Description$";

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -20,12 +20,18 @@ public func Initialize()
public func CheckObjects()
{
// Find all the objects on the switch.
var obj_on_switch = FindObjects(Find_InRect(-20, -30, 40, 30), Find_AtRect(-20, -10, 40, 8), Find_NoContainer(), Find_Not(Find_Category(C4D_StaticBack)));
for (var index = GetLength(obj_on_switch) - 1; index >= 0; index--)
{
var obj = obj_on_switch[index];
if (!obj->GetContact(-1, CNAT_Bottom) || obj->Stuck())
RemoveArrayIndex(obj_on_switch, index);
}
// Get the total mass on the switch.
var total_mass = 0;
var obj_on_switch = FindObjects(Find_InRect(-20, -30, 40, 30), Find_NoContainer(), Find_Not(Find_Category(C4D_StaticBack)));
for (var obj in obj_on_switch)
if (obj->GetContact(-1, CNAT_Bottom))
total_mass += obj->GetMass();
var total_mass = 0;
for (var obj in obj_on_switch)
total_mass += obj->GetMass();
// Determine desired position.
var desired_y = 0;
if (total_mass >= this.SwitchMass)
@ -36,9 +42,12 @@ public func CheckObjects()
// Determine movement change and move switch plus object on it.
var change = BoundBy(desired_y - y_position, -1, 1);
for (var obj in obj_on_switch)
if (obj->GetContact(-1, CNAT_Bottom))
obj->SetPosition(obj->GetX(), obj->GetY() + change);
obj->SetPosition(obj->GetX(), obj->GetY() + change);
SetPosition(GetX(), GetY() + change);
// Do not make objects stuck.
for (var obj in obj_on_switch)
if (obj->Stuck())
obj->SetPosition(obj->GetX(), obj->GetY() - change);
y_position += change;
// Do moving of target door or perform user actions.
if (y_position == desired_y)
@ -71,6 +80,7 @@ public func SaveScenarioObject(proplist props)
{
if (!inherited(props, ...)) return false;
if (up_action || down_action) props->AddCall("Action", this, "SetActions", up_action, down_action);
if (this.SwitchMass != GetID().SwitchMass) props->AddSet("SwitchMass", this, "SwitchMass", this.SwitchMass);
return true;
}
@ -82,6 +92,7 @@ public func Definition(proplist def)
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.up_action = new UserAction.Prop { Name="$UpAction$" };
def.EditorProps.down_action = new UserAction.Prop { Name="$DownAction$" };
def.EditorProps.SwitchMass = { Type = "int", Name = "$SwitchMassAction$", EditorHelp = "$SwitchMassActionHelp$" };
return _inherited(def, ...);
}

View File

@ -2,3 +2,5 @@ Name=Bodenschalter
Description=Antiker Gewichtssensor.
UpAction=Aktion 'Hoch'
DownAction=Aktion 'Runter'
SwitchMassAction=Schaltermasse
SwitchMassActionHelp=Benötigte Masse um den Schalter aus zu lösen.

View File

@ -2,3 +2,5 @@ Name=Floor Switch
Description=Ancient weight sensor.
UpAction='Up' action
DownAction='Down' action
SwitchMassAction=Switch mass
SwitchMassActionHelp=Mass needed to trigger the switch.

View File

@ -12,7 +12,7 @@ static const KEYPADMENU_BackgroundColor = 0x77000000;
static const KEYPADMENU_HoverColor = 0x99888888;
static const KEYPADMENU_BarColor = 0x99888888;
local code, correct_code;
local code, correct_code, correct_code_hashed;
local correct_code_action, wrong_code_action;
local replacement_images;
local menu, menu_id, menu_target, menu_controller;
@ -40,6 +40,12 @@ public func SetKeypadCode(string to_code)
return;
}
public func SetKeypadHashedCode(string to_code)
{
correct_code_hashed = to_code;
return;
}
public func GiveAccess(object clonk)
{
SetSwitchState(true, clonk);
@ -115,10 +121,17 @@ private func UpdateKeypadGraphics()
public func SaveScenarioObject(proplist props)
{
if (!_inherited(props, ...)) return false;
if (correct_code) props->AddCall("Code", this, "SetKeypadCode", Format("%v", correct_code));
if (correct_code_action || wrong_code_action) props->AddCall("Action", this, "SetCodeActions", correct_code_action, wrong_code_action);
if (replacement_images) props->AddCall("Replacements", this, "SetReplacementImages", replacement_images);
if (!_inherited(props, ...))
return false;
// Store the hashed code, but override if the scenario designer changed the code.
if (correct_code)
props->AddCall("Code", this, "SetKeypadHashedCode", Format("%v", Crypto->ComputeHash(correct_code)));
else if (correct_code_hashed)
props->AddCall("Code", this, "SetKeypadHashedCode", Format("%v", correct_code_hashed));
if (correct_code_action || wrong_code_action)
props->AddCall("Action", this, "SetCodeActions", correct_code_action, wrong_code_action);
if (replacement_images)
props->AddCall("Replacements", this, "SetReplacementImages", replacement_images);
return true;
}
@ -358,13 +371,13 @@ public func EnterKeypadCode()
}
else
{
if (correct_code == nil)
if (correct_code == nil && correct_code_hashed == nil)
{
code = nil;
menu.code.value.Text = "$MsgNoCode$";
Sound("UI::Error", {player = menu_controller->GetOwner()});
}
else if (correct_code == code)
else if (correct_code == code || correct_code_hashed == Crypto->ComputeHash(code))
{
code = nil;
Sound("UI::Confirmed", {player = menu_controller->GetOwner()});
@ -398,7 +411,7 @@ public func EnterKeypadCode()
public func ResetKeypadCode()
{
// Only allow resetting the code if the clonk (menu_target) has entered the correct code before.
if (correct_code == nil)
if (correct_code == nil && correct_code_hashed == nil)
{
menu_controller.code_reset_state = "reset";
menu.code.text.Text = "$MsgEnterNewCode$";

View File

@ -1,7 +1,7 @@
[DefCore]
id=DummyChild
id=StoneSign
Version=8,0
Category=C4D_StaticBack
Width=8
Width=10
Height=8
Offset=-4,-4
Offset=-5,-4

View File

@ -0,0 +1,21 @@
material StoneSign
{
receive_shadows on
technique
{
pass
{
ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0
diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0
specular 0.06589147448539734 0.06589147448539734 0.06589147448539734 1.0 31.5
emissive 0.0 0.0 0.0 1.0
texture_unit
{
texture StoneSignDiffuse.jpg
tex_address_mode wrap
filtering trilinear
}
}
}
}

View File

@ -0,0 +1,33 @@
/**
Stone Sign
Is attached to a wall and has an inscription.
@author Maikel, Foaly (graphics)
*/
#include EnvPack_Guidepost
public func Construction()
{
return;
}
// Color for messages.
public func GetColor() { return 0xffb0b0b0; }
public func Definition(proplist def)
{
// Inscription editor props.
if (!def.EditorProps)
def.EditorProps = {};
def.EditorProps.inscription = { Name="$Inscription$", Type="string", EditorHelp="$InscriptionHelp$", Set="SetInscription", Save="Inscription", Translatable=true };
def.MeshTransformation = Trans_Mul(Trans_Translate(-5600, -300), Trans_Rotate(90, 0, 1, 0));
def.PictureTransformation = Trans_Rotate(90, 0, 1, 0);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,4 @@
Name=Steintafel
Description=Behält wichtige Informationen.
Inscription=Beschriftung
InscriptionHelp=Text der beim Lesen der Steintafel angezeigt wird.

View File

@ -0,0 +1,4 @@
Name=Stone Sign
Description=Contains important information.
Inscription=Inscription
InscriptionHelp=Text that can be read by interacting with the stone sign.

View File

@ -0,0 +1,14 @@
Texture Sources:
All textures have been modified.
Rope Texture:
Tim van de Vall <timvandevall.com>
Special permission for use in OpenClonk under the CC BY 3.0 license.
Wood Texture:
Public Domain - CC0
Metal Texture:
"Grzesiek" <https://www.flickr.com/photos/stoyan/>
<https://www.flickr.com/photos/stoyan/387961807/>
CC BY 2.0 (licensed under CC BY 3.0 after modification)

View File

@ -1,4 +1,7 @@
[DefCore]
id=Library_CableCar
id=WoodenSign
Version=8,0
Category=C4D_StaticBack
Width=12
Height=10
Offset=-6,-5

View File

@ -0,0 +1,27 @@
material WoodenSign
{
receive_shadows on
technique
{
pass
{
scene_blend one zero
alpha_rejection greater_equal 128
alpha_to_coverage on
cull_hardware none
ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0
diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0
specular 0.09375 0.09375 0.09375 0.0 52.25
emissive 0.0 0.0 0.0 0.0
texture_unit
{
texture WoodenSign.jpg
tex_address_mode wrap
filtering trilinear
}
}
}
}

View File

@ -0,0 +1,30 @@
/**
Wooden Sign
Is attached to a wall and has an inscription.
@author Maikel, Foaly (graphics)
*/
#include EnvPack_Guidepost
public func Construction()
{
return;
}
public func Definition(def)
{
// Inscription editor props.
if (!def.EditorProps)
def.EditorProps = {};
def.EditorProps.inscription = { Name="$Inscription$", Type="string", EditorHelp="$InscriptionHelp$", Set="SetInscription", Save="Inscription", Translatable=true };
def.MeshTransformation = Trans_Mul(Trans_Translate(-600, -400), Trans_Rotate(90, 0, 1, 0),Trans_Scale(900));
def.PictureTransformation = Trans_Rotate(90, 0, 1, 0);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";

View File

@ -0,0 +1,4 @@
Name=Holzbrett
Description=Behält wichtige Informationen.
Inscription=Beschriftung
InscriptionHelp=Text der beim Lesen des Holzbrettes angezeigt wird.

View File

@ -0,0 +1,4 @@
Name=Wooden Sign
Description=Contains important information.
Inscription=Inscription
InscriptionHelp=Text that can be read by interacting with the wooden sign.

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -1,19 +1,20 @@
/**
Guidepost
@author Graphics Dustin Neß (dness.de), Script Sven2
*/
local Name="$Name$";
local Description="$Description$";
local inscription = "";
// Players can read the sign via the interaction bar.
public func IsInteractable() { return inscription != ""; }
// Adapt appearance in the interaction bar.
public func GetInteractionMetaInfo(object clonk)
{
return { Description = "$MsgRead$", IconName = nil, IconID = GetID(), Selected = false };
return { Description = "$MsgRead$", Selected = false };
}
// Called on player interaction.
@ -33,19 +34,30 @@ public func SetInscription(to_text)
// Color for messages
public func GetColor() { return 0xffcf9c1a; }
protected func Construction()
public func Construction()
{
// Pick an angle range that looks good (some angles show it from the side, which looks weird)
var angle;
if (!Random(2)) angle = -80 + Random(105); else angle = 90 + Random(110);
this.MeshTransformation = Trans_Mul(Trans_Rotate(angle,0,10), GetID().MeshTransformation);
if (!Random(2))
angle = -80 + Random(105);
else
angle = 90 + Random(110);
this.MeshTransformation = Trans_Mul(Trans_Rotate(angle, 0, 10), GetID().MeshTransformation);
}
public func Definition(def)
public func Definition(proplist def)
{
// Model file is way too large
// Model file is way too large.
def.MeshTransformation = Trans_Scale(360);
// Inscription props
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.inscription = { Name="$Inscription$", Type="string", EditorHelp="$InscriptionHelp$", Set="SetInscription", Save="Inscription", Translatable=true };
def.PictureTransformation = Trans_Scale(900);
// Inscription props.
if (!def.EditorProps)
def.EditorProps = {};
def.EditorProps.inscription = { Name = "$Inscription$", Type = "string", EditorHelp = "$InscriptionHelp$", Set = "SetInscription", Save = "Inscription", Translatable = true };
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";

View File

@ -1,24 +1,29 @@
/**
@author Nachtfalter
Guidepost
@author Sven2, Nachtfalter (graphics)
*/
#include EnvPack_Guidepost
local Name="$Name$";
local Description="$Description$";
protected func Construction(...)
public func Construction(...)
{
// Pick an angle range that looks good (some angles show it from the side, which looks weird)
var angle;
if (!Random(2)) angle = -60 + Random(90); else angle = 120 + Random(90);
this.MeshTransformation = Trans_Mul(Trans_Rotate(angle,0,10), GetID().MeshTransformation);
return _inherited(...);
// Pick an angle range that looks good (some angles show it from the side or back, which looks weird).
this.MeshTransformation = Trans_Mul(Trans_Rotate(-60 + Random(90), 0, 10), GetID().MeshTransformation);
return;
}
public func Definition(def)
public func Definition(proplist def)
{
_inherited(def);
// Model file is way too large
// Model file is way too large.
def.MeshTransformation = Trans_Scale(130);
def.PictureTransformation = Trans_Mul(Trans_Translate(-5000, -60000, 150000), Trans_Rotate(-20, 0, 1), Trans_Scale(400));
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";

View File

@ -1,5 +0,0 @@
[DefCore]
id=Ambience
Version=8,0
Category=C4D_StaticBack | C4D_Rule
Picture=0,0,128,128

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,298 +0,0 @@
/**
Ambience
Controls sound and music depending on the environment the player is in
@author Sven2
*/
local exec_counter; // counter to distribute execution of players across frames
local last_environment; // array indexed by player number: pointer to environment the player was in last
local environments; // array of available environments for which it is checked if the player is in. sorted by priority.
// Initialization
protected func Initialize()
{
// Base environment
Environment = {
actions = [],
min_change_delay = 1,
min_initial_change_delay = 5,
AddSound = this.Env_AddSound,
AddAction = this.Env_AddAction,
SetMusic = this.Env_SetMusic
};
// Register default environments (overloadable)
this->InitializeEnvironments();
// Periodic execution of ambience events
last_environment = [];
AddTimer(this.Execute, 10);
return true;
}
func InitializeEnvironments()
{
// Register all standard environments
environments = [];
// Underwater: Clonk is swimming in water
var underwater = this.env_underwater = new Environment {};
underwater->SetMusic("underwater");
underwater.CheckPlayer = this.EnvCheck_Underwater;
AddEnvironment(underwater, 1400);
// City: Clonk is surrounded by buildings
var city = this.env_city = new Environment {};
city->SetMusic("city");
city.CheckPlayer = this.EnvCheck_City;
AddEnvironment(city, 1200);
// Lava: Lava material is nearby
var lava = this.env_lava = new Environment {};
lava->SetMusic("lava");
lava.CheckPlayer = this.EnvCheck_Lava;
lava.mat_mask = CreateArray(); // material mask for lava materials. +1 cuz sky.
lava.mat_mask[Material("Lava")+1] = true; // loop over materials and check incindiary instead? Whoever introduces the next lava type can do that...
lava.mat_mask[Material("DuroLava")+1] = true;
lava.min_change_delay = 3; // Easy to miss lava on search.
AddEnvironment(lava, 1000);
// Underground: Clonk in front of tunnel
var underground = this.env_underground = new Environment {};
underground->SetMusic("underground");
underground.CheckPlayer = this.EnvCheck_Underground;
AddEnvironment(underground, 800);
// Mountains: Overground and lots of rock around
var mountains = this.env_mountains = new Environment {};
mountains->SetMusic("mountains");
mountains.CheckPlayer = this.EnvCheck_Mountains;
mountains.mat_mask = CreateArray(); // material mask for mountain materials. +1 cuz sky.
mountains.mat_mask[Material("Rock")+1] = true;
mountains.mat_mask[Material("Granite")+1] = true;
mountains.mat_mask[Material("Ore")+1] = true;
mountains.mat_mask[Material("Gold")+1] = true;
mountains.min_change_delay = 3; // Pretty unstable condition
AddEnvironment(mountains, 600);
// Snow: It's snowing around the clonk
var snow = this.env_snow = new Environment {};
snow->SetMusic("snow");
snow.CheckPlayer = this.EnvCheck_Snow;
snow.min_change_delay = 6; // Persist a while after snowing stopped
snow.mat = Material("Snow");
AddEnvironment(snow, 400);
// Night: Sunlight blocked by planet
var night = this.env_night = new Environment {};
night->SetMusic("night");
night.CheckPlayer = this.EnvCheck_Night;
AddEnvironment(night, 200);
// Overground: Default environment
var overground = this.env_overground = new Environment {};
overground->SetMusic("overground");
overground.CheckPlayer = this.EnvCheck_Overground;
overground->AddSound("UI::Ding", 100);
AddEnvironment(overground, 0);
return true;
}
private func Execute()
{
// Per-player execution every third timer (~.8 seconds)
var i=GetPlayerCount(C4PT_User);
while (i--) if (!(++exec_counter % 3))
{
ExecutePlayer(GetPlayerByIndex(i, C4PT_User));
}
return true;
}
private func ExecutePlayer(int plr)
{
var cursor = GetCursor(plr);
// Determine environment the player is currently in
var environment = nil;
if (cursor)
{
var last_env = last_environment[plr];
var x = cursor->GetX(), y = cursor->GetY();
for (var test_environment in environments)
{
if (environment = test_environment->CheckPlayer(cursor, x, y, test_environment == last_env))
{
// We've found a matchign environment.
// Was it a change? Then check delays first
if (test_environment != last_env)
{
if (last_env && last_env.no_change_delay)
{
// Environment should change but a delay is specified. Keep last environment for now.
--last_env.no_change_delay;
environment = last_env;
break;
}
// New environment and change delay has passed.
environment.no_change_delay = environment.min_initial_change_delay;
Log("%s environment: %s", GetPlayerName(plr), environment.music);
}
else
{
// Was no change: Reset change delays
environment.no_change_delay = Max(environment.no_change_delay, environment.min_change_delay);
}
break;
}
}
}
last_environment[plr] = environment;
if (!environment) return true;
// Music by environment
this->SetPlayList(environment.music, plr, true, 3000);
// Sounds and actions by environment
for (var action in environment.actions)
if (Random(1000) < action.chance)
cursor->Call(action.fn, action.par[0], action.par[1], action.par[2], action.par[3], action.par[4]);
return true;
}
func InitializePlayer(int plr)
{
// Newly joining players should have set playlist immediately (so they don't start playing a random song just to switch it immediately)
ExecutePlayer(plr);
return true;
}
func RemovePlayer(int plr)
{
// Ensure newly joining players don't check on another player's environment
last_environment[plr] = nil;
return true;
}
protected func Activate(int byplr)
{
MessageWindow(this.Description, byplr);
return true;
}
/* Environment functions */
func AddEnvironment(proplist new_env, priority)
{
if (GetType(priority)) new_env.Priority = priority;
this.environments[GetLength(environments)] = new_env;
SortArrayByProperty(this.environments, "Priority", true);
return true;
}
private func Env_AddSound(string snd_name, chance)
{
return Env_AddAction(Global.Sound, snd_name, chance ?? 50);
}
private func Env_AddAction(afn, par0, par1, par2, par3, par4)
{
return this.actions[GetLength(this.actions)] = { fn=afn, par=[par0, par1, par2, par3, par4] };
}
private func Env_SetMusic(string playlist)
{
this.music = playlist;
return true;
}
/* Default environment checks */
private func EnvCheck_Underwater(object cursor, int x, int y, bool is_current)
{
// Clonk should be swimming
if (cursor->GetProcedure() != "SWIM") return nil;
// For initial change, clonk should also be diving: Check for breath below 80%
// Use > instead of >= to ensure 0-breath-clonks can also get the environment
if (!is_current && cursor->GetBreath() > cursor.MaxBreath*4/5) return nil;
return this;
}
private func EnvCheck_City(object cursor, int x, int y, bool is_current)
{
// There must be buildings around the clonk
var building_count = cursor->ObjectCount(cursor->Find_AtRect(-180,-100,360,200), Find_Func("IsStructure"));
// 3 buildings to start the environment. Just 1 building to sustain it.
if (building_count < 3-2*is_current) return nil;
return this;
}
private func EnvCheck_Lava(object cursor, int x, int y, bool is_current)
{
// Check for lava pixels. First check if the last lava pixel we found is still in place.
var search_range;
if (is_current)
{
if (this.mat_mask[GetMaterial(this.last_x, this.last_y)+1])
if (Distance(this.last_x, this.last_y, x, y) < 140)
return this;
search_range = 140;
}
else
{
search_range = 70;
}
// Now search for lava in search range
var ang = Random(360);
for (; search_range >= 0; search_range -= 10)
{
ang += 200;
var x2 = x + Sin(ang, search_range);
var y2 = y + Cos(ang, search_range);
if (this.mat_mask[GetMaterial(x2, y2)+1])
{
// Lava found!
this.last_x = x2;
this.last_y = y2;
return this;
}
}
// No lava found
return nil;
}
private func EnvCheck_Underground(object cursor, int x, int y, bool is_current)
{
// Check for underground: No sky at cursor or above
if (GetMaterial(x,y)<0) return nil;
if (GetMaterial(x,y-30)<0) return nil;
if (GetMaterial(x-10,y-20)<0) return nil;
if (GetMaterial(x+10,y-20)<0) return nil;
return this;
}
private func EnvCheck_Mountains(object cursor, int x, int y, bool is_current)
{
// Check for mountains: Rock materials below
var num_rock;
for (var y2=0; y2<=45; y2+=15)
for (var x2=-75; x2<=75; x2+=15)
num_rock += this.mat_mask[GetMaterial(x+x2,y+y2)+1];
// need 15pts on first check; 5 to sustain
if (num_rock < 15-is_current*10) return nil;
return this;
}
private func EnvCheck_Snow(object cursor, int x, int y, bool is_current)
{
// Must be snowing from above
if (GetPXSCount(this.mat, x-300, y-200, 600, 300) < 20 - is_current*15) return nil;
return this;
}
private func EnvCheck_Night(object cursor, int x, int y, bool is_current)
{
// Night time.
if (!Time->IsNight()) return nil;
return this;
}
private func EnvCheck_Overground(object cursor, int x, int y, bool is_current)
{
// This is the fallback environment
return this;
}
/*-- Proplist --*/
local Name = "$Name$";
local Description = "$Description$";
local Environment;

View File

@ -1,2 +0,0 @@
Name=Ambiente
Description=Regelt die Geraeuschkulisse.

View File

@ -1,3 +0,0 @@
Name=Ambience
Description=Controls environmental sounds and music.

View File

@ -1,13 +0,0 @@
[DefCore]
id=Fireglobe
Category=C4D_Object
Width=10
Height=10
Offset=-5,-5
Vertices=1
VertexY=0
VertexFriction=100
Picture=0,0,60,60
Value=8
Mass=1
Rotate=1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -1,7 +0,0 @@
[DefCore]
id=VisualPath
Version=8,0
Category=C4D_StaticBack
Width=1
Height=1
Picture=0,0,1,1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 851 B

View File

@ -1,46 +0,0 @@
public func Set(int sx, int sy, int ex, int ey) {
//SetObjectBlitMode(GFX_BLIT_Additive);
SetAction("Vis");
SetPosition(sx,sy);
SetClrModulation(RGB(255,0,0));
var cl = 1000*Distance(sx,sy,ex,ey)/256;
var w = 650;
var r = Angle(sx,sy,ex,ey)-180;
var fsin = -Sin(r, 1000), fcos = Cos(r, 1000);
var xoff = -4;
var yoff = 0;
var width = +fcos*w/1000, height = +fcos*cl/1000;
var xskew = +fsin*cl/1000, yskew = -fsin*w/1000;
var xadjust = +fcos*xoff + fsin*yoff;
var yadjust = -fsin*xoff + fcos*yoff;
// set matrix values
SetObjDrawTransform (
width, xskew, xadjust,
yskew, height, yadjust
);
}
local ActMap = {
Vis = {
Prototype = Action,
Name = "Vis",
Procedure = DFA_FLOAT,
Length = 1,
X = 0,
Y = 0,
Wdt = 32,
Hgt = 256,
OffX = -16,
OffY = 0,
NextAction = "Hold"
},
};
local Name = "Path";

View File

@ -1,206 +0,0 @@
/*
FireGlobe
Author: Newton
*/
local sx,sy,ex,ey;
local vis;
local aimed;
func Construction()
{
vis = nil;
aimed = false;
}
func ControlUse(object clonk, int x, int y)
{
if(!aimed) return false;
// fire fireball
var angle = Angle(0,0,x,y);
Exit();
Launch(angle,120,clonk);
SetDivert(sx,sy,ex,ey);
return true;
}
func ControlUseStart(object clonk, int x, int y)
{
if(aimed) return false;
sx = x+clonk->GetX();
sy = y+clonk->GetY();
if(vis) vis->RemoveObject();
vis = CreateObjectAbove(VisualPath,0,0,clonk->GetOwner());
vis->Set(sx,sy,x+clonk->GetX(),y+clonk->GetY());
vis["Visibility"]=VIS_Owner;
return true;
}
func HoldingEnabled() { return true; }
func ControlUseHolding(object clonk, int x, int y)
{
if(aimed) return false;
if(vis) vis->Set(sx,sy,x+clonk->GetX(),y+clonk->GetY());
}
func ControlUseStop(object clonk, int x, int y)
{
if(aimed) return false;
ex = x+clonk->GetX();
ey = y+clonk->GetY();
vis->Set(sx,sy,ex,ey);
aimed=true;
return true;
}
public func DelLine()
{
if(vis) vis->RemoveObject();
}
public func Deselection()
{
DelLine();
}
public func Destruction()
{
DelLine();
}
public func Launch(int angle, int str, object shooter)
{
var xdir = Sin(angle,str);
var ydir = Cos(angle,-str);
SetXDir(xdir);
SetYDir(ydir);
AddEffect("HitCheck", this, 1,1, nil,nil, shooter);
AddEffect("InFlight", this, 1,1, this);
}
public func SetDivert(int x1, int y1, int x2, int y2)
{
var inflight = GetEffect("InFlight",this);
inflight.ax = x1;
inflight.ay = y1;
inflight.bx = x2;
inflight.by = y2;
inflight.freeflight = true;
}
public func HitObject(object obj)
{
Hit();
}
public func Hit()
{
DelLine();
Explode(20);
}
// rotate arrow according to speed
public func FxInFlightStart(object target, effect, int temp)
{
if(temp) return;
effect.x = target->GetX();
effect.y = target->GetY();
}
public func FxInFlightTimer(object target, effect, int time)
{
var oldx = effect.x;
var oldy = effect.y;
var newx = target->GetX();
var newy = target->GetY();
if(effect.freeflight)
{
var ax = effect.ax;
var ay = effect.ay;
var bx = effect.bx;
var by = effect.by;
var pos = Intersect(oldx, oldy, newx, newy, ax, ay, bx, by);
if (pos != nil)
{
var angle = Angle(ax, ay, bx, by);
var speed = 60;
target->SetXDir(Sin(angle,speed));
target->SetYDir(-Cos(angle, speed));
effect.freeflight = false;
}
}
effect.x = newx;
effect.y = newy;
}
// Returns nil or coordinates of intersection.
global func Intersect(int Ax, int Ay, int Bx, int By, int Px, int Py, int Qx, int Qy)
{
var BAx = Bx-Ax;
var BAy = By-Ay;
var PAx = Px-Ax;
var PAy = Py-Ay;
var QPx = Qx-Px;
var QPy = Qy-Py;
var denominator = (BAy*QPx - BAx*QPy);
var numerator = (BAx*PAy - BAy*PAx);
// parallel!
if(denominator == 0)
{
if(numerator != 0) return nil;
// on same line somewhere
else
{
return [Ax, Ay];
}
}
// in parameter bounds?
var Y = 10000 * numerator/denominator;
if(!Inside(Y,0,10000)) return nil;
// we don't want division by zero...
if(BAy != 0) {
numerator = (PAy + Y*QPy/10000);
denominator = BAy;
}
else if(BAx != 0) {
numerator = (PAx + Y*QPx/10000);
denominator = BAx;
}
// in parameter bounds
var X = 10000*numerator / denominator;
if(!Inside(X,0,10000)) return nil;
// this is the point...
var x = Ax+X*(BAx)/10000;
var y = Ay+X*(BAy)/10000;
return [x, y];
}
local Name = "$Name$";
local Collectible = 1;

View File

@ -1 +0,0 @@
Name=Feuerglob

View File

@ -1 +0,0 @@
Name=Fire globe

View File

@ -1,55 +0,0 @@
material _missing_material_
{
receive_shadows off
technique
{
pass
{
ambient 0.1 0.1 0.1 1.0
diffuse 0.8 0.0 0.0 1.0
specular 0.5 0.5 0.5 1.0 12.5
emissive 0.3 0.3 0.3 1.0
}
}
}
// blender material: flightless_bird_material
material flightless_bird_material
{
receive_shadows on
technique
{
pass flightless_bird_material
{
ambient 0.800000011920929 0.800000011920929 0.800000011920929 0.0
diffuse 0.800000011920929 0.800000011920929 0.800000011920929 0.0
specular 0.0 0.0 0.0 0.0 12.5
emissive 0.0 0.0 0.0 0.0
alpha_to_coverage off
colour_write on
cull_hardware clockwise
depth_check on
depth_func less_equal
depth_write on
illumination_stage
light_clip_planes off
light_scissor off
lighting on
normalise_normals off
polygon_mode solid
scene_blend one zero
scene_blend_op add
shading gouraud
transparent_sorting on
texture_unit
{
texture color.png
tex_address_mode wrap
scale 1.0 1.0
colour_op alpha_blend
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

View File

@ -1,17 +0,0 @@
Information for developers:
This folder should contain all experimental objects which may be used
throughout different scenario's. This aids object designers, cause they
may then combine new and old objects more easily, not having to move
objects around from scenario to scenario. Please abide this rule if you
plan to put experimental objects into the repository. Note that scenario
specific objects may still be located in their respective scenario,
however, be sure that there will not be any reason to use them elsewhere.
Another decent thing to check before committing, are C4Script warnings
and errors. Also try to keep runtime errors at a minimum. This to prevent
other developers from having to fix objects they don't know the details
of, in order to develop their own objects.
Finished objects may be moved to Objects.ocd, though make sure beforehand
that these objects do not break anything. Also they shouldn't cause any
C4Script warnings or errors, or runtime errors.

View File

@ -1,14 +0,0 @@
[DefCore]
id=LiftTower
Version=8,0
Category=C4D_Structure
Width=23
Height=68
Offset=-11,-10
Vertices=4
VertexX=-11,11,-11,11
VertexY=-10,-10,58,58
VertexFriction=50,50,100,100
Mass=4500
Exclusive=1
Construction=1

View File

@ -1,13 +0,0 @@
[DefCore]
id=LiftTower_Hook
Version=8,0
Category=C4D_Object
Width=8
Height=8
Offset=-4,-4
Vertices=3
VertexX=0,2,-2
VertexY=1,-1,-1
VertexFriction=50,50,50
Mass=4
Rotate=1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

View File

@ -1,140 +0,0 @@
/*-- Hook --*/
local tower, rope;
/* Connection */
public func ControlUse(object clonk, int x, int y)
{
// Search for objects to connect with!
var connect = FindObjects(Find_Category(C4D_Vehicle), Find_AtPoint(), Find_Not(Find_Func("NoLiftTowerConnection")), Find_Not(Find_Func("IsEnvironment")));
if (!GetLength(connect)) return true;
if (GetLength(connect) == 1) return ConnectTo(connect[0]);
var menu = clonk->CreateRingMenu(GetID(), this);
for (var connect_object in connect)
menu->AddItem(connect_object);
menu->Show();
}
public func Selected(object menu, object selected)
{
return ConnectTo(selected->GetSymbol());
}
public func ConnectTo(object connect)
{
Hook();
/* rope->BreakRope(true);
SetRope(true);
rope->Connect(tower, connect);*/
rope->Reconnect(connect);
AddEffect("Connecting", this, 1, 1, this, nil, connect);
return true;
}
private func Hook()
{
if (Contained()) Exit();
this.Collectible = 0;
SetCategory(C4D_StaticBack);
}
private func Unhook()
{
this.Collectible = 1;
SetCategory(C4D_Object);
}
private func FxConnectingStart(object target, effect, int temp, object connect_object)
{
if (temp) return;
effect.connection = connect_object;
}
private func FxConnectingTimer(object target, effect)
{
if (!rope)
{
Unhook();
return -1;
}
if (!effect.connection)
{
Unhook();
rope->BreakRope(true);
SetRope();
return -1;
}
SetPosition(effect.connection->GetX(), effect.connection->GetY());
}
public func Connected()
{
return GetEffect("Connecting", this);
}
public func IsInteractable(object clonk)
{
return !this.Collectible && clonk->GetAction() == "Walk";
}
public func GetInteractionMetaInfo(object clonk)
{
return { IconID = LiftTower_Hook, Description = "$Unhook$" };
}
public func Interact(object clonk)
{
if(clonk->Collect(this))
{
RemoveEffect("Connecting", this);
Unhook();
rope->BreakRope(true);
SetRope();
return true;
}
return false;
}
/* Events */
protected func Hit()
{
Sound("Hits::Materials::Metal::LightMetalHit?");
}
func Construction(object constructor)
{
tower = constructor;
}
func Initialize()
{
AddTimer("Rotation", 2);
}
func SetRope(bool no_connect)
{
rope = CreateObjectAbove(LiftTower_Rope,0,0,NO_OWNER);
if (!no_connect) rope->Connect(tower, this);
tower->SetRope(rope);
return rope;
}
public func Destruction()
{
if(rope)
rope->HookRemoved();
}
protected func Rotation()
{
if (!rope) return;
SetR(rope->GetHookAngle());
}
public func NoLiftTowerConnection() { return true; }
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;

View File

@ -1,3 +0,0 @@
Name=Haken
Description=Drücke [Benutzen] vor einem Fahrzeug oder einem anderen großen Gegenstand, um den Haken zu befestigen.
Unhook=Haken abnehmen.

View File

@ -1,3 +0,0 @@
Name=Hook
Description=Press [Use] in front of a vehicle or another big object to attach the hook.
Unhook=Unhook object.

View File

@ -1,8 +0,0 @@
[DefCore]
id=LiftTower_Rope
Version=8,0
Category=C4D_StaticBack
Vertices=2
Width=2
Height=12
Offset=-1,-6

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,255 +0,0 @@
/*
Lift Tower Rope
Author: Randrian, Clonkonaut
The rope used for the lift tower.
Connect(obj1, obj2) connects two objects
BreakRope() breaks the rope
*/
#include Library_Rope
static const Library_Rope_MAXLENGTH = 1000;
// Call this to break the rope.
public func BreakRope(bool silent)
{
if(lib_rope_length == -1) return;
lib_rope_length = -1;
var act1 = lib_rope_objects[0][0];
var act2 = lib_rope_objects[1][0];
SetAction("Idle");
// notify action targets.
if (act1 != nil && !silent)
act1->~OnRopeBreak();
if (act2 != nil && !silent)
act2->~OnRopeBreak();
RemoveRope();
RemoveObject();
return;
}
/* --------------------- Callbacks form the rope ---------------------- */
/* To be overloaded for special segment behaviour */
private func CreateSegment(int index, object previous)
{
if(index == 0) return;
var segment;
segment = CreateObjectAbove(LiftTower_Rope);
return segment;
}
/*-- Rope connecting --*/
// Connects two objects to the rope, but the length will vary on their positions.
public func Connect(object obj1, object obj2, int max_length)
{
StartRopeConnect(obj1, obj2);
if (!max_length) max_length = Library_Rope_MAXLENGTH;
SetMaxLength(max_length);
SetFixed(true, false);
SetAction("Hide");
AddEffect("IntHang", this, 1, 1, this);
return;
}
public func Reconnect(object reconnect)
{
lib_rope_objects[1][0] = reconnect;
}
public func GetConnectStatus() { return !lib_rope_length_auto; }
public func HookRemoved()
{
BreakRope();
}
func FxIntHangTimer() { TimeStep(); }
func UpdateLines()
{
var oldangle;
for(var i=1; i < lib_rope_particle_count; i++)
{
// Update the Position of the Segment
lib_rope_segments[i]->SetPosition(GetPartX(i), GetPartY(i));
// Calculate the angle to the previous segment
var angle = Angle(lib_rope_particles[i].x, lib_rope_particles[i].y, lib_rope_particles[i-1].x, lib_rope_particles[i-1].y);
// Draw the left line
var start = [lib_rope_particles[i-1].x, lib_rope_particles[i-1].y];
var end = [lib_rope_particles[i].x, lib_rope_particles[i].y];
if(i == 1 && lib_rope_particle_count > 2)
{
angle = Angle(lib_rope_particles[2].x, lib_rope_particles[2].y, lib_rope_particles[0].x, lib_rope_particles[0].y);
end = [lib_rope_particles[0].x, lib_rope_particles[0].y];
end[0] += -Sin(angle, 45*LIB_ROPE_Precision/10);
end[1] += +Cos(angle, 45*LIB_ROPE_Precision/10);
lib_rope_segments[i]->SetGraphics("Invis");
}
if(i == 2)
{
angle = Angle(lib_rope_particles[2].x, lib_rope_particles[2].y, lib_rope_particles[0].x, lib_rope_particles[0].y);
start = [lib_rope_particles[0].x, lib_rope_particles[0].y];
start[0] += -Sin(angle, 45*LIB_ROPE_Precision/10);
start[1] += +Cos(angle, 45*LIB_ROPE_Precision/10);
lib_rope_segments[i]->SetGraphics("Short");
}
var diff = Vec_Sub(end,start);
var point = Vec_Add(start, Vec_Div(diff, 2));
var diffangle = Vec_Angle(diff, [0,0]);
var length = Vec_Length(diff)*1000/LIB_ROPE_Precision/10;
if(i == lib_rope_particle_count-1)
{
var old = [lib_rope_particles[i-2].x, lib_rope_particles[i-2].y];
var old_diff = Vec_Sub(start,old);
var o_length = Vec_Length(old_diff)*1000/LIB_ROPE_Precision/10;
if(!o_length) diff = old_diff;
else diff = Vec_Div(Vec_Mul(old_diff, length),o_length);
diffangle = Vec_Angle(diff, [0,0]);
point = Vec_Add(start, Vec_Div(diff, 2));
}
lib_rope_segments[i]->SetGraphics(nil);
SetLineTransform(lib_rope_segments[i], -diffangle, point[0]*10-GetPartX(i)*1000,point[1]*10-GetPartY(i)*1000, length );
// Remember the angle
oldangle = angle;
}
}
public func GetHookAngle()
{
if(lib_rope_particle_count > 3)
return Angle(lib_rope_particles[-2].x, lib_rope_particles[-2].y, lib_rope_particles[-3].x, lib_rope_particles[-3].y)+180;
}
public func SetLineTransform(obj, int r, int xoff, int yoff, int length, int layer, int MirrorSegments) {
if(!MirrorSegments) MirrorSegments = 1;
var fsin=Sin(r, 1000), fcos=Cos(r, 1000);
// set matrix values
obj->SetObjDrawTransform (
+fcos*MirrorSegments, +fsin*length/1000, xoff,
-fsin*MirrorSegments, +fcos*length/1000, yoff,layer
);
}
/* Overload */
local pull_position, pull_faults, pull_frame;
// Altered to not just pull the objects into the rope's direction but
// if the object doesn't not move it is tried to shake it free by applying
// impulses to every direction
func ForcesOnObjects()
{
if(!lib_rope_length) return;
var redo = LengthAutoTryCount();
while(lib_rope_length_auto && redo)
{
var speed = Vec_Length(Vec_Sub([lib_rope_particles[-1].x, lib_rope_particles[-1].y], [lib_rope_particles[-1].oldx, lib_rope_particles[-1].oldy]));
if(lib_rope_length == GetMaxLength())
{
if(ObjContact(lib_rope_objects[1][0]))
speed = 40;
else speed = 100;
}
if(speed > 150) DoLength(1);
else if(speed < 50) DoLength(-1);
else redo = 0;
if(redo) redo --;
}
var j = 0;
if (PullObjects())
for (var i = 0; i < 2; i++)
{
if (i == 1) j = lib_rope_particle_count-1;
var obj = lib_rope_objects[i][0];
if (obj == nil || !lib_rope_objects[i][1]) continue;
if (obj->Contained())
obj = obj->Contained();
if (obj->GetAction() == "Walk" || obj->GetAction() == "Scale" || obj->GetAction() == "Hangle" || obj->GetAction() == "Climb")
obj->SetAction("Jump");
var xdir = BoundBy(lib_rope_particles[j].x-lib_rope_particles[j].oldx, -100, 100);
var ydir = lib_rope_particles[j].y-lib_rope_particles[j].oldy;
if (!obj->GetContact(-1))
ydir = BoundBy(ydir, -120, 120);
if (pull_position && pull_frame != FrameCounter() && !Distance(pull_position[0], pull_position[1], obj->GetX(), obj->GetY()))
{
if (!pull_faults)
{
ydir *= -1;
pull_faults++;
}
else
{
xdir *= -1;
pull_faults = 0;
}
}
else
{
pull_position = [obj->GetX(), obj->GetY()];
pull_faults = 0;
}
pull_frame = FrameCounter();
obj->SetXDir( xdir, LIB_ROPE_Precision);
obj->SetYDir( obj->GetYDir(LIB_ROPE_Precision) + ydir, LIB_ROPE_Precision);
}
}
// Altered to function in 'ConnectPull' mode
public func ConstraintObjects()
{
if(lib_rope_length < GetMaxLength()) // in the rope library this is
{
for (var i = 0, i2 = 0; i < 2; i++ || i2--)
SetParticleToObject(i2, i);
}
}
// This is called constantly by the lift tower as long as something is reeled in
// Altered so the rope will not get shorter than the distance between the tower
// and the hooked up object
public func DoLength(int dolength)
{
var obj = lib_rope_objects[0][0]; // First connected object
var obj2 = lib_rope_objects[1][0]; // Second connected object
// I guess this is not possible but just to be sure
if (!obj || !obj2) return _inherited(dolength);
if (obj->Contained()) obj = obj->Contained();
if (obj2->Contained()) obj2 = obj2->Contained();
// Line would be shorter than the distance? Do nothing
if (dolength < 0 && ObjectDistance(obj, obj2) > GetLineLength()/100) return;
return _inherited(dolength);
}
func Definition(def)
{
def.LineColors = [RGB(66,33,00), RGB(66,33,00)];
}
local ActMap = {
Hide = {
Prototype = Action,
Name = "Hide",
},
};
local Name = "$Name$";

View File

@ -1,14 +0,0 @@
material Material
{
receive_shadows on
technique
{
pass
{
ambient 0.500000 0.500000 0.500000 1.000000
diffuse 0.584337 0.584337 0.584337 1.000000
specular 0.500000 0.500000 0.500000 1.000000 12.500000
emissive 0.000000 0.000000 0.000000 1.000000
}
}
}

View File

@ -1,171 +0,0 @@
/*--
LiftTower
Authors: Clonkonaut
--*/
local hook, rope;
local hook_pos, anim_no, stopped, direction;
static const LIFTTOWER_HOOK_LOOSEDIST = 50;
public func Construction()
{
SetProperty("MeshTransformation",Trans_Rotate(RandomX(-20,20),0,1,0));
return _inherited(...);
}
protected func Initialize()
{
OnRopeBreak();
hook_pos = CreateArray();
anim_no = PlayAnimation("Turn", 10, Anim_Const(0));
stopped = true;
AddEffect("SpinWheel", this, 0, 5);
}
/* Rope */
func OnRopeBreak()
{
if (!hook)
hook = CreateObjectAbove(LiftTower_Hook, 0,0, NO_OWNER);
hook->Enter(this);
}
/* Interaction */
func IsInteractable(object clonk)
{
return GetCon() >= 100;
}
func GetInteractionMetaInfo()
{
if (!hook) OnRopeBreak();
if (hook->Contained() == this)
return { IconID = LiftTower_Hook, Description = "$TakeHook$" };
else
return { IconID = LiftTower_Hook, Description = "$Grab$" };
}
func Interact(object clonk)
{
if (!hook) OnRopeBreak();
if (hook->Contained() == this)
{
if (clonk->Collect(hook,nil,nil,true))
hook->SetRope();
}
else
{
clonk->ObjectCommand("Grab", this);
}
return true;
}
func SetRope(object rope_to_set)
{
rope = rope_to_set;
}
/* Control */
public func ControlUp(object clonk)
{
return DrawIn();
}
public func ControlStop(object clonk)
{
return RemoveEffect("DrawIn", this);
}
public func DrawIn()
{
if (!rope) return false;
if (!hook) OnRopeBreak();
if (hook->Contained() == this) return false;
if (ObjectDistance(hook) < LIFTTOWER_HOOK_LOOSEDIST) return false;
if (GetEffect("DrawIn", this)) return false;
rope->ConnectPull();
return AddEffect("DrawIn", this, 1, 1, this);
}
private func FxDrawInTimer(effect)
{
if (!rope) return -1;
if (!hook)
{
OnRopeBreak();
return -1;
}
rope->DoLength(-1);
if (ObjectDistance(hook) < LIFTTOWER_HOOK_LOOSEDIST) return -1;
}
private func FxDrawInStop(object target, effect, int temp)
{
if (temp) return;
if (!rope) return;
rope->ConnectLoose();
}
/* Animation */
protected func FxSpinWheelTimer()
{
if (!hook) return StopWheel();
if (hook->Contained() == this) return StopWheel();
if (hook->GetX() == hook_pos[0])
if (hook->GetY() == hook_pos[1])
return StopWheel();
stopped = false;
var new_direction = false;
if (!direction)
{
direction = 100;
new_direction = true;
}
if (Distance(GetX(),GetY(), hook->GetX(), hook->GetY()) < Distance(GetX(),GetY(), hook_pos[0], hook_pos[1]))
{
if (direction > 0)
{
direction = -100;
new_direction = true;
}
}
else if (direction < 0)
{
direction = 100;
new_direction = true;
}
hook_pos = [hook->GetX(), hook->GetY()];
if (!new_direction) return;
if (direction < 0)
anim_no = PlayAnimation("Turn", 10, Anim_Linear(GetAnimationPosition(anim_no), GetAnimationLength("Turn"), 0, 40, ANIM_Loop));
else
anim_no = PlayAnimation("Turn", 10, Anim_Linear(GetAnimationPosition(anim_no), 0, GetAnimationLength("Turn"), 40, ANIM_Loop));
}
private func StopWheel()
{
if (stopped) return;
var position = GetAnimationPosition(anim_no);
stopped = true;
direction = 0;
anim_no = PlayAnimation("Turn", 10, Anim_Const(position), Anim_Const(1000));
}
func Definition(def) {
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(2000,0,7000),Trans_Rotate(-20,1,0,0),Trans_Rotate(30,0,1,0)), def);
}
local Name = "$Name$";
local Description = "$Description$";
local Touchable = 2;
local ContainBlast = true;
local BlastIncinerate = 100;

View File

@ -1,4 +0,0 @@
Name=Hebeturm
Description=Um schwere Lasten zu heben.
TakeHook=Haken nehmen.
Grab=Anfassen

View File

@ -1,4 +0,0 @@
Name=Lift Tower
Description=For pulling heavy loads.
TakeHook=Take the hook.
Grab=Grab

View File

@ -1,14 +0,0 @@
[DefCore]
id=LiquidTank
Version=8,0
Category=C4D_Structure
Width=40
Height=72
Offset=-20,-36
Vertices=6
VertexX=-16,16,-18,18,-18,18
VertexY=35,35,0,0,-20,-20
VertexFriction=100,100,50,50,50,50
Mass=800
Exclusive=1
Construction=1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,174 +0,0 @@
/**
Liquid Tank
Holds liquids of any type and can be opened to create a flood.
@author Maikel
*/
#include Library_Structure
#include Library_Ownable
#include Library_Tank
public func Initialize()
{
return _inherited(...);
}
public func Construction(object creator)
{
return _inherited(creator, ...);
}
public func IsHammerBuildable() { return true; }
/*-- Liquid Control --*/
// Only accept a single liquid at the same time, but accept any liquid type.
public func IsLiquidContainerForMaterial(string liquid)
{
for (var liquid_content in GetLiquidContents())
if (GetLiquidDef(liquid) != GetLiquidDef(liquid_content->GetID()))
return false;
return true;
}
public func GetLiquidContainerMaxFillLevel(liquid_name)
{
return this.LiquidCapacity;
}
// The liquid tank may have one drain and one source.
public func QueryConnectPipe(object pipe, bool do_msg)
{
if (GetDrainPipe() && GetSourcePipe())
{
if (do_msg) pipe->Report("$MsgHasPipes$");
return true;
}
else if (GetSourcePipe() && pipe->IsSourcePipe())
{
if (do_msg) pipe->Report("$MsgSourcePipeProhibited$");
return true;
}
else if (GetDrainPipe() && pipe->IsDrainPipe())
{
if (do_msg) pipe->Report("$MsgDrainPipeProhibited$");
return true;
}
else if (pipe->IsAirPipe())
{
if (do_msg) pipe->Report("$MsgPipeProhibited$");
return true;
}
return false;
}
// Set to source or drain pipe.
public func OnPipeConnect(object pipe, string specific_pipe_state)
{
if (PIPE_STATE_Source == specific_pipe_state)
{
SetSourcePipe(pipe);
pipe->SetSourcePipe();
}
else if (PIPE_STATE_Drain == specific_pipe_state)
{
SetDrainPipe(pipe);
pipe->SetDrainPipe();
}
else
{
if (!GetDrainPipe())
OnPipeConnect(pipe, PIPE_STATE_Drain);
else if (!GetSourcePipe())
OnPipeConnect(pipe, PIPE_STATE_Source);
}
pipe->Report("$MsgConnectedPipe$");
}
/*-- Interaction --*/
public func IsInteractable(object clonk)
{
if (GetCon() < 100)
return false;
return !Hostile(GetOwner(), clonk->GetOwner());
}
public func GetInteractionMetaInfo(object clonk)
{
if (GetEffect("FxDisperseLiquid", this))
return { Description = "$MsgCloseTank$", IconName = nil, IconID = Icon_Enter, Selected = false };
return { Description = "$MsgOpenTank$", IconName = nil, IconID = Icon_Exit, Selected = false };
}
public func Interact(object clonk)
{
var fx = GetEffect("FxDisperseLiquid", this);
if (fx)
{
fx->Remove();
return true;
}
CreateEffect(FxDisperseLiquid, 100, 2);
return true;
}
local FxDisperseLiquid = new Effect
{
Construction = func()
{
this.Interval = 2;
return FX_OK;
},
Timer = func()
{
var liquid = Target->Contents();
if (!liquid || !liquid->~IsLiquid())
return FX_OK;
if (liquid->GetLiquidAmount() <= Target.DispersionRate)
{
liquid->Exit();
liquid->SetPosition(Target->GetX(), Target->GetY());
liquid->Disperse(180, 40);
}
else
{
liquid->RemoveLiquid(nil, Target.DispersionRate);
liquid = liquid->GetID()->CreateLiquid(Target.DispersionRate);
liquid->SetPosition(Target->GetX(), Target->GetY());
liquid->Disperse(180, 40);
}
// TODO: Sound.
return FX_OK;
}
};
/*-- Contents Control --*/
public func IsContainer() { return true; }
protected func RejectCollect(id item, object obj)
{
// Accept liquids only.
if (obj->~IsLiquid())
return _inherited(item, obj, ...);
return true;
}
/*-- Properties --*/
local Name = "$Name$";
local Description ="$Description$";
local BlastIncinerate = 100;
local FireproofContainer = true;
local HitPoints = 90;
local Components = {Wood = 3, Metal = 2};
local LiquidCapacity = 10000;
local DispersionRate = 40;

View File

@ -1,11 +0,0 @@
Name=Tank
Description=Hier können Flüssigkeiten gespeichert werden, aber nur eine Art gleichzeitig.
MsgConnectedPipe=Rohr angeschlossen.
MsgPipeProhibited=Dieses Rohr kann nicht an den Tank angeschlossen werden.
MsgHasPipes=Der Tank hat schon ein Zu- und Abflussrohr.
MsgSourcePipeProhibited=Zuflussrohre können nicht an den Tank angeschlossen werden.
MsgDrainPipeProhibited=Abflussrohre können nicht an den Tank angeschlossen werden.
MsgOpenTank=Ventil öffnen
MsgCloseTank=Ventil schließen

View File

@ -1,11 +0,0 @@
Name=Liquid Tank
Description=Liquids can be stored here, but only one type of liquid at the same time.
MsgConnectedPipe=Connected pipe.
MsgPipeProhibited=This pipe cannot be connected to the liquid tank.
MsgHasPipes=Liquid tank already has a source and a drain pipe.
MsgSourcePipeProhibited=Unable to connect source pipe to the liquid tank.
MsgDrainPipeProhibited=Unable to connect drain pipe to the liquid tank.
MsgOpenTank=Open valve
MsgCloseTank=Close valve

View File

@ -1,6 +0,0 @@
[DefCore]
id=CableLine
Version=8,0
Category=C4D_StaticBack
Vertices=2
Line=1

View File

@ -1,106 +0,0 @@
/*-- Cable line --*/
func Initialize()
{
SetAction("Connect");
SetVertexXY(0, GetX(), GetY());
SetVertexXY(1, GetX(), GetY());
SetProperty("LineColors", [RGB(20, 20, 50), RGB(20, 20, 50)]);
}
public func IsCableLine() { return GetAction() == "Connect"; }
/** Returns whether this cable is connected to an object. */
public func IsConnectedTo(object obj)
{
return GetActionTarget(0) == obj || GetActionTarget(1) == obj;
}
/** Connects this cable to obj1 and obj2. */
public func SetConnectedObjects(obj1, obj2)
{
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(activations);
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(activations);
SetVertexXY(0, obj1->GetX(), obj1->GetY());
SetVertexXY(1, obj2->GetX(), obj2->GetY());
SetActionTargets(obj1, obj2);
obj1->AddCableConnection(this);
}
/** Returns the object which is connected to obj through this cable. */
public func GetConnectedObject(object obj)
{
if (GetActionTarget(0) == obj)
return GetActionTarget(1);
if (GetActionTarget(1) == obj)
return GetActionTarget(0);
}
/* Breaking */
func LineBreak(bool no_msg)
{
Sound("Objects::Connect");
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(activations);
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(activations);
if (!no_msg)
BreakMessage();
}
func BreakMessage()
{
var line_end = GetActionTarget(0);
if (line_end->GetID() != CableLorryReel)
line_end = GetActionTarget(1);
if (line_end->Contained()) line_end = line_end->Contained();
line_end->Message("$TxtLinebroke$");
}
/* Activation */
local activations = 0;
/** Called by cable cars whenever one proceeds onto this cable. Will be forwarded to connected objects.
count increases the activation value. Stations will stop animation only if all activations are deactivated. */
public func Activation(int count)
{
// Count must be > 0
if (count < 1) return FatalError("Cable Line: Activation() was called with count < 1.");
activations += count;
if (GetActionTarget(0)) GetActionTarget(0)->~CableActivation(count);
if (GetActionTarget(1)) GetActionTarget(1)->~CableActivation(count);
}
/** Called by cable cars whenever one proceeds off this cable. Will be forwarded to connected objects.
count decreases the activation value. Stations will stop animation only if all activations are deactivated. */
public func Deactivation(int count)
{
// Count must be > 0
if (count < 1) return FatalError("Cable Line: Deactivation() was called with count < 1.");
activations -= count;
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(count);
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(count);
}
/* Saving */
public func SaveScenarioObject(props)
{
if (!inherited(props, ...)) return false;
SaveScenarioObjectAction(props);
if (IsCableLine()) props->AddCall("Connection", this, "SetConnectedObjects", GetActionTarget(0), GetActionTarget(1));
return true;
}
local ActMap = {
Connect = {
Prototype = Action,
Name = "Connect",
Procedure = DFA_CONNECT,
NextAction = "Connect"
}
};
local Name = "$Name$";

View File

@ -1,2 +0,0 @@
TxtLinebroke=Seil gerissen
Name=Seilbahnseil

View File

@ -1,14 +0,0 @@
[DefCore]
id=CableLorryReel
Version=8,0
Category=C4D_Object
Width=8
Height=6
Offset=-4,-3
Vertices=3
VertexX=0,2,-2
VertexY=1,-1,-1
VertexFriction=50,50,50
Value=10
Mass=15
Picture=0,6,64,64

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -1,68 +0,0 @@
/*-- Cable reel --*/
protected func Hit()
{
Sound("Hits::Materials::Rock::RockHit?");
}
public func IsToolProduct() { return true; }
/*-- Line connection --*/
protected func ControlUse(object clonk, int x, int y)
{
// Is there an object which accepts power lines?
var obj = FindObject(Find_AtPoint(), Find_Func("IsCableCrossing"));
// No such object -> message.
if (!obj)
return clonk->Message("$TxtNoNewLine$");
// Is there a cable connected to this wire roll?
var line = FindObject(Find_CableLine());
// There already is a cable
if (line)
{
if (obj == line->GetActionTarget(0) || obj == line->GetActionTarget(1))
{
// Cable is already connected to obj -> remove line.
line->RemoveObject();
Sound("Objects::Connect");
clonk->Message("$TxtLineRemoval$");
return true;
}
else
{
// Connect existing power line to obj.
if(line->GetActionTarget(0) == this)
line->SetActionTargets(obj, line->GetActionTarget(1));
else if(line->GetActionTarget(1) == this)
line->SetActionTargets(line->GetActionTarget(0), obj);
else
return;
Sound("Objects::Connect");
obj->AddCableConnection(line);
clonk->Message("$TxtConnect$", obj->GetName());
//RemoveObject();
return true;
}
}
else // A new cable needs to be created.
{
line = CreateObjectAbove(CableLine, 0, 0, NO_OWNER);
line->SetActionTargets(this, obj);
Sound("Objects::Connect");
clonk->Message("$TxtConnect$", obj->GetName());
return true;
}
}
// Finds all power lines connected to obj (can be nil in local calls).
private func Find_CableLine(object obj)
{
if (!obj)
obj = this;
return [C4FO_Func, "IsConnectedTo", obj];
}
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;

View File

@ -1,6 +0,0 @@
TxtConnectLine=Leitung verbinden
TxtNoNewLine=Hier kann keine neue Leitung verlegt werden.
TxtLineRemoval=Stromleitung abgenommen.
TxtConnect=Stromleitung verbunden|mit %s
Name=Kabelspule
Description=Drücke [Benutzen] vor einem Gebäude und ein weiteres Mal vor einem anderen Gebäude, um diese beiden mit einem Stromkabel zu verbinden.

View File

@ -1,6 +0,0 @@
TxtConnectLine=Connect line
TxtNoNewLine=Cannot create a new line here.
TxtLineRemoval=Power line disconnected.
TxtConnect=Power line connected|to %s
Name=Cable reel
Description=Press [Use] in front of a structure and another time in front of another structure to connect both with a power line.

View File

@ -1,4 +0,0 @@
[DefCore]
id=GUI_DestinationSelectionMenu
Version=8,0
Category=C4D_StaticBack | C4D_Environment

View File

@ -1,193 +0,0 @@
/**
DestinationSelectionMenu
Handles the destination selection for cable cars.
@author Clonkonaut
*/
local Name = "$Name$";
local Description = "$Description$";
// used as a static function
public func CreateFor(object cursor, object car, object station)
{
if (!cursor) return;
if (!car) return;
if (!station) return;
var obj = CreateObject(GUI_DestinationSelectionMenu, AbsX(0), AbsY(0), cursor->GetOwner());
obj.Visibility = VIS_Owner;
obj->Init(cursor, car, station);
cursor->SetMenu(obj);
return obj;
}
// The Clonk whom the menu was opened for
local cursor;
// The menu id of the opened menu
local menu_id;
// The cable car which opened this menu
local cable_car;
// The station the cable car is hooked up to
local cable_station;
// A dummy object used to bring light to stations when previewed
local dummy;
public func Close() { return RemoveObject(); }
public func IsDestinationMenu() { return true; }
public func Show() { this.Visibility = VIS_Owner; return true; }
public func Hide() { this.Visibility = VIS_None; return true; }
// Called when the menu is open and the player clicks outside.
public func OnMouseClick() { return Close(); }
func Destruction()
{
if (menu_id)
GuiClose(menu_id);
if (dummy)
dummy->RemoveObject();
if (cursor)
SetPlrView(cursor->GetOwner(), cursor, true);
}
public func Init(object cursor, object car, object station)
{
this.cursor = cursor;
this.cable_car = car;
this.cable_station = station;
this.dummy = CreateObject(Dummy, AbsX(station->GetX()), AbsY(station->GetY()), GetOwner());
dummy.Visibility = VIS_Owner;
dummy->SetLightRange(5, 20);
var dest_list = station->GetDestinationList(nil);
var dest_menu = {
Target = this,
Decoration = GUI_MenuDeco,
BackgroundColor = RGB(0, 0, 0),
Bottom = "3em",
Left = "50% - 5em",
Right = "50% + 5em",
Priority = 1,
Player = cursor->GetOwner(),
caption = {
Text = "$SelectDestination$",
Bottom = "1em",
Priority = 2,
},
buttons = {
Top = "1em",
Style = GUI_GridLayout,
Priority = 999
}
};
FillDestinationButtons(dest_menu, dest_list);
GuiOpen(dest_menu);
}
func FillDestinationButtons(proplist menu, array list)
{
var priority = 1000;
// Left button
var left = {
Right = "2em",
Bottom = "2em",
Symbol = Icon_LibraryCableCar,
GraphicsName = "LeftGrey",
BackgroundColor = { Std = RGB(0, 0, 0), Hover = RGB(100, 30, 30) },
Priority = ++priority
};
if (list[3] > 3)
{
left.OnMouseIn = GuiAction_SetTag("Hover");
left.OnMouseOut = GuiAction_SetTag("Std");
left.GraphicsName = "Left";
left.OnClick = GuiAction_Call(this, "ShiftSelection", list[0]);
}
// List buttons
var list_button = {
Right = "2em",
Bottom = "2em",
BackgroundColor = { Std = RGB(0, 0, 0), Hover = RGB(100, 30, 30) },
OnMouseOut = GuiAction_SetTag("Std")
};
var buttons = CreateArray(3);
for (var i = 0; i < 3; i++)
{
if (list[i])
{
buttons[i] = new list_button{
Symbol = list[i],
Tooltip = Format("$SendTo$", list[i]->GetName()),
OnMouseIn = [GuiAction_SetTag("Hover"), GuiAction_Call(this, "PreviewDestination", list[i])],
OnClick = GuiAction_Call(this, "SelectDestination", list[i]),
Priority = ++priority
};
} else {
buttons[i] = new list_button {};
}
}
// Right button
var right = {
Right = "2em",
Bottom = "2em",
Symbol = Icon_LibraryCableCar,
GraphicsName = "Grey",
BackgroundColor = { Std = RGB(0, 0, 0), Hover = RGB(100, 30, 30) },
Priority = ++priority
};
if (list[3] > 3)
{
right.OnMouseIn = GuiAction_SetTag("Hover");
right.OnMouseOut = GuiAction_SetTag("Std");
right.GraphicsName = nil;
right.OnClick = GuiAction_Call(this, "ShiftSelection", list[2]);
}
// Assemble
menu.buttons.left = left;
menu.buttons.first = buttons[0];
menu.buttons.second = buttons[1];
menu.buttons.third = buttons[2];
menu.buttons.right = right;
}
func PreviewDestination(object to_preview, int plr, int menu_id, int submenu_id, object target)
{
if (to_preview == nil) return;
if (dummy == nil)
{
dummy = CreateObject(Dummy, AbsX(to_preview->GetX()), AbsY(to_preview->GetY()), GetOwner());
dummy.Visibility = VIS_Owner;
dummy->SetLightRange(5, 20);
}
SetPlrView(plr, to_preview, true);
dummy->SetPosition(to_preview->GetX(), to_preview->GetY());
}
func ShiftSelection(object new_middle, int plr, int menu_id, int submenu_id, object target)
{
if (!cable_station) return;
if (!menu_id) return;
var update = { buttons = { } };
var list = cable_station->GetDestinationList(new_middle);
FillDestinationButtons(update, list);
GuiUpdate(update, menu_id);
Sound("UI::Click", true, nil, plr);
}
func SelectDestination(object target, int plr, int menu_id, int submenu_id, object target)
{
if (target == nil) return;
if (!cable_car) return;
cable_car->SetDestination(target);
Sound("UI::Click", true, nil, plr);
RemoveObject();
}

View File

@ -1,4 +0,0 @@
Name=Destination Selection Menu
Description=
SelectDestination=Select a destination:
SendTo=Send the cable car to %s

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Some files were not shown because too many files have changed in this diff Show More