diff --git a/.git_archival b/.git_archival new file mode 100644 index 000000000..ff4124fe6 --- /dev/null +++ b/.git_archival @@ -0,0 +1 @@ +node: $Format:%H$ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..c16855571 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +.git_archival export-subst +.gitattributes export-ignore +.gitignore export-ignore diff --git a/.hgignore b/.gitignore similarity index 87% rename from .hgignore rename to .gitignore index e2c82299a..f73b0b7c8 100644 --- a/.hgignore +++ b/.gitignore @@ -1,14 +1,13 @@ -syntax: glob - autom4te.cache *~ *.bak .deps deps *.o -./clonk -./netpuncher -./c4group +/openclonk +/netpuncher +/c4group +/c4script .dirstamp *.a *.c4p @@ -41,6 +40,8 @@ planet/CMakeCache.txt CPackConfig.cmake CPackSourceConfig.cmake *.rule +editor-icons.h +oc-icon.h # Documentation *.pyc @@ -85,6 +86,7 @@ openclonk.ilk *.vcproj *.vcxproj *.vcxproj.filters +/ipch # Temporary files created by Microsoft Visual Studio *.ncb @@ -109,8 +111,6 @@ BuildLog.htm xcode/build *.xcodeproj -.anjuta* - # Binaries *.app *.exe @@ -122,11 +122,20 @@ planet/nohg* planet/.project # Code::Blocks files -clonk.layout -clonk.sdf -clonk.cbp +openclonk.layout +openclonk.sdf +openclonk.cbp +tests/openclonk_unittest.cbp # MacOSX saved searches *.savedSearch planet/OpenClonk.bat planet/openclonk.sln +WindowsGamesExplorer.xml + +# Mape +mape +mape-icons.h + + +tests/openclonk_unittest.sln diff --git a/.hgeol b/.hgeol deleted file mode 100644 index 475255608..000000000 --- a/.hgeol +++ /dev/null @@ -1,3 +0,0 @@ -[patterns] -planet/** = LF -** = native diff --git a/CMakeLists.txt b/CMakeLists.txt index 28cc58e20..a32ff93fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,27 +1,15 @@ # OpenClonk, http://www.openclonk.org # -# Copyright (c) 2009-2011 Günther Brammer -# Copyright (c) 2009-2012 Nicolas Hake -# Copyright (c) 2009 David Dormagen -# Copyright (c) 2009-2012 Armin Burgmeier -# Copyright (c) 2009-2010 Sven Eberhardt -# Copyright (c) 2009 Tobias Zwick -# Copyright (c) 2009 Richard Gerum -# Copyright (c) 2010-2011 Julius Michaelis -# Copyright (c) 2010-2011 Peter Wortmann -# Copyright (c) 2010-2011 Martin Plicht -# Copyright (c) 2010 Manuel Riecke +# Copyright (c) 2009-2013, The OpenClonk Team and contributors # -# Portions might be copyrighted by other authors who have contributed -# to OpenClonk. +# Distributed under the terms of the ISC license; see accompanying file +# "COPYING" for details. # -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# See isc_license.txt for full license and disclaimer. +# "Clonk" is a registered trademark of Matthes Bender, used with permission. +# See accompanying file "TRADEMARK" for details. # -# "Clonk" is a registered trademark of Matthes Bender. -# See clonk_trademark_license.txt for full license. +# To redistribute this file separately, substitute the full license texts +# for the above references. cmake_minimum_required (VERSION 2.6.0) project (openclonk CXX C) @@ -29,63 +17,48 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(Version.txt) -set(CMAKE_ADDITIONAL_DEPS_PATH deps CACHE PATH "Additional directory to search for libraries and headers") +set(CMAKE_ADDITIONAL_DEPS_PATH "${CMAKE_CURRENT_BINARY_DIR}/deps" CACHE PATH "Additional directory to search for libraries and headers") list(APPEND CMAKE_PREFIX_PATH ${CMAKE_ADDITIONAL_DEPS_PATH}) set(OC_CXX_FLAGS ${CMAKE_CXX_FLAGS}) separate_arguments(OC_CXX_FLAGS) set(OC_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) separate_arguments(OC_CXX_FLAGS_DEBUG) +set(OC_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) +separate_arguments(OC_EXE_LINKER_FLAGS) set(OC_EXE_LINKER_FLAGS_DEBUG ${CMAKE_EXE_LINKER_FLAGS_DEBUG}) separate_arguments(OC_EXE_LINKER_FLAGS_DEBUG) +function(unseparate_arguments _var _list) + foreach(_arg ${_list}) + set(_string "${_string} ${_arg}") + endforeach() + set(${_var} "${_string}" PARENT_SCOPE) +endfunction() + ############################################################################ # User selectable options ############################################################################ +include(CMakeDependentOption) option(PROJECT_FOLDERS "Put source files into subfolders in project file" ON) -option(USE_GL "Enable OpenGL support" ON) -SET(INITIAL_USE_SDL_MAINLOOP_VALUE OFF) -SET(INITIAL_USE_OPEN_AL OFF) -option(USE_SDL_MAINLOOP "Use SDL to create windows etc." ${INITIAL_USE_SDL_MAINLOOP_VALUE}) -if(WIN32 AND FALSE) # disable DX option while it doesn't work anyway - option(USE_DIRECTX "Enable DirectX support" ON) - if(EXISTS $ENV{DXSDK_DIR}) - list(APPEND CMAKE_INCLUDE_PATH $ENV{DXSDK_DIR}/Include) - if(CMAKE_CL_64) - list(APPEND CMAKE_LIBRARY_PATH $ENV{DXSDK_DIR}/Lib/x64) - else() - list(APPEND CMAKE_LIBRARY_PATH $ENV{DXSDK_DIR}/Lib/x86) - endif() - else() +option(USE_CONSOLE "Build dedicated server" OFF) +CMAKE_DEPENDENT_OPTION(USE_SDL_MAINLOOP "Use SDL to create windows etc." OFF "NOT USE_CONSOLE" OFF) +CMAKE_DEPENDENT_OPTION(USE_X11 "Use X11 to create windows etc." ON + "UNIX AND NOT APPLE AND NOT USE_SDL_MAINLOOP AND NOT USE_CONSOLE" OFF) +CMAKE_DEPENDENT_OPTION(USE_GTK "Use GTK for the developer mode" ON "USE_X11" OFF) +CMAKE_DEPENDENT_OPTION(USE_GTK3 "Use GTK3 instead of GTK2" OFF "USE_GTK" OFF) - endif() -else() - SET(USE_DIRECTX OFF) - SET(HAVE_FMOD OFF) -endif() -if(NOT USE_GL AND NOT USE_DIRECTX) - message(STATUS "No graphics display enabled; building dedicated server") - SET(USE_CONSOLE ON CACHE INTERNAL "Build dedicated server") -endif() -if(UNIX AND NOT USE_SDL_MAINLOOP AND NOT APPLE AND NOT USE_CONSOLE) - option(USE_X11 "Use X11 to create windows etc." ON) - option(USE_GTK "Use GTK for the developer mode" ON) - option(USE_GTK3 "Use GTK3 instead of GTK2" OFF) -else() - SET(USE_X11 OFF) - SET(USE_GTK OFF) - SET(USE_GTK3 OFF) -endif() +CMAKE_DEPENDENT_OPTION(USE_COCOA "Use Apple Cocoa for the developer mode and the windows." ON "APPLE" OFF) +CMAKE_DEPENDENT_OPTION(USE_APPLE_CLANG "Use Apple Clang Compiler as C++ compiler." ON "APPLE" OFF) if(APPLE) - option(USE_COCOA "Use Apple Cocoa for the developer mode and the windows." ON) - option(USE_APPLE_CLANG "Use Apple Clang Compiler as C++ compiler." ON) SET(INITIAL_USE_OPEN_AL ON) else() - option(USE_COCOA OFF) + SET(INITIAL_USE_OPEN_AL OFF) endif() option(USE_OPEN_AL "Use OpenAL to play sounds" ${INITIAL_USE_OPEN_AL}) -option(DEBUGREC "Debug records" OFF) -option(OC_BUILD_MULTIPROCESSOR "Use all processor cores to build" OFF) -option(WITH_AUTOMATIC_UPDATE "Build engine without automatic update support" OFF) +option(WITH_AUTOMATIC_UPDATE "Automatic updates are downloaded from the project website." OFF) + +# Remove obsolete options +unset(OC_BUILD_MULTIPROCESSOR CACHE) ############################################################################ # Check for compiler quirks and features @@ -109,20 +82,27 @@ endforeach() # out because it does not understand -std=gnu++0x set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS ${OC_REQUIRED_FLAGS}) +include(RequireCXXSourceCompiles) +if (NOT USE_APPLE_CLANG) +REQUIRE_CXX_SOURCE_COMPILES("#include \nint main() { std::unique_ptr a; std::shared_ptr b; }" HAVE_C11_SMART_PTRS) +endif() CHECK_CXX_SOURCE_COMPILES("void f(struct D&&); int main() { return 0; }" HAVE_RVALUE_REF) CHECK_CXX_SOURCE_COMPILES("int main() { void *d = nullptr; }" HAVE_NULLPTR) CHECK_CXX_SOURCE_COMPILES("int main() { static_assert(true, \"\"); }" HAVE_STATIC_ASSERT) set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +# g++'s libstdc++ doesn't properly support until 4.8.1 (maybe later?). +# They ship a header that declares functions, but they don't ship an +# implementation for some things (like std::regex_iterator). +# This needs to test *linking*, not compilation; cmake does both at the same +# time, so the test below works. +CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::cregex_iterator ri; }" HAVE_WORKING_REGEX) +CMAKE_DEPENDENT_OPTION(USE_BOOST_REGEX "Use Boost.Regex even if the C++ runtime has a working implementation of " OFF "HAVE_WORKING_REGEX" ON) + if(MSVC_VERSION GREATER 1499) - # Activate minimal rebuild - if(OC_BUILD_MULTIPROCESSOR) list(APPEND OC_CXX_FLAGS /MP) list(REMOVE_ITEM OC_CXX_FLAGS_DEBUG /Gm) - else() - list(REMOVE_ITEM OC_CXX_FLAGS /MP) - list(APPEND OC_CXX_FLAGS_DEBUG /Gm) - endif() + if (NOT CMAKE_CL_64) # Activate edit-and-continue list(REMOVE_ITEM OC_CXX_FLAGS_DEBUG /Zi) @@ -142,7 +122,12 @@ if(MSVC_VERSION) endif() if(CMAKE_COMPILER_IS_GNUCXX) - list(APPEND OC_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 -Wsign-promo") + list(APPEND OC_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") +endif() + +if(WIN32 AND MINGW) + # Activate DEP and ASLR + list(APPEND OC_EXE_LINKER_FLAGS "-Wl,--nxcompat -Wl,--dynamicbase") endif() ############################################################################ # List target source files. Don't directly create a target since we condi- @@ -152,32 +137,12 @@ endif() # OC_SYSTEM_SOURCES: Sources for OpenClonk that are only needed by specific # configurations. set(OC_CLONK_SOURCES - src/C4Application.cpp - src/C4Application.h - src/C4FullScreen.cpp - src/C4FullScreen.h - src/C4Game.cpp - src/C4Game.h src/C4Globals.cpp - src/C4GraphicsSystem.cpp - src/C4GraphicsSystem.h - src/c4group/C4ComponentHost.cpp - src/c4group/C4ComponentHost.h src/c4group/C4Components.h src/c4group/C4Extra.cpp src/c4group/C4Extra.h - src/c4group/C4Group.cpp - src/c4group/C4Group.h - src/c4group/C4GroupSet.cpp - src/c4group/C4GroupSet.h - src/c4group/C4LangStringTable.cpp - src/c4group/C4LangStringTable.h src/c4group/C4Language.cpp src/c4group/C4Language.h - src/c4group/C4Update.cpp - src/c4group/C4Update.h - src/c4group/CStdFile.cpp - src/c4group/CStdFile.h src/C4Include.h src/C4Prototypes.h src/C4Version.h @@ -186,8 +151,6 @@ set(OC_CLONK_SOURCES src/config/C4Constants.h src/config/C4Reloc.cpp src/config/C4Reloc.h - src/config/C4SecurityCertificates.cpp - src/config/C4SecurityCertificates.h src/control/C4Control.cpp src/control/C4Control.h src/control/C4GameControl.cpp @@ -211,102 +174,59 @@ set(OC_CLONK_SOURCES src/editor/C4ConsoleGUICommon.h src/editor/C4ConsoleGUI.h src/editor/C4Console.h - src/editor/C4DevmodeDlg.cpp - src/editor/C4DevmodeDlg.h src/editor/C4EditCursor.cpp src/editor/C4EditCursor.h src/editor/C4ObjectListDlg.cpp src/editor/C4ObjectListDlg.h src/editor/C4ToolsDlg.cpp src/editor/C4ToolsDlg.h + src/editor/C4ViewportWindow.cpp + src/editor/C4ViewportWindow.h + src/game/C4Application.cpp + src/game/C4Application.h + src/game/C4FullScreen.cpp + src/game/C4FullScreen.h + src/game/C4Game.cpp + src/game/C4Game.h src/game/C4GameVersion.h + src/game/C4GraphicsSystem.cpp + src/game/C4GraphicsSystem.h src/game/C4Physics.h - src/game/landscape/C4Landscape.cpp - src/game/landscape/C4Landscape.h - src/game/landscape/C4LandscapeRenderClassic.cpp - src/game/landscape/C4LandscapeRender.cpp - src/game/landscape/C4LandscapeRender.h - src/game/landscape/C4Map.cpp - src/game/landscape/C4MapCreatorS2.cpp - src/game/landscape/C4MapCreatorS2.h - src/game/landscape/C4Map.h - src/game/landscape/C4MassMover.cpp - src/game/landscape/C4MassMover.h - src/game/landscape/C4Material.cpp - src/game/landscape/C4Material.h - src/game/landscape/C4MaterialList.cpp - src/game/landscape/C4MaterialList.h - src/game/landscape/C4Particles.cpp - src/game/landscape/C4Particles.h - src/game/landscape/C4PathFinder.cpp - src/game/landscape/C4PathFinder.h - src/game/landscape/C4PXS.cpp - src/game/landscape/C4PXS.h - src/game/landscape/C4Region.cpp - src/game/landscape/C4Region.h - src/game/landscape/C4Scenario.cpp - src/game/landscape/C4Scenario.h - src/game/landscape/C4Sky.cpp - src/game/landscape/C4Sky.h - src/game/landscape/C4SolidMask.cpp - src/game/landscape/C4SolidMask.h - src/game/landscape/C4Texture.cpp - src/game/landscape/C4Texture.h - src/game/landscape/C4Weather.cpp - src/game/landscape/C4Weather.h - src/game/object/C4Action.cpp - src/game/object/C4Command.cpp - src/game/object/C4Command.h - src/game/object/C4Def.cpp - src/game/object/C4DefGraphics.cpp - src/game/object/C4DefGraphics.h - src/game/object/C4Def.h - src/game/object/C4DefList.cpp - src/game/object/C4DefList.h - src/game/object/C4GameObjects.cpp - src/game/object/C4GameObjects.h - src/game/object/C4Id.cpp - src/game/object/C4Id.h - src/game/object/C4IDList.cpp - src/game/object/C4IDList.h - src/game/object/C4InfoCore.cpp - src/game/object/C4InfoCore.h - src/game/object/C4MeshAnimation.cpp - src/game/object/C4MeshAnimation.h - src/game/object/C4Movement.cpp - src/game/object/C4ObjectCom.cpp - src/game/object/C4ObjectCom.h - src/game/object/C4Object.cpp - src/game/object/C4Object.h - src/game/object/C4ObjectInfo.cpp - src/game/object/C4ObjectInfo.h - src/game/object/C4ObjectInfoList.cpp - src/game/object/C4ObjectInfoList.h - src/game/object/C4ObjectList.cpp - src/game/object/C4ObjectList.h - src/game/object/C4ObjectMenu.cpp - src/game/object/C4ObjectMenu.h - src/game/object/C4ObjectPtr.cpp - src/game/object/C4ObjectPtr.h - src/game/object/C4ObjectScript.cpp - src/game/object/C4Sector.cpp - src/game/object/C4Sector.h - src/game/object/C4Shape.cpp - src/game/object/C4Shape.h - src/game/player/C4Player.cpp - src/game/player/C4Player.h - src/game/player/C4PlayerList.cpp - src/game/player/C4PlayerList.h - src/game/player/C4RankSystem.cpp - src/game/player/C4RankSystem.h - src/game/script/C4Effect.cpp - src/game/script/C4Effects.h - src/game/script/C4FindObject.cpp - src/game/script/C4FindObject.h - src/game/script/C4GameScript.cpp - src/game/script/C4Script.h - src/game/script/C4TransferZone.cpp - src/game/script/C4TransferZone.h + src/game/C4Viewport.cpp + src/game/C4Viewport.h + src/gamescript/C4Effect.cpp + src/gamescript/C4Effect.h + src/gamescript/C4FindObject.cpp + src/gamescript/C4FindObject.h + src/gamescript/C4GameScript.cpp + src/gamescript/C4Script.h + src/gamescript/C4TransferZone.cpp + src/gamescript/C4TransferZone.h + src/graphics/Bitmap256.cpp + src/graphics/Bitmap256.h + src/graphics/C4Draw.cpp + src/graphics/C4DrawGL.cpp + src/graphics/C4DrawGLCtx.cpp + src/graphics/C4DrawGL.h + src/graphics/C4DrawMeshGL.cpp + src/graphics/C4DrawT.cpp + src/graphics/C4DrawT.h + src/graphics/C4Draw.h + src/graphics/C4Facet.cpp + src/graphics/C4FacetEx.cpp + src/graphics/C4FacetEx.h + src/graphics/C4Facet.h + src/graphics/C4FontLoader.cpp + src/graphics/C4FontLoader.h + src/graphics/C4GraphicsResource.cpp + src/graphics/C4GraphicsResource.h + src/graphics/C4Surface.cpp + src/graphics/C4Surface.h + src/graphics/C4SurfaceLoaders.cpp + src/graphics/CSurface8.cpp + src/graphics/CSurface8.h + src/graphics/StdPNG.cpp + src/graphics/StdPNG.h src/gui/C4ChatDlg.cpp src/gui/C4ChatDlg.h src/gui/C4DownloadDlg.cpp @@ -373,23 +293,47 @@ set(OC_CLONK_SOURCES src/gui/C4StartupScenSelDlg.h src/gui/C4UpperBoard.cpp src/gui/C4UpperBoard.h - src/gui/C4UserMessages.h - src/gui/C4Viewport.cpp - src/gui/C4Viewport.h - src/lib/C4InputValidation.cpp - src/lib/C4InputValidation.h + src/landscape/C4Landscape.cpp + src/landscape/C4Landscape.h + src/landscape/C4LandscapeRenderClassic.cpp + src/landscape/C4LandscapeRender.cpp + src/landscape/C4LandscapeRender.h + src/landscape/C4Map.cpp + src/landscape/C4MapCreatorS2.cpp + src/landscape/C4MapCreatorS2.h + src/landscape/C4Map.h + src/landscape/C4MapScript.cpp + src/landscape/C4MapScriptAlgo.cpp + src/landscape/C4MapScript.h + src/landscape/C4MassMover.cpp + src/landscape/C4MassMover.h + src/landscape/C4Material.cpp + src/landscape/C4Material.h + src/landscape/C4MaterialList.cpp + src/landscape/C4MaterialList.h + src/landscape/C4Particles.cpp + src/landscape/C4Particles.h + src/landscape/C4PathFinder.cpp + src/landscape/C4PathFinder.h + src/landscape/C4PXS.cpp + src/landscape/C4PXS.h + src/landscape/C4Scenario.cpp + src/landscape/C4ScenarioSection.cpp + src/landscape/C4Scenario.h + src/landscape/C4Sky.cpp + src/landscape/C4Sky.h + src/landscape/C4SolidMask.cpp + src/landscape/C4SolidMask.h + src/landscape/C4Texture.cpp + src/landscape/C4Texture.h + src/landscape/C4Weather.cpp + src/landscape/C4Weather.h src/lib/C4LogBuf.cpp src/lib/C4LogBuf.h src/lib/C4Log.cpp src/lib/C4Log.h - src/lib/C4Markup.cpp - src/lib/C4Markup.h src/lib/C4NameList.cpp src/lib/C4NameList.h - src/lib/C4Random.cpp - src/lib/C4Random.h - src/lib/C4Real.cpp - src/lib/C4Real.h src/lib/C4Rect.cpp src/lib/C4Rect.h src/lib/C4RTF.cpp @@ -398,17 +342,8 @@ set(OC_CLONK_SOURCES src/lib/C4Stat.h src/lib/PathFinder.cpp src/lib/PathFinder.h - src/lib/SHA1.h - src/lib/Standard.cpp - src/lib/Standard.h src/lib/StdAdaptors.h - src/lib/StdBase64.cpp - src/lib/StdBase64.h - src/lib/StdBuf.cpp - src/lib/StdBuf.h src/lib/StdColors.h - src/lib/StdCompiler.cpp - src/lib/StdCompiler.h src/lib/StdMesh.cpp src/lib/StdMesh.h src/lib/StdMeshLoaderBinaryChunks.cpp @@ -423,18 +358,6 @@ set(OC_CLONK_SOURCES src/lib/StdMeshMath.h src/lib/StdMeshUpdate.cpp src/lib/StdMeshUpdate.h - src/lib/StdResStr2.cpp - src/lib/StdResStr2.h - src/lib/StdResStr.h - src/lib/texture/C4Facet.cpp - src/lib/texture/C4FacetEx.cpp - src/lib/texture/C4FacetEx.h - src/lib/texture/C4Facet.h - src/lib/texture/C4GraphicsResource.cpp - src/lib/texture/C4GraphicsResource.h - src/lib/texture/C4SurfaceLoaders.cpp - src/lib/texture/StdPNG.cpp - src/lib/texture/StdPNG.h src/network/C4Client.cpp src/network/C4Client.h src/network/C4GameControlNetwork.cpp @@ -443,8 +366,6 @@ set(OC_CLONK_SOURCES src/network/C4InteractiveThread.h src/network/C4League.cpp src/network/C4League.h - src/network/C4NetIO.cpp - src/network/C4NetIO.h src/network/C4Network2Client.cpp src/network/C4Network2Client.h src/network/C4Network2.cpp @@ -469,15 +390,48 @@ set(OC_CLONK_SOURCES src/network/C4Network2UPnP.h src/network/C4Packet2.cpp src/network/C4PacketBase.h - src/platform/Bitmap256.cpp - src/platform/Bitmap256.h + src/object/C4Action.cpp + src/object/C4Command.cpp + src/object/C4Command.h + src/object/C4Def.cpp + src/object/C4DefGraphics.cpp + src/object/C4DefGraphics.h + src/object/C4Def.h + src/object/C4DefList.cpp + src/object/C4DefList.h + src/object/C4GameObjects.cpp + src/object/C4GameObjects.h + src/object/C4IDList.cpp + src/object/C4IDList.h + src/object/C4InfoCore.cpp + src/object/C4InfoCore.h + src/object/C4MeshAnimation.cpp + src/object/C4MeshAnimation.h + src/object/C4Movement.cpp + src/object/C4ObjectCom.cpp + src/object/C4ObjectCom.h + src/object/C4Object.cpp + src/object/C4Object.h + src/object/C4ObjectInfo.cpp + src/object/C4ObjectInfo.h + src/object/C4ObjectInfoList.cpp + src/object/C4ObjectInfoList.h + src/object/C4ObjectList.cpp + src/object/C4ObjectList.h + src/object/C4ObjectMenu.cpp + src/object/C4ObjectMenu.h + src/object/C4ObjectPtr.cpp + src/object/C4ObjectPtr.h + src/object/C4ObjectScript.cpp + src/object/C4Sector.cpp + src/object/C4Sector.h + src/object/C4Shape.cpp + src/object/C4Shape.h src/platform/C4App.cpp src/platform/C4App.h - src/platform/C4AppT.cpp + src/platform/C4AppWin32Impl.h src/platform/C4FileMonitor.cpp src/platform/C4FileMonitor.h - src/platform/C4Fonts.cpp - src/platform/C4Fonts.h src/platform/C4GamePadCon.cpp src/platform/C4GamePadCon.h src/platform/C4MusicFile.cpp @@ -488,84 +442,130 @@ set(OC_CLONK_SOURCES src/platform/C4SoundLoaders.h src/platform/C4SoundSystem.cpp src/platform/C4SoundSystem.h - src/platform/C4Surface.cpp - src/platform/C4Surface.h + src/platform/C4TimeMilliseconds.cpp + src/platform/C4TimeMilliseconds.h + src/platform/C4StdInProc.cpp + src/platform/C4StdInProc.h src/platform/C4Video.cpp src/platform/C4Video.h - src/platform/C4VideoPlayback.cpp - src/platform/C4VideoPlayback.h - src/platform/C4ViewportWindow.cpp - src/platform/C4ViewportWindow.h src/platform/C4Window.h src/platform/C4windowswrapper.h - src/platform/GetTime.cpp src/platform/PlatformAbstraction.cpp src/platform/PlatformAbstraction.h - src/platform/StdD3D.cpp - src/platform/StdD3D.h - src/platform/StdD3DShader.cpp - src/platform/StdD3DShader.h - src/platform/StdDDraw2.cpp - src/platform/StdDDraw2.h - src/platform/StdFile.cpp - src/platform/StdFile.h - src/platform/StdFont.cpp - src/platform/StdFont.h - src/platform/StdGL.cpp - src/platform/StdGLCtx.cpp - src/platform/StdGL.h - src/platform/StdNoGfx.cpp - src/platform/StdNoGfx.h - src/platform/StdRegistry.cpp - src/platform/StdRegistry.h - src/platform/StdScheduler.cpp - src/platform/StdScheduler.h - src/platform/StdSurface8.cpp - src/platform/StdSurface8.h src/platform/StdSync.h src/platform/StdVideo.cpp src/platform/StdVideo.h - src/script/C4Aul.cpp + src/player/C4Player.cpp + src/player/C4Player.h + src/player/C4PlayerList.cpp + src/player/C4PlayerList.h + src/player/C4RankSystem.cpp + src/player/C4RankSystem.h src/script/C4AulDebug.cpp src/script/C4AulDebug.h - src/script/C4AulDefFunc.h - src/script/C4AulExec.cpp - src/script/C4AulExec.h - src/script/C4AulFunc.h - src/script/C4Aul.h - src/script/C4AulLink.cpp - src/script/C4AulParse.cpp - src/script/C4PropList.cpp - src/script/C4PropList.h - src/script/C4Script.cpp - src/script/C4ScriptHost.cpp - src/script/C4ScriptHost.h - src/script/C4StringTable.cpp - src/script/C4StringTable.h - src/script/C4ValueArray.cpp - src/script/C4ValueArray.h - src/script/C4Value.cpp - src/script/C4Value.h - src/script/C4ValueMap.cpp - src/script/C4ValueMap.h - src/zlib/gzio.h - src/zlib/gzio.c - src/zlib/zutil.h thirdparty/timsort/sort.h ) -mark_as_advanced(OC_CLONK_SOURCES) -mark_as_advanced(OC_SYSTEM_SOURCES) + +set(MAPE_BASE_SOURCES + src/landscape/C4MapCreatorS2.cpp + src/landscape/C4MapCreatorS2.h + src/landscape/C4Material.cpp + src/landscape/C4Material.h + src/landscape/C4Texture.cpp + src/landscape/C4Texture.h + src/landscape/C4Scenario.cpp + src/landscape/C4Scenario.h + src/lib/C4NameList.cpp + src/lib/C4NameList.h + src/lib/C4Rect.cpp + src/lib/C4Rect.h +) + +set(MAPE_SOURCES + src/mape/cpp-handles/group-handle.h + src/mape/cpp-handles/group-handle.cpp + src/mape/cpp-handles/log-handle.h + src/mape/cpp-handles/log-handle.cpp + src/mape/cpp-handles/mapgen-handle.h + src/mape/cpp-handles/mapgen-handle.cpp + src/mape/cpp-handles/material-handle.h + src/mape/cpp-handles/material-handle.cpp + src/mape/cpp-handles/random-handle.h + src/mape/cpp-handles/random-handle.cpp + src/mape/cpp-handles/texture-handle.h + src/mape/cpp-handles/texture-handle.cpp + src/mape/cpp-handles/version-handle.h + src/mape/cpp-handles/version-handle.cpp + src/mape/cpp-handles/stub-handle.cpp + src/mape/configfile.c + src/mape/configfile.h + src/mape/diskview.c + src/mape/diskview.h + src/mape/editview.c + src/mape/editview.h + src/mape/fileicon.c + src/mape/fileicon.h + src/mape/forward.h + src/mape/group.c + src/mape/group.h + src/mape/header.c + src/mape/header.h + src/mape/iconview.c + src/mape/iconview.h + src/mape/mape.c + src/mape/mapgen.c + src/mape/mapgen.h + src/mape/material.c + src/mape/material.h + src/mape/mattexview.c + src/mape/mattexview.h + src/mape/preferences.c + src/mape/preferences.h + src/mape/preferencesdialog.c + src/mape/preferencesdialog.h + src/mape/preview.c + src/mape/preview.h + src/mape/random.c + src/mape/random.h + src/mape/statusbar.c + src/mape/statusbar.h + src/mape/texture.c + src/mape/texture.h + src/mape/window.c + src/mape/window.h +) + +# generated source files +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mape-icons.h + COMMAND + gdk-pixbuf-csource "--raw" "--static" "--build-list" + "mape_icon_ocd" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocd.ico" + "mape_icon_ocf" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocf.ico" + "mape_icon_ocg" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocg.ico" + "mape_icon_ocm" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocm.ico" + "mape_icon_ocs" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/ocs.ico" + > ${CMAKE_CURRENT_BINARY_DIR}/mape-icons.h + 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 +) +list(APPEND MAPE_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/mape-icons.h) # source files specific to an operating system if(APPLE) list(APPEND OC_SYSTEM_SOURCES src/platform/C4FileMonitorMac.mm - src/platform/ClonkAppDelegate.h - src/platform/ClonkAppDelegate.mm + src/platform/C4AppDelegate.h + src/platform/C4AppDelegate.mm ) else() list(APPEND OC_SYSTEM_SOURCES - src/C4WinMain.cpp + src/game/ClonkMain.cpp ) endif() if(WIN32) @@ -574,6 +574,8 @@ if(WIN32) src/res/resource.h ) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/res/openclonk.manifest" "${CMAKE_CURRENT_BINARY_DIR}/openclonk.manifest" COPYONLY) + if(MINGW) # cmake does not support compiling resources with MinGW # natively, see http://www.cmake.org/Bug/view.php?id=4068. @@ -600,35 +602,73 @@ endif() # source files specific to a GUI library if(USE_GTK) - list(APPEND OC_CLONK_SOURCES - src/res/Brush.h - src/res/Cursor.h - src/res/Dynamic.h - src/res/Exact.h - src/res/Fill.h - src/res/Halt.h - src/res/Ift.h - src/res/Line.h - src/res/Mouse.h - src/res/NoIft.h - src/res/Picker.h - src/res/Play.h - src/res/Rect.h - src/res/resource.h - src/res/Static.h + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/editor-icons.h + COMMAND + gdk-pixbuf-csource "--raw" "--rle" "--static" "--build-list" + "brush_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Brush_Trans.png" + "halt_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Halt_Trans.png" + "picker_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Picker_Trans.png" + "cursor_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Cursor_Trans.png" + "ift_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Ift_Trans.png" + "play_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Play_Trans.png" + "dynamic_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Dynamic_Trans.png" + "line_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Line_Trans.png" + "rect_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Rect_Trans.png" + "exact_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Exact_Trans.png" + "mouse_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Mouse_Trans.png" + "static_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Static_Trans.png" + "fill_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Fill_Trans.png" + "no_ift_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/NoIft_Trans.png" + > ${CMAKE_CURRENT_BINARY_DIR}/editor-icons.h + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Brush_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Halt_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Picker_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Cursor_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Ift_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Play_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Dynamic_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Line_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Rect_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Exact_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Mouse_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Static_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/Fill_Trans.png + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/NoIft_Trans.png + VERBATIM ) + list(APPEND OC_CLONK_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/editor-icons.h) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/oc-icon.h + COMMAND + gdk-pixbuf-csource "--raw" "--rle" "--static" "--build-list" + "oc_icon_pixbuf_data" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc.ico" + > ${CMAKE_CURRENT_BINARY_DIR}/oc-icon.h + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc.ico + VERBATIM + ) + list(APPEND OC_CLONK_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/oc-icon.h) + list(APPEND OC_SYSTEM_SOURCES src/editor/C4ConsoleGTK.cpp - src/platform/C4AppX.cpp - src/platform/C4AppXImpl.h + src/editor/C4ConsoleGTKDlg.cpp + src/editor/C4ConsoleGTKDlg.h + src/platform/C4AppGTK.cpp + src/platform/C4AppGTKImpl.h src/platform/C4WindowGTK.cpp - src/platform/C4WindowX.cpp ) elseif(USE_SDL_MAINLOOP) list(APPEND OC_SYSTEM_SOURCES src/platform/C4AppSDL.cpp src/platform/C4WindowSDL.cpp ) +elseif(USE_CONSOLE) + list(APPEND OC_SYSTEM_SOURCES + src/platform/C4AppT.cpp + ) elseif(WIN32) list(APPEND OC_SYSTEM_SOURCES src/editor/C4ConsoleWin32.cpp @@ -641,14 +681,16 @@ elseif(USE_COCOA) src/editor/C4ConsoleCocoa.mm src/platform/C4AppMac.mm src/platform/C4WindowMac.mm - src/platform/ClonkMainMenuActions.mm - src/platform/ClonkOpenGLView.h - src/platform/ClonkOpenGLView.mm - src/platform/ClonkWindowController.h - src/platform/ClonkWindowController.mm + src/platform/C4AppDelegate+MainMenuActions.h + src/platform/C4AppDelegate+MainMenuActions.mm + src/graphics/C4DrawGLMac.h + src/graphics/C4DrawGLMac.mm + src/platform/C4WindowController.h + src/platform/C4WindowController.mm src/platform/CocoaKeycodeMap.h - src/platform/ConsoleWindowController.h - src/platform/ConsoleWindowController.mm + src/editor/C4EditorWindowController.h + src/editor/C4EditorWindowController.mm + src/platform/ObjectiveCAssociated.h ) endif() if(WITH_AUTOMATIC_UPDATE) @@ -663,36 +705,37 @@ if(PROJECT_FOLDERS) source_group("Platform abstraction" src/platform/.*) source_group("Utility" src/lib/.*) source_group("C4Group" src/c4group/.*) - source_group("Texture" src/lib/texture/.*) + source_group("Graphics" src/graphics/.*) source_group("GUI" src/gui/.*) source_group("Network" src/network/.*) - source_group("Object" src/game/object/.*) - source_group("Landscape" src/game/landscape/.*) - source_group("Player" src/game/player/.*) - source_group("Script" REGULAR_EXPRESSION .*/script/.*) + source_group("Object" src/object/.*) + source_group("Landscape" src/landscape/.*) + source_group("Player" src/player/.*) + source_group("Script" REGULAR_EXPRESSION .*script/.*) source_group("Config" src/config/.*) source_group("Control" src/control/.*) source_group("Editing" src/editor/.*) + source_group("Mape" src/mape/.*) endif() include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/c4group - ${CMAKE_CURRENT_SOURCE_DIR}/src/network - ${CMAKE_CURRENT_SOURCE_DIR}/src/lib - ${CMAKE_CURRENT_SOURCE_DIR}/src/platform ${CMAKE_CURRENT_SOURCE_DIR}/src/config - ${CMAKE_CURRENT_SOURCE_DIR}/src/res ${CMAKE_CURRENT_SOURCE_DIR}/src/control - ${CMAKE_CURRENT_SOURCE_DIR}/src/gui ${CMAKE_CURRENT_SOURCE_DIR}/src/editor - ${CMAKE_CURRENT_SOURCE_DIR}/src/game/landscape - ${CMAKE_CURRENT_SOURCE_DIR}/src/game/player - ${CMAKE_CURRENT_SOURCE_DIR}/src/game/script ${CMAKE_CURRENT_SOURCE_DIR}/src/game - ${CMAKE_CURRENT_SOURCE_DIR}/src/game/object - ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/texture + ${CMAKE_CURRENT_SOURCE_DIR}/src/gamescript + ${CMAKE_CURRENT_SOURCE_DIR}/src/graphics + ${CMAKE_CURRENT_SOURCE_DIR}/src/gui + ${CMAKE_CURRENT_SOURCE_DIR}/src/landscape + ${CMAKE_CURRENT_SOURCE_DIR}/src/lib + ${CMAKE_CURRENT_SOURCE_DIR}/src/network + ${CMAKE_CURRENT_SOURCE_DIR}/src/object + ${CMAKE_CURRENT_SOURCE_DIR}/src/platform + ${CMAKE_CURRENT_SOURCE_DIR}/src/player + ${CMAKE_CURRENT_SOURCE_DIR}/src/res ${CMAKE_CURRENT_SOURCE_DIR}/src/script ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty ) @@ -728,10 +771,8 @@ CHECK_INCLUDE_FILE_CXX(natupnp.h HAVE_NATUPNP_H) # 'Bool' and 'Window' to be defined. Unfortunately, this doesn't exist # as a CXX version (yet?). include(CheckIncludeFiles) -CHECK_INCLUDE_FILES(X11/Xlib.h X11/extensions/xf86vmode.h HAVE_X11_EXTENSIONS_XF86VMODE_H) CHECK_INCLUDE_FILES(X11/Xlib.h X11/extensions/Xrandr.h HAVE_X11_EXTENSIONS_XRANDR_H) CHECK_INCLUDE_FILES(X11/Xlib.h X11/keysym.h HAVE_X11_KEYSYM_H) -CHECK_INCLUDE_FILES(X11/Xlib.h X11/xpm.h HAVE_X11_XPM_H) CHECK_INCLUDE_FILE_CXX(iconv.h HAVE_ICONV) if(HAVE_ICONV) @@ -784,29 +825,26 @@ if(MSVC) endif() endif() -SET(JPEG_NAMES ${JPEG_NAMES} libjpeg) -include(FindJPEG) +if(NOT USE_CONSOLE) + SET(JPEG_NAMES ${JPEG_NAMES} libjpeg jpeg-static) + include(FindJPEG) +endif() include(FindPNG) include(FindZLIB) include_directories(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) -find_package("Boost" 1.40.0) -if(NOT Boost_INCLUDE_DIR) - message(SEND_ERROR "Could not find the Boost C++ Libraries") -else() - include_directories(SYSTEM ${Boost_INCLUDE_DIR}) -endif() +find_package("Boost" 1.40.0 REQUIRED) +include_directories(SYSTEM ${Boost_INCLUDE_DIR}) include(FindThreads) if(NOT WIN32) SET(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT} CACHE INTERNAL "libpthread available") endif() -# isilkor 09-05-29: FindFreetype only checks for no-ver and 219 -find_library(FREETYPE_LIBRARY NAMES freetype239) -include(FindFreetype) -include_directories(${FREETYPE_INCLUDE_DIRS}) -SET(HAVE_FREETYPE ${FREETYPE_FOUND} CACHE INTERNAL "Rename of FREETYPE_FOUND for config.h") +if(NOT USE_CONSOLE) + find_package(Freetype REQUIRED) + include_directories(${FREETYPE_INCLUDE_DIRS}) +endif() # FINDLIB works the same as find_library, but also marks the resulting var as # advanced so it doesn't show in GUIs by default @@ -826,20 +864,45 @@ endif() if(USE_GTK) include(FindPkgConfig) if (USE_GTK3) - pkg_check_modules(GTK3 REQUIRED "glib-2.0 >= 2.27.5" "gtk+-3.0 >= 2.99.0") + pkg_check_modules(GTK3 REQUIRED "glib-2.0 >= 2.32" "gtk+-3.0 >= 3.4") include_directories(${GTK3_INCLUDE_DIRS}) link_directories(${GTK3_LIBRARY_DIRS}) else() - pkg_check_modules(GTK REQUIRED "glib-2.0 >= 2.8" "gtk+-2.0 >= 2.8") + pkg_check_modules(GTK REQUIRED "glib-2.0 >= 2.24" "gtk+-2.0 >= 2.20") include_directories(${GTK_INCLUDE_DIRS}) link_directories(${GTK_LIBRARY_DIRS}) endif() endif() +# Try to find GTK for mape +include(FindPkgConfig) +if (PKG_CONFIG_FOUND) + if (USE_GTK3) + pkg_check_modules(MAPE_GTK glib-2.0>=2.32 gthread-2.0 gtk+-3.0>=3.4 gtksourceview-3.0) + else() + pkg_check_modules(MAPE_GTK glib-2.0>=2.24 gthread-2.0 gtk+-2.0>=2.20 gtksourceview-2.0) + endif() +endif() +if(MAPE_GTK_FOUND) + # hrm, cmake doesn't have target_include_directories... + include_directories(${MAPE_GTK_INCLUDE_DIRS}) + link_directories(${MAPE_GTK_LIBRARY_DIRS}) +endif() + if(USE_OPEN_AL) - FINDLIB(VORBIS_LIBRARY NAMES vorbis) - FINDLIB(VORBISFILE_LIBRARY NAMES vorbisfile) - FINDLIB(OGG_LIBRARY NAMES ogg) + if(MSVC) + if(${FIND_LIBRARY_USE_LIB64_PATHS}) + FINDLIB(OPENAL_LIBRARY NAMES OpenAL64) + else() + FINDLIB(OPENAL_LIBRARY NAMES OpenAL32) + endif() + endif() + FINDLIB(OGG_LIBRARY NAMES libogg_static libogg ogg) + FINDLIB(VORBIS_LIBRARY NAMES libvorbis_static libvorbis vorbis) + FINDLIB(VORBISFILE_LIBRARY NAMES libvorbisfile_static libvorbisfile vorbisfile) + if(NOT APPLE) + FINDLIB(ALUT_LIBRARY NAMES alut_static alut) + endif() endif() ############################################################################ @@ -862,10 +925,10 @@ if(APPLE) src/res/ocd.icns src/res/ocf.icns src/res/ocg.icns src/res/C4P.icns src/res/ocs.icns src/res/ocu.icns src/res/MainMenu.xib - src/res/FullscreenWindow.xib - src/res/ConsoleGUIWindow.xib - src/res/ClonkWindow.xib - src/res/ConsoleWindow.xib + src/res/FullScreen.xib + src/res/EditorGUIWindow.xib + src/res/EditorViewport.xib + src/res/Editor.xib src/res/Mouse_Trans.png src/res/Cursor_Trans.png src/res/Brush_Trans.png @@ -895,114 +958,166 @@ endif() # Generate output files ############################################################################ add_definitions(-DHAVE_CONFIG_H) -add_executable(clonk WIN32 MACOSX_BUNDLE +add_executable(openclonk WIN32 MACOSX_BUNDLE ${OC_SYSTEM_SOURCES} ${OC_CLONK_SOURCES} ) +if(MAPE_GTK_FOUND) + add_executable(mape ${MAPE_BASE_SOURCES} ${MAPE_SOURCES}) + unseparate_arguments(MAPE_GTK_CFLAGS "${MAPE_GTK_CFLAGS}") + set_property(TARGET mape PROPERTY COMPILE_FLAGS "${MAPE_GTK_CFLAGS}") + unseparate_arguments(MAPE_GTK_LDFLAGS "${MAPE_GTK_LDFLAGS}") + set_property(TARGET mape PROPERTY LINK_FLAGS "${MAPE_GTK_LDFLAGS}") +endif() + add_executable(c4group - src/c4group/c4group_ng.cpp - src/c4group/C4Group.cpp - src/lib/C4InputValidation.cpp - src/config/C4SecurityCertificates.cpp - src/c4group/C4Update.cpp - src/lib/Standard.cpp - src/c4group/CStdFile.cpp - src/lib/C4Markup.cpp - src/lib/StdBuf.cpp - src/lib/StdCompiler.cpp - src/platform/StdFile.cpp - src/platform/StdRegistry.cpp - src/lib/StdResStr2.cpp - src/lib/C4SimpleLog.cpp - src/zlib/gzio.c - src/C4Include.cpp + src/c4group/C4GroupMain.cpp ) add_executable(netpuncher EXCLUDE_FROM_ALL - src/C4Include.cpp - src/lib/C4SimpleLog.cpp - src/lib/StdBuf.cpp - src/lib/Standard.cpp - src/platform/GetTime.cpp src/platform/StdScheduler.cpp - src/platform/StdFile.cpp - src/network/C4NetIO.cpp src/netpuncher/main.cpp ) +add_library(libmisc +src/c4group/C4Group.cpp +src/c4group/C4Group.h +src/c4group/C4Update.cpp +src/c4group/C4Update.h +src/c4group/CStdFile.cpp +src/c4group/CStdFile.h +src/lib/C4InputValidation.cpp +src/lib/C4InputValidation.h +src/lib/SHA1.h +src/lib/Standard.cpp +src/lib/Standard.h +src/lib/StdBuf.cpp +src/lib/StdBuf.h +src/lib/StdCompiler.cpp +src/lib/StdCompiler.h +src/lib/C4Markup.cpp +src/lib/C4Markup.h +src/lib/StdResStr2.cpp +src/network/C4NetIO.cpp +src/network/C4NetIO.h +src/platform/StdFile.cpp +src/platform/StdFile.h +src/platform/StdRegistry.cpp +src/platform/StdRegistry.h +src/platform/StdScheduler.cpp +src/platform/StdScheduler.h +src/platform/C4TimeMilliseconds.cpp +src/platform/C4TimeMilliseconds.h +src/zlib/gzio.c +src/zlib/gzio.h +src/zlib/zutil.h + +src/C4Include.cpp +src/lib/C4SimpleLog.cpp +) + +target_link_libraries(libmisc ${ZLIB_LIBRARIES}) + +add_library(libc4script +src/c4group/C4GroupSet.cpp +src/c4group/C4GroupSet.h +src/c4group/C4ComponentHost.cpp +src/c4group/C4ComponentHost.h +src/c4group/C4LangStringTable.cpp +src/c4group/C4LangStringTable.h +src/lib/C4Real.cpp +src/lib/C4Real.h +src/lib/C4Random.cpp +src/lib/C4Random.h +src/object/C4Id.cpp +src/object/C4Id.h +src/script/C4Aul.cpp +src/script/C4AulDefFunc.h +src/script/C4AulExec.cpp +src/script/C4AulExec.h +src/script/C4AulFunc.cpp +src/script/C4AulFunc.h +src/script/C4Aul.h +src/script/C4AulLink.cpp +src/script/C4AulParse.cpp +src/script/C4PropList.cpp +src/script/C4PropList.h +src/script/C4Script.cpp +src/script/C4ScriptHost.cpp +src/script/C4ScriptHost.h +src/script/C4StringTable.cpp +src/script/C4StringTable.h +src/script/C4ValueArray.cpp +src/script/C4ValueArray.h +src/script/C4Value.cpp +src/script/C4Value.h +src/script/C4ValueMap.cpp +src/script/C4ValueMap.h +) + add_executable(c4script include/c4script/c4script.h - src/c4group/C4Group.cpp - src/c4group/C4Group.h - src/c4group/CStdFile.cpp - src/c4group/CStdFile.h - src/lib/C4InputValidation.cpp - src/lib/C4InputValidation.h - src/lib/C4SimpleLog.cpp - src/lib/Standard.cpp - src/lib/Standard.h - src/lib/StdBuf.cpp - src/lib/StdBuf.h - src/lib/StdCompiler.cpp - src/lib/StdCompiler.h - src/lib/C4Markup.cpp - src/lib/C4Markup.h - src/lib/StdResStr2.cpp - src/lib/StdResStr2.h - src/platform/GetTime.cpp - src/platform/StdFile.cpp - src/platform/StdFile.h - src/lib/C4Real.cpp - src/lib/C4Random.cpp - src/script/shell.cpp - src/script/C4Aul.cpp - src/script/C4AulExec.cpp - src/script/C4AulLink.cpp - src/script/C4AulParse.cpp - src/script/C4StringTable.cpp - src/script/C4PropList.cpp - src/script/C4ScriptHost.cpp + src/script/C4ScriptMain.cpp src/script/C4ScriptStandalone.cpp - src/script/C4ValueArray.cpp - src/script/C4Value.cpp - src/script/C4ValueMap.cpp - src/game/object/C4Id.cpp - src/script/C4Script.cpp - src/c4group/C4GroupSet.cpp - src/c4group/C4ComponentHost.cpp - src/c4group/C4LangStringTable.cpp - src/zlib/gzio.c - src/C4Include.cpp ) -target_link_libraries(clonk +target_link_libraries(openclonk ${FREETYPE_LIBRARIES} - ${ZLIB_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${ICONV_LIBRARY} - ${VORBIS_LIBRARY} - ${VORBISFILE_LIBRARY} - ${OGG_LIBRARY} + libc4script + libmisc ) + +if(USE_OPEN_AL) + target_link_libraries(openclonk + ${OPENAL_LIBRARY} + ${ALUT_LIBRARY} + ${VORBIS_LIBRARY} + ${VORBISFILE_LIBRARY} + ${OGG_LIBRARY} + ) +endif() + +if(MAPE_GTK_FOUND) + target_link_libraries(mape + libc4script + libmisc + ) +endif() + +target_link_libraries(netpuncher + libmisc +) + target_link_libraries(c4group - ${ZLIB_LIBRARIES} + libmisc ) + target_link_libraries(c4script - ${ZLIB_LIBRARIES} + libc4script + libmisc ) if(HAVE_PTHREAD) + target_link_libraries(openclonk + pthread + ) target_link_libraries(netpuncher pthread ) target_link_libraries(c4script pthread ) + if(MAPE_GTK_FOUND) + target_link_libraries(mape + pthread + ) + endif() endif() if(USE_CONSOLE) - target_link_libraries(clonk - pthread + target_link_libraries(openclonk ${READLINE_LIBRARIES} ) endif() @@ -1010,14 +1125,17 @@ if(UNIX AND NOT APPLE) target_link_libraries(c4group rt) target_link_libraries(c4script rt) target_link_libraries(netpuncher rt) - target_link_libraries(clonk rt) + target_link_libraries(openclonk rt) + if(MAPE_GTK_FOUND) + target_link_libraries(mape rt) + endif() endif() -set_property(TARGET clonk APPEND PROPERTY COMPILE_DEFINITIONS GLEW_STATIC) +set_property(TARGET openclonk APPEND PROPERTY COMPILE_DEFINITIONS GLEW_STATIC) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG) # This expands some variables in Info.plist as a side-effect. XCode might then # expand a second time, using the same syntax. Try not to get confused by this! -set_target_properties(clonk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Info.plist") +set_target_properties(openclonk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/src/res/Info.plist") if(MSVC) # set target output filenames to a per-configuration value @@ -1031,10 +1149,15 @@ if(MSVC) endif() endforeach() endfunction() - oc_set_target_names(clonk) + oc_set_target_names(openclonk) oc_set_target_names(c4group) oc_set_target_names(c4script) oc_set_target_names(netpuncher) + + # cmake does not support embedding arbitrary manifests, + # so we add it to the resource file ourselves and tell + # MSVC not to create its own. + set_property(TARGET openclonk APPEND PROPERTY LINK_FLAGS "/MANIFEST:NO") endif() ############################################################################ @@ -1042,7 +1165,7 @@ endif() ############################################################################ if(HAVE_PRECOMPILED_HEADERS) if(MSVC_VERSION) - get_property(OC_SOURCES TARGET clonk PROPERTY SOURCES) + get_property(OC_SOURCES TARGET openclonk PROPERTY SOURCES) foreach(FILE ${OC_SOURCES}) get_filename_component(FILE_EXT ${FILE} EXT) get_filename_component(FILE_NAME_WE ${FILE} NAME_WE) @@ -1063,7 +1186,7 @@ if(UNIX) # Don't put this into CMAKE_CXX_FLAGS because otherwise it is cached, # and when the path is changed both the old and new definition appears # in the list of flags. - add_definitions("-DOC_SYSTEM_DATA_DIR=\"${CMAKE_INSTALL_PREFIX}/share/openclonk\"") + add_definitions("-DOC_SYSTEM_DATA_DIR=\"${CMAKE_INSTALL_PREFIX}/share/games/openclonk\"") endif() if(OC_CXX_FLAGS) list(REMOVE_DUPLICATES OC_CXX_FLAGS) @@ -1079,8 +1202,15 @@ set(CMAKE_CXX_FLAGS_DEBUG "" CACHE STRING "Flags used by the compiler during deb foreach(FLAG ${OC_CXX_FLAGS_DEBUG}) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}" CACHE STRING "Flags used by the compiler during debug builds." FORCE) endforeach() +if(OC_EXE_LINKER_FLAGS) + list(REMOVE_DUPLICATES OC_EXE_LINKER_FLAGS) +endif() +set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "Flags used by the linker." FORCE) +foreach(FLAG ${OC_EXE_LINKER_FLAGS}) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}" CACHE STRING "Flags used by the linker." FORCE) +endforeach() if(OC_EXE_LINKER_FLAGS_DEBUG) - list(REMOVE_DUPLICATES OC_CXX_FLAGS_DEBUG) + list(REMOVE_DUPLICATES OC_EXE_LINKER_FLAGS_DEBUG) endif() set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE STRING "Flags used by the linker during debug builds." FORCE) foreach(FLAG ${OC_EXE_LINKER_FLAGS_DEBUG}) @@ -1093,15 +1223,12 @@ endforeach() if(CMAKE_COMPILER_IS_GNUCXX) include(GccPchSupport) - if(NOT DEFINED USE_GCC_PCH) - message("Using GCC precompiled headers! USE_GCC_PCH=Off to disable.") - endif() option(USE_GCC_PCH "Use GCC precompiled headers" ON) endif() if(USE_GCC_PCH) - add_precompiled_header(clonk src/C4Include.h) - add_precompiled_header(c4group src/C4Include.h) - add_precompiled_header(c4script src/C4Include.h) + add_precompiled_header(libmisc src/C4Include.h) + add_precompiled_header(libc4script src/C4Include.h) + add_precompiled_header(openclonk src/C4Include.h) endif() ############################################################################ @@ -1109,19 +1236,23 @@ endif() ############################################################################ if (APPLE) - add_custom_command(TARGET clonk + add_custom_command(TARGET openclonk POST_BUILD COMMAND "/usr/bin/ruby" "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_bundle_libs" ) set(CMAKE_XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES) set(CMAKE_XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h") - SET_TARGET_PROPERTIES(clonk PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES) - SET_TARGET_PROPERTIES(clonk PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++ objective-c++") - SET_TARGET_PROPERTIES(clonk PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h") + SET_TARGET_PROPERTIES(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES) + SET_TARGET_PROPERTIES(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++ objective-c++") + SET_TARGET_PROPERTIES(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h") SET_TARGET_PROPERTIES(c4group PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES) SET_TARGET_PROPERTIES(c4group PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++ objective-c++") SET_TARGET_PROPERTIES(c4group PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h") + SET_TARGET_PROPERTIES(libmisc PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES) + SET_TARGET_PROPERTIES(libmisc PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++ objective-c++") + SET_TARGET_PROPERTIES(libmisc PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h") + SET_TARGET_PROPERTIES(openclonk PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) if (USE_APPLE_CLANG) set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0") @@ -1129,7 +1260,7 @@ if (APPLE) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++0x -stdlib=libc++ -g -Wall") SET_TARGET_PROPERTIES(c4group PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x") - SET_TARGET_PROPERTIES(clonk PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x") + SET_TARGET_PROPERTIES(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x") set(HAVE_RVALUE_REF ON) else() @@ -1144,12 +1275,12 @@ CHECK_INCLUDE_FILE_CXX(getopt.h HAVE_GETOPT_H) if(NOT HAVE_GETOPT_H) include_directories(thirdparty/getopt) add_subdirectory(thirdparty/getopt) - target_link_libraries(clonk getopt) + target_link_libraries(openclonk getopt) elseif(MINGW) # Link libiberty which my contain getopt with mingw FINDLIB(iberty_LIBRARIES iberty) if(iberty_LIBRARIES) - target_link_libraries(clonk iberty) + target_link_libraries(openclonk iberty) endif() endif() @@ -1157,69 +1288,54 @@ CHECK_INCLUDE_FILE_CXX(getopt.h HAVE_GETOPT_H) # TinyXML add_subdirectory(thirdparty/tinyxml) -target_link_libraries(clonk tinyxml) +target_link_libraries(openclonk tinyxml) if(WIN32) find_package(DbgHelp) if(DBGHELP_FOUND) - target_link_libraries(clonk ${DBGHELP_LIBRARIES}) + target_link_libraries(openclonk ${DBGHELP_LIBRARIES}) include_directories(${DBGHELP_INCLUDE_DIR}) endif() set(HAVE_DBGHELP ${DBGHELP_FOUND}) endif() -if(USE_GL) +if(NOT USE_CONSOLE) include(FindOpenGL) FINDLIB(GLEW_LIBRARIES NAMES GLEW glew32 glew32s) FIND_PATH(GLEW_INCLUDE_DIR NAMES GL/glew.h) - target_link_libraries(clonk + target_link_libraries(openclonk ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES} ) include_directories(${GLEW_INCLUDE_DIR}) endif() -if(USE_DIRECTX) - FINDLIB(DIRECT3D_LIBRARIES d3d9) - FINDLIB(DIRECT3DX_LIBRARIES d3dx9) - FIND_PATH(DIRECT3D_INCLUDE_DIR NAMES d3d9.h) - FIND_PATH(DIRECT3DX_INCLUDE_DIR NAMES d3dx9.h) - target_link_libraries(clonk - ${DIRECT3D_LIBRARIES} - ${DIRECT3DX_LIBRARIES} - ) - include_directories( - ${DIRECT3D_INCLUDE_DIR} - ${DIRECT3DX_INCLUDE_DIR} - ) -endif() if(USE_GTK) SET(WITH_DEVELOPER_MODE ${GTK_FOUND}) SET(WITH_GLIB ${GTK_FOUND}) if(USE_GTK3) - target_link_libraries(clonk + target_link_libraries(openclonk ${GTK3_LIBRARIES} ) else() - target_link_libraries(clonk + target_link_libraries(openclonk ${GTK_LIBRARIES} ) endif() endif() +if(MAPE_GTK_FOUND) + target_link_libraries(mape ${MAPE_GTK_LIBRARIES}) +endif() if(USE_X11) FINDLIB(X11_LIBRARIES X11) - FINDLIB(XPM_LIBRARIES Xpm) - FINDLIB(XXF86VM_LIBRARIES Xxf86vm) FINDLIB(XRANDR_LIBRARIES Xrandr) - target_link_libraries(clonk + target_link_libraries(openclonk ${X11_LIBRARIES} - ${XPM_LIBRARIES} - ${XXF86VM_LIBRARIES} ${XRANDR_LIBRARIES} ) endif() if(USE_COCOA) #stupid fix: just link to iconv that way - TARGET_LINK_LIBRARIES(clonk "-framework Cocoa -framework AppKit -framework Quartz -framework OpenAL -framework AudioToolBox -liconv") + TARGET_LINK_LIBRARIES(openclonk "-framework Cocoa -framework AppKit -framework Quartz -framework OpenAL -framework AudioToolBox -liconv") endif() if (WIN32) # CMake is too incompetent to check whether these libraries can be linked to @@ -1227,23 +1343,26 @@ if (WIN32) FINDLIB(VFW32_LIBRARIES vfw32) FINDLIB(wavifil32_LIBRARIES wavifil32) if (VFW32_LIBRARIES) - target_link_libraries(clonk vfw32) + target_link_libraries(openclonk vfw32) set(HAVE_VFW32 TRUE) elseif(wavifil32_LIBRARIES) - target_link_libraries(clonk wavifil32 msvfw32) + target_link_libraries(openclonk wavifil32 msvfw32) set(HAVE_VFW32 TRUE) endif() - target_link_libraries(clonk ws2_32 winmm) + target_link_libraries(openclonk ws2_32 winmm) target_link_libraries(c4group ws2_32) target_link_libraries(netpuncher ws2_32 winmm) target_link_libraries(c4script ws2_32 winmm) + if(MAPE_GTK_FOUND) + target_link_libraries(mape winmm) + endif() if(NOT USE_OPEN_AL) find_package(FMod) if(FMOD_FOUND) set(HAVE_FMOD TRUE) - target_link_libraries(clonk + target_link_libraries(openclonk ${FMOD_LIBRARIES} ) include_directories(${FMOD_INCLUDE_DIR}) @@ -1251,6 +1370,8 @@ if (WIN32) set(HAVE_FMOD FALSE) endif() endif() +else() + SET(HAVE_FMOD FALSE) endif() if(NOT HAVE_FMOD AND NOT USE_OPEN_AL OR USE_SDL_MAINLOOP AND NOT USE_OPEN_AL) include(FindSDL) @@ -1261,7 +1382,7 @@ if(NOT HAVE_FMOD AND NOT USE_OPEN_AL OR USE_SDL_MAINLOOP AND NOT USE_OPEN_AL) if(SDLMIXER_LIBRARIES) SET(HAVE_LIBSDL_MIXER ON) endif() - target_link_libraries(clonk + target_link_libraries(openclonk ${SDL_LIBRARY} ${SDLMIXER_LIBRARIES} ) @@ -1270,47 +1391,68 @@ endif() if(HAVE_UPNP) include_directories(${UPNP_INCLUDE_DIR}) - target_link_libraries(clonk ${UPNP_LIBRARIES}) + target_link_libraries(openclonk ${UPNP_LIBRARIES}) endif() -# GTest -include(FindGTest) -if(GTEST_FOUND) - include_directories(${GTEST_INCLUDE_DIRS}) - add_executable(tests EXCLUDE_FROM_ALL - tests/UnicodeHandlingTest.cpp - tests/main.cpp - ) - target_link_libraries(tests ${GTEST_LIBRARIES}) - if(HAVE_PTHREAD) - target_link_libraries(tests pthread) - endif() +if(USE_BOOST_REGEX) + SET(Boost_USE_STATIC_LIBS ON) + find_package(Boost 1.40.0 REQUIRED COMPONENTS regex) + # Disable automatic linking, we'll do it ourselves + add_definitions(-DBOOST_REGEX_NO_LIB) + target_link_libraries(libc4script ${Boost_REGEX_LIBRARY}) + target_link_libraries(c4group ${Boost_REGEX_LIBRARY}) endif() +add_subdirectory(tests EXCLUDE_FROM_ALL) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) +# CMake support for MSVC 2010 is broken. Change the .sln file to avoid +# millions of "reload X project?" dialog boxes. +# For best results, also change CMake's ReloadProjects macro to only +# call StopBuild(). +if(MSVC_VERSION EQUAL 1600) + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln" "\n# reload me\n") +endif() + ############################################################################ # installation ############################################################################ -# Install the icon into share/icons/hicolor/48x48/apps/clonk.png. Do this by +# Install the icon into share/icons/hicolor/48x48/apps/openclonk.png. Do this by # extracting the correct size from oc.ico. Currently this is layer 2 - let's # hope that it stays this way. -# Only allow installation for WITH_AUTOMATIC_UPDATE because otherwise +# Don't allow installation for WITH_AUTOMATIC_UPDATE because otherwise # the installed binary wouldn't find its game data in the system data path. IF(WITH_AUTOMATIC_UPDATE) INSTALL(CODE "MESSAGE(SEND_ERROR \"Installation is only supported for WITH_AUTOMATIC_UPDATE disabled\")") ENDIF() -# TODO: Check for convert at configure step? -install(DIRECTORY DESTINATION share/icons/hicolor/48x48/apps) -install(CODE " -EXECUTE_PROCESS(COMMAND \"convert\" \"${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc.ico[2]\" \"$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/clonk.png\" RESULT_VARIABLE CONVERT_RESULT) -IF(NOT \${CONVERT_RESULT} EQUAL 0) - MESSAGE(SEND_ERROR \"Creating icon failed\") -ENDIF() -FILE(MAKE_DIRECTORY $ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/share/openclonk) -") +# hack to build the data on install, see +# http://public.kitware.com/Bug/view.php?id=8438 +add_custom_target(data) +install( + CODE + "execute_process( + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target data + )" +) + +FIND_PACKAGE(ImageMagick COMPONENTS convert) +if(ImageMagick_convert_FOUND) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/openclonk.png + COMMAND "${ImageMagick_convert_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc.ico[2]" "${CMAKE_CURRENT_BINARY_DIR}/openclonk.png" + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc.ico + VERBATIM + ) + add_custom_target(icon DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/openclonk.png) + add_dependencies(data icon) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/openclonk.png + DESTINATION share/icons/hicolor/48x48/apps + ) +endif() set(OC_C4GROUPS Graphics.ocg @@ -1319,36 +1461,45 @@ set(OC_C4GROUPS Sound.ocg System.ocg Objects.ocd - BackToTheRocks.ocf + Arena.ocf + Parkour.ocf + Missions.ocf Tutorial.ocf + Worlds.ocf ) get_target_property(C4GROUP_LOCATION c4group LOCATION) -get_target_property(CLONK_LOCATION clonk LOCATION) +get_target_property(CLONK_LOCATION openclonk LOCATION) foreach(group ${OC_C4GROUPS}) if (APPLE) - add_custom_command(TARGET clonk + add_custom_command(TARGET openclonk POST_BUILD COMMAND "/bin/sh" "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_pack_gamedata.sh" "${C4GROUP_LOCATION}" "${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}" DEPENDS c4group ) else() - INSTALL(CODE " - MESSAGE(\"Packing and installing ${group}...\") - EXECUTE_PROCESS(COMMAND \"${CMAKE_CURRENT_BINARY_DIR}/c4group\" \"${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}\" -t \"$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/share/openclonk/${group}\" RESULT_VARIABLE PACK_RESULT) - IF(NOT \${PACK_RESULT} EQUAL 0) - MESSAGE(SEND_ERROR \"Packing ${group} failed\") - ENDIF() - ") + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${group} + COMMAND c4group ARGS "${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}" -t "${CMAKE_CURRENT_BINARY_DIR}/${group}" + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/planet/${group} + DEPENDS c4group + VERBATIM + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${group} DESTINATION share/games/openclonk) endif() endforeach() +if (NOT APPLE) + add_custom_target(groups DEPENDS ${OC_C4GROUPS}) + add_dependencies(data groups) +endif() # Install new files -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/clonk.desktop DESTINATION share/applications) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/openclonk.desktop DESTINATION share/applications) # Install binaries -install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/clonk ${CMAKE_CURRENT_BINARY_DIR}/c4group DESTINATION bin/) +install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/openclonk DESTINATION games/) +install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/c4group DESTINATION bin/) ############################################################################ # setup_openclonk.exe @@ -1359,16 +1510,6 @@ find_program(MAKENSIS makensis PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS]) string(REPLACE / \\ C4GROUP_LOCATION ${C4GROUP_LOCATION}) string(REPLACE / \\ CLONK_LOCATION ${CLONK_LOCATION}) -foreach(group ${OC_C4GROUPS}) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${group}" - COMMAND c4group ARGS "${CMAKE_CURRENT_SOURCE_DIR}/planet/${group}" -t "${CMAKE_CURRENT_BINARY_DIR}/${group}" - MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/planet/${group} - DEPENDS c4group - VERBATIM - ) -endforeach() - add_custom_command( OUTPUT setup_openclonk.exe COMMAND ${MAKENSIS} -NOCD -DSRCDIR=${CMAKE_CURRENT_SOURCE_DIR} -DPROGRAMFILES=$PROGRAMFILES "-DPRODUCT_NAME=${C4ENGINENAME}${C4VERSIONBUILDNAME}" "-DPRODUCT_COMPANY=${C4PROJECT}" "-DCLONK=${CLONK_LOCATION}" "-DC4GROUP=${C4GROUP_LOCATION}" ${CMAKE_CURRENT_SOURCE_DIR}/tools/install/oc.nsi "-XOutFile setup_openclonk.exe" @@ -1378,12 +1519,12 @@ add_custom_command( ${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} clonk c4group + ${OC_C4GROUPS} openclonk c4group VERBATIM ) add_custom_target(setup - DEPENDS setup_openclonk.exe + DEPENDS setup_openclonk.exe groups ) ############################################################################ diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..77db5bac6 --- /dev/null +++ b/COPYING @@ -0,0 +1,47 @@ +Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de +Copyright (c) 2009-2013, The OpenClonk Team and contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Portions of the code have been contributed by other authors: +Copyright (c) 2006-2007 Alexander Post +Copyright (c) 2004-2013 Armin Burgmeier +Copyright (c) 2005-2006, 2008-2010 Asmageddon +Copyright (c) 2010, 2012 Benjamin Herr +Copyright (c) 2006, 2012 Bernhard Bonigl +Copyright (c) 2009-2010 Carl-Philip Hänsch +Copyright (c) 2001 Carlo Teubner +Copyright (c) 2009, 2011-2013 David Dormagen +Copyright (c) 2011-2012 Felix Wagner +Copyright (c) 2006 Florian Groß +Copyright (c) 2004-2012 Günther Brammer +Copyright (c) 2006-2008 Julian Raschke +Copyright (c) 2010-2012 Julius Michaelis +Copyright (c) 2010-2011 Maikel de Vries +Copyright (c) 2010 Manuel Riecke +Copyright (c) 2009 Mark Haßelbusch +Copyright (c) 2009-2012 Martin Plicht +Copyright (c) 1998-2008 Matthes Bender +Copyright (c) 2001 Michael Käser +Copyright (c) 2009 mizipzor +Copyright (c) 2009-2013 Nicolas Hake +Copyright (c) 2010 Peewee +Copyright (c) 2001-2011 Peter Wortmann +Copyright (c) 2012 Philipp Kern +Copyright (c) 2009-2010 Richard Gerum +Copyright (c) 2001-2013 Sven Eberhardt +Copyright (c) 2004-2005, 2009-2013 Tobias Zwick + +Code inside the "thirdparty" directory has been included for convenience +and may be licensed under different terms. See the respective directories +for details. diff --git a/Credits.txt b/Credits.txt index efe1d9b09..2c09384c7 100644 --- a/Credits.txt +++ b/Credits.txt @@ -1,20 +1,25 @@ - + Armin Burgmeier (Clonk-Karl) Günther Brammer (Günther) -Sven Eberhardt (Sven2) Nicolas Hake (Isilkor) -Peter Wortmann (PeterW) +Sven Eberhardt (Sven2) Martin Plicht (Mortimer) +Peter Wortmann (PeterW) +Julius Michaelis (Caesar) + + +Charles Spurrill (Ringwaul) +Richard Gerum (Randrian) +Timo Stabbert (Mimmo) + + +Maikel de Vries (Maikel) +Bernhard Bonigl (Boni) +Felix Wagner (Clonkonaut) +David Dormagen (Zapper) Tobias Zwick (Newton) - -Charles Spurrill (Ringwaul) -Maikel de Vries (Maikel) -Timo Stabbert (Mimmo) -Richard Gerum (Randrian) -David Dormagen (Zapper) - -Benjamin Herr (Loriel), Julius Michaelis (Caesar), Felix Wagner (Clonkonaut), Manuel Riecke (MrBeast), Benedict Etzel (B_E), Carl-Philip Hänsch (Carli), Alexander Semeniuk (AlteredARMOR), Asmageddon, Florian Graier (Nachtfalter), Merten Ehmig (pluto), Mark Haßelbusch (Marky), Luchs, Peewee, Lauri Niskanen (Ape), Dominik Bayerl (Kanibal), Matthias Rottländer (Matthi), Faby, Checkmaty, TomyLobo, Stan, Gurkenglas, Clonkine, mizipzor, RedWolf Design GmbH 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. \ No newline at end of file +Benjamin Herr (Loriel), Matthias Rottländer (Matthi), Felix Riese (Fungiform), Manuel Riecke (MrBeast), Benedict Etzel (B_E), Carl-Philip Hänsch (Carli), Alexander Semeniuk (AlteredARMOR), Florian Graier (Nachtfalter), Daniel Theuke (ST-DDT), Asmageddon, Merten Ehmig (Pluto), Mark Haßelbusch (Marky), Luchs, Peewee, Lauri Niskanen (Ape), Dominik Bayerl (Kanibal), Faby, Checkmaty, Gurkenglas, Clonkine, mizipzor, mixi, Pyrit, grgecko, Koronis, RedWolf Design GmbH 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. \ No newline at end of file diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 4209c0cbe..000000000 --- a/Makefile.am +++ /dev/null @@ -1,871 +0,0 @@ -# Copyright (c) 2005-2011 Günther Brammer -# Copyright (c) 2009 Armin Burgmeier -# Copyright (c) 2010-2011 Nicolas Hake -# Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de - -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. - -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -ACLOCAL_AMFLAGS = -I autotools --install - -bin_PROGRAMS = clonk c4group puncher c4script - -EXTRA_PROGRAMS = tstc4netio gunzip4c4group - -noinst_LIBRARIES = lib.a - -# Some defines and warning options -if RECENT_GCC -WARNING_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 -Wsign-promo -##-Wmissing-format-attribute -Wdisabled-optimization -Wlogical-op -##-Weffc++ -Wold-style-cast -Woverloaded-virtual -Wunsafe-loop-optimizations -else -WARNING_FLAGS = -Wall -endif - -AM_CXXFLAGS = $(PTHREAD_CFLAGS) $(WINDOWS_CFLAGS) $(WARNING_FLAGS) - -AM_CFLAGS = -Wall - -AM_CPPFLAGS = \ --I$(builddir) \ --I$(srcdir)/src \ --I$(srcdir)/src/c4group \ --I$(srcdir)/src/network \ --I$(srcdir)/src/lib \ --I$(srcdir)/src/platform \ --I$(srcdir)/src/config \ --I$(srcdir)/src/res \ --I$(srcdir)/src/control \ --I$(srcdir)/src/gui \ --I$(srcdir)/src/editor \ --I$(srcdir)/src/game/landscape \ --I$(srcdir)/src/game/player \ --I$(srcdir)/src/game/script \ --I$(srcdir)/src/game \ --I$(srcdir)/src/game/object \ --I$(srcdir)/src/lib/texture \ --I$(srcdir)/src/script \ --I$(srcdir)/thirdparty \ -$(GLEW_CFLAGS) \ -$(GTK_CFLAGS) \ -$(OPENAL_CFLAGS) \ -$(FREETYPE_CFLAGS) \ -$(SDL_CFLAGS) \ -$(BOOST_CPPFLAGS) \ -$(LIBUPNP_CFLAGS) - -##BUILT_SOURCES = hgrevision.h -##hgrevision.h: $(srcdir)/.hg/dirstate -## $(srcdir)/tools/get_hg_revision.sh > hgrevision.h -##$(srcdir)/.hg/dirstate: - -BUILT_SOURCES = C4Version.h -CLEANFILES = -DISTCLEANFILES = C4Version.h -do_subst = sed -e 's,[@]C4PROJECT[@],'"$$(sed -n 's/SET(C4PROJECT\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4PROJECT_DOMAIN[@],'"$$(sed -n 's/SET(C4PROJECT_DOMAIN\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4PROJECT_TLD[@],'"$$(sed -n 's/SET(C4PROJECT_TLD\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4PROJECT_URL[@],http://www.openclonk.org,g' \ - -e 's,[@]C4COPYRIGHT_YEAR[@],'"$$(date '+%Y')"',g' \ - -e 's,[@]C4ENGINENAME[@],'"$$(sed -n 's/SET(C4ENGINENAME\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4ENGINENICK[@],'"$$(sed -n 's/SET(C4ENGINENICK\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4ENGINEID[@],org.openclonk." C4ENGINENICK ",g' \ - -e 's,[@]C4XVER1[@],'"$$(sed -n 's/SET(C4XVER1\s\+\(.\+\))/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4XVER2[@],'"$$(sed -n 's/SET(C4XVER2\s\+\(.\+\))/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4XVER3[@],'"$$(sed -n 's/SET(C4XVER3\s\+\(.\+\))/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4XVER4[@],'"$$(sed -n 's/SET(C4XVER4\s\+\(.\+\))/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4VERSIONBUILDNAME[@],'"$$(sed -n 's/SET(C4VERSIONBUILDNAME\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' \ - -e 's,[@]C4VERSIONEXTRA[@],'"$$(sed -n 's/SET(C4VERSIONEXTRA\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)"',g' - -C4Version.h: $(srcdir)/src/C4Version.h.in $(srcdir)/Version.txt - $(do_subst) < $< > $@ -WindowsGamesExplorer.xml: $(srcdir)/src/res/WindowsGamesExplorer.xml.in $(srcdir)/Version.txt - $(do_subst) < $< > $@ -src/res/engine.o: WindowsGamesExplorer.xml - -#various hacks to get dependency tracking working with a precompiled C4Include -if RECENT_GCC -BUILT_SOURCES += C4Include.h.gch -CLEANFILES += C4Include.h.gch -DISTCLEANFILES += @am__quote@$(DEPDIR)/C4Include.Po@am__quote@ - -# Adapted from the automake compile-command for normal source files. -# Has to be updated after certain changes in this file. -C4Include.h.gch: src/C4Include.h -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -x c++-header -MT C4Include.h.gch -MD -MP -MF $(DEPDIR)/C4Include.Tpo -c -o $@ $(srcdir)/src/C4Include.h -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/C4Include.Tpo $(DEPDIR)/C4Include.Po -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -x c++-header -c -o $@ $(srcdir)/src/C4Include.h - -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/C4Include.Po@am__quote@ - -if am__fastdepCXX -AM_CXXFLAGS += -fpch-deps -endif - -WARNING_FLAGS += -Winvalid-pch - -endif - -lib_a_SOURCES = \ -src/c4group/C4Group.cpp \ -src/c4group/C4Group.h \ -src/c4group/C4Update.cpp \ -src/c4group/C4Update.h \ -src/c4group/CStdFile.cpp \ -src/c4group/CStdFile.h \ -src/config/C4SecurityCertificates.cpp \ -src/config/C4SecurityCertificates.h \ -src/lib/C4InputValidation.cpp \ -src/lib/C4InputValidation.h \ -src/lib/SHA1.h \ -src/lib/Standard.cpp \ -src/lib/Standard.h \ -src/lib/StdBuf.cpp \ -src/lib/StdBuf.h \ -src/lib/StdCompiler.cpp \ -src/lib/StdCompiler.h \ -src/lib/C4Markup.cpp \ -src/lib/C4Markup.h \ -src/lib/StdResStr2.cpp \ -src/lib/StdResStr2.h \ -src/network/C4NetIO.cpp \ -src/platform/GetTime.cpp \ -src/platform/StdFile.cpp \ -src/platform/StdFile.h \ -src/platform/StdRegistry.cpp \ -src/platform/StdRegistry.h \ -src/platform/StdScheduler.cpp \ -src/platform/StdScheduler.h \ -src/zlib/gzio.c \ -src/zlib/gzio.h \ -src/zlib/zutil.h - -clonk_SOURCES = \ -src/C4Application.cpp \ -src/C4Application.h \ -src/C4FullScreen.cpp \ -src/C4FullScreen.h \ -src/C4Game.cpp \ -src/C4Game.h \ -src/C4Globals.cpp \ -src/C4GraphicsSystem.cpp \ -src/C4GraphicsSystem.h \ -src/c4group/C4ComponentHost.cpp \ -src/c4group/C4ComponentHost.h \ -src/c4group/C4Components.h \ -src/c4group/C4Extra.cpp \ -src/c4group/C4Extra.h \ -src/c4group/C4GroupSet.cpp \ -src/c4group/C4GroupSet.h \ -src/c4group/C4LangStringTable.cpp \ -src/c4group/C4LangStringTable.h \ -src/c4group/C4Language.cpp \ -src/c4group/C4Language.h \ -src/C4Include.h \ -src/C4Prototypes.h \ -src/C4Version.h.in \ -src/C4WinMain.cpp \ -src/config/C4Config.cpp \ -src/config/C4Config.h \ -src/config/C4Constants.h \ -src/config/C4Reloc.cpp \ -src/config/C4Reloc.h \ -src/control/C4Control.cpp \ -src/control/C4Control.h \ -src/control/C4GameControl.cpp \ -src/control/C4GameControl.h \ -src/control/C4GameParameters.cpp \ -src/control/C4GameParameters.h \ -src/control/C4GameSave.cpp \ -src/control/C4GameSave.h \ -src/control/C4PlayerControl.cpp \ -src/control/C4PlayerControl.h \ -src/control/C4PlayerInfoConflicts.cpp \ -src/control/C4PlayerInfo.cpp \ -src/control/C4PlayerInfo.h \ -src/control/C4Record.cpp \ -src/control/C4Record.h \ -src/control/C4RoundResults.cpp \ -src/control/C4RoundResults.h \ -src/control/C4Teams.cpp \ -src/control/C4Teams.h \ -src/editor/C4Console.cpp \ -src/editor/C4ConsoleGUICommon.h \ -src/editor/C4ConsoleGUI.h \ -src/editor/C4Console.h \ -src/editor/C4DevmodeDlg.cpp \ -src/editor/C4DevmodeDlg.h \ -src/editor/C4EditCursor.cpp \ -src/editor/C4EditCursor.h \ -src/editor/C4ObjectListDlg.cpp \ -src/editor/C4ObjectListDlg.h \ -src/editor/C4ToolsDlg.cpp \ -src/editor/C4ToolsDlg.h \ -src/game/C4GameVersion.h \ -src/game/C4Physics.h \ -src/game/landscape/C4Landscape.cpp \ -src/game/landscape/C4Landscape.h \ -src/game/landscape/C4LandscapeRenderClassic.cpp \ -src/game/landscape/C4LandscapeRender.cpp \ -src/game/landscape/C4LandscapeRender.h \ -src/game/landscape/C4Map.cpp \ -src/game/landscape/C4MapCreatorS2.cpp \ -src/game/landscape/C4MapCreatorS2.h \ -src/game/landscape/C4Map.h \ -src/game/landscape/C4MassMover.cpp \ -src/game/landscape/C4MassMover.h \ -src/game/landscape/C4Material.cpp \ -src/game/landscape/C4Material.h \ -src/game/landscape/C4MaterialList.cpp \ -src/game/landscape/C4MaterialList.h \ -src/game/landscape/C4Particles.cpp \ -src/game/landscape/C4Particles.h \ -src/game/landscape/C4PathFinder.cpp \ -src/game/landscape/C4PathFinder.h \ -src/game/landscape/C4PXS.cpp \ -src/game/landscape/C4PXS.h \ -src/game/landscape/C4Region.cpp \ -src/game/landscape/C4Region.h \ -src/game/landscape/C4Scenario.cpp \ -src/game/landscape/C4Scenario.h \ -src/game/landscape/C4Sky.cpp \ -src/game/landscape/C4Sky.h \ -src/game/landscape/C4SolidMask.cpp \ -src/game/landscape/C4SolidMask.h \ -src/game/landscape/C4Texture.cpp \ -src/game/landscape/C4Texture.h \ -src/game/landscape/C4Weather.cpp \ -src/game/landscape/C4Weather.h \ -src/game/object/C4Action.cpp \ -src/game/object/C4Command.cpp \ -src/game/object/C4Command.h \ -src/game/object/C4Def.cpp \ -src/game/object/C4DefGraphics.cpp \ -src/game/object/C4DefGraphics.h \ -src/game/object/C4Def.h \ -src/game/object/C4DefList.cpp \ -src/game/object/C4DefList.h \ -src/game/object/C4GameObjects.cpp \ -src/game/object/C4GameObjects.h \ -src/game/object/C4Id.cpp \ -src/game/object/C4Id.h \ -src/game/object/C4IDList.cpp \ -src/game/object/C4IDList.h \ -src/game/object/C4InfoCore.cpp \ -src/game/object/C4InfoCore.h \ -src/game/object/C4MeshAnimation.cpp \ -src/game/object/C4MeshAnimation.h \ -src/game/object/C4Movement.cpp \ -src/game/object/C4ObjectCom.cpp \ -src/game/object/C4ObjectCom.h \ -src/game/object/C4Object.cpp \ -src/game/object/C4Object.h \ -src/game/object/C4ObjectInfo.cpp \ -src/game/object/C4ObjectInfo.h \ -src/game/object/C4ObjectInfoList.cpp \ -src/game/object/C4ObjectInfoList.h \ -src/game/object/C4ObjectList.cpp \ -src/game/object/C4ObjectList.h \ -src/game/object/C4ObjectMenu.cpp \ -src/game/object/C4ObjectMenu.h \ -src/game/object/C4ObjectPtr.cpp \ -src/game/object/C4ObjectPtr.h \ -src/game/object/C4ObjectScript.cpp \ -src/game/object/C4Sector.cpp \ -src/game/object/C4Sector.h \ -src/game/object/C4Shape.cpp \ -src/game/object/C4Shape.h \ -src/game/player/C4Player.cpp \ -src/game/player/C4Player.h \ -src/game/player/C4PlayerList.cpp \ -src/game/player/C4PlayerList.h \ -src/game/player/C4RankSystem.cpp \ -src/game/player/C4RankSystem.h \ -src/game/script/C4Effect.cpp \ -src/game/script/C4Effects.h \ -src/game/script/C4FindObject.cpp \ -src/game/script/C4FindObject.h \ -src/game/script/C4GameScript.cpp \ -src/game/script/C4Script.h \ -src/game/script/C4TransferZone.cpp \ -src/game/script/C4TransferZone.h \ -src/gui/C4ChatDlg.cpp \ -src/gui/C4ChatDlg.h \ -src/gui/C4DownloadDlg.cpp \ -src/gui/C4DownloadDlg.h \ -src/gui/C4FileSelDlg.cpp \ -src/gui/C4FileSelDlg.h \ -src/gui/C4Folder.cpp \ -src/gui/C4Folder.h \ -src/gui/C4GameDialogs.cpp \ -src/gui/C4GameDialogs.h \ -src/gui/C4GameLobby.cpp \ -src/gui/C4GameLobby.h \ -src/gui/C4GameMessage.cpp \ -src/gui/C4GameMessage.h \ -src/gui/C4GameOptions.cpp \ -src/gui/C4GameOptions.h \ -src/gui/C4GameOverDlg.cpp \ -src/gui/C4GameOverDlg.h \ -src/gui/C4GfxErrorDlg.cpp \ -src/gui/C4GfxErrorDlg.h \ -src/gui/C4GuiButton.cpp \ -src/gui/C4GuiCheckBox.cpp \ -src/gui/C4GuiComboBox.cpp \ -src/gui/C4GuiContainers.cpp \ -src/gui/C4Gui.cpp \ -src/gui/C4GuiDialogs.cpp \ -src/gui/C4GuiEdit.cpp \ -src/gui/C4Gui.h \ -src/gui/C4GuiLabels.cpp \ -src/gui/C4GuiListBox.cpp \ -src/gui/C4GuiMenu.cpp \ -src/gui/C4GuiTabular.cpp \ -src/gui/C4KeyboardInput.cpp \ -src/gui/C4KeyboardInput.h \ -src/gui/C4LoaderScreen.cpp \ -src/gui/C4LoaderScreen.h \ -src/gui/C4MainMenu.cpp \ -src/gui/C4MainMenu.h \ -src/gui/C4Menu.cpp \ -src/gui/C4Menu.h \ -src/gui/C4MessageBoard.cpp \ -src/gui/C4MessageBoard.h \ -src/gui/C4MessageInput.cpp \ -src/gui/C4MessageInput.h \ -src/gui/C4MouseControl.cpp \ -src/gui/C4MouseControl.h \ -src/gui/C4PlayerInfoListBox.cpp \ -src/gui/C4PlayerInfoListBox.h \ -src/gui/C4Scoreboard.cpp \ -src/gui/C4Scoreboard.h \ -src/gui/C4StartupAboutDlg.cpp \ -src/gui/C4StartupAboutDlg.h \ -src/gui/C4Startup.cpp \ -src/gui/C4Startup.h \ -src/gui/C4StartupMainDlg.cpp \ -src/gui/C4StartupMainDlg.h \ -src/gui/C4StartupNetDlg.cpp \ -src/gui/C4StartupNetDlg.h \ -src/gui/C4StartupOptionsDlg.cpp \ -src/gui/C4StartupOptionsDlg.h \ -src/gui/C4StartupPlrSelDlg.cpp \ -src/gui/C4StartupPlrSelDlg.h \ -src/gui/C4StartupScenSelDlg.cpp \ -src/gui/C4StartupScenSelDlg.h \ -src/gui/C4UpdateDlg.cpp \ -src/gui/C4UpdateDlg.h \ -src/gui/C4UpperBoard.cpp \ -src/gui/C4UpperBoard.h \ -src/gui/C4UserMessages.h \ -src/gui/C4Viewport.cpp \ -src/gui/C4Viewport.h \ -src/lib/C4LogBuf.cpp \ -src/lib/C4LogBuf.h \ -src/lib/C4Log.cpp \ -src/lib/C4Log.h \ -src/lib/C4NameList.cpp \ -src/lib/C4NameList.h \ -src/lib/C4Random.cpp \ -src/lib/C4Random.h \ -src/lib/C4Real.cpp \ -src/lib/C4Real.h \ -src/lib/C4Rect.cpp \ -src/lib/C4Rect.h \ -src/lib/C4RTF.cpp \ -src/lib/C4RTF.h \ -src/lib/C4Stat.cpp \ -src/lib/C4Stat.h \ -src/lib/PathFinder.cpp \ -src/lib/PathFinder.h \ -src/lib/StdAdaptors.h \ -src/lib/StdBase64.cpp \ -src/lib/StdBase64.h \ -src/lib/StdColors.h \ -src/lib/StdMesh.cpp \ -src/lib/StdMesh.h \ -src/lib/StdMeshLoaderBinaryChunks.cpp \ -src/lib/StdMeshLoaderBinaryChunks.h \ -src/lib/StdMeshLoaderBinary.cpp \ -src/lib/StdMeshLoaderDataStream.h \ -src/lib/StdMeshLoader.h \ -src/lib/StdMeshLoaderXml.cpp \ -src/lib/StdMeshMaterial.cpp \ -src/lib/StdMeshMaterial.h \ -src/lib/StdMeshMath.cpp \ -src/lib/StdMeshMath.h \ -src/lib/StdMeshUpdate.cpp \ -src/lib/StdMeshUpdate.h \ -src/lib/StdResStr.h \ -src/lib/texture/C4Facet.cpp \ -src/lib/texture/C4FacetEx.cpp \ -src/lib/texture/C4FacetEx.h \ -src/lib/texture/C4Facet.h \ -src/lib/texture/C4GraphicsResource.cpp \ -src/lib/texture/C4GraphicsResource.h \ -src/lib/texture/C4SurfaceLoaders.cpp \ -src/lib/texture/StdPNG.cpp \ -src/lib/texture/StdPNG.h \ -src/network/C4Client.cpp \ -src/network/C4Client.h \ -src/network/C4GameControlNetwork.cpp \ -src/network/C4GameControlNetwork.h \ -src/network/C4InteractiveThread.cpp \ -src/network/C4InteractiveThread.h \ -src/network/C4League.cpp \ -src/network/C4League.h \ -src/network/C4NetIO.h \ -src/network/C4Network2Client.cpp \ -src/network/C4Network2Client.h \ -src/network/C4Network2.cpp \ -src/network/C4Network2Dialogs.cpp \ -src/network/C4Network2Dialogs.h \ -src/network/C4Network2Discover.cpp \ -src/network/C4Network2Discover.h \ -src/network/C4Network2.h \ -src/network/C4Network2IO.cpp \ -src/network/C4Network2IO.h \ -src/network/C4Network2IRC.cpp \ -src/network/C4Network2IRC.h \ -src/network/C4Network2Players.cpp \ -src/network/C4Network2Players.h \ -src/network/C4Network2Reference.cpp \ -src/network/C4Network2Reference.h \ -src/network/C4Network2Res.cpp \ -src/network/C4Network2ResDlg.cpp \ -src/network/C4Network2Res.h \ -src/network/C4Network2Stats.cpp \ -src/network/C4Network2Stats.h \ -src/network/C4Network2UPnP.h \ -src/network/C4Packet2.cpp \ -src/network/C4PacketBase.h \ -src/platform/Bitmap256.cpp \ -src/platform/Bitmap256.h \ -src/platform/C4App.cpp \ -src/platform/C4App.h \ -src/platform/C4AppT.cpp \ -src/platform/C4FileMonitor.cpp \ -src/platform/C4FileMonitor.h \ -src/platform/C4Fonts.cpp \ -src/platform/C4Fonts.h \ -src/platform/C4GamePadCon.cpp \ -src/platform/C4GamePadCon.h \ -src/platform/C4MusicFile.cpp \ -src/platform/C4MusicFile.h \ -src/platform/C4MusicSystem.cpp \ -src/platform/C4MusicSystem.h \ -src/platform/C4SoundLoaders.cpp \ -src/platform/C4SoundLoaders.h \ -src/platform/C4SoundSystem.cpp \ -src/platform/C4SoundSystem.h \ -src/platform/C4Surface.cpp \ -src/platform/C4Surface.h \ -src/platform/C4Video.cpp \ -src/platform/C4Video.h \ -src/platform/C4VideoPlayback.cpp \ -src/platform/C4VideoPlayback.h \ -src/platform/C4ViewportWindow.cpp \ -src/platform/C4ViewportWindow.h \ -src/platform/C4Window.h \ -src/platform/C4windowswrapper.h \ -src/platform/PlatformAbstraction.cpp \ -src/platform/PlatformAbstraction.h \ -src/platform/StdD3D.cpp \ -src/platform/StdD3D.h \ -src/platform/StdD3DShader.cpp \ -src/platform/StdD3DShader.h \ -src/platform/StdDDraw2.cpp \ -src/platform/StdDDraw2.h \ -src/platform/StdFont.cpp \ -src/platform/StdFont.h \ -src/platform/StdGL.cpp \ -src/platform/StdGLCtx.cpp \ -src/platform/StdGL.h \ -src/platform/StdNoGfx.cpp \ -src/platform/StdNoGfx.h \ -src/platform/StdSurface8.cpp \ -src/platform/StdSurface8.h \ -src/platform/StdSync.h \ -src/platform/StdVideo.cpp \ -src/platform/StdVideo.h \ -src/res/Brush.h \ -src/res/Cursor.h \ -src/res/Dynamic.h \ -src/res/Exact.h \ -src/res/Fill.h \ -src/res/Halt.h \ -src/res/Ift.h \ -src/res/Line.h \ -src/res/Mouse.h \ -src/res/NoIft.h \ -src/res/Picker.h \ -src/res/Play.h \ -src/res/Rect.h \ -src/res/resource.h \ -src/res/Static.h \ -src/script/C4Aul.cpp \ -src/script/C4AulDebug.cpp \ -src/script/C4AulDebug.h \ -src/script/C4AulDefFunc.h \ -src/script/C4AulExec.cpp \ -src/script/C4AulExec.h \ -src/script/C4AulFunc.h \ -src/script/C4Aul.h \ -src/script/C4AulLink.cpp \ -src/script/C4AulParse.cpp \ -src/script/C4PropList.cpp \ -src/script/C4PropList.h \ -src/script/C4Script.cpp \ -src/script/C4ScriptHost.cpp \ -src/script/C4ScriptHost.h \ -src/script/C4StringTable.cpp \ -src/script/C4StringTable.h \ -src/script/C4ValueArray.cpp \ -src/script/C4ValueArray.h \ -src/script/C4Value.cpp \ -src/script/C4Value.h \ -src/script/C4ValueMap.cpp \ -src/script/C4ValueMap.h \ -thirdparty/timsort/sort.h \ -thirdparty/tinyxml/tinystr.cpp \ -thirdparty/tinyxml/tinystr.h \ -thirdparty/tinyxml/tinyxml.cpp \ -thirdparty/tinyxml/tinyxmlerror.cpp \ -thirdparty/tinyxml/tinyxml.h \ -thirdparty/tinyxml/tinyxmlparser.cpp - -if WIN32 -clonk_SOURCES += \ -src/platform/C4CrashHandlerWin32.cpp \ -src/res/engine.rc \ -src/res/resource.h -endif - -if SDL_MAIN_LOOP -clonk_SOURCES += \ -src/platform/C4AppSDL.cpp \ -src/platform/C4WindowSDL.cpp -else -if GTK -clonk_SOURCES += \ -src/editor/C4ConsoleGTK.cpp \ -src/platform/C4AppX.cpp \ -src/platform/C4AppXImpl.h \ -src/platform/C4WindowGTK.cpp \ -src/platform/C4WindowX.cpp -else -if WIN32 -clonk_SOURCES += \ -src/editor/C4ConsoleWin32.cpp \ -src/platform/C4WindowWin32.cpp \ -src/platform/StdJoystick.cpp \ -src/platform/StdJoystick.h -endif -if MACOSX -clonk_SOURCES += \ -src/editor/C4ConsoleCocoa.mm \ -src/platform/C4AppMac.mm \ -src/platform/C4FileMonitorMac.mm \ -src/platform/C4WindowMac.mm \ -src/platform/ClonkAppDelegate.h \ -src/platform/ClonkAppDelegate.mm \ -src/platform/ConsoleWindowController.h \ -src/platform/ConsoleWindowController.mm \ -src/platform/ClonkWindowController.h \ -src/platform/ClonkWindowController.mm \ -src/platform/ClonkOpenGLView.h \ -src/platform/ClonkOpenGLView.mm \ -src/platform/CocoaKeycodeMap.h \ -src/platform/ClonkMainMenuActions.h \ -src/platform/ClonkMainMenuActions.mm -endif -endif -endif - -if LIBUPNP -clonk_SOURCES += src/network/C4Network2UPnPLinux.cpp -else -if NATUPNP -clonk_SOURCES += src/network/C4Network2UPnPWin32.cpp -else -clonk_SOURCES += src/network/C4Network2UPnPDummy.cpp -endif -endif - -clonk_LDADD = \ - lib.a \ - $(LDADD) \ - $(LIBICONV) \ - $(GTK_LIBS) \ - $(OPENAL_LIBS) \ - $(FREETYPE_LIBS) \ - $(SDL_LIBS) \ - $(PTHREAD_LIBS) \ - $(Z_LIBS) \ - $(CLONK_LIBS) \ - $(LIBUPNP_LIBS) - -# build the resources -.rc.o: - $(WINDRES) -I $(srcdir)/src/res -I $(builddir) -i $< -o $@ - -c4group_CPPFLAGS = \ - -I$(builddir) \ - -I$(srcdir)/src \ - -I$(srcdir)/src/c4group \ - -I$(srcdir)/src/network \ - -I$(srcdir)/src/lib \ - -I$(srcdir)/src/platform \ - -I$(srcdir)/src/config \ - -I$(srcdir)/src/res \ - -I$(srcdir)/src/control \ - -I$(srcdir)/src/gui \ - -I$(srcdir)/src/editor \ - -I$(srcdir)/src/game/landscape \ - -I$(srcdir)/src/game/player \ - -I$(srcdir)/src/game/script \ - -I$(srcdir)/src/game \ - -I$(srcdir)/src/game/object \ - -I$(srcdir)/src/lib/texture \ - -I$(srcdir)/src/script \ -$(BOOST_CPPFLAGS) - -c4group_SOURCES = \ -src/lib/C4SimpleLog.cpp \ -src/c4group/c4group_ng.cpp - -if WIN32 -c4group_SOURCES += src/c4group/Resource.rc -endif - -c4group_LDADD = \ - lib.a \ - $(LDADD) \ - $(LIBICONV) \ - $(Z_LIBS) \ - $(PTHREAD_LIBS) - -## gunzip4c4group - -gunzip4c4group_SOURCES = \ -src/lib/C4SimpleLog.cpp \ -src/c4group/gunzip4c4group.cpp - -gunzip4c4group_LDADD = \ - lib.a \ - $(LDADD) \ - $(Z_LIBS) \ - $(PTHREAD_LIBS) - -## puncher - -puncher_SOURCES = \ -src/lib/C4SimpleLog.cpp \ -src/netpuncher/main.cpp - -puncher_LDADD = \ - lib.a \ - $(LDADD) \ - $(PTHREAD_LIBS) - -if WIN32 -puncher_LDADD += -lws2_32 -endif - -## tstc4netio - -tstc4netio_SOURCES = \ -src/lib/C4SimpleLog.cpp \ -src/netio/TstC4NetIO.cpp - -tstc4netio_LDADD = \ - lib.a \ - $(LDADD) \ - $(Z_LIBS) \ - $(PTHREAD_LIBS) - -if WIN32 -tstc4netio_LDADD += -lws2_32 -endif - -## c4script shell -c4script_SOURCES = \ -include/c4script/c4script.h \ -src/lib/C4SimpleLog.cpp \ -src/lib/C4Real.cpp \ -src/lib/C4Random.cpp \ -src/script/shell.cpp \ -src/script/C4Aul.cpp \ -src/script/C4AulExec.cpp \ -src/script/C4AulLink.cpp \ -src/script/C4AulParse.cpp \ -src/script/C4StringTable.cpp \ -src/script/C4PropList.cpp \ -src/script/C4ScriptHost.cpp \ -src/script/C4ScriptStandalone.cpp \ -src/script/C4ValueArray.cpp \ -src/script/C4Value.cpp \ -src/script/C4ValueMap.cpp \ -src/game/object/C4Id.cpp \ -src/script/C4Script.cpp \ -src/c4group/C4GroupSet.cpp \ -src/c4group/C4ComponentHost.cpp \ -src/c4group/C4LangStringTable.cpp - -c4script_LDADD = \ - lib.a \ - $(LDADD) \ - $(Z_LIBS) - -if WIN32 -c4script_LDADD += -lwinmm -endif - -## documentation -dist_doc_DATA = planet/AUTHORS planet/COPYING licenses/LGPL.txt Credits.txt - -## game data -c4groups = \ - Graphics.ocg \ - Material.ocg \ - Music.ocg \ - Sound.ocg \ - System.ocg \ - Objects.ocd \ - BackToTheRocks.ocf \ - Tutorial.ocf - -CLEANFILES += $(c4groups) -pkgdata_DATA = $(c4groups) -AM_CXXFLAGS += -DOC_SYSTEM_DATA_DIR=\"${pkgdatadir}\" - -%.ocg: $(srcdir)/planet/%.ocg c4group$(EXEEXT) - ./c4group$(EXEEXT) $< -t $@ || c4group $< -t $@ -%.ocd: $(srcdir)/planet/%.ocd c4group$(EXEEXT) - ./c4group$(EXEEXT) $< -t $@ || c4group $< -t $@ -%.ocf: $(srcdir)/planet/%.ocf c4group$(EXEEXT) - ./c4group$(EXEEXT) $< -t $@ || c4group $< -t $@ - -## windows setup.exe -if WIN32 -tools/install/firewall.dll: $(srcdir)/tools/install/firewall.cpp - mkdir -p tools/install - $(CXX) -shared -o tools/install/firewall.dll $(srcdir)/tools/install/firewall.cpp -lole32 -loleaut32 -setup_openclonk.exe: $(srcdir)/tools/install/oc.nsi c4group$(EXEEXT) clonk$(EXEEXT) $(c4groups) - makensis -NOCD -DSRCDIR=$(srcdir) '-DPROGRAMFILES=$$PROGRAMFILES' \ - -DPRODUCT_NAME="$$(sed -n 's/SET(C4ENGINENAME\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)$$(sed -n 's/SET(C4VERSIONBUILDNAME\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)" \ - -DPRODUCT_COMPANY="$$(sed -n 's/SET(C4PROJECT\s\+"\(.\+\)")/\1/ p' $(srcdir)/Version.txt)" \ - $< "-XOutFile $@" -endif - -## other stuff - -EXTRA_DIST = \ - planet \ - Version.txt \ - CMakeLists.txt \ - Makefile.am \ - config.h.cmake \ - planet/System.ocg/LanguageUS.txt \ - planet/System.ocg/LanguageDE.txt \ - clonk.anjuta \ - licenses \ - src/netio/NetIO.dsp \ - src/netpuncher/Puncher.dsp \ - src/c4group/Resource.rc \ - src/res/brush1.bmp \ - src/res/Brush2.bmp \ - src/res/Brush.bmp \ - src/res/Brush.h \ - src/res/Brush_Trans.png \ - src/res/C4K.icns \ - src/res/C4P.icns \ - src/res/c4x.xpm \ - src/res/Clonk.icns \ - src/res/ClonkWindow.xib \ - src/res/ConsoleGUIWindow.xib \ - src/res/ConsoleWindow.xib \ - src/res/Cursor2.bmp \ - src/res/Cursor.bmp \ - src/res/Cursor.h \ - src/res/Cursor_Trans.png \ - src/res/dynamic1.bmp \ - src/res/Dynamic.h \ - src/res/Dynamic_Trans.png \ - src/res/Exact.h \ - src/res/Exact_Trans.png \ - src/res/fill1.bmp \ - src/res/Fill.bmp \ - src/res/Fill.h \ - src/res/Fill_Trans.png \ - src/res/FullscreenWindow.xib \ - src/res/Game.pal \ - src/res/Grab.bmp \ - src/res/Halt2.bmp \ - src/res/Halt.bmp \ - src/res/Halt.h \ - src/res/Halt_Trans.png \ - src/res/ift1.bmp \ - src/res/IFT.bmp \ - src/res/Ift.h \ - src/res/Ift_Trans.png \ - src/res/Info.plist \ - src/res/line1.bmp \ - src/res/Line.bmp \ - src/res/Line.h \ - src/res/Line_Trans.png \ - src/res/MainMenu.xib \ - src/res/mouse1.bmp \ - src/res/mouse.bmp \ - src/res/Mouse.h \ - src/res/Mouse_Trans.png \ - src/res/NoIFT.bmp \ - src/res/NoIft.h \ - src/res/NoIft_Trans.png \ - src/res/ocb.ico \ - src/res/ocd.icns \ - src/res/ocd.ico \ - src/res/ocf.icns \ - src/res/ocf.ico \ - src/res/ocg.icns \ - src/res/ocg.ico \ - src/res/oc.ico \ - src/res/oci.ico \ - src/res/ocl.ico \ - src/res/ocm.ico \ - src/res/ocp.ico \ - src/res/ocs.icns \ - src/res/ocs.ico \ - src/res/ocu.icns \ - src/res/ocu.ico \ - src/res/ocv.ico \ - src/res/picker1.bmp \ - src/res/Picker.h \ - src/res/Picker_Trans.png \ - src/res/Play2.bmp \ - src/res/Play.bmp \ - src/res/Play.h \ - src/res/Play_Trans.png \ - src/res/rect1.bmp \ - src/res/Rectangle.bmp \ - src/res/Rect.h \ - src/res/Rect_Trans.png \ - src/res/static1.bmp \ - src/res/Static.h \ - src/res/Static_Trans.png \ - src/res/English.lproj/InfoPlist.strings \ - src/res/English.lproj/Localizable.strings \ - src/res/German.lproj/Localizable.strings \ - src/res/SDLMain.nib/objects.nib diff --git a/README b/README new file mode 100644 index 000000000..e266fa585 --- /dev/null +++ b/README @@ -0,0 +1,55 @@ +Requirements +============ +You should be able to build OpenClonk with any C++ compiler that supports +ISO C++11. That said, on Windows, we recommend using Microsoft Visual C++ +2010 or higher; the Express edition will be sufficient. On Linux, you will +be fine with GNU g++ 4.6 or later. Apple users should use a clang-based +XCode version. + +To generate project files for your chosen build system, you will also have to +install CMake from http://www.cmake.org/. + +Additionally, OpenClonk depends on a number of third-party libraries: + - zlib (http://zlib.net/) + - libpng (http://www.libpng.org/pub/png/libpng.html) + - libjpeg-turbo (http://sourceforge.net/projects/libjpeg-turbo/files/) + - FreeType (http://www.freetype.org/) + - The OpenGL Extension Wrangler Library (http://glew.sourceforge.net/) + - FreeALUT (https://github.com/openclonk/freealut) + - libogg and libvorbis (https://www.xiph.org/downloads/) + - Boost (http://www.boost.org/users/download/) + +OS X Specific +============= +OpenClonk supports OS X versions 10.6 "Snow Leopard" and later. You can build +universal binaries by setting CMAKE_OSX_ARCHITECTURES to "x86_64 i386", but +you will of course need universal versions of the dependencies in that case. +If you are using brew (https://github.com/mxcl/homebrew) or MacPorts +(http://www.macports.org/), the packages you'll have to install are: + libjpeg, libpng, freetype, glew, libogg, libvorbis, boost + +Linux Specific +============== +For building OpenClonk on Linux, you need the following libraries in addition +to the ones listed above: + - libxpm + - libGL + - SDL 1.2 (http://www.libsdl.org/download-1.2.php) + - SDL_mixer 1.2 (http://www.libsdl.org/projects/SDL_mixer/release-1.2.html) +Most distributions should provide these dependencies via their packaging +system. For Debian based distributions, you will need these packages: + build-essential cmake libx11-dev libxxf86vm-dev libxrandr-dev libxpm-dev + libglew-dev libgl1-mesa-dev libpng12-dev libsdl1.2-dev + libsdl-mixer1.2-dev libgtk2.0-dev libjpeg8-dev zlib1g-dev libboost-dev +(This list was compiled on Debian 7.0 "Wheezy". More recent distributions may +provide packages with a higher version number.) + +Windows Specific +================ +In addition to the libraries above, you will need one more if you want to +target Windows: + - OpenAL Soft (http://kcat.strangesoft.net/openal.html) +To create an installer, you will also need the Nullsoft Install System +(http://nsis.sourceforge.net/). makensis needs to be in the PATH, and +the DLLs used by openclonk must be in the build directory. To create the +installer, build the "setup" target. diff --git a/README.linux.txt b/README.linux.txt deleted file mode 100644 index 1d9f661ff..000000000 --- a/README.linux.txt +++ /dev/null @@ -1,74 +0,0 @@ -Requirements -============ - -To build on DEB-based Linux distributions (Debian, Ubuntu etc.) you need the -following packages: - - make gcc g++ - cmake OR automake autoconf - libc6-dev libx11-dev libxxf86vm-dev libxrandr-dev libxpm-dev libglew1.5-dev - libgl1-mesa-dev libpng12-dev libsdl1.2-dev libsdl-mixer1.2-dev libgtk2.0-dev - libjpeg62-dev zlib1g-dev libboost-dev - -(Most of those packages can be substituted with a newer version if required, -for example libglew1.6-dev instead of libglew1.5-dev.) - -To build on RPM-based Linux distributions (Red Hat, Fedora, Mandriva, -SuSE etc.) you need the following packages: - - make gcc gcc-c++ - cmake OR automake autoconf - libX11-devel libXxf86vm-devel libXrandr-devel libXpm-devel glew-devel - mesa-libGL-devel libpng-devel SDL-devel SDL_mixer1.2-dev gtk2-devel - libjpeg-devel zlib-devel boost-devel - - -Build using cmake -================= - -To build OpenClonk, execute the following command inside of the source tree: - - cmake . && make - -By default, the binary will be built without debugging support. If you want -to generate a debug build, pass the parameter -DCMAKE_BUILD_TYPE=Debug to -your cmake invocation. - -Please note that you do not need to build a Debug binary if you only want to -debug C4Script code. - -You can see other build variables with: - - cmake . -N -L - - -Build using autotools -===================== - -If you build from version control, you need to run this: - - autoreconf -i && ./configure && make - -To build from tarball, run this: - - ./configure && make - -If you want a debug build, pass --enable-debug to configure. Other options are -listed by ./configure --help. - -On subsequent build runs, you only have to execute make. - - -Running -======= - -You can run the game from the build directory: - - ./clonk - -See docs/sdk/cmdline.xml for the supported command line options. - -Or install it with this: - - make install - diff --git a/README.mac.txt b/README.mac.txt deleted file mode 100644 index fead0d4ae..000000000 --- a/README.mac.txt +++ /dev/null @@ -1,45 +0,0 @@ -Requirements -============ - -OSX 10.6 or higher (might also work with 10.5) -an Intel mac -brew (https://github.com/mxcl/homebrew) or macports (http://www.macports.org/) -Xcode -Apple X11 -CMake (http://www.cmake.org/) - -Build -===== - --Install dependencies using brew or port (libjpeg, libpng, freetype, glew, libogg, libvorbis, libvorbisfile) --Launch the CMake GUI application --Click Browse Source… button, navigate to your openclonk repository folder --Also Specify location where you want to build --Click Configure and use default native compilers --Wait -- --If you want 64-bit builds set the CMAKE_OSX_ARCHITECTURES setting to "x86_64" - -For universal builds set it to "x86_64 i386", but then you'll also need universal versions of the dependencies --Click Configure button again for good measure --Click Generate --Launch xcode and load the project. Select the desired configuration and build. - -It should be pretty straight forward, hopefully. - -Additional CMake hints -===================== - -FREETYPE_LIBRARY should be set to /usr/X11/lib/libfreetype.6.dylib -ZLIB_LIBRARY to /usr/lib/libz.dylib -ZLIB_INCLUDE_DIR to /usr/include - -Situation with Xcode 4.3+ -======================== -Xcode is now a self-contained application bundle which confuses CMake. -The CMake git repo contains necessary fixes but those haven't been incorporated into a new CMake release yet so to use those you have to build the cmake command line tool yourself by - * cloning git://cmake.org/cmake.git - * running git checkout next - * running ./configure, make and sudo make install -The project generation command I (Mortimer) used was `cmake -G Xcode -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++`, obviously specifying clang as the compiler. There is a related CMake option called USE_APPLE_CLANG which should be ON by default. -After that I had a proper Xcode 4.3 project. -To use the CMake GUI for setting some library paths I put the self-built cmake command from /usr/local/bin into CMake 2.8-7.app/Contents/bin/ but one could have probably done that by editing CMakeCache.txt or setting via however the cli syntax for setting variables is. diff --git a/README.windows.txt b/README.windows.txt deleted file mode 100644 index 016ecb86b..000000000 --- a/README.windows.txt +++ /dev/null @@ -1,61 +0,0 @@ -Requirements -============ - -You can build on Windows using either: - -* vc10 (Microsoft Visual C++ 2010) - - you need CMake (http://www.cmake.org/cmake/resources/software.html) to - create the "solution" - - you might have to set the correct DXSDK include and library directories - -* MinGW and MSYS - - plus DXSDK 9 (if you want DirectX support) - -* Some other compilers and IDEs which are supported by CMake might also work - -OpenClonk requires some additional libraries. Prebuilt versions of them can be -found on http://openclonk.org. - -Building the installer -====================== - -The installer is created with NSIS. makensis needs to be in the PATH, and -the dlls used by openclonk in the build directory. To create the installer, -build the "setup" target if using CMake, or if using autotools, run: - - make setup_openclonk.exe - -Get NSIS from http://nsis.sourceforge.net/. - -Notes for MinGW -=============== - -You need gcc, g++, mingw-runtime, w32api, msys, msyscore, autoconf, automake, -and any packages needed by these. - -Get the library package from openclonk.org and unpack it into the mingw -directory. - -If you want DirectX support, get a DirectX 9 SDK from Microsoft. Copy the -contents of its include dir to the include dir of your MinGW installation, -and pass --with-directx to configure below. - -Start msys (your MinGW directory, e.g. C:\MinGW -> msys.bat), -cd to this directory, and execute: - - ./autogen.sh && ./configure && make - -To compile a debugbuild, pass --enable-debug to configure. Other options are -listed by ./configure --help. - -On subsequent build runs, you only have to execute make. - -If you want to separate the source directory and the output files, you can call -configure from another directory. You can call configure by it's relative path, -but using the full path helps gdb find the source files. Example: - - mkdir build - cd build - /path/to/clonksource/configure --with-directx CXXFLAGS='-Os' - make - diff --git a/licenses/clonk_trademark_license.txt b/TRADEMARK similarity index 100% rename from licenses/clonk_trademark_license.txt rename to TRADEMARK diff --git a/Version.txt b/Version.txt index e72c0b37a..bed80390f 100644 --- a/Version.txt +++ b/Version.txt @@ -12,33 +12,20 @@ SET(C4ENGINENICK "openclonk") SET(C4ENGINEID "${C4PROJECT_TLD}.${C4PROJECT_DOMAIN}.${C4ENGINENICK}") SET(C4XVER1 5) -SET(C4XVER2 2) +SET(C4XVER2 3) SET(C4XVER3 90) -SET(C4XVER4 21) # C4VERSIONBUILDNAME should be witty and somewhat frequently changing # for alpha and beta releases, and meaningful and stable for stable releases. # Both variables need to start with a space if they aren't empty. SET(C4VERSIONBUILDNAME " Beyond the Rocks") -SET(C4VERSIONEXTRA " Alpha") +SET(C4VERSIONEXTRA " Delta") ############################################################################ -# Get revision from Mercurial +# Get revision from Git ############################################################################ -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.hg_archival.txt") - # Archives generated by hg archive - file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/.hg_archival.txt" C4REVISION - LIMIT_COUNT 1 - REGEX "node: [0-9a-f]+" - ) - string(SUBSTRING "${C4REVISION}" 6 12 C4REVISION) -else() - # Working copies - execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMAND "hg" "id" "--id" - OUTPUT_VARIABLE C4REVISION - OUTPUT_STRIP_TRAILING_WHITESPACE) -endif() +include(GitGetChangesetID) +git_get_changeset_id(C4REVISION) ############################################################################ # Get year diff --git a/autogen.sh b/autogen.sh deleted file mode 100644 index 6a5025ce3..000000000 --- a/autogen.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -aclocal -I autotools --install -autoheader -autoconf -automake -a - diff --git a/autotools/ax_boost_base.m4 b/autotools/ax_boost_base.m4 deleted file mode 100644 index 54a2a1bee..000000000 --- a/autotools/ax_boost_base.m4 +++ /dev/null @@ -1,258 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# DESCRIPTION -# -# Test for the Boost C++ libraries of a particular version (or newer) -# -# If no path to the installed boost library is given the macro searchs -# under /usr, /usr/local, /opt and /opt/local and evaluates the -# $BOOST_ROOT environment variable. Further documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) -# -# And sets: -# -# HAVE_BOOST -# -# LICENSE -# -# Copyright (c) 2008 Thomas Porschberg -# Copyright (c) 2009 Peter Adolphs -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 20 - -AC_DEFUN([AX_BOOST_BASE], -[ -AC_ARG_WITH([boost], - [AS_HELP_STRING([--with-boost@<:@=ARG@:>@], - [use Boost library from a standard location (ARG=yes), - from the specified location (ARG=), - or disable it (ARG=no) - @<:@ARG=yes@:>@ ])], - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ac_boost_path="" - else - want_boost="yes" - ac_boost_path="$withval" - fi - ], - [want_boost="yes"]) - - -AC_ARG_WITH([boost-libdir], - AS_HELP_STRING([--with-boost-libdir=LIB_DIR], - [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), - [ - if test -d "$withval" - then - ac_boost_lib_path="$withval" - else - AC_MSG_ERROR(--with-boost-libdir expected directory name) - fi - ], - [ac_boost_lib_path=""] -) - -if test "x$want_boost" = "xyes"; then - boost_lib_version_req=ifelse([$1], ,1.20.0,$1) - boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` - boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` - boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` - boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$boost_lib_version_req_sub_minor" = "x" ; then - boost_lib_version_req_sub_minor="0" - fi - WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` - AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) - succeeded=no - - dnl On 64-bit systems check for system libraries in both lib64 and lib. - dnl The former is specified by FHS, but e.g. Debian does not adhere to - dnl this (as it rises problems for generic multi-arch support). - dnl The last entry in the list is chosen by default when no libraries - dnl are found, e.g. when only header-only libraries are installed! - libsubdirs="lib" - ax_arch=`uname -m` - if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64; then - libsubdirs="lib64 lib lib64" - fi - - dnl first we check the system location for boost libraries - dnl this location ist chosen if boost libraries are installed with the --layout=system option - dnl or if you install boost with RPM - if test "$ac_boost_path" != ""; then - BOOST_CPPFLAGS="-I$ac_boost_path/include" - for ac_boost_path_tmp in $libsubdirs; do - if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then - BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" - break - fi - done - elif test "$cross_compiling" != yes; then - for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then - for libsubdir in $libsubdirs ; do - if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi - done - BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" - BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" - break; - fi - done - fi - - dnl overwrite ld flags if we have required special directory with - dnl --with-boost-libdir parameter - if test "$ac_boost_lib_path" != ""; then - BOOST_LDFLAGS="-L$ac_boost_lib_path" - fi - - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_REQUIRE([AC_PROG_CXX]) - AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ - AC_MSG_RESULT(yes) - succeeded=yes - found_system=yes - ],[ - ]) - AC_LANG_POP([C++]) - - - - dnl if we found no boost with system layout we search for boost libraries - dnl built and installed without the --layout=system option or for a staged(not installed) version - if test "x$succeeded" != "xyes"; then - _version=0 - if test "$ac_boost_path" != ""; then - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` - V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then - _version=$_version_tmp - fi - VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" - done - fi - else - if test "$cross_compiling" != yes; then - for ac_boost_path in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` - V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then - _version=$_version_tmp - best_path=$ac_boost_path - fi - done - fi - done - - VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" - if test "$ac_boost_lib_path" = ""; then - for libsubdir in $libsubdirs ; do - if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi - done - BOOST_LDFLAGS="-L$best_path/$libsubdir" - fi - fi - - if test "x$BOOST_ROOT" != "x"; then - for libsubdir in $libsubdirs ; do - if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi - done - if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then - version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` - stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` - stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` - V_CHECK=`expr $stage_version_shorten \>\= $_version` - if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then - AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) - BOOST_CPPFLAGS="-I$BOOST_ROOT" - BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" - fi - fi - fi - fi - - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ - AC_MSG_RESULT(yes) - succeeded=yes - found_system=yes - ],[ - ]) - AC_LANG_POP([C++]) - fi - - if test "$succeeded" != "yes" ; then - if test "$_version" = "0" ; then - AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) - else - AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) - fi - # execute ACTION-IF-NOT-FOUND (if present): - ifelse([$3], , :, [$3]) - else - AC_SUBST(BOOST_CPPFLAGS) - AC_SUBST(BOOST_LDFLAGS) - AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) - # execute ACTION-IF-FOUND (if present): - ifelse([$2], , :, [$2]) - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" -fi - -]) diff --git a/autotools/ax_check_compile_flag.m4 b/autotools/ax_check_compile_flag.m4 deleted file mode 100644 index c3a8d695a..000000000 --- a/autotools/ax_check_compile_flag.m4 +++ /dev/null @@ -1,72 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the current language's compiler -# or gives an error. (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 2 - -AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ - ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_COMPILE_FLAGS diff --git a/autotools/ax_iconv.m4 b/autotools/ax_iconv.m4 deleted file mode 100644 index 5fed613f1..000000000 --- a/autotools/ax_iconv.m4 +++ /dev/null @@ -1,75 +0,0 @@ -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl Modified for Clonk to not do all that weird stuff - -AC_DEFUN([_AX_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - - dnl Search for libiconv and define LIBICONV and INCICONV - dnl accordingly. - - AC_CACHE_CHECK(for iconv, ax_cv_func_iconv, [ - ax_cv_func_iconv="no, consider installing GNU libiconv" - ax_cv_lib_iconv=no - LIBICONV="" - AC_TRY_LINK([#include -#include ], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - ax_cv_func_iconv=yes) - if test "$ax_cv_func_iconv" != yes; then - ax_save_LIBS="$LIBS" - LIBS="$LIBS -liconv" - AC_TRY_LINK([#include -#include ], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - ax_cv_lib_iconv=yes - ax_cv_func_iconv=yes - LIBICONV=-liconv) - LIBS="$ax_save_LIBS" - fi - ]) - if test "$ax_cv_func_iconv" = yes; then - AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) - fi - if test "$ax_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([-liconv]) - fi - AC_SUBST(LIBICONV) -]) - -AC_DEFUN([AX_ICONV], -[ - _AX_ICONV_LINK - if test "$ax_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL(ax_cv_proto_iconv, [ - AC_TRY_COMPILE([ -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif -], [], ax_cv_proto_iconv_arg1="", ax_cv_proto_iconv_arg1="const")]) - AC_MSG_RESULT([extern size_t iconv (iconv_t cd, $ax_cv_proto_iconv_arg1 char * * inbuf, size_t * inbytesleft, char * * outbuf, size_t * outbytesleft);]) - AC_DEFINE_UNQUOTED(ICONV_CONST, $ax_cv_proto_iconv_arg1, - [Define as const if the declaration of iconv() needs const.]) - fi -]) diff --git a/autotools/ax_pthread.m4 b/autotools/ax_pthread.m4 deleted file mode 100644 index e20a388ca..000000000 --- a/autotools/ax_pthread.m4 +++ /dev/null @@ -1,309 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -# -# DESCRIPTION -# -# This macro figures out how to build C programs using POSIX threads. It -# sets the PTHREAD_LIBS output variable to the threads library and linker -# flags, and the PTHREAD_CFLAGS output variable to any special C compiler -# flags that are needed. (The user can also force certain compiler -# flags/libs to be tested by setting these environment variables.) -# -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) -# -# NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with -# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS -# -# If you are only building threads programs, you may wish to use these -# variables in your default LIBS, CFLAGS, and CC: -# -# LIBS="$PTHREAD_LIBS $LIBS" -# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -# CC="$PTHREAD_CC" -# -# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). -# -# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the -# PTHREAD_PRIO_INHERIT symbol is defined when compiling with -# PTHREAD_CFLAGS. -# -# ACTION-IF-FOUND is a list of shell commands to run if a threads library -# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it -# is not found. If ACTION-IF-FOUND is not specified, the default action -# will define HAVE_PTHREAD. -# -# Please let the authors know if this macro fails on any platform, or if -# you have any other suggestions or comments. This macro was based on work -# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help -# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by -# Alejandro Forero Cuervo to the autoconf macro repository. We are also -# grateful for the helpful feedback of numerous users. -# -# Updated for Autoconf 2.68 by Daniel Richard G. -# -# LICENSE -# -# Copyright (c) 2008 Steven G. Johnson -# Copyright (c) 2011 Daniel Richard G. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 17 - -AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) -AC_DEFUN([AX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) -AC_LANG_PUSH([C]) -ax_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) - AC_MSG_RESULT($ax_pthread_ok) - if test x"$ax_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. - -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC -# pthread: Linux, etcetera -# --thread-safe: KAI C++ -# pthread-config: use pthread-config program (for GNU Pth library) - -case "${host_cpu}-${host_os}" in - *solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" - ;; - - *-darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" - ;; -esac - -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do - - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" - ;; - - pthread-config) - AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) - if test x"$ax_pthread_config" = xno; then continue; fi - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" - ;; - esac - - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - AC_MSG_RESULT($ax_pthread_ok) - if test "x$ax_pthread_ok" = xyes; then - break; - fi - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi - -# Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT($attr_name) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case "${host_cpu}-${host_os}" in - *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; - *-osf* | *-hpux*) flag="-D_REENTRANT";; - *solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT(${flag}) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi - - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - ax_cv_PTHREAD_PRIO_INHERIT, [ - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - # More AIX lossage: must compile with xlc_r or cc_r - if test x"$GCC" != xyes; then - AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) - else - PTHREAD_CC=$CC - fi -else - PTHREAD_CC="$CC" -fi - -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_CC) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then - ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) - : -else - ax_pthread_ok=no - $2 -fi -AC_LANG_POP -])dnl AX_PTHREAD diff --git a/autotools/pkg.m4 b/autotools/pkg.m4 deleted file mode 100644 index 9bb3e068c..000000000 --- a/autotools/pkg.m4 +++ /dev/null @@ -1,157 +0,0 @@ -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 1 (pkg-config-0.24) -# -# Copyright © 2004 Scott James Remnant . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) -AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) -AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -# only at the first occurence in configure.ac, so if the first place -# it's called might be skipped (such as if it is within an "if", you -# have to call PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_default([$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$$1"; then - pkg_cv_[]$1="$$1" - elif test -n "$PKG_CONFIG"; then - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - m4_default([$4], [AC_MSG_ERROR( -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT])dnl - ]) -elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see .])dnl - ]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - $3 -fi[]dnl -])# PKG_CHECK_MODULES diff --git a/autotools/reftotemp.m4 b/autotools/reftotemp.m4 deleted file mode 100644 index 63d4e7c98..000000000 --- a/autotools/reftotemp.m4 +++ /dev/null @@ -1,23 +0,0 @@ -dnl Copyright (C) 2009 Günther Brammer - -AC_DEFUN([AX_PROG_CXX_REFTOTEMP], -[ - AC_LANG_ASSERT([C++]) - AC_CACHE_CHECK([wether the C++ compiler is friendly], [ax_cv_reftotemp], [ - AC_COMPILE_IFELSE([ -struct Foo { - operator Foo & () { return *this; } -}; -#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) -void frobnicate(Foo &&) { } -#else -void frobnicate(Foo &) { } -#endif -int main () { - frobnicate (Foo()); -} -], [ax_cv_reftotemp=yes], [ax_cv_reftotemp=no])]) - if test $ax_cv_reftotemp = no; then - AC_MSG_ERROR([The C++ compiler won't be able to compile Clonk. Try CXX='g++ -std=gnu++0x' or CXX='g++-4.1'.]) - fi[]dnl -])# AX_PROG_CXX_REFTOTEMP diff --git a/autotools/sdl.m4 b/autotools/sdl.m4 deleted file mode 100644 index 639eb8517..000000000 --- a/autotools/sdl.m4 +++ /dev/null @@ -1,185 +0,0 @@ -# Configure paths for SDL -# Sam Lantinga 9/21/99 -# stolen from Manish Singh -# stolen back from Frank Belew -# stolen from Manish Singh -# Shamelessly stolen from Owen Taylor - -# serial 1 - -dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS -dnl -AC_DEFUN([AM_PATH_SDL], -[dnl -dnl Get the cflags and libraries from the sdl-config script -dnl -AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], - sdl_prefix="$withval", sdl_prefix="") -AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], - sdl_exec_prefix="$withval", sdl_exec_prefix="") -AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], - , enable_sdltest=yes) - - if test x$sdl_exec_prefix != x ; then - sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config - fi - fi - if test x$sdl_prefix != x ; then - sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_prefix/bin/sdl-config - fi - fi - - as_save_PATH="$PATH" - if test "x$prefix" != xNONE; then - PATH="$prefix/bin:$prefix/usr/bin:$PATH" - fi - AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH]) - PATH="$as_save_PATH" - min_sdl_version=ifelse([$1], ,0.11.0,$1) - AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) - no_sdl="" - if test "$SDL_CONFIG" = "no" ; then - no_sdl=yes - else - SDL_CFLAGS=`$SDL_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL_CONFIG $sdl_config_args --libs` - - sdl_major_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - sdl_minor_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_sdltest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_CXXFLAGS="$CXXFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $SDL_CFLAGS" - CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" -dnl -dnl Now check if the installed SDL is sufficiently new. (Also sanity -dnl checks the results of sdl-config to some extent -dnl - rm -f conf.sdltest - AC_TRY_RUN([ -#include -#include -#include -#include "SDL.h" - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main (int argc, char *argv[]) -{ - int major, minor, micro; - char *tmp_version; - - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_sdl_version"); - exit(1); - } - - if (($sdl_major_version > major) || - (($sdl_major_version == major) && ($sdl_minor_version > minor)) || - (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); - printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); - printf("*** to point to the correct copy of sdl-config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - CXXFLAGS="$ac_save_CXXFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_sdl" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$SDL_CONFIG" = "no" ; then - echo "*** The sdl-config script installed by SDL could not be found" - echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the SDL_CONFIG environment variable to the" - echo "*** full path to sdl-config." - else - if test -f conf.sdltest ; then - : - else - echo "*** Could not run SDL test program, checking why..." - CFLAGS="$CFLAGS $SDL_CFLAGS" - CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" - AC_TRY_LINK([ -#include -#include "SDL.h" - -int main(int argc, char *argv[]) -{ return 0; } -#undef main -#define main K_and_R_C_main -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding SDL or finding the wrong" - echo "*** version of SDL. If it is not finding SDL, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means SDL was incorrectly installed" - echo "*** or that you have moved SDL since it was installed. In the latter case, you" - echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - CXXFLAGS="$ac_save_CXXFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - SDL_CFLAGS="" - SDL_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(SDL_CFLAGS) - AC_SUBST(SDL_LIBS) - rm -f conf.sdltest -]) diff --git a/autotools/vl_lib_readline.m4 b/autotools/vl_lib_readline.m4 deleted file mode 100644 index f466dbf79..000000000 --- a/autotools/vl_lib_readline.m4 +++ /dev/null @@ -1,93 +0,0 @@ -dnl @synopsis VL_LIB_READLINE -dnl -dnl Searches for a readline compatible library. If found, defines -dnl `HAVE_LIBREADLINE'. If the found library has the `add_history' -dnl function, sets also `HAVE_READLINE_HISTORY'. Also checks for the -dnl locations of the necessary include files and sets `HAVE_READLINE_H' -dnl or `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or -dnl 'HAVE_HISTORY_H' if the corresponding include files exists. -dnl -dnl The libraries that may be readline compatible are `libedit', -dnl `libeditline' and `libreadline'. Sometimes we need to link a -dnl termcap library for readline to work, this macro tests these cases -dnl too by trying to link with `libtermcap', `libcurses' or -dnl `libncurses' before giving up. -dnl -dnl Here is an example of how to use the information provided by this -dnl macro to perform the necessary includes or declarations in a C -dnl file: -dnl -dnl #ifdef HAVE_LIBREADLINE -dnl # if defined(HAVE_READLINE_READLINE_H) -dnl # include -dnl # elif defined(HAVE_READLINE_H) -dnl # include -dnl # else /* !defined(HAVE_READLINE_H) */ -dnl extern char *readline (); -dnl # endif /* !defined(HAVE_READLINE_H) */ -dnl char *cmdline = NULL; -dnl #else /* !defined(HAVE_READLINE_READLINE_H) */ -dnl /* no readline */ -dnl #endif /* HAVE_LIBREADLINE */ -dnl -dnl #ifdef HAVE_READLINE_HISTORY -dnl # if defined(HAVE_READLINE_HISTORY_H) -dnl # include -dnl # elif defined(HAVE_HISTORY_H) -dnl # include -dnl # else /* !defined(HAVE_HISTORY_H) */ -dnl extern void add_history (); -dnl extern int write_history (); -dnl extern int read_history (); -dnl # endif /* defined(HAVE_READLINE_HISTORY_H) */ -dnl /* no history */ -dnl #endif /* HAVE_READLINE_HISTORY */ -dnl -dnl @category InstalledPackages -dnl @author Ville Laurikari -dnl @version 2002-04-04 -dnl @license AllPermissive - -AC_DEFUN([VL_LIB_READLINE], [ - AC_CACHE_CHECK([for a readline compatible library], - vl_cv_lib_readline, [ - ORIG_LIBS="$LIBS" - for readline_lib in readline edit editline; do - for termcap_lib in "" termcap curses ncurses; do - if test -z "$termcap_lib"; then - TRY_LIB="-l$readline_lib" - else - TRY_LIB="-l$readline_lib -l$termcap_lib" - fi - LIBS="$ORIG_LIBS $TRY_LIB" - AC_TRY_LINK_FUNC(readline, vl_cv_lib_readline="$TRY_LIB") - if test -n "$vl_cv_lib_readline"; then - break - fi - done - if test -n "$vl_cv_lib_readline"; then - break - fi - done - if test -z "$vl_cv_lib_readline"; then - vl_cv_lib_readline="no" - LIBS="$ORIG_LIBS" - fi - ]) - - if test "$vl_cv_lib_readline" != "no"; then - AC_DEFINE(HAVE_LIBREADLINE, 1, - [Define if you have a readline compatible library]) - AC_CHECK_HEADERS(readline.h readline/readline.h) - AC_CACHE_CHECK([whether readline supports history], - vl_cv_lib_readline_history, [ - vl_cv_lib_readline_history="no" - AC_TRY_LINK_FUNC(add_history, vl_cv_lib_readline_history="yes") - ]) - if test "$vl_cv_lib_readline_history" = "yes"; then - AC_DEFINE(HAVE_READLINE_HISTORY, 1, - [Define if your readline library has \`add_history']) - AC_CHECK_HEADERS(history.h readline/history.h) - fi - fi -])dnl diff --git a/clonk.anjuta b/clonk.anjuta deleted file mode 100644 index a9f9e82ef..000000000 --- a/clonk.anjuta +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/cmake/FindDbgHelp.cmake b/cmake/FindDbgHelp.cmake index 7c46a154c..21a1cfe5b 100644 --- a/cmake/FindDbgHelp.cmake +++ b/cmake/FindDbgHelp.cmake @@ -1,3 +1,16 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2011-2013, 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. + # - Find DbgHelp # Find the DbgHelp library # This module defines @@ -5,20 +18,6 @@ # DBGHELP_LIBRARIES, the libraries needed to use DbgHelp. # DBGHELP_FOUND, If false, do not try to use DbgHelp. -#============================================================================= -# OpenClonk, http://www.openclonk.org -# -# Copyright (c) 2011 Nicolas Hake -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# See isc_license.txt for full license and disclaimer. -# -# "Clonk" is a registered trademark of Matthes Bender. -# See clonk_trademark_license.txt for full license. -#============================================================================= - find_path(DBGHELP_INCLUDE_DIR NAMES dbghelp.h) set(DBGHELP_NAMES ${DBGHELP_NAMES} dbghelp) find_library(DBGHELP_LIBRARY NAMES ${DBGHELP_NAMES}) diff --git a/cmake/FindFMod.cmake b/cmake/FindFMod.cmake index 209f97648..560b1357b 100644 --- a/cmake/FindFMod.cmake +++ b/cmake/FindFMod.cmake @@ -1,3 +1,16 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2011-2013, 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. + # - Find FMod # Find the FMod library # This module defines @@ -5,20 +18,6 @@ # FMOD_LIBRARIES, the libraries needed to use FMod. # FMOD_FOUND, If false, do not try to use FMod. -#============================================================================= -# OpenClonk, http://www.openclonk.org -# -# Copyright (c) 2011 Nicolas Hake -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# See isc_license.txt for full license and disclaimer. -# -# "Clonk" is a registered trademark of Matthes Bender. -# See clonk_trademark_license.txt for full license. -#============================================================================= - find_path(FMOD_INCLUDE_DIR fmod.h) if(CMAKE_CL_64) diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake new file mode 100644 index 000000000..891d1e200 --- /dev/null +++ b/cmake/FindFreetype.cmake @@ -0,0 +1,143 @@ +# - Locate FreeType library +# This module defines +# FREETYPE_LIBRARIES, the library to link against +# FREETYPE_FOUND, if false, do not try to link to FREETYPE +# FREETYPE_INCLUDE_DIRS, where to find headers. +# FREETYPE_VERSION_STRING, the version of freetype found (since CMake 2.8.8) +# This is the concatenation of the paths: +# FREETYPE_INCLUDE_DIR_ft2build +# FREETYPE_INCLUDE_DIR_freetype2 +# +# $FREETYPE_DIR is an environment variable that would +# correspond to the ./configure --prefix=$FREETYPE_DIR +# used in building FREETYPE. + +#============================================================================= +# CMake - Cross Platform Makefile Generator +# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Created by Eric Wing. +# Modifications by Alexander Neundorf. +# This file has been renamed to "FindFreetype.cmake" instead of the correct +# "FindFreeType.cmake" in order to be compatible with the one from KDE4, Alex. + +# Modified by Nicolas Hake for the OpenClonk Project to make FindFreetype also +# look for the versioned libraries the freetype MSVC project generates. + +# Ugh, FreeType seems to use some #include trickery which +# makes this harder than it should be. It looks like they +# put ft2build.h in a common/easier-to-find location which +# then contains a #include to a more specific header in a +# more specific location (#include ). +# Then from there, they need to set a bunch of #define's +# so you can do something like: +# #include FT_FREETYPE_H +# Unfortunately, using CMake's mechanisms like include_directories() +# wants explicit full paths and this trickery doesn't work too well. +# I'm going to attempt to cut out the middleman and hope +# everything still works. +find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h + HINTS + ENV FREETYPE_DIR + PATHS + /usr/X11R6 + /usr/local/X11R6 + /usr/local/X11 + /usr/freeware + PATH_SUFFIXES include/freetype2 include +) + +find_path(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h + HINTS + ENV FREETYPE_DIR + PATHS + /usr/X11R6 + /usr/local/X11R6 + /usr/local/X11 + /usr/freeware + PATH_SUFFIXES include/freetype2 include +) + +if(FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h") + file(STRINGS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h" freetype_version_str + REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$") + + unset(FREETYPE_VERSION_STRING) + foreach(VPART MAJOR MINOR PATCH) + foreach(VLINE ${freetype_version_str}) + if(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}") + string(REGEX REPLACE "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$" "\\1" + FREETYPE_VERSION_PART "${VLINE}") + if(FREETYPE_VERSION_STRING) + set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_STRING}.${FREETYPE_VERSION_PART}") + else() + set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}") + endif() + unset(FREETYPE_VERSION_PART) + endif() + endforeach() + endforeach() + if(FREETYPE_VERSION_STRING) + string(REPLACE "." "" FREETYPE_VERSIONED_LIBRARY "${FREETYPE_VERSION_STRING}") + set(FREETYPE_VERSIONED_LIBRARY "freetype${FREETYPE_VERSIONED_LIBRARY}") + endif() +endif() + +find_library(FREETYPE_LIBRARY + NAMES freetype libfreetype freetype219 ${FREETYPE_VERSIONED_LIBRARY} + HINTS + ENV FREETYPE_DIR + PATH_SUFFIXES lib + PATHS + /usr/X11R6 + /usr/local/X11R6 + /usr/local/X11 + /usr/freeware +) + +unset(FREETYPE_VERSIONED_LIBRARY) + +# set the user variables +if(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2) + set(FREETYPE_INCLUDE_DIRS "${FREETYPE_INCLUDE_DIR_ft2build};${FREETYPE_INCLUDE_DIR_freetype2}") +endif() +set(FREETYPE_LIBRARIES "${FREETYPE_LIBRARY}") + +# handle the QUIETLY and REQUIRED arguments and set FREETYPE_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype + REQUIRED_VARS FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS + VERSION_VAR FREETYPE_VERSION_STRING) + +mark_as_advanced(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR_freetype2 FREETYPE_INCLUDE_DIR_ft2build) diff --git a/cmake/FindPNG.cmake b/cmake/FindPNG.cmake new file mode 100644 index 000000000..8ee0cadef --- /dev/null +++ b/cmake/FindPNG.cmake @@ -0,0 +1,105 @@ +# - Find the native PNG includes and library +# +# This module searches libpng, the library for working with PNG images. +# +# It defines the following variables +# PNG_INCLUDE_DIRS, where to find png.h, etc. +# PNG_LIBRARIES, the libraries to link against to use PNG. +# PNG_DEFINITIONS - You should add_definitons(${PNG_DEFINITIONS}) before compiling code that includes png library files. +# PNG_FOUND, If false, do not try to use PNG. +# PNG_VERSION_STRING - the version of the PNG library found (since CMake 2.8.8) +# Also defined, but not for general use are +# PNG_LIBRARY, where to find the PNG library. +# For backward compatiblity the variable PNG_INCLUDE_DIR is also set. It has the same value as PNG_INCLUDE_DIRS. +# +# Since PNG depends on the ZLib compression library, none of the above will be +# defined unless ZLib can be found. + +#============================================================================= +# CMake - Cross Platform Makefile Generator +# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Modified by Nicolas Hake for the OpenClonk Project to make FindPNG also +# look for versioned libraries. + +if(PNG_FIND_QUIETLY) + set(_FIND_ZLIB_ARG QUIET) +endif() +find_package(ZLIB ${_FIND_ZLIB_ARG}) + +if(ZLIB_FOUND) + find_path(PNG_PNG_INCLUDE_DIR png.h + /usr/local/include/libpng # OpenBSD + ) + + if (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h") + file(STRINGS "${PNG_PNG_INCLUDE_DIR}/png.h" png_version_str REGEX "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\".+\"") + + string(REGEX REPLACE "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\"([^\"]+)\".*" "\\1" PNG_VERSION_STRING "${png_version_str}") + unset(png_version_str) + endif () + if (PNG_VERSION_STRING) + string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*" "png\\1\\2" PNG_VERSIONED_LIBRARY "${PNG_VERSION_STRING}") + set(PNG_VERSIONED_LIBRARY ${PNG_VERSIONED_LIBRARY} lib${PNG_VERSIONED_LIBRARY} lib${PNG_VERSIONED_LIBRARY}_static ${PNG_VERSIONED_LIBRARY}d lib${PNG_VERSIONED_LIBRARY}d lib${PNG_VERSIONED_LIBRARY}d_static) + endif () + + set(PNG_NAMES ${PNG_NAMES} png libpng ${PNG_VERSIONED_LIBRARY} png15 libpng15 png15d libpng15d png14 libpng14 png14d libpng14d png12 libpng12 png12d libpng12d) + unset(PNG_VERSIONED_LIBRARY) + find_library(PNG_LIBRARY NAMES ${PNG_NAMES} ) + + if (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR) + # png.h includes zlib.h. Sigh. + set(PNG_INCLUDE_DIRS ${PNG_PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) + set(PNG_INCLUDE_DIR ${PNG_INCLUDE_DIRS} ) # for backward compatiblity + set(PNG_LIBRARIES ${PNG_LIBRARY} ${ZLIB_LIBRARY}) + + if (CYGWIN) + if(BUILD_SHARED_LIBS) + # No need to define PNG_USE_DLL here, because it's default for Cygwin. + else() + set (PNG_DEFINITIONS -DPNG_STATIC) + endif() + endif () + + endif () + +endif() + +# handle the QUIETLY and REQUIRED arguments and set PNG_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PNG + REQUIRED_VARS PNG_LIBRARY PNG_PNG_INCLUDE_DIR + VERSION_VAR PNG_VERSION_STRING) + +mark_as_advanced(PNG_PNG_INCLUDE_DIR PNG_LIBRARY ) diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index 21f1f2c97..4324d03fb 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -1,3 +1,16 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2011-2013, 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. + # - Find READLINE # Find the native READLINE includes and library # diff --git a/cmake/FindUpnp.cmake b/cmake/FindUpnp.cmake index f8615a0b8..18bbcfbf1 100644 --- a/cmake/FindUpnp.cmake +++ b/cmake/FindUpnp.cmake @@ -1,3 +1,16 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2012-2013, 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. + # - Find libupnp # Find the libupnp library # This module defines @@ -5,34 +18,21 @@ # UPNP_LIBRARIES, the libraries needed to use libupnp. # UPNP_FOUND, If false, do not try to use libupnp. -#============================================================================= -# OpenClonk, http://www.openclonk.org -# -# Copyright (c) 2012 Armin Burgmeier -# Copyright (c) 2012 Nicolas Hake -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# See isc_license.txt for full license and disclaimer. -# -# "Clonk" is a registered trademark of Matthes Bender. -# See clonk_trademark_license.txt for full license. -#============================================================================= - # TODO: Use pkg-config if available find_path(UPNP_INCLUDE_DIR NAMES upnp.h PATH_SUFFIXES upnp) set(UPNP_NAMES ${UPNP_NAMES} upnp) +set(THREADUTIL_NAMES ${THREADUTIL_NAMES} threadutil) set(IXML_NAMES ${IXML_NAMES} ixml) find_library(UPNP_LIBRARY NAMES ${UPNP_NAMES}) +find_library(THREADUTIL_LIBRARY NAMES ${THREADUTIL_NAMES}) find_library(IXML_LIBRARY NAMES ${IXML_NAMES}) include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(UPNP DEFAULT_MSG UPNP_LIBRARY IXML_LIBRARY UPNP_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(UPNP DEFAULT_MSG UPNP_LIBRARY THREADUTIL_LIBRARY IXML_LIBRARY UPNP_INCLUDE_DIR) if(UPNP_FOUND) - set(UPNP_LIBRARIES ${UPNP_LIBRARY} ${IXML_LIBRARY}) + set(UPNP_LIBRARIES ${UPNP_LIBRARY} ${THREADUTIL_LIBRARY} ${IXML_LIBRARY}) set(UPNP_INCLUDE_DIR ${UPNP_INCLUDE_DIR}) endif() diff --git a/cmake/FindZLIB.cmake b/cmake/FindZLIB.cmake new file mode 100644 index 000000000..ac4e0f965 --- /dev/null +++ b/cmake/FindZLIB.cmake @@ -0,0 +1,113 @@ +# - Find zlib +# Find the native ZLIB includes and library. +# Once done this will define +# +# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. +# ZLIB_LIBRARIES - List of libraries when using zlib. +# ZLIB_FOUND - True if zlib found. +# +# ZLIB_VERSION_STRING - The version of zlib found (x.y.z) +# ZLIB_VERSION_MAJOR - The major version of zlib +# ZLIB_VERSION_MINOR - The minor version of zlib +# ZLIB_VERSION_PATCH - The patch version of zlib +# ZLIB_VERSION_TWEAK - The tweak version of zlib +# +# The following variable are provided for backward compatibility +# +# ZLIB_MAJOR_VERSION - The major version of zlib +# ZLIB_MINOR_VERSION - The minor version of zlib +# ZLIB_PATCH_VERSION - The patch version of zlib +# +# An includer may set ZLIB_ROOT to a zlib installation root to tell +# this module where to look. + +#============================================================================= +# CMake - Cross Platform Makefile Generator +# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +set(_ZLIB_SEARCHES) + +# Search ZLIB_ROOT first if it is set. +if(ZLIB_ROOT) + set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH) + list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT) +endif() + +# Normal search. +set(_ZLIB_SEARCH_NORMAL + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" + "$ENV{PROGRAMFILES}/zlib" + ) +list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) + +set(ZLIB_NAMES z zlib zlibstatic zdll zlib1 zlibd zlibd1) + +# Try each search configuration. +foreach(search ${_ZLIB_SEARCHES}) + find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include) + find_library(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib) +endforeach() + +mark_as_advanced(ZLIB_LIBRARY ZLIB_INCLUDE_DIR) + +if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") + file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$") + + string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}") + + # only append a TWEAK version if it exists: + set(ZLIB_VERSION_TWEAK "") + if( "${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$") + set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}") + endif() + + set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") + set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") + set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") +endif() + +# handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR + VERSION_VAR ZLIB_VERSION_STRING) + +if(ZLIB_FOUND) + set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) +endif() + diff --git a/cmake/GccPchSupport.cmake b/cmake/GccPchSupport.cmake index fba882b13..8f9c665fc 100644 --- a/cmake/GccPchSupport.cmake +++ b/cmake/GccPchSupport.cmake @@ -68,7 +68,7 @@ MACRO(ADD_PRECOMPILED_HEADER _targetName _input) ${_compiler_FLAGS} -x c++-header -o ${_output} ${_source} IMPLICIT_DEPENDS CXX ${_source} ) - FILE(WRITE "${_pchdir}/${_name}" "") # This file is added so the cc-units don't stumble over not being able to include the file + FILE(WRITE "${_pchdir}/${_name}" "#ifdef __cplusplus\n#warning Precompiled header not used. Turn off or fix!\n#endif") # This file is added so the cc-units don't stumble over not being able to include the file ADD_CUSTOM_TARGET(${_targetName}_pch DEPENDS ${_output}) ADD_DEPENDENCIES(${_targetName} ${_targetName}_pch) SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS "-include ${_includeput}") diff --git a/cmake/GitGetChangesetID.cmake b/cmake/GitGetChangesetID.cmake new file mode 100644 index 000000000..96a856e40 --- /dev/null +++ b/cmake/GitGetChangesetID.cmake @@ -0,0 +1,52 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2012-2013, 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. + +function(git_get_changeset_id VAR) + find_package(Git QUIET) + if (GIT_FOUND) + execute_process(WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND "${GIT_EXECUTABLE}" "rev-parse" "HEAD" + RESULT_VARIABLE GIT_RESULT + OUTPUT_VARIABLE C4REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + + if(GIT_RESULT EQUAL 0) + string(SUBSTRING "${C4REVISION}" 0 12 C4REVISION) + execute_process(WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND "${GIT_EXECUTABLE}" "status" "--porcelain" + OUTPUT_VARIABLE GIT_STATUS + ) + string(REGEX MATCH "^[MADRC ][MD ]" WORKDIR_DIRTY "${GIT_STATUS}") + endif() + endif() + if (NOT C4REVISION) + # Git not found or not a git workdir + file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/.git_archival" C4REVISION + LIMIT_COUNT 1 + REGEX "node: [0-9a-f]+" + ) + string(LENGTH "${C4REVISION}" revlength) + if(revlength LESS 18) + set(C4REVISION "unknown") + message(WARNING "Could not retrieve git revision. Please set GIT_EXECUTABLE!") + else() + string(SUBSTRING "${C4REVISION}" 6 12 C4REVISION) + endif() + unset(revlength) + endif() + if(WORKDIR_DIRTY) + set(C4REVISION "${C4REVISION}+") + endif() + set(${VAR} "${C4REVISION}" PARENT_SCOPE) +endfunction() diff --git a/cmake/RequireCXXSourceCompiles.cmake b/cmake/RequireCXXSourceCompiles.cmake new file mode 100644 index 000000000..4877502de --- /dev/null +++ b/cmake/RequireCXXSourceCompiles.cmake @@ -0,0 +1,21 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2013, 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. + +include(CheckCXXSourceCompiles) +macro(REQUIRE_CXX_SOURCE_COMPILES _code _var) + CHECK_CXX_SOURCE_COMPILES("${_code}" ${_var}) + if(NOT ${_var}) + unset(${_var} CACHE) + MESSAGE(FATAL_ERROR "${_var} is required for this project to build properly. Aborting.") + endif() +endmacro() diff --git a/config.h.cmake b/config.h.cmake index d6c4d98b2..c8e1ed003 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,14 +1,17 @@ /* Activate DebugRecs */ #cmakedefine DEBUGREC 1 +/* Generate minidumps on crash */ +#cmakedefine HAVE_DBGHELP 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DIRECT_H 1 -/* Define to 1 if you have the header file. */ +/* The backtrace function is declared in execinfo.h and works */ #cmakedefine HAVE_EXECINFO_H 1 -/* Define to 1 if you have FreeType2. */ -#cmakedefine HAVE_FREETYPE 1 +/* Whether FMOD shall be used */ +#cmakedefine HAVE_FMOD 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_HISTORY_H 1 @@ -31,20 +34,14 @@ /* Define to 1 if you have SDL_mixer. */ #cmakedefine HAVE_LIBSDL_MIXER 1 -/* Define to 1 if FMOD is available */ -#cmakedefine HAVE_FMOD 1 - -/* Use OpenAL for playing sounds */ -#cmakedefine USE_OPEN_AL 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LOCALE_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MEMORY_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MULTIMON_H 1 +/* Define to 1 if you have support for nullptr. */ +#cmakedefine HAVE_NULLPTR 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_POLL_H 1 @@ -64,6 +61,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_READLINE_READLINE_H 1 +/* C++ Compiler has rvalue references, a C++0x feature. */ +#cmakedefine HAVE_RVALUE_REF 1 + /* Define to 1 if you have SDL. */ #cmakedefine HAVE_SDL 1 @@ -73,6 +73,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SIGNAL_H 1 +/* Define to 1 if your compiler supports static_assert */ +#cmakedefine HAVE_STATIC_ASSERT 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 @@ -85,15 +88,15 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_INOTIFY_H 1 - /* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_EVENTFD_H +#cmakedefine HAVE_SYS_EVENTFD_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_FILE_H 1 +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_INOTIFY_H 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_SOCKET_H 1 @@ -114,18 +117,12 @@ #cmakedefine HAVE_VFW32 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_X11_EXTENSIONS_XF86VMODE_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_X11_EXTENSIONS_XRANDR_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_X11_KEYSYM_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_X11_XPM_H 1 - /* Define as const if the declaration of iconv() needs const. */ #cmakedefine ICONV_CONST @@ -160,53 +157,38 @@ /* dedicated server mode */ #cmakedefine USE_CONSOLE 1 -/* DirectX graphics */ -#cmakedefine USE_DIRECTX 1 - -/* OpenGL graphics */ -#cmakedefine USE_GL 1 - /* MP3 music */ #cmakedefine USE_MP3 1 +/* OpenAL sound */ +#cmakedefine USE_OPEN_AL 1 + /* Define to 1 if SDL is used for the main loop */ #cmakedefine USE_SDL_MAINLOOP 1 /* Define to 1 if the X Window System is used */ #cmakedefine USE_X11 1 +/* Enable automatic update system */ +#cmakedefine WITH_AUTOMATIC_UPDATE 1 + /* Developer mode */ #cmakedefine WITH_DEVELOPER_MODE 1 +/* Define to 1 if you want to use Boost.Regex instead of . */ +#cmakedefine USE_BOOST_REGEX 1 + /* Glib */ #cmakedefine WITH_GLIB 1 -/* Use GTK+3 for the developer mode */ -#cmakedefine WITH_GTK3 1 - -/* Enable the automatic update system */ -#cmakedefine WITH_AUTOMATIC_UPDATE 1 - /* Define to 1 if the X Window System is missing or not being used. */ #cmakedefine X_DISPLAY_MISSING 1 /* compile with debug options */ -#cmakedefine _DEBUG - -/* Define to 1 if rvalue references are supported */ -#cmakedefine HAVE_RVALUE_REF 1 +#cmakedefine _DEBUG 1 /* Define to 1 if you have support for precompiled headers */ #cmakedefine HAVE_PRECOMPILED_HEADERS 1 -/* Define to 1 if you have support for nullptr. */ -#cmakedefine HAVE_NULLPTR 1 - /* Use Apple Cocoa for the UI */ #cmakedefine USE_COCOA 1 - -/* Define to 1 if your compiler supports static_assert */ -#cmakedefine HAVE_STATIC_ASSERT 1 - -/* Generate minidumps on crash */ -#cmakedefine HAVE_DBGHELP 1 diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 756b02b66..000000000 --- a/config.h.in +++ /dev/null @@ -1,209 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Activate DebugRecs */ -#undef DEBUGREC - -/* define if the Boost library is available */ -#undef HAVE_BOOST - -/* Define to 1 if you have the header file. */ -#undef HAVE_DIRECT_H - -/* The backtrace function is declared in execinfo.h and works */ -#undef HAVE_EXECINFO_H - -/* Define to 1 if you have FreeType2. */ -#undef HAVE_FREETYPE - -/* Define to 1 if you have the header file. */ -#undef HAVE_HISTORY_H - -/* Define if you have the iconv() function. */ -#undef HAVE_ICONV - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_IO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LANGINFO_H - -/* Define if you have a readline compatible library */ -#undef HAVE_LIBREADLINE - -/* Define to 1 if you have SDL_mixer. */ -#undef HAVE_LIBSDL_MIXER - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MULTIMON_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NATUPNP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_POLL_H - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Have PTHREAD_PRIO_INHERIT. */ -#undef HAVE_PTHREAD_PRIO_INHERIT - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_H - -/* Define if your readline library has \`add_history' */ -#undef HAVE_READLINE_HISTORY - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_HISTORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_READLINE_H - -/* C++ Compiler has rvalue references, a C++0x feature. */ -#undef HAVE_RVALUE_REF - -/* Define to 1 if you have SDL. */ -#undef HAVE_SDL - -/* Define to 1 if you have the header file. */ -#undef HAVE_SHARE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_EVENTFD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_FILE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_INOTIFY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIMERFD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `vasprintf' function. */ -#undef HAVE_VASPRINTF - -/* */ -#undef HAVE_VFW32 - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_EXTENSIONS_XF86VMODE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_EXTENSIONS_XRANDR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_KEYSYM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XPM_H - -/* Define as const if the declaration of iconv() needs const. */ -#undef ICONV_CONST - -/* compile without debug options */ -#undef NDEBUG - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* dedicated server mode */ -#undef USE_CONSOLE - -/* DirectX graphics */ -#undef USE_DIRECTX - -/* Whether FMOD shall be used */ -#undef USE_FMOD - -/* OpenGL graphics */ -#undef USE_GL - -/* MP3 music */ -#undef USE_MP3 - -/* OpenAL sound */ -#undef USE_OPEN_AL - -/* Define to 1 if SDL is used for the main loop */ -#undef USE_SDL_MAINLOOP - -/* Define to 1 if the X Window System is used */ -#undef USE_X11 - -/* Enable automatic update system */ -#undef WITH_AUTOMATIC_UPDATE - -/* Developer mode */ -#undef WITH_DEVELOPER_MODE - -/* Glib */ -#undef WITH_GLIB - -/* Define to 1 if the X Window System is missing or not being used. */ -#undef X_DISPLAY_MISSING - -/* compile with debug options */ -#undef _DEBUG diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 615638f9b..000000000 --- a/configure.ac +++ /dev/null @@ -1,403 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -# Copyright (c) 2005-2011 Günther Brammer -# Copyright (c) 2005, 2008 Peter Wortmann -# Copyright (c) 2006 Julian Raschke -# Copyright (c) 2010 Armin Burgmeier -# Copyright (c) 2010 Martin Plicht -# Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de - -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. - -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -AC_PREREQ([2.67]) -AC_INIT([clonk], [5]) -AC_COPYRIGHT([©2005-2011 Günther Brammer]) -AC_CONFIG_SRCDIR([/src/C4Game.cpp]) -AC_CONFIG_AUX_DIR([autotools]) -AC_CONFIG_HEADER([config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CANONICAL_HOST -dnl foreign to tell automake to shut up, -dnl and subdir-objects because it makes the Makefile smaller. -dnl no-define because PACKAGE and VERSION are not used -AM_INIT_AUTOMAKE([foreign tar-ustar nostdinc no-define 1.10]) -m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) - -AC_PROG_CXX -AC_LANG([C++]) -AX_CHECK_COMPILE_FLAG([-std=gnu++0x], [CXX="${CXX} -std=gnu++0x"], []) -AC_COMPILE_IFELSE([ -void f(struct D&&); int main() { return 0; } -], [AC_DEFINE([HAVE_RVALUE_REF], [], [C++ Compiler has rvalue references, a C++0x feature.])], [AX_PROG_CXX_REFTOTEMP]) -AC_PROG_CC -AM_PROG_CC_C_O -AC_PROG_RANLIB - -case $host in - *-*-mingw32* | *-*-cygwin* | *-*-windows*) - win32=true; osx=false;; - *-*-darwin*) - win32=false; osx=true; - m4_ifdef([AC_PROG_OBJCXX], [AC_PROG_OBJCXX], [AC_MSG_ERROR([this configure script was created with an autoconf version older than 2.65 and does not support macosx.])]) - ;; - *) - win32=false; osx=false;; -esac - -# Detect Wine. Unfortunately, at the moment winegcc does not meet the demands -AC_CHECK_HEADER([windows.h], [win32=true], [], [[ ]]) - -AM_CONDITIONAL(WIN32, [test $win32 = true]) -AM_CONDITIONAL(MACOSX, [test $osx = true]) - -# various used headers -dnl the whitespace is there to prevent AC_INCLUDES_DEFAULT -AC_CHECK_HEADERS([stdint.h unistd.h poll.h sys/file.h sys/stat.h sys/types.h locale.h sys/socket.h signal.h langinfo.h sys/eventfd.h sys/timerfd.h sys/inotify.h], , , [[ ]]) -# Mingw does not ship with multimon.h -AC_CHECK_HEADERS([multimon.h io.h direct.h share.h natupnp.h], [], [], [[#include ]]) -# iconv -AX_ICONV -# vasprintf is a GNU extension -AC_CHECK_FUNCS(vasprintf) -# so is execinfo.h - and some systems have the header despite the functions not being in the c library -AC_CHECK_HEADER(execinfo.h) -if test "x$ac_cv_header_execinfo_h" = xyes; then - AC_CHECK_FUNC(backtrace, [], [ - AC_CHECK_LIB(execinfo, backtrace, [ - CLONK_LIBS="-lexecinfo $CLONK_LIBS" - ], [ - ac_cv_header_execinfo_h=no - ]) - ]) -fi -if test "x$ac_cv_header_execinfo_h" = xyes; then - AC_DEFINE(HAVE_EXECINFO_H, 1, [The backtrace function is declared in execinfo.h and works]) -fi - -AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug],[debugging options [default=no]])], - , [enable_debug=no]) -if test $enable_debug = yes; then - AC_DEFINE([_DEBUG], 1, [compile with debug options]) -else - AC_DEFINE([NDEBUG], 1, [compile without debug options]) -fi - -AC_ARG_ENABLE([debugrec], - [AS_HELP_STRING([--enable-debugrec],[write additional debug control to records [default=no]])], - , [enable_debugrec=no]) -if test $enable_debugrec = yes; then - AC_DEFINE([DEBUGREC], 1, [Activate DebugRecs]) -fi - -AC_ARG_ENABLE([console], - [AS_HELP_STRING([--enable-console],[compile as pure console application [default=no]])], - , [enable_console=no]) - -AC_ARG_ENABLE([sound], - [AS_HELP_STRING([--enable-sound],[compile with sound support [default=yes]])], - , [if test $enable_console = yes; then enable_sound=no; else if test $win32 = true; then enable_sound=no; else enable_sound=yes; fi; fi]) - -# GTK+ -GTK2_REQUIRED="glib-2.0 >= 2.8 gtk+-2.0 >= 2.8" -GTK3_REQUIRED="glib-2.0 >= 2.27.5 gtk+-3.0 >= 2.99.0" -PKG_PROG_PKG_CONFIG -AC_MSG_CHECKING([which gtk+ version to compile against]) -AC_ARG_WITH([gtk], - [AS_HELP_STRING([--with-gtk=2.0|3.0],[which gtk+ version to compile against [default: auto]])], - [case "$with_gtk" in - 2.0|3.0) ;; - no) ;; - *) AC_MSG_ERROR([invalid gtk version specified]) ;; - esac], - [AS_IF([test $enable_console = no], - [PKG_CHECK_EXISTS([$GTK3_REQUIRED], - [with_gtk=3.0], - [PKG_CHECK_EXISTS([$GTK2_REQUIRED], - [with_gtk=2.0], - [with_gtk=no])])], - [with_gtk=no])]) -AC_MSG_RESULT([$with_gtk]) -AS_IF([test $with_gtk != no],[ - case "$with_gtk" in - 2.0) GTK_REQUIRED="$GTK2_REQUIRED" - ;; - 3.0) GTK_REQUIRED="$GTK3_REQUIRED" - ;; - esac - PKG_CHECK_MODULES(GTK, [$GTK_REQUIRED]) - AC_DEFINE([WITH_GLIB], 1, [Glib]) - AC_DEFINE([WITH_DEVELOPER_MODE], 1, [Developer mode]) -]) -AM_CONDITIONAL(GTK, [test $with_gtk != no]) - -# OpenAL -AC_ARG_WITH([openal], - [AS_HELP_STRING([--with-openal],[compile with openal support [default=no]])], - , [with_openal=no]) -if test $with_openal = yes; then - PKG_CHECK_MODULES(OPENAL, [vorbis vorbisfile openal]) - AC_DEFINE([USE_OPEN_AL], 1, [OpenAL sound]) - if test $enable_sound = no; then - AC_MSG_ERROR([--with-openal cannot be used with --disable-sound.]) - fi -fi - -# SDL -with_sdl_mixer=no -AC_ARG_WITH([sdl], - AS_HELP_STRING([--with-sdl], [Use SDL @<:@default=yes (no for win32)@:>@]), - , [if test $win32 = true; then with_sdl=no; else if test $enable_console = yes; then with_sdl=no; else with_sdl=yes; fi fi]) -if test $with_sdl = yes; then - # Check for SDL - SDL_VERSION=1.2.0 - AM_PATH_SDL($SDL_VERSION, - [AC_DEFINE(HAVE_SDL, 1, [Define to 1 if you have SDL.])], - [AC_MSG_ERROR([libSDL not found.])]) - AC_SUBST(SDL_CFLAGS) - AC_SUBST(SDL_LIBS) - if test $enable_sound = yes && test $with_openal = no; then - # Check for SDL_mixer library - AC_CHECK_LIB(SDL_mixer, Mix_OpenAudio, - [AC_DEFINE(HAVE_LIBSDL_MIXER,1,[Define to 1 if you have SDL_mixer.]) - SDL_LIBS="-lSDL_mixer $SDL_LIBS" - with_sdl_mixer=yes], - [AC_MSG_ERROR([SDL_mixer not found.])], - [$SDL_LIBS]) - fi - AC_ARG_ENABLE(sdlmainloop, - [AS_HELP_STRING([--enable-sdlmainloop],[use SDL instead of X11 or Win32 [default=no]])], - , [if test $osx = true; then enable_sdlmainloop=yes; else enable_sdlmainloop=no; fi ]) -else - enable_sdlmainloop=no -fi -if test $enable_sdlmainloop = yes; then - with_x=no - AC_DEFINE(USE_SDL_MAINLOOP, 1, [Define to 1 if SDL is used for the main loop]) -fi -AM_CONDITIONAL(SDL_MAIN_LOOP, [test $enable_sdlmainloop = yes]) - -if test $enable_sound = yes; then - AC_ARG_ENABLE([mp3], - [AS_HELP_STRING([--enable-mp3],[enable mp3 support [default=no]])], - , [enable_mp3=no]) - if test $enable_mp3 = yes; then - AC_DEFINE([USE_MP3], 1, [MP3 music]) - fi -fi - -if test $enable_console = no; then - if test $win32 = true; then - AC_SUBST(WINDOWS_CFLAGS, "-mwindows") - fi -else - # console mode - AC_DEFINE([USE_CONSOLE], 1, [dedicated server mode]) - with_x=no - enable_sdlmainloop=no - VL_LIB_READLINE -fi - -# Check for boost -AX_BOOST_BASE([1.40.0], [], [ - AC_MSG_ERROR([Boost not found.]) -]) - -# Check for libjpeg -AC_CHECK_LIB(jpeg, jpeg_read_header, [ - CLONK_LIBS="-ljpeg $CLONK_LIBS" -], [ - AC_MSG_ERROR([libjpeg not found.]) -]) - -# Check for libpng -AC_CHECK_LIB(png, png_read_image, [ - CLONK_LIBS="-lpng $CLONK_LIBS" -], [ - AC_MSG_ERROR([libpng not found.]) -], [-lz]) - -# Check for libz -AC_CHECK_LIB(z, deflate, [ - Z_LIBS="-lz $Z_LIBS" -], [ - AC_MSG_ERROR([libz not found.]) -]) - -# Check for librt -AC_CHECK_LIB(rt, clock_gettime, [ - LDADD="-lrt $LDADD" -], []) - -# Check for libfreetype -if test $enable_console = no; then - PKG_CHECK_MODULES(FREETYPE, freetype2, ,[ - if test "$cross_compiling" = no; then - AC_CHECK_PROG(FREETYPE_CONFIG, freetype-config, freetype-config) - fi - if test $FREETYPE_CONFIG; then - AC_SUBST(FREETYPE_CFLAGS, [`$FREETYPE_CONFIG --cflags`]) - AC_SUBST(FREETYPE_LIBS, [`$FREETYPE_CONFIG --libs`]) - else - AC_MSG_ERROR([Freetype not found.]) - fi - ]) - AC_DEFINE(HAVE_FREETYPE, 1, [Define to 1 if you have FreeType2.]) -fi - -# X11, Xpm, Xrandr -AC_PATH_XTRA -if test $have_x = yes; then - AC_DEFINE(USE_X11, 1, [Define to 1 if the X Window System is used]) - CLONK_LIBS="$X_LIBS $CLONK_LIBS" - AC_CHECK_HEADERS([X11/keysym.h X11/extensions/xf86vmode.h X11/xpm.h X11/extensions/Xrandr.h], , - [AC_MSG_ERROR([A required X11 header was not found.])], [[#include ]]) - AC_CHECK_LIB(X11, XOpenDisplay, [CLONK_LIBS="-lX11 $CLONK_LIBS"], - [AC_MSG_ERROR([libX11 not found.])], [$X_LIBS]) - AC_CHECK_LIB(Xpm, XpmCreatePixmapFromData, [CLONK_LIBS="-lXpm $CLONK_LIBS"], - [AC_MSG_ERROR([libXpm not found.])], [$X_LIBS]) - AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryVersion, [CLONK_LIBS="-lXxf86vm $CLONK_LIBS"], - [AC_MSG_ERROR([XF86VidMode not found.])], [$X_LIBS]) - AC_CHECK_LIB(Xrandr, XRRQueryExtension, [CLONK_LIBS="-lXrandr $CLONK_LIBS"], - [AC_MSG_ERROR([libXrandr not found.])], [$X_LIBS]) -fi - -# OpenGL -AC_ARG_WITH([gl], - [AS_HELP_STRING([--with-gl],[compile with opengl support [default=yes]])], - , [if test $enable_console = yes; then with_gl=no; else with_gl=yes; fi]) -if test $with_gl = yes; then - if test $osx = true; then - CLONK_LIBS="-framework OpenGL $CLONK_LIBS" - AC_CHECK_LIB(GLEW, glewInit, [CLONK_LIBS="-lGLEW $CLONK_LIBS"], - [AC_MSG_ERROR([glew not found.])]) - elif test $win32 = true; then - AC_CHECK_LIB(opengl32, main, [CLONK_LIBS="-lopengl32 $CLONK_LIBS"], - [AC_MSG_ERROR([opengl32 not found.])]) - AC_CHECK_LIB(glu32, main, [CLONK_LIBS="-lglu32 $CLONK_LIBS"], - [AC_MSG_ERROR([glu32 not found.])]) - AC_CHECK_LIB(glew32, main, [CLONK_LIBS="-lglew32 $CLONK_LIBS"], - [AC_MSG_ERROR([glew not found.])]) - AC_SUBST([GLEW_CFLAGS],["-DGLEW_STATIC"]) - else - AC_CHECK_LIB(GL, glBegin, [CLONK_LIBS="-lGL $CLONK_LIBS"], - [AC_MSG_ERROR([libGL not found.])]) - AC_CHECK_LIB(GLU, gluOrtho2D, [CLONK_LIBS="-lGLU $CLONK_LIBS"], - [AC_MSG_ERROR([libGLU not found.])]) - AC_CHECK_LIB(GLEW, glewInit, [CLONK_LIBS="-lGLEW $CLONK_LIBS"], - [AC_MSG_ERROR([glew not found.])]) - fi - AC_DEFINE([USE_GL], 1, [OpenGL graphics]) -fi - -# DirectX -AC_ARG_WITH([directx], - [AS_HELP_STRING([--with-directx],[compile with directx support [default=no]])], - , [with_directx="no"]) -if test "$with_directx" = yes; then - AC_CHECK_LIB(d3d9, main, [CLONK_LIBS="-ld3d9 $CLONK_LIBS"], - [AC_MSG_ERROR([d3d9 not found.])]) - AC_DEFINE([USE_DIRECTX], 1, [DirectX graphics]) -fi - -# UPnP -AC_ARG_WITH([upnp], - [AS_HELP_STRING([--with-upnp],[compile with upnp support [default=no]])], - , [with_upnp=no]) -AS_IF([test $with_upnp = yes], [ - AM_CONDITIONAL(NATUPNP, [test "$ac_cv_header_natupnp_h" = yes]) - PKG_CHECK_MODULES(LIBUPNP, [libupnp], [have_libupnp=yes], [have_libupnp=no]) -], [ - AM_CONDITIONAL(NATUPNP, [false]) - have_libupnp=no -]) -AM_CONDITIONAL(LIBUPNP, [test "$have_libupnp" = yes]) - -# Automatic Update -AC_ARG_WITH([automatic-update], - [AS_HELP_STRING([--with-automatic-update],[enable support for automatic engine updates [default=yes]])], - , [with_automatic_update="yes"]) -if test "$with_automatic_update" = "yes"; then - AC_DEFINE([WITH_AUTOMATIC_UPDATE], 1, [Enable automatic update system]) -fi - -if test $win32 = false; then - # pthread - AX_PTHREAD( , [AC_MSG_ERROR([No pthread support.])]) - AC_SUBST(PTHREAD_LIBS) - AC_SUBST(PTHREAD_CFLAGS) - - # FMod is used for windows only - AM_CONDITIONAL(USE_FMOD, false) -else - # Windows - for WIN32LIB in gdi32 comdlg32 ws2_32 - do - AC_CHECK_LIB([$WIN32LIB], main, [CLONK_LIBS="-l$WIN32LIB $CLONK_LIBS"], [AC_MSG_ERROR([$WIN32LIB not found.])]) - done - - AC_CHECK_LIB([winmm], main, [LDADD="-lwinmm $LDADD"], [AC_MSG_ERROR([winmm not found.])]) - - AC_CHECK_LIB([vfw32], main, [ - CLONK_LIBS="-lvfw32 $CLONK_LIBS" - AC_DEFINE([HAVE_VFW32], 1, [ ]) - ], []) - - # FMod (Library comes with standard) - if test "$enable_sound" = yes; then - AC_DEFINE([USE_FMOD], 1, [Whether FMOD shall be used]) - fi - AM_CONDITIONAL(USE_FMOD, test "$enable_sound" = yes) - - # windres - AC_CHECK_TOOL(WINDRES, windres, no) - if test $WINDRES = no; then - AC_MSG_ERROR([windres not found.]) - fi -fi - -AC_SUBST(LDADD) -AC_SUBST(CLONK_LIBS) -AC_SUBST(Z_LIBS) - -# precompiled headers and -Wextra -AC_MSG_CHECKING([whether we are using a GNU C++ compiler version 4.1 or newer]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#if defined(__GNUC__) && (((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)) -// all ok -#else - choke me -#endif -]])], RECENT_GCC="yes", RECENT_GCC="no") -AC_MSG_RESULT([$RECENT_GCC]) -AM_CONDITIONAL(RECENT_GCC, [test $RECENT_GCC = yes]) - -AC_OUTPUT - -echo "Configuration: - Debug: $enable_debug - Debugrec: $enable_debugrec - Pure console: $enable_console - DirectX: $with_directx - OpenGL: $with_gl - Sound: $enable_sound - SDL_Mixer: $with_sdl_mixer - OpenAL: $with_openal - GTK+: $with_gtk - X11: $have_x - Nat/LibUPnP: $ac_cv_header_natupnp_h/$have_libupnp - CFLAGS: $CFLAGS - CXXFLAGS: $CXXFLAGS" - -if test "$enable_sdlmainloop" = yes; then echo " SDL: mainloop"; -else echo " SDL: $with_sdl"; fi - diff --git a/docs/Makefile b/docs/Makefile index 514ef1719..dccb4b310 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,8 +1,15 @@ -# Notable targets: -# all (default): German and English onlinedocs -# online-en: only English onlinedocs, which can be partially updated -# Enwickler.chm: the German offline doc -# use with make Entwickler.chm HHC = /path/to/hhc +# German and English online docs: +# make all +# make install prefix=/path/to/webspace +# The offline docs: +# make chm HHC=/path/to/hhc.exe + +# Only English online docs, which can be partially updated: +# make online-en +# The English offline doc: +# make chm/en/Developer.chm HHC=/path/to/hhc.exe +# XML syntax check: +# make check # Extra Parameters for xsltproc can be given in the XSLTFLAGS variable. # Use prefix to select the directory where the docs are to be installed @@ -20,13 +27,13 @@ stylesheet = clonk.xsl # find all directories neither beginning nor contained within a directory beginning with a dot sdk-dirs := $(shell find sdk -name '.*' -prune -o -type d -print) +# find all *.xml files recursively in sdk/ +xmlfiles := $(sort $(shell find sdk -name '.*' -prune -o -name 'content.xml' -prune -o -name \*.xml -print)) + # misc extra-files := $(sort $(wildcard *.css *.php *.js images/*.*)) extra-files-chm := $(sort $(wildcard *.css *.js images/*.*)) -# find all *.xml files recursively in sdk/ -xmlfiles := $(sort $(shell find sdk -name '.*' -prune -o -name 'content.xml' -prune -o -name \*.xml -print)) - # Targets: # strip from all files the .xml, and add a .html @@ -36,8 +43,8 @@ htmlfiles := $(addsuffix .html, $(basename $(xmlfiles))) sdk-de-dirs := $(subst sdk, sdk-de, $(sdk-dirs)) # For openclonk.org -online-sdk-files := $(foreach lang, en de, $(addprefix online/$(lang)/, $(htmlfiles) sdk/content.html)) online-dirs := $(foreach lang, en de, $(addprefix online/$(lang)/, $(sdk-dirs) images)) +online-sdk-files := $(foreach lang, en de, $(addprefix online/$(lang)/, $(htmlfiles) sdk/content.html)) online-extra-files := $(foreach lang, en de, $(addprefix online/$(lang)/, $(extra-files))) # For Entwickler.chm @@ -45,21 +52,21 @@ chm-dirs := $(foreach lang, en de, $(addprefix chm/$(lang)/, . $(sdk-dirs) image .PHONY: all online-en chm install check clean -all: $(online-dirs) $(sdk-de-dirs) $(online-extra-files) $(online-sdk-files) +all: $(sdk-de-dirs) $(online-dirs) $(online-sdk-files) $(online-extra-files) online-en: $(addprefix online/en/, $(sdk-dirs) images $(htmlfiles) sdk/content.html $(extra-files)) -chm: $(chm-dirs) $(sdk-de-dirs) chm/en/Developer.chm chm/de/Entwickler.chm +chm: $(sdk-de-dirs) $(chm-dirs) chm/en/Developer.chm chm/de/Entwickler.chm install: all $(MKDIR_P) $(prefix) - $(CP_R) $(PWD)/online/* $(prefix) + $(CP_R) online/* $(prefix) check: - xmllint --noblanks --noout --valid $(xmlfiles) + @xmllint --noblanks --noout --valid $(xmlfiles) clean: - rm -f *.mo Entwickler.chm Developer.chm doku.pot + rm -f *.mo Entwickler.chm Developer.chm doku.pot sdk/content.xml rm -rf online sdk-de chm sdk/content.xml: sdk/content.xml.in $(xmlfiles) build_contents.py experimental.py @@ -122,7 +129,7 @@ $(addprefix chm/de/, $(extra-files-chm)): chm/de/%: % $(CP) $< $@ chm/en/Developer.chm: chm/en/Output.hhp chm/en/Output.hhk chm/en/Output.hhc $(addprefix chm/en/, $(sdk-dirs) images $(htmlfiles) $(extra-files-chm)) - "$(HHC)" $< + ! "$(HHC)" $< chm/de/Entwickler.chm: chm/de/Output.hhp chm/de/Output.hhk chm/de/Output.hhc $(addprefix chm/de/, $(sdk-dirs) images $(htmlfiles) $(extra-files-chm)) - "$(HHC)" $< + ! "$(HHC)" $< diff --git a/docs/README.cygwin.txt b/docs/README.cygwin.txt index 816d3030f..997eeed0c 100644 --- a/docs/README.cygwin.txt +++ b/docs/README.cygwin.txt @@ -4,7 +4,7 @@ This section explains how to build the German and English HTML-documentation fro In Linux, it should be as easy as: Open the console and run make in this directory. -In Windows, you ned Python and Cygwin. During the Cygwin installation, select these additional libraries to install: +In Windows, you need Python and Cygwin. During the Cygwin installation, select these additional libraries to install: + make + xsltproc (libxml2 + libxslt + python-libxml2) + findutils @@ -12,7 +12,8 @@ In Windows, you ned Python and Cygwin. During the Cygwin installation, select th + gettext + gettext-devel + libgcrypt + libgpg-error (for whatever reason) -Also you might have to rename find.exe, so that the cygwin provided one is used - first in Windows\System32\dllback then in Windows\System32 to make sure it isn't used. -After the installation, run cygwin, cd to this directory (/cygdrive/c/.../openclonk/docs/) and run make. The process takes about ten minutes to complete. -The online version of the documentation has been generated into the online/ directory. \ No newline at end of file +After the installation, run cygwin, cd to this directory (/cygdrive/c/.../openclonk/docs/) and run make. The process takes a few minutes to complete. +The online version of the documentation has been generated into the online/ directory. + +To build the .chm files, install the html help compiler from http://www.microsoft.com/en-us/download/details.aspx?id=21138 or http://go.microsoft.com/fwlink/?LinkId=14188 and run make chm HHC=/path/to/hhc.exe diff --git a/docs/build_contents.py b/docs/build_contents.py index 6ed6110bf..06477aa35 100644 --- a/docs/build_contents.py +++ b/docs/build_contents.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import sys import xml.sax +from xml.sax.saxutils import escape, quoteattr import experimental class ClonkEntityResolver(xml.sax.handler.EntityResolver): @@ -125,11 +126,11 @@ class Clonkparser(xml.sax.handler.ContentHandler): def printfunctions(f, _): def folder(name): - f.write("
  • " + name + "\n
      \n") + f.write("
    • " + escape(name) + "\n
        \n") def sheet(url, name): - f.write("
      • " + name + "
      • \n") + f.write("
      • " + escape(name) + "
      • \n") def sheetE(url, name): - f.write("
      • " + name + " (extended)
      • \n") + f.write("
      • " + escape(name) + " (extended)
      • \n") folder("Functions by Category") cats = parser.cats.keys() cats.sort() @@ -153,9 +154,9 @@ def printfunctions(f, _): def printindex(f, _): def folder(name): - f.write("
      • " + name + "\n
          \n") + f.write("
        • " + escape(name) + "\n
            \n") def sheet(url, name): - f.write("
          • " + name.replace('&', '&').replace('<', '<').replace('>', '>') + "
          • \n") + f.write("
          • " + escape(name) + "
          • \n") folder("Index") titles = parser.files.keys() titles.sort(key=unicode.lower) diff --git a/docs/clonk.dtd b/docs/clonk.dtd index a09cc80b6..b64b014c5 100644 --- a/docs/clonk.dtd +++ b/docs/clonk.dtd @@ -23,58 +23,68 @@ - + + + + - + - - + + + + + + id CDATA #IMPLIED> + id CDATA #IMPLIED> - + - + - + + + id CDATA #IMPLIED> - - - + alt CDATA #IMPLIED + class CDATA #IMPLIED + width CDATA #IMPLIED + height CDATA #IMPLIED + id CDATA #IMPLIED> -
            - - - -
            + +
            + + + +
            +
            @@ -514,7 +516,7 @@ - + diff --git a/docs/de.po b/docs/de.po index 775031ac7..3e3129239 100644 --- a/docs/de.po +++ b/docs/de.po @@ -4,14 +4,15 @@ # Sven2 # Armin Burgmeier , 2010. # Benedict Etzel , 2011. -# Günther Brammer , 2009, 2010, 2011. +# Nicolas Hake , 2013. +# Günther Brammer , 2009, 2010, 2011, 2012, 2013. # msgid "" msgstr "" "Project-Id-Version: OpenClonk documentation\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-09 19:12+0100\n" -"PO-Revision-Date: 2011-09-07 15:52+0200\n" +"POT-Creation-Date: 2013-02-24 14:39+0100\n" +"PO-Revision-Date: 2013-02-24 14:38+0100\n" "Last-Translator: Günther Brammer \n" "Language-Team: German <>\n" "Language: German\n" @@ -129,7 +130,7 @@ msgid "CNAT - Contact Attachment" msgstr "CNAT - Contact Attachment" #: sdk/content.xml.in:75(emlink) -#: sdk/definition/script.xml:20(h) +#: sdk/definition/script.xml:18(h) #: sdk/definition/index.xml:16(emlink) #: sdk/definition/actmap.xml:6(title) #: sdk/definition/actmap.xml:7(h) @@ -150,6 +151,7 @@ msgstr "Scripte" #: sdk/content.xml.in:81(emlink) #: sdk/script/fn/SetProperty.xml:9(subcat) #: sdk/script/fn/GetProperty.xml:9(subcat) +#: sdk/script/fn/GetProperties.xml:9(subcat) #: sdk/particle/index.xml:161(h) #: sdk/definition/properties.xml:6(title) #: sdk/definition/properties.xml:7(h) @@ -209,16 +211,19 @@ msgstr "Steuerung" #: sdk/script/fn/_inherited.xml:8(category) #: sdk/script/fn/WildcardMatch.xml:8(category) #: sdk/script/fn/Translate.xml:8(category) +#: sdk/script/fn/SortArrayByProperty.xml:8(category) +#: sdk/script/fn/SortArrayByArrayElement.xml:8(category) +#: sdk/script/fn/SortArray.xml:8(category) #: sdk/script/fn/SetLength.xml:8(category) #: sdk/script/fn/ScheduleCall.xml:8(category) #: sdk/script/fn/Schedule.xml:8(category) #: sdk/script/fn/Par.xml:8(category) #: sdk/script/fn/GetLength.xml:8(category) +#: sdk/script/fn/GetIndexOf.xml:8(category) #: sdk/script/fn/GetChar.xml:8(category) #: sdk/script/fn/GameCallEx.xml:8(category) #: sdk/script/fn/GameCall.xml:8(category) #: sdk/script/fn/Format.xml:8(category) -#: sdk/script/fn/DefinitionCall.xml:8(category) #: sdk/script/fn/CreateArray.xml:8(category) #: sdk/script/fn/ClearScheduleCall.xml:8(category) #: sdk/script/fn/Call.xml:8(category) @@ -364,18 +369,18 @@ msgstr "Operator" #: sdk/scenario/scenario.xml:96(col) #: sdk/scenario/scenario.xml:126(col) #: sdk/scenario/scenario.xml:186(col) -#: sdk/scenario/scenario.xml:341(col) -#: sdk/scenario/scenario.xml:361(col) -#: sdk/scenario/scenario.xml:406(col) -#: sdk/scenario/scenario.xml:421(col) +#: sdk/scenario/scenario.xml:346(col) +#: sdk/scenario/scenario.xml:366(col) +#: sdk/scenario/scenario.xml:401(col) +#: sdk/scenario/scenario.xml:416(col) #: sdk/scenario/Teams.xml:15(col) #: sdk/scenario/Teams.xml:74(col) #: sdk/scenario/MapCreatorS2.xml:34(col) -#: sdk/playercontrols.xml:23(col) +#: sdk/playercontrols.xml:22(col) #: sdk/playercontrols.xml:84(col) -#: sdk/playercontrols.xml:128(col) -#: sdk/playercontrols.xml:142(col) -#: sdk/playercontrols.xml:173(col) +#: sdk/playercontrols.xml:144(col) +#: sdk/playercontrols.xml:177(col) +#: sdk/playercontrols.xml:229(col) #: sdk/particle/index.xml:32(col) #: sdk/material/ocm.xml:16(col) #: sdk/material/ocm.xml:230(col) @@ -384,11 +389,11 @@ msgstr "Operator" #: sdk/folder/foldermap.xml:46(col) #: sdk/folder/foldermap.xml:71(col) #: sdk/definition/visibility.xml:19(col) -#: sdk/definition/script.xml:36(col) +#: sdk/definition/script.xml:34(col) #: sdk/definition/properties.xml:26(col) #: sdk/definition/procedures.xml:13(col) #: sdk/definition/defcore.xml:16(col) -#: sdk/definition/defcore.xml:406(col) +#: sdk/definition/defcore.xml:361(col) #: sdk/definition/cnat.xml:15(col) #: sdk/definition/category.xml:14(col) #: sdk/definition/actmap.xml:16(col) @@ -546,6 +551,9 @@ msgstr "Potenziert zwei Werte" #: sdk/script/operatoren.xml:236(col) #: sdk/script/operatoren.xml:243(col) #: sdk/script/operatoren.xml:250(col) +#: sdk/script/operatoren.xml:257(col) +#: sdk/script/operatoren.xml:264(col) +#: sdk/script/operatoren.xml:271(col) msgid "postfix" msgstr "postfix" @@ -557,9 +565,9 @@ msgstr "postfix" #: sdk/script/operatoren.xml:118(col) #: sdk/script/operatoren.xml:125(col) #: sdk/script/operatoren.xml:132(col) -#: sdk/script/operatoren.xml:181(col) -#: sdk/script/operatoren.xml:188(col) #: sdk/script/operatoren.xml:195(col) +#: sdk/script/operatoren.xml:202(col) +#: sdk/script/operatoren.xml:209(col) msgid "int, int/int" msgstr "int, int/int" @@ -675,6 +683,8 @@ msgstr "gibt zurück, ob der erste Wert größer oder gleich dem zweiten ist." #: sdk/script/operatoren.xml:163(col) #: sdk/script/operatoren.xml:170(col) +#: sdk/script/operatoren.xml:177(col) +#: sdk/script/operatoren.xml:184(col) msgid "9l" msgstr "9l" @@ -688,6 +698,8 @@ msgstr "gibt zurück, ob zwei Werte gleich sind" #: sdk/script/operatoren.xml:167(col) #: sdk/script/operatoren.xml:174(col) +#: sdk/script/operatoren.xml:181(col) +#: sdk/script/operatoren.xml:188(col) msgid "bool, any/any" msgstr "bool, any/any" @@ -699,244 +711,289 @@ msgstr "!=" msgid "Returns whether a is unequal to b." msgstr "gibt zurück, ob zwei Werte nicht gleich sind." -#: sdk/script/operatoren.xml:177(col) +#: sdk/script/operatoren.xml:178(col) +msgid "===" +msgstr "===" + +#: sdk/script/operatoren.xml:179(col) +msgid "Returns whether a and b refer to the same thing." +msgstr "gibt zurück, ob a und b dasselbe (nicht nur das gleiche) sind." + +#: sdk/script/operatoren.xml:185(col) +msgid "!==" +msgstr "!==" + +#: sdk/script/operatoren.xml:186(col) +msgid "Returns whether a and b do not refer to the same thing." +msgstr "gibt zurück, ob a und b nicht dasselbe sind." + +#: sdk/script/operatoren.xml:191(col) msgid "8l" msgstr "8l" -#: sdk/script/operatoren.xml:178(col) +#: sdk/script/operatoren.xml:192(col) msgid "&" msgstr "&" -#: sdk/script/operatoren.xml:179(col) +#: sdk/script/operatoren.xml:193(col) msgid "Performs a bitwise AND operation." msgstr "führt ein bitweises And aus" -#: sdk/script/operatoren.xml:184(col) -#: sdk/script/operatoren.xml:191(col) +#: sdk/script/operatoren.xml:198(col) +#: sdk/script/operatoren.xml:205(col) msgid "6l" msgstr "6l" -#: sdk/script/operatoren.xml:185(col) +#: sdk/script/operatoren.xml:199(col) msgid "^" msgstr "^" -#: sdk/script/operatoren.xml:186(col) +#: sdk/script/operatoren.xml:200(col) msgid "Performs a bitwise XOR operation." msgstr "führt ein bitweises XOr aus" -#: sdk/script/operatoren.xml:192(col) +#: sdk/script/operatoren.xml:206(col) msgid "|" msgstr "|" -#: sdk/script/operatoren.xml:193(col) +#: sdk/script/operatoren.xml:207(col) msgid "Performs a bitwise OR operation." msgstr "führt ein bitweises Or aus" -#: sdk/script/operatoren.xml:198(col) +#: sdk/script/operatoren.xml:212(col) msgid "5l" msgstr "5l" -#: sdk/script/operatoren.xml:199(col) +#: sdk/script/operatoren.xml:213(col) msgid "&&" msgstr "&&" -#: sdk/script/operatoren.xml:200(col) +#: sdk/script/operatoren.xml:214(col) msgid "Performs a logical AND operation." msgstr "führt ein logisches And aus" -#: sdk/script/operatoren.xml:202(col) -#: sdk/script/operatoren.xml:209(col) -msgid "any, any/any" -msgstr "any, any/any" - -#: sdk/script/operatoren.xml:205(col) -msgid "4l" -msgstr "4l" - -#: sdk/script/operatoren.xml:206(col) -msgid "||" -msgstr "||" - -#: sdk/script/operatoren.xml:207(col) -msgid "Performs a logical OR operation." -msgstr "führt ein logisches Or aus" - -#: sdk/script/operatoren.xml:212(col) -#: sdk/script/operatoren.xml:219(col) -#: sdk/script/operatoren.xml:226(col) -#: sdk/script/operatoren.xml:233(col) -#: sdk/script/operatoren.xml:240(col) -#: sdk/script/operatoren.xml:247(col) -msgid "2r" -msgstr "2r" - -#: sdk/script/operatoren.xml:213(col) -msgid "*=" -msgstr "*=" - -#: sdk/script/operatoren.xml:214(col) -msgid "Multiplies the preceeding variables by the following value." -msgstr "vervielfacht die vorangestellte Variable mit dem nachgestellten Wert" - #: sdk/script/operatoren.xml:216(col) #: sdk/script/operatoren.xml:223(col) #: sdk/script/operatoren.xml:230(col) +msgid "any, any/any" +msgstr "any, any/any" + +#: sdk/script/operatoren.xml:219(col) +msgid "4l" +msgstr "4l" + +#: sdk/script/operatoren.xml:220(col) +msgid "||" +msgstr "||" + +#: sdk/script/operatoren.xml:221(col) +msgid "Performs a logical OR operation." +msgstr "führt ein logisches Or aus" + +#: sdk/script/operatoren.xml:226(col) +msgid "3l" +msgstr "3l" + +#: sdk/script/operatoren.xml:227(col) +msgid "??" +msgstr "??" + +#: sdk/script/operatoren.xml:228(col) +msgid "Returns the left-hand operand if the operand is not nil, or the right-hand operand otherwise." +msgstr "Gibt den rechten Operanden zurück wenn der linke Operand nil ist, ansonsten den linken Operanden." + +#: sdk/script/operatoren.xml:233(col) +#: sdk/script/operatoren.xml:240(col) +#: sdk/script/operatoren.xml:247(col) +#: sdk/script/operatoren.xml:254(col) +#: sdk/script/operatoren.xml:261(col) +#: sdk/script/operatoren.xml:268(col) +msgid "2r" +msgstr "2r" + +#: sdk/script/operatoren.xml:234(col) +msgid "*=" +msgstr "*=" + +#: sdk/script/operatoren.xml:235(col) +msgid "Multiplies the preceeding variables by the following value." +msgstr "vervielfacht die vorangestellte Variable mit dem nachgestellten Wert" + #: sdk/script/operatoren.xml:237(col) #: sdk/script/operatoren.xml:244(col) +#: sdk/script/operatoren.xml:251(col) +#: sdk/script/operatoren.xml:258(col) +#: sdk/script/operatoren.xml:265(col) msgid "reference, reference/int" msgstr "Referenz, Referenz/int" -#: sdk/script/operatoren.xml:220(col) +#: sdk/script/operatoren.xml:241(col) msgid "/=" msgstr "/=" -#: sdk/script/operatoren.xml:221(col) +#: sdk/script/operatoren.xml:242(col) msgid "Divides the preceeding variable by the following value." msgstr "teilt den Wert der vorangestellten Variable durch den nachgestellten Wert" -#: sdk/script/operatoren.xml:227(col) +#: sdk/script/operatoren.xml:248(col) msgid "%=" msgstr "%=" -#: sdk/script/operatoren.xml:228(col) +#: sdk/script/operatoren.xml:249(col) msgid "Sets the preceeding variable to the remainder of the devision of that variable by the following value." msgstr "Schreibt den Divisionrest der Division des Wertes vorangestellten Variable mit dem nachgestellten Wert in die Variable" -#: sdk/script/operatoren.xml:234(col) +#: sdk/script/operatoren.xml:255(col) msgid "+=" msgstr "+=" -#: sdk/script/operatoren.xml:235(col) +#: sdk/script/operatoren.xml:256(col) msgid "Increases the preceeding variable by the following value." msgstr "erhöht die vorangestellte Variable um den nachgestellten Wert" -#: sdk/script/operatoren.xml:241(col) +#: sdk/script/operatoren.xml:262(col) msgid "-=" msgstr "-=" -#: sdk/script/operatoren.xml:242(col) +#: sdk/script/operatoren.xml:263(col) msgid "Decreases the preeceding variable by the following value." msgstr "vermindert den Wert der vorangestellten Variable um den nachgestellten Wert" -#: sdk/script/operatoren.xml:248(col) +#: sdk/script/operatoren.xml:269(col) msgid "=" msgstr "=" -#: sdk/script/operatoren.xml:249(col) +#: sdk/script/operatoren.xml:270(col) msgid "Assigns the following value to the preceeding variable." msgstr "weist der vorangestellten Variable den nachgestellten Wert zu" -#: sdk/script/operatoren.xml:251(col) +#: sdk/script/operatoren.xml:272(col) msgid "reference, reference/any" msgstr "Referenz, Referenz/any" -#: sdk/script/operatoren.xml:255(h) +#: sdk/script/operatoren.xml:276(h) msgid "Explanation and examples:" msgstr "Erklärungen und Beispiele:" -#: sdk/script/operatoren.xml:257(h) +#: sdk/script/operatoren.xml:278(h) msgid "Postfix or prefix?" msgstr "Postfix oder prefix?" -#: sdk/script/operatoren.xml:259(text) +#: sdk/script/operatoren.xml:280(text) msgid "This property of an operator determines whether it is used before (pre) or after (post) its parameter." msgstr "Diese Eigenschaft eines Operators gibt an, ob er vor(pre) oder nach(post) seinem ersten Parameter steht." -#: sdk/script/operatoren.xml:260(text) +#: sdk/script/operatoren.xml:281(text) msgid "Prefix operators only have one parameter while postfix operators usually have two parameters (one preceeding and one following). See also operators ++/--." msgstr "Prefix - Operatoren haben immer nur einen Parameter (nach dem Operator), während Postfix - Operatoren in der Regel 2 Parameter haben, einen vor und einen danach. (siehe auch Operatoren ++/--)" -#: sdk/script/operatoren.xml:261(h) +#: sdk/script/operatoren.xml:282(h) msgid "Example 1:" msgstr "Beispiel 1:" -#: sdk/script/operatoren.xml:265(h) -#: sdk/script/operatoren.xml:274(h) +#: sdk/script/operatoren.xml:286(h) +#: sdk/script/operatoren.xml:295(h) #: sdk/script/BreakContinue.xml:25(h) msgid "Output:" msgstr "Ausgabe:" -#: sdk/script/operatoren.xml:269(text) +#: sdk/script/operatoren.xml:290(text) msgid "Addition, subtraction, multiplication, division, and similar form the group of postfix operators. They combine the two values preceeding and following the operator." msgstr "Plus, Minus, Multiplikation u.ä. Operatoren bilden die Klasse der Postfix - Operatoren. Es werden jeweils zwei Werte (die vor bzw. nach dem Operator stehen) verrechnet." -#: sdk/script/operatoren.xml:270(h) +#: sdk/script/operatoren.xml:291(h) msgid "Example 2:" msgstr "Beispiel 2:" -#: sdk/script/operatoren.xml:278(text) +#: sdk/script/operatoren.xml:299(text) msgid "Prefix operators are located before the value to which they are applied." msgstr "Bei diesen Operatoren handelt es sich um sogenannte Prefix - Operatoren. Sie stehen jeweils vor dem zu verarbeitenden Wert." -#: sdk/script/operatoren.xml:280(h) +#: sdk/script/operatoren.xml:301(h) msgid "Operators ++ and --" msgstr "Die Operatoren ++ und --" -#: sdk/script/operatoren.xml:282(text) +#: sdk/script/operatoren.xml:303(text) msgid "Operators ++ and -- exist as both postfix and prefix operators. The postfix version of these operators does not have a second parameter." msgstr "Die Operatoren ++ bzw. -- existierten sowohl als postfix- als auch als prefix-Operatoren. Dabei haben die postfix-Varianten noch die Besonderheit, dass sie keinen nachgestellten Wert benötigen." -#: sdk/script/operatoren.xml:283(h) +#: sdk/script/operatoren.xml:304(h) msgid "Example 1 (postfix):" msgstr "Beispiel: (postfix)" -#: sdk/script/operatoren.xml:285(strong) +#: sdk/script/operatoren.xml:306(strong) msgid "somevar++" msgstr "somevar++" -#: sdk/script/operatoren.xml:287(h) +#: sdk/script/operatoren.xml:308(h) msgid "Example 2 (prefix):" msgstr "Beispiel 2: (prefix)" -#: sdk/script/operatoren.xml:289(strong) +#: sdk/script/operatoren.xml:310(strong) msgid "++somevar" msgstr "++somevar" -#: sdk/script/operatoren.xml:291(text) +#: sdk/script/operatoren.xml:312(text) msgid "These two examples are almost identical. In both cases the value of somevar is increased by one per loop repetition. The result is compared to 10 in each case." msgstr "Diese beiden Beispiele sind fast identisch. In jedem Fall wird bei jeder Schleifenwiederholung somevar um 1 erhöht. Das Ergebnis wird jeweils mit 10 verglichen." -#: sdk/script/operatoren.xml:292(text) +#: sdk/script/operatoren.xml:313(text) msgid "Yet there is an important difference between the two versions: when using the postfix version, the previous value of the variable is returned. The first example will result in a count from 1 to 10, since at beginning of the last loop repetition is value of somevar is 9. It is then increased by one (somevar is now 10) but the previous value of 9 is returned and compared to 10. Thus the loop will be repeated one more time and then the value of 10 is printed." msgstr "Doch eine wichtige Feinheit unterscheidet die beiden Operatorenvarianten: wird der postfix-Operator benutzt, so wird jeweils alte Wert der Variable zurückgegeben. D.h. das Ergebnis der Schleife im 1. Beispiel wäre eine Zahlenreihe von 1 bis 10. Denn bei dem letzten Schleifendurchlauf ist somevar am Anfang 9. Dann wird sie um eins erhöht (somevar ist dann 10), es wird aber der alte Wert (9) zurückgegeben und mit der 10 verglichen. Die Schleife wird also ein weiteres Mal durchlaufen, und es wird der Wert 10 ausgegeben." -#: sdk/script/operatoren.xml:293(text) +#: sdk/script/operatoren.xml:314(text) msgid "In the second example, on the other hand, the loop runs from 1 to 9. When somevar is 9 and is increased, the new value of 10 is returned immediately. The result is not less than 10 and the loop ends." msgstr "Anders beim 2. Beispiel. Hier läuft die Schleife von 1 bis 9. Denn wenn somevar 9 ist und erhöht wird, so wird der neue Wert, eben 10, zurückgegeben. Dieser Wert ist nicht kleiner als 10, deshalb wird die Schleife abgebrochen." -#: sdk/script/operatoren.xml:295(h) -msgid "The Operators && and ||" -msgstr "Die Operatoren && und ||" +#: sdk/script/operatoren.xml:316(h) +msgid "The Short-Circuiting Operators &&, || and ??" +msgstr "Die Operatoren &&, || und ??" -#: sdk/script/operatoren.xml:297(text) -msgid "These two operators are special. If the result can be determined by the first parameter alone, the second parameter is not computed at all. For example, this script does not explode an object, because the overall result would be false, regardless of the result of Explode:" -msgstr "Diese beiden Operatoren haben eine Besonderheit. Wenn das Ergebnis bereits nach Auswertung des ersten Parameter feststeht, wird der zweite Parameter gar nicht erst ausgewertet. Beispielsweise explodiert ein Objekt durch dieses Script nicht, weil das Ergebnis 0 wäre, egal was Explode zurücklieferte:" +#: sdk/script/operatoren.xml:318(text) +msgid "These operators are special. If the result can be determined by the first parameter alone, the second parameter is not computed at all. For example, this script does not explode an object, because the overall result would be false, regardless of the result of Explode:" +msgstr "Diese Operatoren haben eine Besonderheit. Wenn das Ergebnis bereits nach Auswertung des ersten Parameter feststeht, wird der zweite Parameter gar nicht erst ausgewertet. Beispielsweise explodiert ein Objekt durch dieses Script nicht, weil das Ergebnis false wäre, egal was Explode zurücklieferte:" -#: sdk/script/operatoren.xml:299(text) +#: sdk/script/operatoren.xml:320(text) msgid "Further, the result is the value of the first or second parameter, depending on whether one or both were evaluated. For example, one can create a knight if possible or else a Clonk:" msgstr "Außerdem ist das Ergebnis des Operators der Wert des ersten oder zweiten Parameters, je nachdem ob einer oder beide ausgewertet wurden. Beispielsweise kann man so wenn möglich einen Ritter, und ansonsten einen Clonk erzeugen:" -#: sdk/script/operatoren.xml:302(h) +#: sdk/script/operatoren.xml:323(h) +msgid "The operator ??" +msgstr "Der Operator ??." + +#: sdk/script/operatoren.xml:325(text) +msgid "The ?? operator is called the nil-coalescing operator. It can be used to specify a default value for an expression or function call that may evaluate to nil." +msgstr "Der ??-Operator kann logisches definiert-oder genannt werden. Er ist nützlich um einen Default-Wert für einen Ausdruck oder Funktionsaufruf anzugeben, wenn dieser nil ergeben könnte." + +#: sdk/script/operatoren.xml:327(h) +msgid "The equality operators ==, !=, === and !==" +msgstr "Die Gleichheits-Operatoren ==, !=, === und !==" + +#: sdk/script/operatoren.xml:329(text) +msgid "The shorter operators basically consider more things equal. For example, two arrays with the same contents are equal, but === only returns true when both sides of the operator contain the same array. This matters mostly when arrays or proplists are modified. Modification can change the return value of the ==/!= operators, but not of the ===/!== operators." +msgstr "Kurzgefasst betrachten die kürzeren Operatoren mehr Dinge als gleich. Zum Beispiel sind zwei Arrays mit dem gleichen Inhalt für == gleich, aber für === nur, wenn auf beiden Seiten des Operators dasselbe Array steht. Dies spielt hauptsächlich dann eine Rolle, wenn Arrays oder Proplisten geändert werden." + +#: sdk/script/operatoren.xml:331(h) msgid "Priority and Associating" msgstr "Prioritäten und Assoziativität" -#: sdk/script/operatoren.xml:304(text) +#: sdk/script/operatoren.xml:333(text) msgid "This subject shows how operator priority is evaluated in detail." msgstr "Dieses Thema ist nicht unbedingt zum Verständnis der Operatoren vonnöten. Es soll nur zeigen, wie die Mechanismen wie Punkt-vor-Strich u.ä. im Detail funktionieren." -#: sdk/script/operatoren.xml:305(text) +#: sdk/script/operatoren.xml:334(text) msgid "To calculate the result of a complex term, first we have to decide in which order to evaluate the individual operations and to which other operator the result is to be passed." msgstr "Um einen längeren Ausdruck mit mehreren Operatoren ausrechnen zu können, muss entschieden werden, in welcher Reinfolge die Operatoren ausgeführt werden und welches Ergebnis welchem anderem Operator zu übergeben ist." -#: sdk/script/operatoren.xml:306(text) +#: sdk/script/operatoren.xml:335(text) msgid "Generally, operators with a higher priority are evaluate before operators with a lower priority. Notice: this does not apply to the evaluation of parameters - those are normally evaluated from left to right." msgstr "Allgemein gilt: Operatoren mit höherer Priorität werden vor Operatoren mit niedriger Priorität ausgeführt. Anmerkung: das gilt nicht für die Reihenfolge der Ausführung der Parameter. Diese werden ganz \"normal\" von links nach rechts ausgeführt." -#: sdk/script/operatoren.xml:307(h) -#: sdk/script/operatoren.xml:312(h) -#: sdk/script/operatoren.xml:334(h) -#: sdk/script/operatoren.xml:460(h) -#: sdk/script/operatoren.xml:587(h) +#: sdk/script/operatoren.xml:336(h) +#: sdk/script/operatoren.xml:341(h) +#: sdk/script/operatoren.xml:363(h) +#: sdk/script/operatoren.xml:489(h) +#: sdk/script/operatoren.xml:616(h) #: sdk/script/ScriptPlayers.xml:14(text) #: sdk/script/NamedVar.xml:40(h) #: sdk/script/Funcs.xml:74(h) @@ -949,87 +1006,87 @@ msgstr "Allgemein gilt: Operatoren mit höherer Priorität werden vor Operatoren msgid "Example:" msgstr "Beispiel:" -#: sdk/script/operatoren.xml:309(text) -#: sdk/script/operatoren.xml:314(text) +#: sdk/script/operatoren.xml:338(text) +#: sdk/script/operatoren.xml:343(text) msgid "evaluated as:" msgstr "entspricht:" -#: sdk/script/operatoren.xml:311(text) +#: sdk/script/operatoren.xml:340(text) msgid "Here we have another problem: what to do when 'neighbouring' operators have the same priority? Should we first process the left or the right term? This is decided by the so called associativity. If an operator is left-associative then the term on the left is evaluated first (this is the usual case). With right-associative operators the term on the right is evaluated first." msgstr "Dabei taucht aber noch ein Problem auf: was ist zu tun, wenn \"benachbarte\" Operatoren dieselbe Priorität haben? Ist dann der linke oder der rechte Ausdruck zu klammern? Über diese Frage entscheidet die sog. Assoziativität. Ist ein Operator links-assoziativ, so hat jeweils der linke Operator Priorität (übrigens auch der Regelfall, denn meistens wird von links nach rechts gerechnet). Anders bei den rechts-assoziativen Operatoren, wo jeweils der rechte Operator Priorität hat." -#: sdk/script/operatoren.xml:316(text) +#: sdk/script/operatoren.xml:345(text) msgid "Here you can see that the operator \"+\" is left-associative, the term \"1 + 2 + 3\" is evaluated as \"(1 + 2) + 3\"." msgstr "Hier sieht man deutlich, dass der Operator \"+\" links-assoziativ ist, der Ausdruck \"1 + 2 + 3\" wird zu \"(1 + 2) + 3\"." -#: sdk/script/operatoren.xml:317(text) +#: sdk/script/operatoren.xml:346(text) msgid "As opposed to this, the term \"somevar = othervar = x\" becomes \"somevar = (othervar = x)\", since the operator \"=\" is right-associative." msgstr "Dagegen wird der Ausdruck \"somevar = othervar = x\" zu \"somevar = (othervar = x)\", da der Operator \"=\" rechts-assoziativ ist." -#: sdk/script/operatoren.xml:318(text) +#: sdk/script/operatoren.xml:347(text) msgid "To find out about an operator's associativity, see the table above." msgstr "Die Angaben über Prioritäten bzw. Assoziativitäten finden sich in der obigen Liste." -#: sdk/script/operatoren.xml:320(h) +#: sdk/script/operatoren.xml:349(h) msgid "Bit Manipulation Operators" msgstr "Bitweise Operatoren" -#: sdk/script/operatoren.xml:321(text) +#: sdk/script/operatoren.xml:350(text) msgid "In the operator list you will have noticed some operators which perform bitwise operations or bit shift." msgstr "In der Liste der Operatoren fallen einige Operatoren auf, die bitweise Opererationen oder Bitschieben durchführen." -#: sdk/script/operatoren.xml:322(text) +#: sdk/script/operatoren.xml:351(text) msgid "To start out, a short description of bits: any computer internally works with 'binary numbers'. In this system there are only two digits: 0 and 1. Humans, by the way, usually work with 10 digits: 0 to 9. With the binary system, number can be represented as follows:" msgstr "Erst mal eine kurze Beschreibung von Bits: der Computer rechnet intern im sog. binären Zahlensystem. In diesem System gibt es nur zwei Ziffern, nämlich 0 und 1. (wir rechnen üblicherweise im 10er-System, wir haben 10 Ziffern von 0 bis 9). Damit lassen sich die Zahlen folgendermaßen darstellen:" -#: sdk/script/operatoren.xml:323(h) +#: sdk/script/operatoren.xml:352(h) msgid "The Binary System" msgstr "Das Binärsystem" -#: sdk/script/operatoren.xml:325(text) +#: sdk/script/operatoren.xml:354(text) msgid "(each number is presented in the decimal system first, then binary)" msgstr "(jeweils erst im Zehnersystem, dann im Binärsystem)" -#: sdk/script/operatoren.xml:332(text) +#: sdk/script/operatoren.xml:361(text) msgid "Each digit in the binary system is called a \"bit\". A sequence of 8 bits (see above) is called a \"byte\"." msgstr "Dabei wird jede Ziffer als \"Bit\" bezeichnet. Eine Folge von 8 Bits (s.o.) nennt man ein \"Byte\"." -#: sdk/script/operatoren.xml:333(text) +#: sdk/script/operatoren.xml:362(text) msgid "Bitwise operatiors perform actions on the bits of a number." msgstr "Bitweise Operatoren bearbeiten Zahlen nun bitweise." -#: sdk/script/operatoren.xml:338(text) +#: sdk/script/operatoren.xml:367(text) msgid "This example shows a binary NOT. That means, each bit of the number is negated individually (0 becomes 1, 1 becomes 0)." msgstr "In diesem Beispiel handelt es sich um bitweises Not. D.h. jedes Bit wird einzeln negiert (aus 0 wird 1, aus 1 wird 0)." -#: sdk/script/operatoren.xml:339(text) +#: sdk/script/operatoren.xml:368(text) msgid "Bitwise operators with two parameters combine the bits of two numbers." msgstr "Bitweise Operatoren mit 2 Parametern verrechnen nun jeweils die Bits zweier Zahlen." -#: sdk/script/operatoren.xml:340(h) +#: sdk/script/operatoren.xml:369(h) msgid "Examples:" msgstr "Beispiele:" -#: sdk/script/operatoren.xml:389(text) +#: sdk/script/operatoren.xml:418(text) msgid "These three operators are (in order) AND (&), OR (|) and EXCLUSIVE-OR (^)." msgstr "Diese drei Operatoren sind (der Reihe nach) Und (&), Oder (|) und Exklusiv-Oder (^)." -#: sdk/script/operatoren.xml:390(text) +#: sdk/script/operatoren.xml:419(text) msgid "With the AND operator, the resulting bit will only be 1 if both incoming bits are 1. AND gives the following result:" msgstr "Bei dem ersten Operator (Und) steht beim Ergebnis nur dann eine 1, wenn in beiden Eingaben an der entsprechenden Stelle ebenfalls eine 1 steht. \"Und\" hat also die folgende Wahrheitstabelle (senkrecht bzw. waagerecht sind die beiden möglichen Parameter jeweils gelistet, in der Tabelle selbst das Ergebnis):" -#: sdk/script/operatoren.xml:395(col) -#: sdk/script/operatoren.xml:399(col) -#: sdk/script/operatoren.xml:400(col) -#: sdk/script/operatoren.xml:401(col) -#: sdk/script/operatoren.xml:405(col) -#: sdk/script/operatoren.xml:415(col) -#: sdk/script/operatoren.xml:419(col) -#: sdk/script/operatoren.xml:420(col) -#: sdk/script/operatoren.xml:435(col) -#: sdk/script/operatoren.xml:439(col) -#: sdk/script/operatoren.xml:440(col) -#: sdk/script/operatoren.xml:446(col) +#: sdk/script/operatoren.xml:424(col) +#: sdk/script/operatoren.xml:428(col) +#: sdk/script/operatoren.xml:429(col) +#: sdk/script/operatoren.xml:430(col) +#: sdk/script/operatoren.xml:434(col) +#: sdk/script/operatoren.xml:444(col) +#: sdk/script/operatoren.xml:448(col) +#: sdk/script/operatoren.xml:449(col) +#: sdk/script/operatoren.xml:464(col) +#: sdk/script/operatoren.xml:468(col) +#: sdk/script/operatoren.xml:469(col) +#: sdk/script/operatoren.xml:475(col) #: sdk/script/fn/SetPhysical.xml:37(col) #: sdk/script/fn/SetGraphics.xml:45(col) #: sdk/script/fn/SetGamma.xml:44(col) @@ -1041,8 +1098,8 @@ msgstr "Bei dem ersten Operator (Und) steht beim Ergebnis nur dann eine 1, wenn #: sdk/script/fn/CreateMenu.xml:93(col) #: sdk/script/fn/Anim_Linear.xml:40(col) #: sdk/script/fn/AddCommand.xml:76(col) -#: sdk/script/Effects.xml:512(col) -#: sdk/script/Effects.xml:564(col) +#: sdk/script/Effects.xml:514(col) +#: sdk/script/Effects.xml:570(col) #: sdk/scenario/Teams.xml:34(col) #: sdk/scenario/Teams.xml:52(col) #: sdk/scenario/Teams.xml:58(col) @@ -1054,18 +1111,18 @@ msgstr "Bei dem ersten Operator (Und) steht beim Ergebnis nur dann eine 1, wenn msgid "0" msgstr "0" -#: sdk/script/operatoren.xml:396(col) -#: sdk/script/operatoren.xml:404(col) -#: sdk/script/operatoren.xml:406(col) -#: sdk/script/operatoren.xml:416(col) -#: sdk/script/operatoren.xml:421(col) -#: sdk/script/operatoren.xml:424(col) #: sdk/script/operatoren.xml:425(col) -#: sdk/script/operatoren.xml:426(col) -#: sdk/script/operatoren.xml:436(col) -#: sdk/script/operatoren.xml:441(col) -#: sdk/script/operatoren.xml:444(col) +#: sdk/script/operatoren.xml:433(col) +#: sdk/script/operatoren.xml:435(col) #: sdk/script/operatoren.xml:445(col) +#: sdk/script/operatoren.xml:450(col) +#: sdk/script/operatoren.xml:453(col) +#: sdk/script/operatoren.xml:454(col) +#: sdk/script/operatoren.xml:455(col) +#: sdk/script/operatoren.xml:465(col) +#: sdk/script/operatoren.xml:470(col) +#: sdk/script/operatoren.xml:473(col) +#: sdk/script/operatoren.xml:474(col) #: sdk/script/fn/SetPhysical.xml:42(col) #: sdk/script/fn/SetObjectBlitMode.xml:39(col) #: sdk/script/fn/SetGraphics.xml:50(col) @@ -1080,8 +1137,8 @@ msgstr "0" #: sdk/script/fn/Anim_Linear.xml:41(col) #: sdk/script/fn/AddCommand.xml:97(col) #: sdk/script/Effects.xml:199(col) -#: sdk/script/Effects.xml:516(col) -#: sdk/script/Effects.xml:569(col) +#: sdk/script/Effects.xml:519(col) +#: sdk/script/Effects.xml:575(col) #: sdk/scenario/Teams.xml:22(col) #: sdk/material/ocm.xml:299(col) #: sdk/definition/cnat.xml:19(col) @@ -1089,107 +1146,107 @@ msgstr "0" msgid "1" msgstr "1" -#: sdk/script/operatoren.xml:410(text) +#: sdk/script/operatoren.xml:439(text) msgid "The OR operator results in 1 if one or both of the incoming bits are 1:" msgstr "Der Operator \"Oder\" gibt 1 zurück, wenn eins (oder beide) der Eingaben 1 sind:" -#: sdk/script/operatoren.xml:430(text) +#: sdk/script/operatoren.xml:459(text) msgid "The XOR operator results in 1 if either (but not both) of the incoming bits are 1:" msgstr "Der Operator \"Exklusiv-Oder\" (XOr) verhält sich wie das \"Oder\", doch wird 0 zurückgegeben, wenn beide Parameter 0 sind." -#: sdk/script/operatoren.xml:450(h) +#: sdk/script/operatoren.xml:479(h) msgid "Applications:" msgstr "Anwendungen" -#: sdk/script/operatoren.xml:451(text) +#: sdk/script/operatoren.xml:480(text) msgid "Clonk often uses bitwise operations when storing the characteristics of an object in a single value. The best known example is the category (\"C4D\" values) of an object. Here, each bit of the category value represents a certain class or characteristic." msgstr "In Clonk werden häufig Bitoperationen benutzt, wenn es darum geht, verschiedene Eigenschaften eines Objekts in einem Wert zu speichern. Das prominenteste Beispiel sind hier wohl die C4D(Category)-Werte. Hier repräsentiert jedes Bit des C4D-Wertes eine bestimmte Eigenschaft (für Einzelheiten siehe Entwickler-Dokumentation)." -#: sdk/script/operatoren.xml:452(text) +#: sdk/script/operatoren.xml:481(text) msgid "To access or sort out the individual characteristics, you can easily access a C4D value with bitwise operators:" msgstr "Auf diese Bits kann man recht bequem über die bitweisen Operatoren zugreifen. Ein C4D-Wert kann z.B. folgendermaßen aussehen:" -#: sdk/script/operatoren.xml:453(h) +#: sdk/script/operatoren.xml:482(h) msgid "Example (wipf):" msgstr "Beispiel: (Wipf)" -#: sdk/script/operatoren.xml:455(text) +#: sdk/script/operatoren.xml:484(text) msgid "This value in binary system:" msgstr "Dieser Wert ergibt im Binär-System: (kann mit Windows-Taschenrechner umgerechnet werden)" -#: sdk/script/operatoren.xml:457(text) +#: sdk/script/operatoren.xml:486(text) msgid "You can see that bit 3, 12, and 16 are set (counting from left to right, starting with 0)." msgstr "Hier sieht man, dass Bit 3, Bit 12 und Bit 16 gesetzt sind (es wird von rechts gezählt und mit 0 begonnen)" -#: sdk/script/operatoren.xml:458(text) +#: sdk/script/operatoren.xml:487(text) msgid "This represents the C4D values (objects is a living being), C4D_SelectAnimal (living being can be selected in the menu system) and C4D_TradeLiving (living being can be bought or sold)." msgstr "Dies entspricht der Reihe nach den C4D-Werten (Objekt ist ein Lebewesen), C4D_SelectAnimal (Objekt kann im Menu für Lebewesen hinzugefügt werden) und C4D_TradeLiving (Objekt ist ein Lebewesen, darf aber trotzdem verkauft werden)." -#: sdk/script/operatoren.xml:459(text) +#: sdk/script/operatoren.xml:488(text) msgid "In script you can now easily check whether a given bit is set: simply use the AND operator (&) with a second parameter (\"mask\"). In this mask, only a single bit is set, representing the category value which we we like to test for. In the result of the AND operation all bits that do not interest us, will be 0. Only the one bit that does interest us, has the chance of being 1 - that is, if it is set in the original value. Since a single bit set in a number will already cause that number's value to be different from 0, all you have to do now is to compare the resulting number to 0: if it is different from 0, the characteristic we have been looking for is given; if the result is equal to 0, the characteristic is not given." msgstr "Im Script kann nun recht einfach geprüft werden, ob ein bestimmtes Bit gesetzt ist: man benutzt den Operator \"Und\" (&), dem man den Wert und die \"Maske\" übergibt. In der Maske ist nur das Bit gesetzt, dass von Interesse ist. Auf diese Weise müssen im Ergebnis alle Bits, die nicht interessieren, 0 sein (denn sie sind es in der Maske). Ist nun das Bit, das interressiert, 1, so wird diese in das Ergebnis übernommen, ist es 0, so wird im Ergebnis dort auch 0 stehen. Im letzteren Fall ist sogar das gesamte Ergebnis 0, da alle anderen Bits ja auch 0 sind. Es genügt also zu überprüfen, ob das Ergebnis von [Val] & [Mask] ungleich null ist, um herauszufinden, ob ein bestimmtes Bit gesetzt ist." -#: sdk/script/operatoren.xml:466(col) -#: sdk/script/operatoren.xml:486(col) -#: sdk/script/operatoren.xml:510(col) -#: sdk/script/operatoren.xml:530(col) -#: sdk/script/operatoren.xml:550(col) -#: sdk/script/operatoren.xml:569(col) +#: sdk/script/operatoren.xml:495(col) +#: sdk/script/operatoren.xml:515(col) +#: sdk/script/operatoren.xml:539(col) +#: sdk/script/operatoren.xml:559(col) +#: sdk/script/operatoren.xml:579(col) +#: sdk/script/operatoren.xml:598(col) msgid "(value)" msgstr "(Wert)" -#: sdk/script/operatoren.xml:471(col) -#: sdk/script/operatoren.xml:491(col) -#: sdk/script/operatoren.xml:515(col) -#: sdk/script/operatoren.xml:555(col) -#: sdk/script/operatoren.xml:574(col) +#: sdk/script/operatoren.xml:500(col) +#: sdk/script/operatoren.xml:520(col) +#: sdk/script/operatoren.xml:544(col) +#: sdk/script/operatoren.xml:584(col) +#: sdk/script/operatoren.xml:603(col) msgid "(mask)" msgstr "(Maske)" -#: sdk/script/operatoren.xml:480(text) +#: sdk/script/operatoren.xml:509(text) msgid "In this case, the result is unequal to 0, so we know the bit we have set in the mask is also set in the original value." msgstr "Das Ergebnis ist in diesem Fall nicht 0, also ist das Bit, dass in der Maske gesetzt ist, auch im Wert gesetzt." -#: sdk/script/operatoren.xml:500(text) +#: sdk/script/operatoren.xml:529(text) msgid "Here the result is equal to 0, meaning the bit we are looking for was not set in the original value." msgstr "Hier ist das Ergebnis 0, denn das Bit in der Maske ist nicht beim Wert gesetzt." -#: sdk/script/operatoren.xml:501(text) +#: sdk/script/operatoren.xml:530(text) msgid "The question remains where to get the proper mask from. In the case of the C4D categories, there are predefined values we can use. They are called C4D_xxx. So to find out whether an object is a living being we use the following code:" msgstr "Es bleibt noch die Frage zu klären, wo man die entsprechende Maske denn herbekommt. Im Fall der Category-Werte sind diese bereits mit Namen mitgeliefert, sie können über C4D_[XXX] abgerufen werden. Wollte man z.B. herausfinden, ob es sich bei einem Objekt um ein Lebewesen handelt, so sähe der Script folgendermaßen aus:" -#: sdk/script/operatoren.xml:504(text) +#: sdk/script/operatoren.xml:533(text) msgid "Now we can test whether an individual bit is set. But how can we change bits, for example set them? For this, we can use the OR operator (|). Again, it is applied using a value and a mask as a second parameter:" msgstr "Auf diese Weise kann man also einzelne Bits gezielt prüfen. Doch wie soll man diese nun bearbeiten? Will man ein einzelnes Bit setzen, so wird der Operator \"Oder\" (|) benutzt. Dieser wird wieder auf Wert und Maske angewendet:" -#: sdk/script/operatoren.xml:520(col) -#: sdk/script/operatoren.xml:540(col) -#: sdk/script/operatoren.xml:560(col) -#: sdk/script/operatoren.xml:579(col) +#: sdk/script/operatoren.xml:549(col) +#: sdk/script/operatoren.xml:569(col) +#: sdk/script/operatoren.xml:589(col) +#: sdk/script/operatoren.xml:608(col) msgid "(new value)" msgstr "(neuer Wert)" -#: sdk/script/operatoren.xml:524(text) +#: sdk/script/operatoren.xml:553(text) msgid "In this way it is only possible to set a certain bit to 1. If the bit was already set, the value will remain unchanged. To set a certain bit to 0 we have to use the AND operator and the inverse (logical NOT) mask, or [value] &~[mask]." msgstr "Auf diese Weise ist es allerdings immer nur möglich, ein bestimmtes Bit auf 1 zu setzen. War dieses bereits gesetzt, so bleibt der Wert unverändert. Will man nun ein bestimmtes Bit auf 0 setzen, so benutzt man wieder den \"Und\"-Operator und die inverse(logisch Not) Maske, also [Wert] & ~[Maske]:" -#: sdk/script/operatoren.xml:544(text) +#: sdk/script/operatoren.xml:573(text) msgid "It is also possibly to toggle a certain bit from 1 to 0 or 0 to 1, whichever way it is set. This is done with the XOR operator (^):" msgstr "Es ist auch möglich, ein bestimmtes Bit gezielt umzuschalten, also von 1 auf 0 und von 0 nach 1. Dies leistet der bitweise \"Exklusiv-Oder\"-Operator (^):" -#: sdk/script/operatoren.xml:584(h) +#: sdk/script/operatoren.xml:613(h) msgid "Bit Shifts" msgstr "Bitschiebereien" -#: sdk/script/operatoren.xml:586(text) +#: sdk/script/operatoren.xml:615(text) msgid "Besides operators for bitwise combination of values there are also the bit shift operators. All these operators do is move all the bits in a number from left to right (adding a new 0 on the left) or from right to left (adding a new 0 on the right)." msgstr "Außer den Operatoren, die bitweises Manipulieren von Werten erlauben (s.o.) gibt es noch sog. Bitschiebe-Operatoren. Die Funktion dieser Operatoren beschränkt sich darauf (anschaulich gesprochen), an einen Bit-Wert Nullen anzuhängen (<<) bzw. Ziffern abzuschneiden (>>)." -#: sdk/script/operatoren.xml:593(text) +#: sdk/script/operatoren.xml:622(text) msgid "Mathematically, the operator << performs a multiplication by 2 (exactly in the same way that in the decimal system appending a 0 performs a multiplication by 10) and the operator >> is a division by 2 (including some rounding)." msgstr "Mathematisch entspricht der Operator << der Multiplikation mit 2 ^ X (genau wie im Zehnersystem das Anhängen einer Null mit einer Multiplikation mit 10 gleichkommt) und der Operator >> einer Division mit 2 ^ X (mit anschließendem Abrunden)." -#: sdk/script/operatoren.xml:594(text) +#: sdk/script/operatoren.xml:623(text) msgid "Using these operators you can put together masks (1 << bit-no.) and mix or take apart color values." msgstr "Mit den Operatoren können vor allem Masken erstellt (1 << BitNr), und -Farbwerte zusammengesetzt und auseinandergenommen werden." @@ -1460,6 +1517,7 @@ msgstr "Entfernt alle Objekte." #: sdk/script/fn/GetRDir.xml:8(category) #: sdk/script/fn/GetR.xml:8(category) #: sdk/script/fn/GetProperty.xml:8(category) +#: sdk/script/fn/GetProperties.xml:8(category) #: sdk/script/fn/GetProcedure.xml:8(category) #: sdk/script/fn/GetPhysical.xml:8(category) #: sdk/script/fn/GetPhase.xml:8(category) @@ -1555,6 +1613,7 @@ msgstr "Entfernt alle Objekte." #: sdk/script/fn/CloseMenu.xml:8(category) #: sdk/script/fn/ClearMenuItems.xml:8(category) #: sdk/script/fn/CheckVisibility.xml:8(category) +#: sdk/script/fn/CheckConstructionSite.xml:8(category) #: sdk/script/fn/ChangeDef.xml:8(category) #: sdk/script/fn/CastObjects.xml:8(category) #: sdk/script/fn/CanConcatPictureWith.xml:8(category) @@ -2022,6 +2081,7 @@ msgstr "Es ist zu beachten, dass rechenintensive Scripte nicht die einzigen Brem #: sdk/script/fn/Anim_Y.xml:8(category) #: sdk/script/fn/Anim_XDir.xml:8(category) #: sdk/script/fn/Anim_X.xml:8(category) +#: sdk/script/fn/Anim_R.xml:8(category) #: sdk/script/fn/Anim_Linear.xml:8(category) #: sdk/script/fn/Anim_Const.xml:8(category) #: sdk/script/fn/Anim_Action.xml:8(category) @@ -2054,6 +2114,7 @@ msgstr "Stoppt die Animation mit der angegeben Nummer (wie sie von ." msgstr "Für ein ausführliches Beispiel siehe ." +#: sdk/script/fn/SortArrayByProperty.xml:9(subcat) +#: sdk/script/fn/SortArrayByArrayElement.xml:9(subcat) +#: sdk/script/fn/SortArray.xml:9(subcat) +#: sdk/script/fn/GetIndexOf.xml:9(subcat) +#: sdk/script/Typechecks.xml:86(h) +msgid "Arrays" +msgstr "Arrays" + +#: sdk/script/fn/SortArrayByProperty.xml:17(desc) +#: sdk/script/fn/SortArrayByArrayElement.xml:17(desc) +#: sdk/script/fn/SortArray.xml:17(desc) +msgid "Array that is to be sorted" +msgstr "Array das sortiert werden soll" + +#: sdk/script/fn/SortArrayByProperty.xml:22(desc) +msgid "Name of property by which the array is to be sorted" +msgstr "Name der Eigenschaft nach der das Array sortiert werden soll" + +#: sdk/script/fn/SortArrayByProperty.xml:27(desc) +#: sdk/script/fn/SortArrayByArrayElement.xml:27(desc) +#: sdk/script/fn/SortArray.xml:22(desc) +msgid "If true, elements are sorted in descending (highest to lowest) order. Otherwise ascending order." +msgstr "Wenn wahr, wird in absteigender Reihenfolge sortiert. Ansonsten in aufsteigender Reihenfolge." + +#: sdk/script/fn/SortArrayByProperty.xml:31(desc) +msgid "Sorts an array of proplists by a property. All elements must be proplists. Properties should be either all strings or all integer. If a property is not assigned, it is assumed to be integer zero." +msgstr "" + +#: sdk/script/fn/SortArrayByArrayElement.xml:22(desc) +msgid "Index of element in sub-array by which sorting should happen" +msgstr "" + +#: sdk/script/fn/SortArrayByArrayElement.xml:31(desc) +msgid "Sorts an array of arrays by a subarray element. All elements must be arrays of at least element_index+1 size. Subarray elements should be either all strings or all integer." +msgstr "" + +#: sdk/script/fn/SortArray.xml:26(desc) +msgid "Sorts an array by its elements. Elements should be either all strings or all integers." +msgstr "" + #: sdk/script/fn/Smoke.xml:8(category) #: sdk/script/fn/SetWind.xml:8(category) #: sdk/script/fn/SetTemperature.xml:8(category) @@ -2507,7 +2607,6 @@ msgstr "Schüttelt alle Lebewesen durch." #: sdk/script/fn/ShakeFree.xml:8(category) #: sdk/script/fn/SetMatAdjust.xml:8(category) -#: sdk/script/fn/SetLandscapePixel.xml:8(category) #: sdk/script/fn/SetClimate.xml:8(category) #: sdk/script/fn/PathFree.xml:8(category) #: sdk/script/fn/MaterialName.xml:8(category) @@ -2631,6 +2730,7 @@ msgstr "Der Wind bläst immer in die Richtung in die die Kanone geschoben wird." #: sdk/script/fn/GetPlayerName.xml:8(category) #: sdk/script/fn/GetPlayerID.xml:8(category) #: sdk/script/fn/GetPlayerCount.xml:8(category) +#: sdk/script/fn/GetPlayerControlAssignment.xml:8(category) #: sdk/script/fn/GetPlayerByName.xml:8(category) #: sdk/script/fn/GetPlayerByIndex.xml:8(category) #: sdk/script/fn/GetHomebaseProduction.xml:8(category) @@ -2738,17 +2838,17 @@ msgstr "Index des Vertex." #: sdk/scenario/scenario.xml:94(col) #: sdk/scenario/scenario.xml:124(col) #: sdk/scenario/scenario.xml:184(col) -#: sdk/scenario/scenario.xml:339(col) -#: sdk/scenario/scenario.xml:359(col) -#: sdk/scenario/scenario.xml:404(col) -#: sdk/scenario/scenario.xml:419(col) +#: sdk/scenario/scenario.xml:344(col) +#: sdk/scenario/scenario.xml:364(col) +#: sdk/scenario/scenario.xml:399(col) +#: sdk/scenario/scenario.xml:414(col) #: sdk/scenario/Teams.xml:13(col) #: sdk/scenario/Teams.xml:72(col) -#: sdk/playercontrols.xml:21(col) +#: sdk/playercontrols.xml:20(col) #: sdk/playercontrols.xml:83(col) -#: sdk/playercontrols.xml:126(col) -#: sdk/playercontrols.xml:140(col) -#: sdk/playercontrols.xml:172(col) +#: sdk/playercontrols.xml:142(col) +#: sdk/playercontrols.xml:175(col) +#: sdk/playercontrols.xml:228(col) #: sdk/particle/index.xml:30(col) #: sdk/material/ocm.xml:14(col) #: sdk/material/ocm.xml:228(col) @@ -2756,7 +2856,7 @@ msgstr "Index des Vertex." #: sdk/folder/foldermap.xml:14(col) #: sdk/folder/foldermap.xml:44(col) #: sdk/definition/defcore.xml:14(col) -#: sdk/definition/defcore.xml:404(col) +#: sdk/definition/defcore.xml:359(col) #: sdk/definition/cnat.xml:13(col) msgid "Value" msgstr "Wert" @@ -2768,8 +2868,8 @@ msgstr "Wert" #: sdk/script/fn/GetPhysical.xml:28(col) #: sdk/script/fn/Format.xml:31(col) #: sdk/script/Effects.xml:451(col) -#: sdk/script/Effects.xml:509(col) -#: sdk/script/Effects.xml:560(col) +#: sdk/script/Effects.xml:510(col) +#: sdk/script/Effects.xml:566(col) msgid "Meaning" msgstr "Bedeutung" @@ -2854,8 +2954,8 @@ msgid "Sets the transfer zone of the object. If the pathfinding trail of another msgstr "Setzt einen neuen Transferbereich für das aufrufende Objekt. Führt die Suche der Wegfindung durch einen Transferbereich (dieser gilt für die Wegfindung immer als komplett durchlaufbar), werden für den Clonk ControlTransfer-Aufrufe an das Script des Objekts aufgerufen. In diesen sollte mit Hilfe von Befehlen dafür gesorgt werden, dass der Clonk an seine Zielposition kommt." #: sdk/script/fn/SetTransferZone.xml:37(remark) -msgid "Transfer zones have to be set anew when the object has moved. Also, they should be set anew in response to a UpdateTransferZone callback made by the engine." -msgstr "Transferzonen müssen neu gesetzt werden, wenn sich das Objekt bewegt. Außerdem sollten sie immer als Antwort auf einen UpdateTransferZone-Callback der Engine neu gesetzt werden." +msgid "Transfer zones have to be set anew when the object has moved. Also, they should be set anew in response to a OnSynchronized callback made by the engine." +msgstr "Transferzonen müssen neu gesetzt werden, wenn sich das Objekt bewegt. Außerdem sollten sie immer als Antwort auf einen OnSynchronized-Callback der Engine neu gesetzt werden." #: sdk/script/fn/SetTransferZone.xml:49(text) msgid "Script for a cheat object: a clonk with a movement command will be immediately warped to the destination." @@ -3002,8 +3102,8 @@ msgid "Changes the bounding rectangle of the object. This rectangle is used e.g. msgstr "Ändert das interne Objektrechteck des aufrufenden Objekts. Das Objektrechteck wird beispielsweise für Kollisionsabfragen verwendet. Dies hat keine Auswirkung auf die Darstellung des Objekts." #: sdk/script/fn/SetShape.xml:36(remark) -msgid "In various situations the engine will reset the object's shape to the definition value. This might overwrite changes made with SetShape. This will happen e.g. during object rotation but also when resuming a saved game. So this function should only be used for mainly static, unchanging objects and you should readjust the shape manually in synchronization calls like UpdateTransferZone." -msgstr "Die Engine aktualisiert in diversen Fällen das Objektrechteck, wobei es die Definitionswerte zurückkopiert (und damit eventuelle, durch SetShape gesetzte Objektrechtecke verwirft). Die ist beispielsweise beim Ändern der Objektrotation, aber auch beim Neuladen der Spielstände der Fall. Die Funktion sollte also besser nur bei statischen, relativ unveränderten Objekten verwendet werden, und das Shape muss jeweils in einem Synchronisationsaufruf wie UpdateTransferZone neu gesetzt werden." +msgid "In various situations the engine will reset the object's shape to the definition value. This might overwrite changes made with SetShape. This will happen e.g. during object rotation but also when resuming a saved game. So this function should only be used for mainly static, unchanging objects and you should readjust the shape manually in synchronization calls like OnSynchronized." +msgstr "Die Engine aktualisiert in diversen Fällen das Objektrechteck, wobei es die Definitionswerte zurückkopiert (und damit eventuelle, durch SetShape gesetzte Objektrechtecke verwirft). Die ist beispielsweise beim Ändern der Objektrotation, aber auch beim Neuladen der Spielstände der Fall. Die Funktion sollte also besser nur bei statischen, relativ unveränderten Objekten verwendet werden, und das Shape muss jeweils in einem Synchronisationsaufruf wie OnSynchronized neu gesetzt werden." #: sdk/script/fn/SetShape.xml:40(text) msgid "Enlarges the area or distance from which you can chop down one coniferous tree." @@ -3473,8 +3573,8 @@ msgstr "PHYS_Temporary" #: sdk/script/fn/CreateMenu.xml:103(col) #: sdk/script/fn/Anim_Linear.xml:42(col) #: sdk/script/fn/AddCommand.xml:90(col) -#: sdk/script/Effects.xml:520(col) -#: sdk/script/Effects.xml:574(col) +#: sdk/script/Effects.xml:524(col) +#: sdk/script/Effects.xml:580(col) #: sdk/material/ocm.xml:304(col) #: sdk/definition/cnat.xml:25(col) #: sdk/definition/cnat.xml:30(col) @@ -3497,8 +3597,8 @@ msgstr "PHYS_StackTemporary" #: sdk/script/fn/CreateMenu.xml:52(col) #: sdk/script/fn/CreateMenu.xml:108(col) #: sdk/script/fn/AddCommand.xml:83(col) -#: sdk/script/Effects.xml:524(col) -#: sdk/script/Effects.xml:579(col) +#: sdk/script/Effects.xml:529(col) +#: sdk/script/Effects.xml:585(col) #: sdk/definition/cnat.xml:36(col) msgid "3" msgstr "3" @@ -3609,7 +3709,7 @@ msgstr "GFX_BLIT_ClrSfc_OwnClr" #: sdk/script/fn/SetGraphics.xml:65(col) #: sdk/script/fn/SetGamma.xml:60(col) #: sdk/script/fn/CreateMenu.xml:57(col) -#: sdk/script/Effects.xml:528(col) +#: sdk/script/Effects.xml:534(col) #: sdk/definition/cnat.xml:31(col) #: sdk/definition/cnat.xml:42(col) msgid "4" @@ -3634,43 +3734,56 @@ msgid "The overlay (owner color) is drawn using additive modulation. This flag m msgstr "Die Besitzergrafik (Overlay) wird mit additiver Modulation gezeichnet. Dieses Flag muss gegebenenfalls unabhängig von Bit 2 gesetzt werden." #: sdk/script/fn/SetObjectBlitMode.xml:58(col) +msgid "GFX_BLIT_Wireframe" +msgstr "GFX_BLIT_Wireframe" + +#: sdk/script/fn/SetObjectBlitMode.xml:59(col) +#: sdk/definition/cnat.xml:43(col) +msgid "16" +msgstr "16" + +#: sdk/script/fn/SetObjectBlitMode.xml:60(col) +msgid "Draws the mesh as a wireframe. Only works with meshes!" +msgstr "Zeichnet das Modell als Drahtgitter. Funktioniert nur mit Modellen!" + +#: sdk/script/fn/SetObjectBlitMode.xml:63(col) msgid "5-7" msgstr "5-7" -#: sdk/script/fn/SetObjectBlitMode.xml:59(col) -msgid "16, 32, 64" -msgstr "16, 32, 64" +#: sdk/script/fn/SetObjectBlitMode.xml:64(col) +msgid "32, 64" +msgstr "32, 64" -#: sdk/script/fn/SetObjectBlitMode.xml:60(col) +#: sdk/script/fn/SetObjectBlitMode.xml:65(col) msgid "reserved" msgstr "reserviert" -#: sdk/script/fn/SetObjectBlitMode.xml:63(col) +#: sdk/script/fn/SetObjectBlitMode.xml:68(col) msgid "GFX_BLIT_Custom" msgstr "GFX_BLIT_Custom" -#: sdk/script/fn/SetObjectBlitMode.xml:64(col) +#: sdk/script/fn/SetObjectBlitMode.xml:69(col) #: sdk/script/fn/CreateMenu.xml:113(col) msgid "128" msgstr "128" -#: sdk/script/fn/SetObjectBlitMode.xml:65(col) +#: sdk/script/fn/SetObjectBlitMode.xml:70(col) msgid "User defined color value. This value can be specified if no special color mode is desired and to overwrite a DefCore setting. Also, this bit is set in the return value of this function and if the current blit mode of the object does not correspond to the definition blit mode." msgstr "Benutzerdefinierter Farbwert. Dieser Wert kann angegeben werden, wenn kein spezieller Farbmodus gewünscht ist, und damit eine DefCore-Einstellung überschrieben werden soll. Außerdem ist dieses Bit im Rückgabewert dieser Funktion und von () gesetzt, wenn der Blitmodus des Objekts nicht dem Definitionswert entspricht." -#: sdk/script/fn/SetObjectBlitMode.xml:68(col) +#: sdk/script/fn/SetObjectBlitMode.xml:73(col) msgid "GFX_BLIT_Parent" msgstr "GFX_BLIT_Parent" -#: sdk/script/fn/SetObjectBlitMode.xml:69(col) +#: sdk/script/fn/SetObjectBlitMode.xml:74(col) msgid "256" msgstr "256" -#: sdk/script/fn/SetObjectBlitMode.xml:70(col) +#: sdk/script/fn/SetObjectBlitMode.xml:75(col) msgid "Only for overlays: the blit mode of the base surface is used when drawing this overlay." msgstr "Nur für Overlays: Es wird der Blitmodus verwendet, den auch das Basisobjekt benutzt, auf das dieses Overlay gezeichnet wird." -#: sdk/script/fn/SetObjectBlitMode.xml:99(text) +#: sdk/script/fn/SetObjectBlitMode.xml:104(text) msgid "Part of a scenario script: colors the selected clonk of the first player bright green for a while.
            To handle the timing properly, it would be better to use an effect in order to avoid conflicts with other scripts that might change the color at the same time." msgstr "Teil eines Szenarioscripts: Färbt den ausgewählten Clonk des ersten Spielers für eine Weile teilweise leuchtend grün.
            Für einen solchen Effekt in aufwändigeren Szenarien oder in allgemein verwendbaren Objekten sollte an solcher Stelle natürlich ein Effekt verwendet werden, um beispielsweise Komplikationen mit verfärbenden Zaubern zu vermeiden." @@ -3822,26 +3935,6 @@ msgstr "Neue Länge des Feldes" msgid "Changes the length of the array to the specified value. Surplus elements will be deleted, if necessary." msgstr "Verändert die Länge eines Arrays auf den angegebenen Wert. Überzählige Elemente werden dabei gegebenenfalls gelöscht." -#: sdk/script/fn/SetLandscapePixel.xml:16(desc) -msgid "X position of the pixel to be set; relative coordinates in local calls" -msgstr "X-Position des Pixels, das umgefärbt werden soll; relative Koordinaten bei objektlokalem Aufruf" - -#: sdk/script/fn/SetLandscapePixel.xml:21(desc) -msgid "Y position of the pixel to be set; relative coordinates in local calls" -msgstr "Y-Position des Pixels, das umgefärbt werden soll; relative Koordinaten bei objektlokalem Aufruf" - -#: sdk/script/fn/SetLandscapePixel.xml:26(desc) -msgid "32 bit color value of the pixel" -msgstr "32Bit-Farbwert des Pixels." - -#: sdk/script/fn/SetLandscapePixel.xml:30(desc) -msgid "Sets a pixel in the landscape. Not available in the old 8 bit graphics system." -msgstr "Färbt ein Pixel in der Landschaft ein. Diese Funktion ist nicht im 8Bit-Grafiksystem verfügbar." - -#: sdk/script/fn/SetLandscapePixel.xml:34(text) -msgid "Colors the landscape pixel directly behind the calling object brown." -msgstr "Färbt das Landschaftspixel direkt hinter dem aufrufenden Objekt braun." - #: sdk/script/fn/SetKiller.xml:17(desc) msgid "Player number of the new killer. NO_OWNER for no owner." msgstr "Spielernummer des neuen Besitzers. NO_OWNER für keinen Besitzer." @@ -3894,12 +3987,12 @@ msgid "Global" msgstr "Global" #: sdk/script/fn/SetGravity.xml:16(desc) -msgid "New gravity: value -300 til 300 (in percent)" -msgstr "Neue Schwerkraft: Werte -300 bis 300 (in Prozent)" +msgid "New gravity in 1/100 pixel/tick²" +msgstr "" #: sdk/script/fn/SetGravity.xml:20(desc) -msgid "Sets the gravity. Normal gravity is 100% and results in an acceleration of 0.2 pixels per Tick. (increasing YDir by 2 per Tick with precision=10)." -msgstr "Setzt die Schwerkraft. Dabei entspricht die Standardgravitation (100%) einer Beschleunigung von 0.2 Pixeln pro Tick. (Zunahme der YDir um 2 pro Tick bei precision=10)" +msgid "Sets the gravity. It is usually a good idea to set this to a multiple or a fraction of the previous value." +msgstr "" #: sdk/script/fn/SetGraphics.xml:17(desc) msgid "Name of the graphic to be set. If nil, the default graphic is set." @@ -4058,7 +4151,7 @@ msgstr "ramp_index" #: sdk/script/NamedVar.xml:21(col) #: sdk/script/GetXXVal.xml:24(col) #: sdk/scenario/script.xml:15(col) -#: sdk/definition/script.xml:34(col) +#: sdk/definition/script.xml:32(col) #: sdk/definition/animations.xml:24(col) msgid "Function" msgstr "Funktion" @@ -4099,8 +4192,8 @@ msgid "The eight gamma ramps have the following effects:



            Allgemein stehen niedrigere Rampenindizes für längerfristige Farbveränderungen; höhere für kürzere Effekte." #: sdk/script/fn/SetGamma.xml:81(text) -msgid "Adds a light blue hue to the game." -msgstr "Gibt dem Spiel einen leichten Blauschimmer" +msgid "Adds a light red hue to the game." +msgstr "Gibt dem Spiel einen leichten Rotschimmer." #: sdk/script/fn/SetGameSpeed.xml:16(desc) msgid "Game speed in FPS (frames per second). If this parameter is omitted or false, the default game speed of 38 FPS is used." @@ -4206,9 +4299,8 @@ msgid "true if you want to add a clonk to the crew and false< msgstr "true wenn der Clonk der Crew hinzugefügt und false wenn er aus dieser entfernt werden soll." #: sdk/script/fn/SetCrewStatus.xml:26(desc) -#, fuzzy msgid "Adds or removes an object (usually a clonk) to or from the crew of a player. The object must have the CrewMember property set in the DefCore. This does not add the object to the permanent crew of the player, use for that." -msgstr "Fügt das aufrufende Objekt (z.B. einen Clonk) der Crew eines Spielers hinzu oder entfernt dieses aus der Crew. Das Objekt muss die CrewMember-Eigenschaft in der DefCore gesetzt haben." +msgstr "Fügt das aufrufende Objekt (z.B. einen Clonk) der Crew eines Spielers hinzu oder entfernt dieses aus der Crew. Das Objekt muss die CrewMember-Eigenschaft in der DefCore gesetzt haben. Das Objekt wird dabei nicht zur permanenten Crew des Spielers hinzugefügt, dazu dient ." #: sdk/script/fn/SetCrewStatus.xml:32(text) #: sdk/script/fn/MakeCrewMember.xml:27(text) @@ -5209,6 +5301,7 @@ msgstr "Setzt einen 32Bit-Farbwert aus den drei Grundfarben zusammen. 0-255 für #: sdk/script/fn/PushParticles.xml:8(category) #: sdk/script/fn/DrawParticleLine.xml:8(category) +#: sdk/script/fn/CreateParticleAtBone.xml:8(category) #: sdk/script/fn/CreateParticle.xml:8(category) #: sdk/script/fn/ClearParticles.xml:8(category) #: sdk/script/fn/CastParticles.xml:8(category) @@ -5334,6 +5427,7 @@ msgstr "Platziert Vegetation im angegebenen Zielrechteck. Bei lokalen Aufrufen g #: sdk/script/fn/CreateContents.xml:9(subcat) #: sdk/script/fn/CreateConstruction.xml:9(subcat) #: sdk/script/fn/ComposeContents.xml:9(subcat) +#: sdk/script/fn/CheckConstructionSite.xml:9(subcat) #: sdk/script/fn/CastObjects.xml:9(subcat) #: sdk/script/fn/Buy.xml:9(subcat) #: sdk/definition/script.xml:10(h) @@ -5996,10 +6090,18 @@ msgstr "X-Geschwindigkeit des eingefügten Mateiralpixels" msgid "vertical speed of material pixel to be inserted" msgstr "Y-Geschwindigkeit des eingefügten Mateiralpixels" -#: sdk/script/fn/InsertMaterial.xml:45(desc) +#: sdk/script/fn/InsertMaterial.xml:46(desc) +msgid "If a writeable proplist is passed, members x and y are filled with the actual insertion position." +msgstr "" + +#: sdk/script/fn/InsertMaterial.xml:51(desc) msgid "Inserts a material pixel at the given position and given speed." msgstr "Fügt ein Materialpixel an der angegebenen Position in der angegebenen Geschwindigkeit ein." +#: sdk/script/fn/InsertMaterial.xml:52(remark) +msgid "If the target position already contains material of the same density as the inserted material, the engine will search upwards for a proper insertion position. Use the parameter out_insertpos to find out where material was actually inserted." +msgstr "" + #: sdk/script/fn/Incinerate.xml:11(desc) msgid "Incinerates the specified object. This may cause an Incineration() call in the object." msgstr "Zündet das aufrufende Objekt an. In dem jeweiligen Objekt wird ggf. Incineration() aufgerufen" @@ -6377,6 +6479,7 @@ msgid "Requested property." msgstr "Abzufragende Eigenschaft." #: sdk/script/fn/GetProperty.xml:23(desc) +#: sdk/script/fn/GetProperties.xml:17(desc) msgid "Object to request property from, nil in local calls." msgstr "Objekt von dem die Eigenschaft abgefragt wird. nil für lokale Aufrufe." @@ -6384,6 +6487,10 @@ msgstr "Objekt von dem die Eigenschaft abgefragt wird. nil für lok msgid "Returns the property key of object." msgstr "Liefert die Eigenschaft key von object." +#: sdk/script/fn/GetProperties.xml:22(desc) +msgid "Returns the names of all properties of object." +msgstr "Liefert die Namen aller Eigenschaften von object." + #: sdk/script/fn/GetProcedure.xml:12(desc) msgid "Returns the procedure of the current activity of an object (e.g. FLOAT, ATTACH, WALK). If the procedure is NONE or the object has no activity set the return value is nil." msgstr "Gibt die Prozedur der gegenwärtigen Aktivität des aufrufenden Objekts zurück (z.B. FLOAT, ATTACH, etc.). Bei einer NONE-Prozedur oder keiner Aktivität wird nil zurückgegeben." @@ -6620,6 +6727,37 @@ msgstr "Liefert die Anzahl der Spieler, die momentan im Spiel sind." msgid "See ." msgstr "Siehe ." +#: sdk/script/fn/GetPlayerControlAssignment.xml:16(desc) +#, fuzzy +msgid "Number of the player for whom the control set is queried." +msgstr "Spielernummer, dessen Verbündete Besitzer der zu suchenden Objekte sein müssen" + +#: sdk/script/fn/GetPlayerControlAssignment.xml:21(desc) +msgid "Control to query. A CON_* constant should be used here." +msgstr "" + +#: sdk/script/fn/GetPlayerControlAssignment.xml:26(desc) +msgid "If true, some internal names such as JOY_* for joystick buttons are replaced by variants suitable for display to the player." +msgstr "" + +#: sdk/script/fn/GetPlayerControlAssignment.xml:31(desc) +msgid "If true, short names are preferred if available. Currently effects Mac builds only." +msgstr "" + +#: sdk/script/fn/GetPlayerControlAssignment.xml:35(desc) +#, fuzzy +msgid "Returns the name of the key, mouse of joystick button assigned to a control for a player. If the player number is invalid, nil is returned. For unassigned or invalid controls, \"\" is returned." +msgstr "Liefert den Namen eines Spielers mit Markup in dessen Spielerfarbe. Wenn die Spielernummer zu keinem gültigen Spieler gehört, wird nil zurückgegeben. Dadurch kann diese Funktion auch benutzt werden, um zu ermitteln, ob eine Spielernummer gültig ist." + +#: sdk/script/fn/GetPlayerControlAssignment.xml:36(remark) +msgid "For network games and replays, the returned value is not synchronized. If the function is called for a remote player or during replay, \"\" is always returned for valid player numbers." +msgstr "" + +#: sdk/script/fn/GetPlayerControlAssignment.xml:40(text) +#, fuzzy +msgid "Tells the first player how to walk left." +msgstr "Der höchstrangige Clonk des ersten Spielers explodiert." + #: sdk/script/fn/GetPlayerByName.xml:16(desc) msgid "Name of the player" msgstr "Name des Spielers" @@ -6885,6 +7023,18 @@ msgstr "Aufgrund der Komplexität der Spielwelt von Clonk ist es nicht immer mö msgid "Script for the death of a Clonk: Customized death messages which show the murderer are shown." msgstr "Script für den Tod eines Clonks: Anstatt der normalen Todesnachricht richtet sich die Nachricht danach, wer den Clonk getötet hat." +#: sdk/script/fn/GetIndexOf.xml:17(desc) +msgid "Array in which the element should be searched. The array can be zero, in which case the element is never found and -1 is returned." +msgstr "" + +#: sdk/script/fn/GetIndexOf.xml:22(desc) +msgid "The value to which every element of the array is to be compared." +msgstr "" + +#: sdk/script/fn/GetIndexOf.xml:26(desc) +msgid "Finds the first occurrence of a value in an array and returns its zero-based index. If the element is not found, -1 is returned. The usual rules for comparison using the ==-operator apply." +msgstr "" + #: sdk/script/fn/GetID.xml:11(desc) msgid "Returns the object definition id of an object." msgstr "Gibt die ID des aufrufenden Objekts zurück." @@ -6948,8 +7098,8 @@ msgid "Kills the highest ranking clonk of the third player." msgstr "Tötet den höchstrangigen Clonk des dritten Spielers. (Die Zählung beginnt mit 0)" #: sdk/script/fn/GetGravity.xml:11(desc) -msgid "Returns the current gravity in percent." -msgstr "Liest die Schwerkraft (in Prozent) aus." +msgid "Returns the current gravity in 1/100 pixel/tick²." +msgstr "Liest die Schwerkraft in 1/100 pixel/tick² aus." #: sdk/script/fn/GetGravity.xml:16(text) msgid "Makes the gravitation within a radius of 100 pixels vanish if called every frame." @@ -7201,8 +7351,8 @@ msgid "Returns the current command direction of an object. This indicates the ob msgstr "Liefert die aktuelle Befehlsrichtung des aufrufenden Objekts. Diese gibt die momentane, beabsichtigte Bewegungsrichtung an. Die Auswirkung dieser Richtung hängt von der Prozedur der aktuellen Aktivität ab." #: sdk/script/fn/GetColor.xml:12(desc) -msgid "Gets the RGB color value of the ColorByOwner areas of an object. These are controlled by , or ." -msgstr "Fragt den RGB-Farbwert der Färbung der ColorByOwner-Flächen des aufrufenden Objekts ab. Diese werden beispielsweise durch oder gesetzt." +msgid "Gets the RGB color value of the ColorByOwner areas of an object. These are controlled by or ." +msgstr "Fragt den RGB-Farbwert der Färbung der ColorByOwner-Flächen des Objekts ab. Diese werden beispielsweise durch oder gesetzt." #: sdk/script/fn/GetColor.xml:16(text) msgid "Colors otherclonk like the current object." @@ -7378,7 +7528,6 @@ msgstr "Beendet die Runde, falls keine Steine da sind." #: sdk/script/fn/GameCallEx.xml:9(subcat) #: sdk/script/fn/GameCall.xml:9(subcat) -#: sdk/script/fn/DefinitionCall.xml:9(subcat) #: sdk/script/fn/Call.xml:9(subcat) msgid "Function call" msgstr "Funktionsaufruf" @@ -7572,15 +7721,17 @@ msgstr "s" #: sdk/scenario/scenario.xml:210(col) #: sdk/scenario/scenario.xml:280(col) #: sdk/scenario/scenario.xml:285(col) -#: sdk/scenario/scenario.xml:390(col) #: sdk/scenario/Teams.xml:62(col) #: sdk/scenario/Teams.xml:103(col) -#: sdk/playercontrols.xml:32(col) -#: sdk/playercontrols.xml:37(col) -#: sdk/playercontrols.xml:77(col) -#: sdk/playercontrols.xml:132(col) -#: sdk/playercontrols.xml:146(col) -#: sdk/playercontrols.xml:156(col) +#: sdk/playercontrols.xml:31(col) +#: sdk/playercontrols.xml:36(col) +#: sdk/playercontrols.xml:76(col) +#: sdk/playercontrols.xml:148(col) +#: sdk/playercontrols.xml:153(col) +#: sdk/playercontrols.xml:181(col) +#: sdk/playercontrols.xml:191(col) +#: sdk/playercontrols.xml:196(col) +#: sdk/playercontrols.xml:201(col) #: sdk/material/ocm.xml:234(col) #: sdk/material/ocm.xml:239(col) #: sdk/material/ocm.xml:244(col) @@ -7593,9 +7744,9 @@ msgstr "s" #: sdk/folder/foldermap.xml:95(col) #: sdk/definition/actmap.xml:20(col) #: sdk/definition/actmap.xml:25(col) -#: sdk/definition/actmap.xml:95(col) -#: sdk/definition/actmap.xml:125(col) -#: sdk/definition/actmap.xml:145(col) +#: sdk/definition/actmap.xml:110(col) +#: sdk/definition/actmap.xml:140(col) +#: sdk/definition/actmap.xml:160(col) msgid "String" msgstr "Zeichenkette" @@ -7974,7 +8125,7 @@ msgstr "Sucht eine Heimatbasis eines Spielers. Die Heimatbasis ist zumeist das G msgid "Gives the selected clonk the order to enter his home base." msgstr "Gibt dem ausgewählten Clonk des ersten Spielers das Kommando, seine Basis zu betreten." -#: sdk/script/fn/FatalError.xml:17(desc) +#: sdk/script/fn/FatalError.xml:16(desc) msgid "Error message to be displayed" msgstr "Fehlermeldung, die ausgegeben wird" @@ -8171,6 +8322,7 @@ msgid "Distance between particles. This may not be applied exactly as particles msgstr "Abstand zwischen zwei Partikeln. Dieser Abstand kann möglicherweise nicht genau eingehalten werden, da die Partikel immer gleichmäßig auf die Strecke verteilt werden." #: sdk/script/fn/DrawParticleLine.xml:46(desc) +#: sdk/script/fn/CreateParticleAtBone.xml:36(desc) #: sdk/script/fn/CreateParticle.xml:41(desc) msgid "Extra parameter. This is usually the size of the particle in 1/5 pixels." msgstr "Zusatzparameter. Dies ist normalerweise die Größe des Partikels in 1/5-Pixeln." @@ -8272,27 +8424,24 @@ msgid "Definition of the dynamic map. The enclosing map { ... } tag must be pres msgstr "Definition der dynamischen Karte. Das umschließende map { ...} - Tag muss vorhanden sein." #: sdk/script/fn/DrawMap.xml:40(desc) -#, fuzzy msgid "Draws a dynamic map within the specified rectangle over the old landscape. This is done using the same evaluation as with Landscape.txt components." -msgstr "Zeichnet eine dynamische Zufallskarte innerhalb eines Bereichs. Dazu wird derselbe Generator benutzt, der auch die Karten der Landscape.txt zeichnet." +msgstr "Zeichnet eine dynamische Zufallskarte über einen Bereich der alten Landschaft. Dazu wird derselbe Generator benutzt, der auch die Karten der Landscape.txt zeichnet." #: sdk/script/fn/DrawMap.xml:41(remark) msgid "As maximum string length in C4Script is limited by internal buffers you should use for very complex maps." msgstr "Da die Maximallänge von Strings in C4Script durch interne Puffer begrenzt ist, wird empfohlen, für aufwändigere Karten zu benutzen." #: sdk/script/fn/DrawMap.xml:45(text) -#, fuzzy msgid "Fills the top half of the map with earth." -msgstr "Leert die obere Hälfte der Karte aus." +msgstr "Füllt die obere hälfte der Karte mit Erde." #: sdk/script/fn/DrawDefMap.xml:36(desc) msgid "Name of the map to be used from Landscape.txt." msgstr "Name der zu benutzenden Karte aus der Landscape.txt" #: sdk/script/fn/DrawDefMap.xml:40(desc) -#, fuzzy msgid "Draws a dynamic map within the specified rectangle over the old landscape using a given map specification from Landscape.txt." -msgstr "Zeichnet eine dynamische Zufallskarte innerhalb eines Bereichs. Dazu wird die angegebene Karte in der Landscape.txt gesucht." +msgstr "Zeichnet eine dynamische Zufallskarte über einen Bereich der alten Landschaft. Dazu wird die angegebene Karte in der Landscape.txt gesucht." #: sdk/script/fn/DrawDefMap.xml:41(remark) msgid "The Landscape.txt component is usually removed from memory after scenario initialization. To keep it in memory for later use by this command you should specify the option KeepMapCreator=1 in Scenario.txt section [Landscape]." @@ -8507,6 +8656,7 @@ msgstr "Gibt an, wie weit der ausgewählte Clonk noch vom Punkt 1000/200 entfern #: sdk/script/fn/DigFree.xml:16(desc) #: sdk/script/fn/CreateObject.xml:22(desc) #: sdk/script/fn/CreateConstruction.xml:22(desc) +#: sdk/script/fn/CheckConstructionSite.xml:22(desc) #: sdk/script/fn/CastPXS.xml:31(desc) #: sdk/script/fn/BlastObjects.xml:16(desc) msgid "X coordinate" @@ -8516,6 +8666,7 @@ msgstr "X-Koordinate" #: sdk/script/fn/DigFree.xml:21(desc) #: sdk/script/fn/CreateObject.xml:27(desc) #: sdk/script/fn/CreateConstruction.xml:27(desc) +#: sdk/script/fn/CheckConstructionSite.xml:27(desc) #: sdk/script/fn/CastPXS.xml:36(desc) #: sdk/script/fn/BlastObjects.xml:21(desc) msgid "Y coordinate" @@ -8529,23 +8680,28 @@ msgstr "Breite" msgid "Height" msgstr "Höhe" -#: sdk/script/fn/DigFreeRect.xml:35(desc) -msgid "Makes a rectangular hole in semi-solid materials." -msgstr "Gräbt ein rechteckiges Loch in halbfesten Materialien." +#: sdk/script/fn/DigFreeRect.xml:36(desc) +#: sdk/script/fn/DigFree.xml:31(desc) +msgid "Prevent objects from being dug out" +msgstr "" -#: sdk/script/fn/DigFreeRect.xml:36(remark) +#: sdk/script/fn/DigFreeRect.xml:40(desc) +msgid "Makes a rectangular hole in semi-solid materials. The return value is the amount of pixels that were dug free. If no_dig2objects is true, the dug out material does neither create objects according to the Dig2Objects in the *.ocm nor will the amount be stored in the internal buffer." +msgstr "" + +#: sdk/script/fn/DigFreeRect.xml:41(remark) msgid "Drills an elevator shaft." msgstr "CreateShaft im Fahrstuhl gräbt einen Fahrstuhlschacht." -#: sdk/script/fn/DigFreeRect.xml:40(text) +#: sdk/script/fn/DigFreeRect.xml:45(text) msgid "Makes a square hole in the middle of the landscape." msgstr "Gräbt ein kleines quadratisches Loch mitten in die Landschaft." -#: sdk/script/fn/DigFree.xml:30(desc) -msgid "Makes a circular hole in semi-solid materials." -msgstr "Gräbt ein kreisrundes Loch in halbfesten Materialien." +#: sdk/script/fn/DigFree.xml:35(desc) +msgid "Makes a circular hole in semi-solid materials. The return value is the amount of pixels that were dug free. If no_dig2objects is true, the dug out material does neither create objects according to the Dig2Objects in the *.ocm nor will the amount be stored in the internal buffer." +msgstr "" -#: sdk/script/fn/DigFree.xml:34(text) +#: sdk/script/fn/DigFree.xml:39(text) msgid "Makes a small hole in the middle of the landscape." msgstr "Gräbt ein kleines Loch mitten in der Landschaft." @@ -8561,18 +8717,6 @@ msgstr "Wurde zuvor mit ein Mesh an einem anderen befestigt, so msgid "Script for an effect: The effect target carries a bow as long as the effect remains active." msgstr "Script für einen Effekt: Während der Effekt aktiv ist trägt das Effektziel einen Bogen." -#: sdk/script/fn/DefinitionCall.xml:17(desc) -msgid "id of the definition in the script of which to call the function." -msgstr "ID der Definition, in dessen Script die Funktion aufgerufen wird" - -#: sdk/script/fn/DefinitionCall.xml:27(desc) -msgid "Additional parameters to be passed to the function." -msgstr "Zusätzliche Parameter, die an die Funktion übergeben werden" - -#: sdk/script/fn/DefinitionCall.xml:32(desc) -msgid "Calls a function in a script without object context. returns in this case (comparable to scenario scripts)." -msgstr "Ruft eine Funktion in einem Script ohne zugehöriges Objekt auf. Der ()-Zeiger gibt in einem solchen Aufruf zurück (Vergleichbar mit dem Szenarioscript)." - #: sdk/script/fn/Definition.xml:8(category) #: sdk/script/fn/Construction.xml:8(category) msgid "Callbacks" @@ -8721,7 +8865,8 @@ msgid "CSPF_NoScenarioInit" msgstr "CSPF_NoScenarioInit" #: sdk/script/fn/CreateScriptPlayer.xml:48(col) -msgid "If true, the scenario initialization (i.e. placement of home base material, clonks, setting of build knowledge, etc.) is not performed for this player. Also, the global callbacks PreInitializePlayer and InitializePlayer to the scenario script and to goal, rule, and environment objects are not performed. Instead, the callback InitializeScriptPlayer(Player number, Team) is made to the object definition specified in extra_data. The call is made as DefinitionCall (without object). Using this parameter you can create script-controlled AI players which do not receive the same standard treatment as user-controlled players." +#, fuzzy +msgid "If true, the scenario initialization (i.e. placement of home base material, clonks, setting of build knowledge, etc.) is not performed for this player. Also, the global callbacks PreInitializePlayer and InitializePlayer to the scenario script and to goal, rule, and environment objects are not performed. Instead, the callback InitializeScriptPlayer(Player number, Team) is made to the object definition specified in extra_data. Using this parameter you can create script-controlled AI players which do not receive the same standard treatment as user-controlled players." msgstr "Wenn wahr, wird die Szenarieninitialisierung, also das Erzeugen von Heimatbasismaterial und Clonks, das Setzen der Baupläne nach Szenarienvorgaben, etc., nicht durchgeführt. Außerdem werden die globalen PreInitializePlayer- und InitializePlayer-Callbacks ans Szenarienscript und die Spielziel-, Regel- und Umweltobjekte nicht ausgeführt. Stattdessen wird ein InitializeScriptPlayer(Spielernummer, Team)-Callback als DefinitionCall (d.h. ohne -Objekt) auf der in extra_data angegebenen Definition ausgeführt. Mit diesem Parameter lassen sich also spezialisierte Scriptspieler realisieren, die nicht gleichberechtigt mit menschlichen Spielern agieren." #: sdk/script/fn/CreateScriptPlayer.xml:52(col) @@ -8760,10 +8905,54 @@ msgstr "Scriptspieler treten in Netzwerkspielen genau wie reguläre Spieler verz msgid "For examples see Script Players." msgstr "Für Beispiele siehe Scriptspieler." +#: sdk/script/fn/CreateParticleAtBone.xml:16(desc) #: sdk/script/fn/CreateParticle.xml:16(desc) msgid "Name of the particle" msgstr "Name des Partikels" +#: sdk/script/fn/CreateParticleAtBone.xml:21(desc) +#, fuzzy +msgid "Name of the bone at which to create the particle" +msgstr "Geschwindigkeit, mit der verschleudert werden soll" + +#: sdk/script/fn/CreateParticleAtBone.xml:26(desc) +msgid "Vector of three elements with the X,Y and Z coordinates of the particle relative to the bone position and orientation." +msgstr "" + +#: sdk/script/fn/CreateParticleAtBone.xml:31(desc) +msgid "Vector of three elements with the X,Y and Z components of the velocity of theparticle relative to the bone orientation." +msgstr "" + +#: sdk/script/fn/CreateParticleAtBone.xml:41(desc) +#: sdk/script/fn/CreateParticle.xml:46(desc) +msgid "Extra parameter. This is usually the color modulation of the particle." +msgstr "Zweiter Zusatzparameter. Dies ist normalerweise die Farbmodulation des Partikels." + +#: sdk/script/fn/CreateParticleAtBone.xml:46(desc) +#: sdk/script/fn/CreateParticle.xml:51(desc) +#: sdk/script/fn/CastParticles.xml:61(desc) +msgid "Target object for object local particles. Object local particles are drawn directly on top of the object and are removed when the object is deleted." +msgstr "Zielobjekt für objektlokale Partikel. Objektlokale Partikel werden direkt über den jeweiligen Objekten gezeichnet, und beim Entfernen des Objekts gelöscht." + +#: sdk/script/fn/CreateParticleAtBone.xml:52(desc) +#: sdk/script/fn/CreateParticle.xml:57(desc) +msgid "If specified and not false, the particle is drawn directly behind the target object." +msgstr "Wenn angegeben und nicht false, wird der Partikel hinter dem Zielobjekt gezeichnet." + +#: sdk/script/fn/CreateParticleAtBone.xml:57(desc) +#, fuzzy +msgid "Creates a particle relative to a bone of the calling object's skeleton. The named particle definition must be loaded. For more information see the particle documentation." +msgstr "Erzeugt ein Partikel. Das Partikel muss unter dem angegebenen Namen geladen sein. Für weitere Informationen siehe Partikeldokumentation." + +#: sdk/script/fn/CreateParticleAtBone.xml:58(remark) +#, fuzzy +msgid "This function returns false if the particle definition was not found, or the function is called for an object which does not have a mesh graphics, or the skeleton of the mesh does not have a bone called szBoneName. Otherwise, true is returned. There is no return value indicating whether the particle has actually been created. This must be so to prevent synchronization problems in network games, as particles may be handled differently on each computer in the network." +msgstr "Diese Funktion gibt false zurück wenn die Partikeldefinition unter dem Namen nicht geladen wurde. Ansonsten immer true. Es gibt also keine Möglichkeit, herauszufinden, ob ein Partikel wirklich erzeugt wurde. Dies muss aus Gründen der Netzwerksynchronisation so sein, und Partikel sollten darum nur für kurzzeitige Effekte verwendet werden. Wer mehr Kontolle benötigt, sollte stattdessen auf Objekte zurückgreifen." + +#: sdk/script/fn/CreateParticleAtBone.xml:73(text) +msgid "Scenario script. Creates an effect which traces a Clonk's body, left hand and right hand with differently colored sparks." +msgstr "" + #: sdk/script/fn/CreateParticle.xml:21(desc) #: sdk/script/fn/CastParticles.xml:31(desc) msgid "X coordinate of the particle. Offset in local calls." @@ -8782,19 +8971,6 @@ msgstr "Horizontale Anfangsgeschwindigkeit des Partikels" msgid "Initial vertical velocity of the particle." msgstr "Vertikale Anfangsgeschwindigkeit des Partikels" -#: sdk/script/fn/CreateParticle.xml:46(desc) -msgid "Extra parameter. This is usually the color modulation of the particle." -msgstr "Zweiter Zusatzparameter. Dies ist normalerweise die Farbmodulation des Partikels." - -#: sdk/script/fn/CreateParticle.xml:51(desc) -#: sdk/script/fn/CastParticles.xml:61(desc) -msgid "Target object for object local particles. Object local particles are drawn directly on top of the object and are removed when the object is deleted." -msgstr "Zielobjekt für objektlokale Partikel. Objektlokale Partikel werden direkt über den jeweiligen Objekten gezeichnet, und beim Entfernen des Objekts gelöscht." - -#: sdk/script/fn/CreateParticle.xml:57(desc) -msgid "If specified and not false, the particle is drawn directly behind the target object." -msgstr "Wenn angegeben und nicht false, wird der Partikel hinter dem Zielobjekt gezeichnet." - #: sdk/script/fn/CreateParticle.xml:62(desc) msgid "Creates a particle. The named particle definition must be loaded. For more information see the particle documentation." msgstr "Erzeugt ein Partikel. Das Partikel muss unter dem angegebenen Namen geladen sein. Für weitere Informationen siehe Partikeldokumentation." @@ -9100,7 +9276,6 @@ msgid "Opens a text window containing the entry \"Old Text\" for the selected cl msgstr "Öffnet zunächst ein Textfenster mit dem Inhalt \"Alter Text\" für den ausgewählten Clonk des ersten Spielers, und ändert die Beschriftung dann später auf \"Neuer Text\"." #: sdk/script/fn/CheckVisibility.xml:9(subcat) -#: sdk/script/fn/CheckVisibility.xml:24(emlink) #: sdk/definition/visibility.xml:6(title) #: sdk/definition/visibility.xml:7(h) msgid "Visibility" @@ -9114,9 +9289,9 @@ msgstr "Spieler für den die Sichtbarkeit abgefragt wird." msgid "Checks whether this object is visible for the given player." msgstr "Prüft ob dieses Objekt für den angegebenen Spieler sichtbar ist." -#: sdk/script/fn/CheckVisibility.xml:23(related) -msgid "-Property" -msgstr "-Eigenschaft" +#: sdk/script/fn/CheckVisibility.xml:24(emlink) +msgid "Visibility Property" +msgstr "Visibility-Eigenschaft" #: sdk/script/fn/CheckEffect.xml:16(desc) #: sdk/script/fn/AddEffect.xml:16(desc) @@ -9156,6 +9331,14 @@ msgstr "Vierter Zusatzparameter, der an Fx*Effect-Callbacks übergeben wird" msgid "Makes Fx*Effect (and in cases Fx*Add) callbacks to the specified list of effects, without actually creating any effect. The return value is -1 if another effect has rejected the call. If an effect accepts the call, the return value is the effect number of that effect." msgstr "Führt Fx*Effect (und ggf. auch Fx*Add)-Callbacks in der entsprechenden Effektliste aus, ohne einen Effekt selber zu erstellen. Rückgabewert ist -1, wenn ein anderer Effekt den Effekt abgelehnt hat, und die Effektnummer des aufnehmenden Effektes, wenn der Effekt aufgenommen wurde." +#: sdk/script/fn/CheckConstructionSite.xml:17(desc) +msgid "Type of object to be checked." +msgstr "Typ des zu prüfenden Objekts" + +#: sdk/script/fn/CheckConstructionSite.xml:31(desc) +msgid "Checks whether the given location is suitable for the construction of object_id. The same check is used before creation in if check_side is true. In local calls the specified position will be an offset to the position of the calling object." +msgstr "" + #: sdk/script/fn/ChangeDef.xml:17(desc) msgid "id of the new definition." msgstr "ID der neuen Definition für das Objekt" @@ -9291,8 +9474,8 @@ msgid "Function to be called." msgstr "Funktion, die aufgerufen werden soll." #: sdk/script/fn/Call.xml:26(desc) -msgid "Calls the local function function. If \"~\" is prepended to the function name then the call does not fail if the function does not exist." -msgstr "Ruft die lokale Funktion function auf. Wird \"~\" vor den Funktionsnamen gesetzt, wird der Aufruf failsafe durchgeführt." +msgid "Calls the specified function. If given a string, the function is looked up in the context object (this). For example, obj->Call(\"Foo\") is the same as obj->Foo(). Using Call like this is primarily useful when the name of the function can vary. If \"~\" is prepended to the function name then the call does not fail if the function does not exist." +msgstr "" #: sdk/script/fn/COMD_UpRight.xml:12(desc) msgid "Movement direction: diagonally up and to the right. For more information see ." @@ -9458,19 +9641,16 @@ msgid "Moves the calling object into the background and adds horizontal parallax msgstr "Versetzt das aufrufende Objekt in den Hintergrund, und gibt ihm horizontale Parallaxität." #: sdk/script/fn/C4D_Object.xml:12(desc) -#, fuzzy msgid "Object category: Item that can hit alive objects." -msgstr "Objektkategorie: Spielregeln" +msgstr "Objektkategorie: Objekt, welches Lebewesen Bewegungsschaden zufügt" #: sdk/script/fn/C4D_Object.xml:16(text) -#, fuzzy msgid "Returns the id of the first loaded definition with C4D_Object. Similar scripting is used in the research lab to list researchable objects." -msgstr "Liefert die id des ersten geladenen Objekts zurück. Ein ähnlicher Code wird vom Forschungslabor benutzt, um die erforschbaren Objekte aufzulisten." +msgstr "Liefert die id des ersten geladenen Objekts mit Kategorie C4D_Object zurück. Ein ähnlicher Code wird vom Forschungslabor benutzt, um die erforschbaren Objekte aufzulisten." #: sdk/script/fn/C4D_Living.xml:12(desc) -#, fuzzy msgid "Objects with this category are alive when created." -msgstr "Objektkategorie: Spielregeln" +msgstr "Objektkategorie: Lebewesen" #: sdk/script/fn/C4D_Living.xml:16(text) msgid "Returns the first type of living beings which can be built by player 1 - usually none." @@ -9658,6 +9838,7 @@ msgstr "Gibt dem Clonk den Befehl, zuerst zu der ersten (gefundenen) Basis zu la #: sdk/script/fn/Anim_Y.xml:21(desc) #: sdk/script/fn/Anim_XDir.xml:16(desc) #: sdk/script/fn/Anim_X.xml:21(desc) +#: sdk/script/fn/Anim_R.xml:16(desc) #: sdk/script/fn/Anim_Linear.xml:21(desc) #: sdk/script/fn/Anim_AbsY.xml:21(desc) #: sdk/script/fn/Anim_AbsX.xml:21(desc) @@ -9735,6 +9916,20 @@ msgstr "Der Wert hängt von der Bewegung des Objekts in X-Richtung ab. Jeder Pix msgid "Plays the animation \"Drive\" in slot 5 and superimposes any other potential animations in slot 5. The animation is played the faster the faster the object moves into X direction. Once the object moved 15 pixels the animation will have been played from begin to end and it restarts from the beginning. Here we use instead of so that the wheels of a vehicle turn backwards when driving backwards." msgstr "Spielt die Animation \"Drive\" in Slot 5 ab und überlagert dabei eventuelle andere Animationen in Slot 5. Die Animation wird dabei umso schneller abgespielt je schneller sich das Objekt in X-Richtung bewegt. Nachdem es 15 Pixel zurückgelegt hat ist die Animation einmal von vorne bis hinten durchgespielt worden und fängt wieder von vorne an. Hier wird anstelle von verwendet, da sich die Räder eines Fahrzeugs beim Rückwärtsfahren auch rückwärts drehen sollen." +#: sdk/script/fn/Anim_R.xml:21(desc) +#, fuzzy +msgid "End of the interval. If end is chosen to be greater than begin then the value increases with clockwise rotation, otherwise it decreases." +msgstr "Schluss des Intervalls. Wenn end größer als begin ist, so nimmt der Wert mit der Bewegung des Objekts in positiver X-Richtung zu, andernfalls nimmt er ab." + +#: sdk/script/fn/Anim_R.xml:25(desc) +msgid "The value depends on the rotation of the object. Upward rotation (0 degrees) is mapped to the value given by begin, and moves toward end when the object rotates clockwise, up to end after one revolution (360 degrees)." +msgstr "" + +#: sdk/script/fn/Anim_R.xml:30(text) +#, fuzzy +msgid "Plays the animation \"Turn\" in slot 5 and superimposes any other potential animations in slot 5. The animation is synchronized to the object's rotation so that the full animation is played once per revolution." +msgstr "Spielt die Animation \"Lift\" in Slot 5 ab und überlagert dabei eventuelle andere Animationen in Slot 5. Die Animation wird dabei umso schneller abgespielt je schneller sich das Objekt in Y-Richtung bewegt. Nachdem es 25 Pixel zurückgelegt hat ist die Animation einmal von vorne bis hinten durchgespielt worden und fängt wieder von vorne an." + #: sdk/script/fn/Anim_Linear.xml:26(desc) msgid "End of the interval. If end is larger than begin then the value increases linearily with time, otherwise it decreases." msgstr "Schluss des Intervalls. Wenn end größer als begin ist, so steigt der Wert mit der Zeit an, andernfalls nimmt er ab." @@ -10118,7 +10313,7 @@ msgstr "Variableninhalt" #: sdk/script/Typechecks.xml:16(col) #: sdk/definition/category.xml:74(h) -#: sdk/definition/actmap.xml:150(h) +#: sdk/definition/actmap.xml:165(h) msgid "Example" msgstr "Beispiel" @@ -10142,8 +10337,9 @@ msgstr "Beispiel" #: sdk/scenario/scenario.xml:320(col) #: sdk/scenario/scenario.xml:325(col) #: sdk/scenario/scenario.xml:330(col) -#: sdk/scenario/scenario.xml:395(col) -#: sdk/scenario/scenario.xml:425(col) +#: sdk/scenario/scenario.xml:335(col) +#: sdk/scenario/scenario.xml:390(col) +#: sdk/scenario/scenario.xml:420(col) #: sdk/scenario/Teams.xml:20(col) #: sdk/scenario/Teams.xml:26(col) #: sdk/scenario/Teams.xml:32(col) @@ -10162,9 +10358,10 @@ msgstr "Beispiel" #: sdk/scenario/MapCreatorS2.xml:78(col) #: sdk/scenario/MapCreatorS2.xml:88(col) #: sdk/scenario/MapCreatorS2.xml:113(col) -#: sdk/playercontrols.xml:52(col) -#: sdk/playercontrols.xml:57(col) -#: sdk/playercontrols.xml:161(col) +#: sdk/playercontrols.xml:51(col) +#: sdk/playercontrols.xml:56(col) +#: sdk/playercontrols.xml:206(col) +#: sdk/playercontrols.xml:216(col) #: sdk/particle/index.xml:41(col) #: sdk/particle/index.xml:46(col) #: sdk/particle/index.xml:51(col) @@ -10229,34 +10426,40 @@ msgstr "Beispiel" #: sdk/folder/foldermap.xml:115(col) #: sdk/folder/foldermap.xml:120(col) #: sdk/folder/foldermap.xml:125(col) +#: sdk/definition/properties.xml:135(col) +#: sdk/definition/properties.xml:140(col) +#: sdk/definition/properties.xml:150(col) +#: sdk/definition/properties.xml:155(col) #: sdk/definition/defcore.xml:35(col) #: sdk/definition/defcore.xml:40(col) +#: sdk/definition/defcore.xml:45(col) #: sdk/definition/defcore.xml:50(col) #: sdk/definition/defcore.xml:55(col) -#: sdk/definition/defcore.xml:60(col) #: sdk/definition/defcore.xml:65(col) -#: sdk/definition/defcore.xml:75(col) -#: sdk/definition/defcore.xml:80(col) -#: sdk/definition/defcore.xml:105(col) +#: sdk/definition/defcore.xml:70(col) +#: sdk/definition/defcore.xml:95(col) +#: sdk/definition/defcore.xml:130(col) +#: sdk/definition/defcore.xml:135(col) #: sdk/definition/defcore.xml:140(col) #: sdk/definition/defcore.xml:145(col) #: sdk/definition/defcore.xml:150(col) #: sdk/definition/defcore.xml:155(col) #: sdk/definition/defcore.xml:160(col) -#: sdk/definition/defcore.xml:170(col) +#: sdk/definition/defcore.xml:165(col) #: sdk/definition/defcore.xml:175(col) #: sdk/definition/defcore.xml:180(col) #: sdk/definition/defcore.xml:185(col) #: sdk/definition/defcore.xml:190(col) #: sdk/definition/defcore.xml:195(col) +#: sdk/definition/defcore.xml:200(col) #: sdk/definition/defcore.xml:205(col) #: sdk/definition/defcore.xml:210(col) -#: sdk/definition/defcore.xml:215(col) #: sdk/definition/defcore.xml:220(col) #: sdk/definition/defcore.xml:225(col) #: sdk/definition/defcore.xml:230(col) #: sdk/definition/defcore.xml:235(col) #: sdk/definition/defcore.xml:240(col) +#: sdk/definition/defcore.xml:245(col) #: sdk/definition/defcore.xml:250(col) #: sdk/definition/defcore.xml:255(col) #: sdk/definition/defcore.xml:260(col) @@ -10278,8 +10481,6 @@ msgstr "Beispiel" #: sdk/definition/defcore.xml:340(col) #: sdk/definition/defcore.xml:345(col) #: sdk/definition/defcore.xml:350(col) -#: sdk/definition/defcore.xml:355(col) -#: sdk/definition/defcore.xml:360(col) #: sdk/definition/defcore.xml:365(col) #: sdk/definition/defcore.xml:370(col) #: sdk/definition/defcore.xml:375(col) @@ -10287,6 +10488,8 @@ msgstr "Beispiel" #: sdk/definition/defcore.xml:385(col) #: sdk/definition/defcore.xml:390(col) #: sdk/definition/defcore.xml:395(col) +#: sdk/definition/defcore.xml:400(col) +#: sdk/definition/defcore.xml:405(col) #: sdk/definition/defcore.xml:410(col) #: sdk/definition/defcore.xml:415(col) #: sdk/definition/defcore.xml:420(col) @@ -10296,15 +10499,6 @@ msgstr "Beispiel" #: sdk/definition/defcore.xml:440(col) #: sdk/definition/defcore.xml:445(col) #: sdk/definition/defcore.xml:450(col) -#: sdk/definition/defcore.xml:455(col) -#: sdk/definition/defcore.xml:460(col) -#: sdk/definition/defcore.xml:465(col) -#: sdk/definition/defcore.xml:470(col) -#: sdk/definition/defcore.xml:475(col) -#: sdk/definition/defcore.xml:480(col) -#: sdk/definition/defcore.xml:485(col) -#: sdk/definition/defcore.xml:490(col) -#: sdk/definition/defcore.xml:495(col) #: sdk/definition/actmap.xml:30(col) #: sdk/definition/actmap.xml:35(col) #: sdk/definition/actmap.xml:40(col) @@ -10314,11 +10508,15 @@ msgstr "Beispiel" #: sdk/definition/actmap.xml:60(col) #: sdk/definition/actmap.xml:65(col) #: sdk/definition/actmap.xml:70(col) +#: sdk/definition/actmap.xml:75(col) #: sdk/definition/actmap.xml:80(col) #: sdk/definition/actmap.xml:85(col) +#: sdk/definition/actmap.xml:90(col) +#: sdk/definition/actmap.xml:95(col) #: sdk/definition/actmap.xml:100(col) -#: sdk/definition/actmap.xml:135(col) -#: sdk/definition/actmap.xml:140(col) +#: sdk/definition/actmap.xml:115(col) +#: sdk/definition/actmap.xml:150(col) +#: sdk/definition/actmap.xml:155(col) msgid "Integer" msgstr "Integer" @@ -10331,16 +10529,20 @@ msgstr "Eine ganze Zahl im Bereich von -2.147.483.648 bis +2.147.483.647." #: sdk/scenario/MapCreatorS2.xml:93(col) #: sdk/scenario/MapCreatorS2.xml:98(col) #: sdk/scenario/MapCreatorS2.xml:108(col) -#: sdk/playercontrols.xml:42(col) -#: sdk/playercontrols.xml:47(col) -#: sdk/playercontrols.xml:62(col) -#: sdk/playercontrols.xml:72(col) -#: sdk/playercontrols.xml:151(col) +#: sdk/playercontrols.xml:41(col) +#: sdk/playercontrols.xml:46(col) +#: sdk/playercontrols.xml:61(col) +#: sdk/playercontrols.xml:71(col) +#: sdk/playercontrols.xml:158(col) +#: sdk/playercontrols.xml:163(col) +#: sdk/playercontrols.xml:168(col) +#: sdk/playercontrols.xml:186(col) +#: sdk/playercontrols.xml:211(col) #: sdk/material/ocm.xml:254(col) #: sdk/material/ocm.xml:259(col) #: sdk/material/ocm.xml:264(col) #: sdk/folder/foldermap.xml:130(col) -#: sdk/definition/actmap.xml:90(col) +#: sdk/definition/actmap.xml:105(col) msgid "Boolean" msgstr "Boolean" @@ -10377,13 +10579,12 @@ msgid "When used as a function parameter type, the type check is skipped." msgstr "Wenn als Parametertyp für eine Funktion benutzt wird die Typüberprüfung nicht vorgenommen." #: sdk/script/Typechecks.xml:68(emlink) -#, fuzzy msgid "Object Definition" -msgstr "Objektdefinitionen" +msgstr "Objektdefinition" #: sdk/script/Typechecks.xml:69(col) msgid "Represents a DefCore.txt and the associated Script.c. A special kind of proplist." -msgstr "" +msgstr "Repräsentiert eine DefCore.txt und die angeschlossene Script.c. Eine spezielle Proplist." #: sdk/script/Typechecks.xml:74(col) msgid "Ingame Object" @@ -10391,15 +10592,11 @@ msgstr "Spielobjekt" #: sdk/script/Typechecks.xml:75(col) msgid "An instance of an Object Definition. A special kind of proplist." -msgstr "" +msgstr "Eine Instanz einer Object Definition. Eine spezielle Proplist." #: sdk/script/Typechecks.xml:81(col) msgid "A special kind of proplist with associated timers and stacking callbacks." -msgstr "" - -#: sdk/script/Typechecks.xml:86(h) -msgid "Arrays" -msgstr "Arrays" +msgstr "Eine spezielle Proplist mit Timer und Stapel-Callbacks." #: sdk/script/Typechecks.xml:88(text) msgid "Arrays can be created directly with [expression 1, expression 2, ...] or indirectly with (). They are automatically enlarged if necessary on element access, but it's faster to create them with the needed length from the start. Arrays behave like objects, you can only store references of them. Example: var a = CreateArray(), b = a; b[0] = 42; // a is now [42] A copy of a can be obtained with a[:], as explained below." @@ -10470,9 +10667,8 @@ msgid "nil can always be used as a function parameter, if the funct msgstr "nil kann immer als Funktionsparameter verwendet werden wenn die Funktion keine separate Überprüfung vornimmt." #: sdk/script/Typechecks.xml:133(li) -#, fuzzy msgid "Objects, Definitions and Effects can be converted to proplists, and then back. Normal proplists cannot be converted into them." -msgstr "Wenn ein Objekt in eine Proplist konvertiert wurde, kann es wieder in ein Objekt konvertiert werden. Ansonsten können Proplists nicht in Objekte konvertiert werden." +msgstr "Objekte, Definitionen und Effekte können in eine Proplist und zurück konvertiert werden. Ansonsten können Proplisten nicht in diese konvertiert werden." #: sdk/script/ScriptPlayers.xml:10(text) msgid "It is possible to create non-human players by script. These players have all the properties of normal players. They have a crew, wealth, build knowledge, home base material, hostility, teams, etc. However, script players do not have a game view port and they can not be controlled by human users." @@ -10571,9 +10767,8 @@ msgid "The variable's scope, followed by the variable's name." msgstr "Als erstes wird der Gültigkeitbereich angegeben. Danach muss der Name einer benannten Variable folgen." #: sdk/script/NamedVar.xml:38(text) -#, fuzzy msgid "Optionally, you can assign a value to the variable directly at declaration time. However, this is not possible for static variables. Without initialization variables always start with nil." -msgstr "Optional kann der Variable auch gleich ein Wert zugewiesen werden. Dies funktioniert allerdings nicht für globale Variablen. Ohne Initialisierung enthält die Variable anfangs nil." +msgstr "Optional kann der Variable auch gleich ein Wert zugewiesen werden. Dies funktioniert allerdings nicht für static Variablen. Ohne Initialisierung enthält die Variable anfangs nil." #: sdk/script/NamedVar.xml:39(text) msgid "Additional variable declarations may follow, separated by comma. The declaration must always be ended with a semicolon." @@ -10589,7 +10784,7 @@ msgstr "Definitionen objektlokaler Variablen werden sowohl bei #appendto also au #: sdk/script/NamedVar.xml:73(li) msgid "When this is a definition, local variables are constant. That protects against accidental modifications that would appear to work fine while there is only one object of a kind, but break in subtle ways as soon as there are multiple instances." -msgstr "" +msgstr "Wenn this eine Definition ist, sind lokale Variablen konstant. Dies schützt vor versehentlichen Änderungen die nur funktionieren wenn es nur ein Objekt der Definition gibt, aber auf subtile Weise schief gehen sobald es mehrere gibt." #: sdk/script/NamedVar.xml:74(li) msgid "Using the obj.foo or obj[\"foo\"] notation one can access local variables in other objects." @@ -10772,19 +10967,19 @@ msgstr "führt also zu der Nachricht \"The sum of the first four parameters is 1 #: sdk/script/Funcs.xml:37(text) msgid "All functions also have a hidden parameter called this. When calling a function in another proplist (which can be an object, a definition, or any other type of proplist) with p -> Foo(); or p ->~ Foo();, the function Foo gets the proplist p as this." -msgstr "" +msgstr "Alle Funktionen haben einen versteckten Parameter, der this genannt wird. Wenn eine Funktion in einer anderen Proplist (welche auch ein Objekt, Definition oder irgendeine andere Art von Proplist sein kann) mit p -> Foo(); oder p ->~ Foo(); aufgerufen wird, bekommt die Funktion Foo die Proplist p als this." #: sdk/script/Funcs.xml:47(text) msgid "Calling Bar in this script results in this output:" -msgstr "" +msgstr "In diesem Script Bar aufzurufen ergibt diese Ausgabe:" #: sdk/script/Funcs.xml:51(text) -msgid "The last call to Foo shows the reason for this: Most of the functions in an object need that object to do something with it, and passing the object to every function would result in a lot of repetetive code." -msgstr "" +msgid "The last call to Foo shows the reason for this: Most of the functions in an object need that object to do something with it, and passing the object to every function would result in a lot of repetitive code." +msgstr "Der letzte Aufruf von Foo zeigt den Grund für this: Die meisten Funktionen in einem Objekt brauchen das Objekt um damit etwas zu tun, und das Objekt an jede Funktion zu übergeben würde zu einer Menge sich wiederholendem Code führen." #: sdk/script/Funcs.xml:52(text) -msgid "Note for everyone familiar with previous versions of C4Script: When calling a function in a definition like Flint->Hit();, the definition is returned from this. In the Flint->Hit(); example, that will probably result in an error message from the engine like \"passed proplist, but expected object\"." -msgstr "" +msgid "Note for everyone familiar with previous versions of C4Script: When calling a function in a definition like Flint->Hit();, the definition is returned from this. In the Flint->Hit(); example, that will probably result in an error message from the engine like \"passed proplist, but expected object\", because the Hit function of the Flint is not designed to be called like that." +msgstr "Hinweise für Kenner vorheriger Versionen von C4Script: Beim Aufruf einer Funktion in einer Definition wie etwa Flint->Hit();, wird die Definition von this zurückgegeben. In diesem Beispiel führt das wahrscheinlich zu einer Fehlermeldung wie \"passed proplist, but expected object\", da die Hit-Funktion des Flints nicht dazu gedacht ist, so aufgerufen zu werden." #: sdk/script/Funcs.xml:53(h) msgid "Parameter Types" @@ -10923,8 +11118,8 @@ msgid "Remarks" msgstr "Anmerkungen" #: sdk/script/FuncCall.xml:44(text) -msgid "You don't have to store the object pointer in a variable as done in this example. You could also continue calling the function directly on the search result as in this case:" -msgstr "Die Speicherung des Objektzeigers in der Variable obj im Beispiel ist nicht erforderlich. Die folgende Schreibweise der Funktion Activate() in B ist gleichwertig:" +msgid "You don't have to store the object pointer in a variable as done in this example. You could also continue calling the function directly on the search result as in this case:" +msgstr "Die Speicherung des Objektzeigers in der Variable obj im Beispiel ist nicht erforderlich. Die folgende Schreibweise der Funktion Activate() in B ist gleichwertig:" #: sdk/script/FuncCall.xml:50(h) msgid "Indirect call of script functions" @@ -10947,9 +11142,8 @@ msgid "This process has to be done with indirect calls as only at runtime we can msgstr "Call muss hier verwendet werden, da erst zur Laufzeit bestimmt wird, welche Funktion aufgerufen wird. Außerdem wird bei jeder Ausführung von TestFunction() eine andere Scriptfunktion ausgewählt, die aufgerufen wird. Dies wäre mit einem direkten Aufruf nicht möglich." #: sdk/script/FuncCall.xml:74(text) -#, fuzzy msgid "There are also some other methods of indirect calls. See ." -msgstr "Für weitere Informationen und Beispiele zur Benutzung dieser Funktion sehe ." +msgstr "Es gibt noch ein paar weitere Methoden für indirekte Aufrufe. Siehe ." #: sdk/script/Effects.xml:9(text) msgid "Any number of effects can be attached to an object. Effects can perform various tasks, thus eliminating the need for helper objects. This is especially of interest for magic spells that act with a given duration." @@ -10992,7 +11186,7 @@ msgid "To store the previous status of the target object, properties of the effe msgstr "Zum Speichern der vorherigen Statuswerte des Effektziels werden die Eigenschaften des Effekts verwendet. Dies ist nötig, da die Effekt-Callbacks in diesem Fall keinen Befehlskontext haben. Es können also keine objektlokalen Variablen verwendet werden - das Zauberobjekt wurde schließlich gelöscht. Falls ein Objektkontext benötigt wird, kann man diesen auch an () übergeben. Die Aufrufe sind dann objektlokal, und der Effekt wird automatisch gelöscht, wenn das Befehlszielobjekt gelöscht wurde." #: sdk/script/Effects.xml:101(h) -#: sdk/playercontrols.xml:357(h) +#: sdk/playercontrols.xml:404(h) msgid "Priorities" msgstr "Prioritäten" @@ -11162,27 +11356,26 @@ msgstr "Eigenschaften-Referenz" #: sdk/script/Effects.xml:332(text) msgid "Effects have a number of standard properties:" -msgstr "" +msgstr "Effekte haben folgende Standard-eigenschaften" #: sdk/script/Effects.xml:334(caption) -#, fuzzy msgid "Effect Properties" -msgstr "Objekteigenschaften" +msgstr "Effekt Properties" #: sdk/script/Effects.xml:336(col) #: sdk/scenario/scenario.xml:15(col) #: sdk/scenario/scenario.xml:95(col) #: sdk/scenario/scenario.xml:125(col) #: sdk/scenario/scenario.xml:185(col) -#: sdk/scenario/scenario.xml:340(col) -#: sdk/scenario/scenario.xml:360(col) -#: sdk/scenario/scenario.xml:405(col) -#: sdk/scenario/scenario.xml:420(col) +#: sdk/scenario/scenario.xml:345(col) +#: sdk/scenario/scenario.xml:365(col) +#: sdk/scenario/scenario.xml:400(col) +#: sdk/scenario/scenario.xml:415(col) #: sdk/scenario/Teams.xml:14(col) #: sdk/scenario/Teams.xml:73(col) -#: sdk/playercontrols.xml:22(col) -#: sdk/playercontrols.xml:127(col) -#: sdk/playercontrols.xml:141(col) +#: sdk/playercontrols.xml:21(col) +#: sdk/playercontrols.xml:143(col) +#: sdk/playercontrols.xml:176(col) #: sdk/particle/index.xml:31(col) #: sdk/material/ocm.xml:15(col) #: sdk/material/ocm.xml:229(col) @@ -11192,7 +11385,7 @@ msgstr "Objekteigenschaften" #: sdk/folder/foldermap.xml:70(col) #: sdk/definition/properties.xml:25(col) #: sdk/definition/defcore.xml:15(col) -#: sdk/definition/defcore.xml:405(col) +#: sdk/definition/defcore.xml:360(col) #: sdk/definition/actmap.xml:15(col) msgid "Data type" msgstr "Datentyp" @@ -11203,9 +11396,8 @@ msgid "string" msgstr "string" #: sdk/script/Effects.xml:343(col) -#, fuzzy msgid "Can be changed." -msgstr "0-3: Farbwert, der geändert werden soll" +msgstr "Kann geändert werden." #: sdk/script/Effects.xml:346(col) #: sdk/script/Effects.xml:351(col) @@ -11219,7 +11411,7 @@ msgstr "int" #: sdk/script/Effects.xml:348(col) msgid "See Priorities" -msgstr "" +msgstr "Siehe Prioritäten" #: sdk/script/Effects.xml:353(col) msgid "Of the Timer callback." @@ -11413,287 +11605,308 @@ msgid "reason contains the cause of the removal and can be one of the following msgstr "reason gibt den Grund für das Entfernen des Effektes an, und kann einer der folgenden Werte sein:" #: sdk/script/Effects.xml:508(col) +#: sdk/script/Effects.xml:564(col) +msgid "Script constant" +msgstr "Scriptkonstante" + +#: sdk/script/Effects.xml:509(col) msgid "reason" msgstr "reason" #: sdk/script/Effects.xml:513(col) +msgid "FX_Call_Normal" +msgstr "FX_Call_Normal" + +#: sdk/script/Effects.xml:515(col) msgid "Normal removal" msgstr "Effekt wird regulär entfernt" -#: sdk/script/Effects.xml:517(col) +#: sdk/script/Effects.xml:518(col) +msgid "FX_Call_Temp" +msgstr "FX_Call_Temp" + +#: sdk/script/Effects.xml:520(col) msgid "Temporary removal (temporary is 1)." msgstr "Effekt wird nur temporär entfernt. temporary ist in dem Fall 1." -#: sdk/script/Effects.xml:521(col) +#: sdk/script/Effects.xml:523(col) +msgid "FX_Call_TempAddForRemoval" +msgstr "FX_Call_TempAddForRemoval" + +#: sdk/script/Effects.xml:525(col) msgid "Not used" msgstr "nicht verwendet" -#: sdk/script/Effects.xml:525(col) +#: sdk/script/Effects.xml:528(col) +msgid "FX_Call_RemoveClear" +msgstr "FX_Call_RemoveClear" + +#: sdk/script/Effects.xml:530(col) msgid "The target object has been deleted" msgstr "Effekt wird entfernt, weil das Objekt gelöscht wird" -#: sdk/script/Effects.xml:529(col) +#: sdk/script/Effects.xml:533(col) +msgid "FX_Call_RemoveDeath" +msgstr "FX_Call_RemoveDeath" + +#: sdk/script/Effects.xml:535(col) msgid "The target object has died" msgstr "Effekt wird entfernt, weil das Objekt stirbt" -#: sdk/script/Effects.xml:533(text) +#: sdk/script/Effects.xml:539(text) msgid "The effect can prevent removal by returning -1. This will not help, however, in temporary removals or if the target object has been deleted." msgstr "Wenn der Effekt nicht gelöscht werden soll, kann in der Funktion -1 zurückgegeben werden, um das Löschen zu verhindern. Bei temporären Aufrufen oder wenn das Zielobjekt gelöscht wird, bringt dies natürlich nichts." -#: sdk/script/Effects.xml:534(h) +#: sdk/script/Effects.xml:540(h) msgid "Fx*Timer" msgstr "Fx*Timer" -#: sdk/script/Effects.xml:536(text) +#: sdk/script/Effects.xml:542(text) msgid "Periodic timer call, if a timer interval has been specified at effect creation. target and effect as usual." msgstr "Periodischer Timer-Aufruf, wenn bei der Effekterzeugung ein Timer-Intervall angegeben wurde. target und effect spezifizieren auch hier Zielobjekt und Effekt." -#: sdk/script/Effects.xml:537(text) +#: sdk/script/Effects.xml:543(text) msgid "time specifies how long the effect has now been active. This might alternatively be determined using effect.Time." msgstr "time gibt die die Zeit an, die der Effekt schon läuft. Diese lässt sich auch über effect.Time herausfinden." -#: sdk/script/Effects.xml:538(text) +#: sdk/script/Effects.xml:544(text) msgid "If this function is not implemented or returns -1, the effect will be deleted after this call." msgstr "Ein Rückgabewert von -1 bedeutet, dass der Effekt nach dem Aufruf gelöscht wird. Dasselbe passiert, wenn die Funktion nicht implementiert wird." -#: sdk/script/Effects.xml:539(h) +#: sdk/script/Effects.xml:545(h) msgid "Fx*Effect" msgstr "Fx*Effect" -#: sdk/script/Effects.xml:541(text) +#: sdk/script/Effects.xml:547(text) msgid "A call to all effects of higher priority if a new effect is to be added to the same target object. new_name is the name of the new effect; effect is the effect being called." msgstr "Aufruf an alle Effekte mit höherer Priorität, wenn ein neuer Effekt zu demselben Objekt (target) hinzugefügt werden soll. new_name gibt den Namen des neuen Effektes an; effect ist der Effekt bei dem angefragt wird." -#: sdk/script/Effects.xml:542(text) +#: sdk/script/Effects.xml:548(text) msgid "Warning: the new effect is not yet properly initialized and should not be manipulated in any way. Especially the priority field might not yet have been set." msgstr "Achtung: Der neue Effekt ist noch nicht fertig initialisiert, und sollte daher nicht manipuliert werden. Insbesondere das Priority-Feld ist möglicherweise noch nicht initialisiert." -#: sdk/script/Effects.xml:543(text) +#: sdk/script/Effects.xml:549(text) msgid "This function can return -1 to reject the new effect. As the new effect might also be rejected by other effects, this callback should not try to add effects or similar (see gravitation spell). Generally you should not try to manipulate any effects during this callback." msgstr "Die Funktion sollte -1 zurückgeben, wenn sie den neuen Effekt ablehnt. Da der Effekt auch noch von einem anderen Effekt abgelehnt werden kann, sollte dieser Callback nicht dazu verwendet werden, um beispielsweise Effekte zusammenzufassen (siehe Beispiel zum Gravitationszauber). Überhaupt sollte es möglichst vermieden werden, in diesem Aufruf die Effektliste zu manipulieren." -#: sdk/script/Effects.xml:544(text) +#: sdk/script/Effects.xml:550(text) msgid "Return -2 or -3 to accept the new effect. As long as the new effect is not rejected by any other effect, the Fx*Add call is then made to the accepting effect, the new effect is not actually created, and the calling AddEffect function returns the effect index of the accepting effect. The return value -3 will also temporarily remove all higher prioriy effects just before the Fx*Add callback and re-add them later." msgstr "Ein Rückgabewert von -2 oder -3 sollte angegeben werden, wenn der Effekt übernommen wird. Sofern der Effekt dann von keinem anderen Effekt abgelehnt wurde (über Rückgabewert -1), wird ein Fx*Add-Aufruf an den übernehmenden Effekt gesendet, der neue Effekt selber entfernt, und die aufrufende AddEffect-Funktion erhält als Rückgabewert die Nummer des übernehmenden Effektes. Rückgabewert -3 bedeutet dabei im Gegensatz zu -2, dass vor dem Fx*Add-Aufruf alle Effekte mit höherer Priorität temporär entfernt, und nach dem Aufruf dieselben wieder temporär hinzugefügt werden." -#: sdk/script/Effects.xml:545(text) +#: sdk/script/Effects.xml:551(text) msgid "var1 bis var4 are the parameters passed to ()" msgstr "var1 bis var4 sind die Parameter, die an die ()-Funktion übergeben wurden." -#: sdk/script/Effects.xml:546(h) +#: sdk/script/Effects.xml:552(h) msgid "Fx*Add" msgstr "Fx*Add" -#: sdk/script/Effects.xml:548(text) +#: sdk/script/Effects.xml:554(text) msgid "Callback to the accepting effect if that has returned -2 or -3 to a prior Fx*Effect call. effect identifies the accepting effect to which the consequences of the new effect will be added; target is the target object (0 for global effects)." msgstr "Aufruf an einen übernehmenden Effekt, wenn dieser zuvor auf einen Fx*Effect-Callback hin -2 oder -3 zurückgegeben hat. effect gibt den Effektes an, zu dem hinzugefügt wird; target das Zielobjekt (0 bei globalen Effekten)." -#: sdk/script/Effects.xml:549(text) +#: sdk/script/Effects.xml:555(text) msgid "new_timer is the timer interval of the new effect; var1 to var4 are the parameters from AddEffect. Notice: in temporary calls, these parameters are not available - here they will be 0." msgstr "new_timer ist das Timer-Intervall des neu erzeugten Effektes; var1 bis var4 die an AddEffect übergebenen Zusatzparameter. ACHTUNG: Diese Zusatzparameter werden natürlich nicht bei temporären Aufrufen übergeben, sondern sind dann 0." -#: sdk/script/Effects.xml:550(text) +#: sdk/script/Effects.xml:556(text) msgid "If -1 is returned, the accepting effect is deleted also. Logically, the calling AddEffect function will then return -2." msgstr "Wird -1 zurückgegeben, wird auch der übernehmende Effekt entfernt. Logischerweise gibt die erzeugende AddEffect-Funktion dann -2 zurück." -#: sdk/script/Effects.xml:551(h) +#: sdk/script/Effects.xml:557(h) msgid "Fx*Damage" msgstr "Fx*Damage" -#: sdk/script/Effects.xml:553(text) +#: sdk/script/Effects.xml:559(text) msgid "Every effect receives this callback whenever the energy or damage value of the target object is to change. If the function is defined, it should then return whether to allow the change." msgstr "Jeder Effekt erhält diesen Callback, wann immer sich der Energie- oder Schadenswert des Zielobjektes ändert. Falls die Funktion definiert wird, sollte der Rückgabewert dabei die erlaubte Änderung angeben." -#: sdk/script/Effects.xml:554(text) +#: sdk/script/Effects.xml:560(text) msgid "This callback is made upon life energy changes in living beings and damage value changes in non-livings - but not vice versa. cause contains the value change and reason:" msgstr "Der Callback wird bei Energiewertänderungen bei Lebewesen, sowie bei Schadenswertänderungen bei nicht-Lebewesen durchgeführt - nicht aber umgekehrt. cause gibt den geänderten Wert und den Grund an:" -#: sdk/script/Effects.xml:558(col) -msgid "Script constant" -msgstr "Scriptkonstante" - -#: sdk/script/Effects.xml:559(col) +#: sdk/script/Effects.xml:565(col) msgid "cause" msgstr "cause" -#: sdk/script/Effects.xml:563(col) +#: sdk/script/Effects.xml:569(col) msgid "FX_Call_DmgScript" msgstr "FX_Call_DmgScript" -#: sdk/script/Effects.xml:565(col) +#: sdk/script/Effects.xml:571(col) msgid "Damage by script call ()" msgstr "Schaden durch Scriptaufruf ()" -#: sdk/script/Effects.xml:568(col) +#: sdk/script/Effects.xml:574(col) msgid "FX_Call_DmgBlast" msgstr "FX_Call_DmgBlast" -#: sdk/script/Effects.xml:570(col) +#: sdk/script/Effects.xml:576(col) msgid "Damage by explosion" msgstr "Schaden durch Explosion" -#: sdk/script/Effects.xml:573(col) +#: sdk/script/Effects.xml:579(col) msgid "FX_Call_DmgFire" msgstr "FX_Call_DmgFire" -#: sdk/script/Effects.xml:575(col) +#: sdk/script/Effects.xml:581(col) msgid "Damage by fire" msgstr "Schaden durch Feuer" -#: sdk/script/Effects.xml:578(col) +#: sdk/script/Effects.xml:584(col) msgid "FX_Call_DmgChop" msgstr "FX_Call_DmgChop" -#: sdk/script/Effects.xml:580(col) +#: sdk/script/Effects.xml:586(col) msgid "Damage by chopping (only trees)" msgstr "Schaden durch Fällen (nur Bäume)" -#: sdk/script/Effects.xml:583(col) +#: sdk/script/Effects.xml:589(col) msgid "FX_Call_EngScript" msgstr "FX_Call_EngScript" -#: sdk/script/Effects.xml:584(col) +#: sdk/script/Effects.xml:590(col) #: sdk/definition/cnat.xml:49(col) msgid "32" msgstr "32" -#: sdk/script/Effects.xml:585(col) +#: sdk/script/Effects.xml:591(col) msgid "Energy value change by script call ()" msgstr "Energieänderung durch Scriptaufruf ()" -#: sdk/script/Effects.xml:588(col) +#: sdk/script/Effects.xml:594(col) msgid "FX_Call_EngBlast" msgstr "FX_Call_EngBlast" -#: sdk/script/Effects.xml:589(col) +#: sdk/script/Effects.xml:595(col) msgid "33" msgstr "33" -#: sdk/script/Effects.xml:590(col) +#: sdk/script/Effects.xml:596(col) msgid "Energy loss by explosion" msgstr "Energieverlust durch Explosion" -#: sdk/script/Effects.xml:593(col) +#: sdk/script/Effects.xml:599(col) msgid "FX_Call_EngObjHit" msgstr "FX_Call_EngObjHit" -#: sdk/script/Effects.xml:594(col) +#: sdk/script/Effects.xml:600(col) msgid "34" msgstr "34" -#: sdk/script/Effects.xml:595(col) +#: sdk/script/Effects.xml:601(col) msgid "Energy loss by object hit" msgstr "Energieverlust durch Objekttreffer" -#: sdk/script/Effects.xml:598(col) +#: sdk/script/Effects.xml:604(col) msgid "FX_Call_EngFire" msgstr "FX_Call_EngFire" -#: sdk/script/Effects.xml:599(col) +#: sdk/script/Effects.xml:605(col) msgid "35" msgstr "35" -#: sdk/script/Effects.xml:600(col) +#: sdk/script/Effects.xml:606(col) msgid "Energy loss by fire" msgstr "Energieverlust durch Feuer" -#: sdk/script/Effects.xml:603(col) +#: sdk/script/Effects.xml:609(col) msgid "FX_Call_EngBaseRefresh" msgstr "FX_Call_EngBaseRefresh" -#: sdk/script/Effects.xml:604(col) +#: sdk/script/Effects.xml:610(col) msgid "36" msgstr "36" -#: sdk/script/Effects.xml:605(col) +#: sdk/script/Effects.xml:611(col) msgid "Energy recharge at the home base" msgstr "Energieaufnahme in der Basis - auch Abgabe und Kauf der Basis, wenn die Basis ein Lebewesen ist" -#: sdk/script/Effects.xml:608(col) +#: sdk/script/Effects.xml:614(col) msgid "FX_Call_EngAsphyxiation" msgstr "FX_Call_EngAsphyxiation" -#: sdk/script/Effects.xml:609(col) +#: sdk/script/Effects.xml:615(col) msgid "37" msgstr "37" -#: sdk/script/Effects.xml:610(col) +#: sdk/script/Effects.xml:616(col) msgid "Energy loss by suffocation" msgstr "Energieverlust durch Ersticken" -#: sdk/script/Effects.xml:613(col) +#: sdk/script/Effects.xml:619(col) msgid "FX_Call_EngCorrosion" msgstr "FX_Call_EngCorrosion" -#: sdk/script/Effects.xml:614(col) +#: sdk/script/Effects.xml:620(col) msgid "38" msgstr "38" -#: sdk/script/Effects.xml:615(col) +#: sdk/script/Effects.xml:621(col) msgid "Energy loss through acid" msgstr "Energieverlust durch Säure" -#: sdk/script/Effects.xml:618(col) +#: sdk/script/Effects.xml:624(col) msgid "FX_Call_EngStruct" msgstr "FX_Call_EngStruct" -#: sdk/script/Effects.xml:619(col) +#: sdk/script/Effects.xml:625(col) msgid "39" msgstr "39" -#: sdk/script/Effects.xml:620(col) +#: sdk/script/Effects.xml:626(col) msgid "Energy loss of buildings (only \"living\" buildings)" msgstr "Energieverlust von Gebäuden (Nur lebende Gebäude)" -#: sdk/script/Effects.xml:623(col) +#: sdk/script/Effects.xml:629(col) msgid "FX_Call_EngGetPunched" msgstr "FX_Call_EngGetPunched" -#: sdk/script/Effects.xml:624(col) +#: sdk/script/Effects.xml:630(col) msgid "40" msgstr "40" -#: sdk/script/Effects.xml:625(col) +#: sdk/script/Effects.xml:631(col) msgid "Energy loss through clonk-to-clonk battle" msgstr "Energieverlust im Clonk-zu-Clonk-Kampf" -#: sdk/script/Effects.xml:629(text) +#: sdk/script/Effects.xml:635(text) msgid "Generally, the expression \"cause & 32\" can be used to determine whether the energy or damage values were changed." msgstr "Allgemein kann der Ausdruck \"cause & 32\" verwendet werden, um festzustellen, ob Energie oder Schadenswert verändert wurden." -#: sdk/script/Effects.xml:630(text) +#: sdk/script/Effects.xml:636(text) msgid "Using this callback, damage to an object can be prevented, lessened, or increased. You could deduct magic energy instead, transfer damage to other objects, or something similar." msgstr "Über diesen Callback kann zum Beispiel Schaden an einem Objekt verhindert, abgeschwächt oder verstärkt werden; man kann Lebensschaden zunächst nur von der Zauberenergie abziehen, gleichmäßig auf verbundene Clonks verteilen und so weiter." -#: sdk/script/Effects.xml:632(h) +#: sdk/script/Effects.xml:638(h) msgid "Function Reference" msgstr "Funktions-Referenz" -#: sdk/script/Effects.xml:633(text) +#: sdk/script/Effects.xml:639(text) msgid "There are the following functions for manipulation of effects:" msgstr "Es gibt folgende Funktionen sind zum Manipulieren und Abfragen von Effekten:" -#: sdk/script/Effects.xml:636(li) +#: sdk/script/Effects.xml:642(li) msgid "() - for effect creation" msgstr "() - zum Erzeugen von Effekten" -#: sdk/script/Effects.xml:637(li) +#: sdk/script/Effects.xml:643(li) msgid "() - for effect removal" msgstr "() - zum Entfernen von Effekten" -#: sdk/script/Effects.xml:638(li) +#: sdk/script/Effects.xml:644(li) msgid "() - to search for effects" msgstr "() - zum Suchen nach Effekten" -#: sdk/script/Effects.xml:639(li) +#: sdk/script/Effects.xml:645(li) msgid "() - for effect counting" msgstr "() - um Effekte zu zählen" -#: sdk/script/Effects.xml:640(li) +#: sdk/script/Effects.xml:646(li) msgid "() - for user defined calls in effects" msgstr "() - für Benutzeraufrufe in Effekten" -#: sdk/script/Effects.xml:641(li) +#: sdk/script/Effects.xml:647(li) msgid "() - to cause effects callbacks without actually creating an effect" msgstr "() - um Effekt-Callbacks auszuführen, ohne den Effekt selber zu erstellen" @@ -11769,7 +11982,7 @@ msgid "The following callbacks are made to the scenario script. All callbacks ex msgstr "Die folgenden Callbacks werden an das Szenarioscript gemacht. Alle Callbacks außer Initialize die an das Szenarioscript gemacht werden, werden ebenfalls an alle Spielziele, -regeln und Umweltobjekte im Spiel gemacht. Mit den Funktionen und können Callbacks an das Szenarioscript von anderen Skripten aus gemacht werden." #: sdk/scenario/script.xml:16(col) -#: sdk/definition/script.xml:35(col) +#: sdk/definition/script.xml:33(col) msgid "Parameter" msgstr "Parameter" @@ -11818,7 +12031,7 @@ msgid "Called after the hostility of two players has been changed. See ." #: sdk/scenario/script.xml:54(col) -#: sdk/definition/script.xml:315(col) +#: sdk/definition/script.xml:318(col) msgid "int player, int new_team" msgstr "int player, int new_team" @@ -11827,7 +12040,7 @@ msgid "When the team of a player is about to be changed, this function is called msgstr "Wenn das Team eines Spielers geändert werden soll, wird diese Funktion zuerst aufgerufen. Wenn sie true zurückgibt, wird das Team des Spielers nicht geändert. Siehe " #: sdk/scenario/script.xml:59(col) -#: sdk/definition/script.xml:320(col) +#: sdk/definition/script.xml:323(col) msgid "int player, int new_team, int old_team" msgstr "int player, int new_team, int old_team" @@ -11840,8 +12053,8 @@ msgid "Called if a round is ended through the game by player elimination, fulfil msgstr "Wird eine Runde durch Spielziele wie Spielereliminierung, Materialabbau, usw. (wie in der Scenario.txt definiert) oder durch den Scriptbefehl beendet (also nicht bei abgebrochenen Runden), wird diese Funktion aufgerufen." #: sdk/scenario/script.xml:71(col) -#: sdk/definition/script.xml:290(col) -#: sdk/definition/script.xml:310(col) +#: sdk/definition/script.xml:293(col) +#: sdk/definition/script.xml:313(col) msgid "int player" msgstr "int player" @@ -11910,7 +12123,6 @@ msgstr "Version" #: sdk/scenario/scenario.xml:275(col) #: sdk/scenario/scenario.xml:290(col) #: sdk/scenario/scenario.xml:310(col) -#: sdk/scenario/scenario.xml:365(col) #: sdk/scenario/scenario.xml:370(col) #: sdk/scenario/scenario.xml:375(col) #: sdk/scenario/scenario.xml:380(col) @@ -11919,9 +12131,9 @@ msgstr "Version" #: sdk/folder/foldermap.xml:20(col) #: sdk/folder/foldermap.xml:60(col) #: sdk/folder/foldermap.xml:90(col) -#: sdk/definition/defcore.xml:100(col) -#: sdk/definition/defcore.xml:130(col) -#: sdk/definition/defcore.xml:135(col) +#: sdk/definition/defcore.xml:90(col) +#: sdk/definition/defcore.xml:120(col) +#: sdk/definition/defcore.xml:125(col) msgid "4 integers" msgstr "4 Integer" @@ -12039,11 +12251,11 @@ msgstr "Rules" #: sdk/scenario/scenario.xml:175(col) #: sdk/scenario/scenario.xml:190(col) #: sdk/scenario/scenario.xml:200(col) -#: sdk/scenario/scenario.xml:345(col) #: sdk/scenario/scenario.xml:350(col) -#: sdk/scenario/scenario.xml:410(col) -#: sdk/scenario/scenario.xml:435(col) -#: sdk/definition/defcore.xml:85(col) +#: sdk/scenario/scenario.xml:355(col) +#: sdk/scenario/scenario.xml:405(col) +#: sdk/scenario/scenario.xml:430(col) +#: sdk/definition/defcore.xml:75(col) msgid "ID list" msgstr "ID-Liste" @@ -12089,7 +12301,7 @@ msgstr "Startkapital." #: sdk/scenario/scenario.xml:135(col) #: sdk/particle/index.xml:151(col) -#: sdk/definition/defcore.xml:70(col) +#: sdk/definition/defcore.xml:60(col) msgid "2 Integer" msgstr "2 Integer" @@ -12156,9 +12368,8 @@ msgstr "Himmeltextur wie in der Graphics.ocg vorhanden (ohne Dateierweiterung)." #: sdk/scenario/scenario.xml:215(col) #: sdk/particle/index.xml:76(col) #: sdk/material/ocm.xml:190(col) -#: sdk/definition/defcore.xml:90(col) -#: sdk/definition/defcore.xml:95(col) -#: sdk/definition/actmap.xml:75(col) +#: sdk/definition/defcore.xml:80(col) +#: sdk/definition/defcore.xml:85(col) msgid "6 integers" msgstr "6 Integer" @@ -12266,62 +12477,58 @@ msgstr "0 bis 2. Bei 1 bewegt sich der Himmel mit dem Wind, bei 2 ist er halbpar msgid "Granularity of the Fog of War. Default: 64. Warning: smaller values will improve the looks of the FoW but will also severely increase processing times." msgstr "Größe der Blöcke, in denen der Kriegsnebel (Fog of War) berechnet wird. Standardwert 64. Achtung: Kleinere Werte verbessern zwar die Darstellung des Kriegsnebels, erhöhen aber auch die benötigte Rechenleistung bei hohen Bildschirmauflösungen." -#: sdk/scenario/scenario.xml:337(caption) +#: sdk/scenario/scenario.xml:336(col) +msgid "0 or 1. If 1, all landscape chunks are drawn flat when the map is zoomed to draw the landscape. Set this while drawing a static map in console mode to fix small gaps of lower order materials hidden behind materials of chunky shape." +msgstr "" + +#: sdk/scenario/scenario.xml:342(caption) msgid "Section [Animals]" msgstr "Sektion [Animals]" -#: sdk/scenario/scenario.xml:344(col) +#: sdk/scenario/scenario.xml:349(col) msgid "Animals" msgstr "Animals" -#: sdk/scenario/scenario.xml:346(col) +#: sdk/scenario/scenario.xml:351(col) msgid "Freewheeling creatures." msgstr "Freilaufende Lebewesen." -#: sdk/scenario/scenario.xml:349(col) +#: sdk/scenario/scenario.xml:354(col) msgid "Nest" msgstr "Nest" -#: sdk/scenario/scenario.xml:351(col) +#: sdk/scenario/scenario.xml:356(col) msgid "Buried nests." msgstr "Nester im Erdreich." -#: sdk/scenario/scenario.xml:357(caption) +#: sdk/scenario/scenario.xml:362(caption) msgid "Section [Weather]" msgstr "Sektion [Weather]" -#: sdk/scenario/scenario.xml:364(col) +#: sdk/scenario/scenario.xml:369(col) msgid "Climate" msgstr "Climate" -#: sdk/scenario/scenario.xml:366(col) +#: sdk/scenario/scenario.xml:371(col) msgid "0-100 with tolerance. Average temperature. 0 warm, 100 cold." msgstr "0-100 und Abweichung. Durchschnittstemperatur. 0 warm, 100 kalt." -#: sdk/scenario/scenario.xml:369(col) +#: sdk/scenario/scenario.xml:374(col) msgid "StartSeason" msgstr "StartSeason" -#: sdk/scenario/scenario.xml:371(col) +#: sdk/scenario/scenario.xml:376(col) msgid "0-100 with tolerance. Season at game start." msgstr "0-100 und Abweichung. Startjahreszeit." -#: sdk/scenario/scenario.xml:374(col) +#: sdk/scenario/scenario.xml:379(col) msgid "YearSpeed" msgstr "YearSpeed" -#: sdk/scenario/scenario.xml:376(col) +#: sdk/scenario/scenario.xml:381(col) msgid "0-100 with tolerance. Speed of season change." msgstr "0-100 und Abweichung. Geschwindigkeit des Jahreszeitenwechsels." -#: sdk/scenario/scenario.xml:379(col) -msgid "Rain" -msgstr "Rain" - -#: sdk/scenario/scenario.xml:381(col) -msgid "0-100 with tolerance. Precipitation amount." -msgstr "0-100 und Abweichung. Regenwahrscheinlichkeit." - #: sdk/scenario/scenario.xml:384(col) msgid "Wind" msgstr "Wind" @@ -12331,58 +12538,50 @@ msgid "-100-100 with tolerance. Wind direction and strength." msgstr "-100-100 und Abweichung. Windrichtung und -stärke." #: sdk/scenario/scenario.xml:389(col) -msgid "Precipitation" -msgstr "Precipitation" - -#: sdk/scenario/scenario.xml:391(col) -msgid "Simple material definition precipitation." -msgstr "Einfache Materialdefinition Niederschlag." - -#: sdk/scenario/scenario.xml:394(col) msgid "NoGamma" msgstr "NoGamma" -#: sdk/scenario/scenario.xml:396(col) +#: sdk/scenario/scenario.xml:391(col) msgid "0 or 1. If 1, the current season won't cause a small global color change." msgstr "0 oder 1. Bei 1 wirken sich die Jahreszeiten nicht auf die Bildschirmfärbung aus." -#: sdk/scenario/scenario.xml:402(caption) +#: sdk/scenario/scenario.xml:397(caption) msgid "Section [Environment]" msgstr "Sektion [Environment]" -#: sdk/scenario/scenario.xml:411(col) +#: sdk/scenario/scenario.xml:406(col) msgid "Environment control objects that are placed at game start." msgstr "Umweltsteuerungsobjekte, die am Anfang der Runde platziert werden." -#: sdk/scenario/scenario.xml:417(caption) +#: sdk/scenario/scenario.xml:412(caption) msgid "Section [Definitions]" msgstr "Sektion [Definitions]" -#: sdk/scenario/scenario.xml:424(col) +#: sdk/scenario/scenario.xml:419(col) msgid "LocalOnly" msgstr "LocalOnly" -#: sdk/scenario/scenario.xml:426(col) +#: sdk/scenario/scenario.xml:421(col) msgid "If LocalOnly is 1, only definitions local to the scenario file will be load." msgstr "Wenn LocalOnly den Wert 1 hat, werden alle angegebenen Objektdefinitions-pakete ignoriert und nur lokale Objektdefinitionen geladen." -#: sdk/scenario/scenario.xml:429(col) +#: sdk/scenario/scenario.xml:424(col) msgid "Definition1 to 9" msgstr "Definition1 (bis 9)" -#: sdk/scenario/scenario.xml:430(col) +#: sdk/scenario/scenario.xml:425(col) msgid "String(s)" msgstr "Zeichenfolge(n)" -#: sdk/scenario/scenario.xml:431(col) +#: sdk/scenario/scenario.xml:426(col) msgid "With Definitionx entries you can specify which object definition packs (ocd) are to be loaded with this scenario. The specified files must be available in the Clonk directory. If files are specified here, manual pack selection in the menu system is disabled." msgstr "Über Definitionx-Einträge kann vorgegeben werden, welche Objektdefinitionspakete (ocd) das Szenario benutzen soll. Die Pakete müssen im Clonk-Verzeichnis vorhanden sein. Sind Pakete im Szenario angegeben, wird die vom Menüsystem bestimmte Auswahl ignoriert." -#: sdk/scenario/scenario.xml:434(col) +#: sdk/scenario/scenario.xml:429(col) msgid "SkipDefs" msgstr "SkipDefs" -#: sdk/scenario/scenario.xml:436(col) +#: sdk/scenario/scenario.xml:431(col) msgid "List of object definitions (C4IDs) which are not to be loaded with this scenario. This can be used to prevent researching certain object types in the game." msgstr "Liste der Definitionen, die im Spiel nicht geladen werden sollen. So lässt sich beispielsweise die Erforschung bestimmter Objekte verhindern." @@ -12606,7 +12805,7 @@ msgstr "Sektion [Teams]" #: sdk/scenario/Teams.xml:16(col) #: sdk/scenario/Teams.xml:75(col) -#: sdk/playercontrols.xml:176(col) +#: sdk/playercontrols.xml:232(col) msgid "Default value" msgstr "Standardwert" @@ -12715,12 +12914,11 @@ msgstr "Muss angegeben werden!" #: sdk/particle/index.xml:71(col) #: sdk/material/ocm.xml:210(col) #: sdk/definition/defcore.xml:30(col) -#: sdk/definition/defcore.xml:45(col) -#: sdk/definition/actmap.xml:105(col) -#: sdk/definition/actmap.xml:110(col) -#: sdk/definition/actmap.xml:115(col) #: sdk/definition/actmap.xml:120(col) +#: sdk/definition/actmap.xml:125(col) #: sdk/definition/actmap.xml:130(col) +#: sdk/definition/actmap.xml:135(col) +#: sdk/definition/actmap.xml:145(col) msgid "String (max. 30 chars)" msgstr "Zeichenfolge (max. 30)" @@ -13102,71 +13300,77 @@ msgid "PlayerControls.txt" msgstr "PlayerControls.txt" #: sdk/playercontrols.xml:11(text) -msgid "All control commands which a player can send to the game are defined in the file PlayerControls.txt. The standard keys as well as their standard mapping for various input devices are contained in the global definition file in the Systems.ocg folder. Object definitions and scenarios can add more keys or overload the parameters of existing commands in their local Systems.ocg folder**." +#, fuzzy +msgid "All control commands which a player can send to the game are defined in the file PlayerControls.txt. The standard keys as well as their standard mapping for various input devices are contained in the global definition file in the Systems.ocg folder. Object definitions and scenarios can add more keys or overload the parameters of existing commands in their local Systems.ocg folder." msgstr "Alle Steuerungsbefehle, die ein Spieler an das Spiel geben kann, werden in der Datei PlayerControls.txt definiert. Die Standardtasten sowie deren Standardbelegung fuer verschiedene Eingabegeraete befinden sich in der globalen Definitionsdatei in der System.ocg. Objektdefinitionen und Szenarien koennen weitere Tasten in ihrer lokalen System.ocg hinzufuegen oder die Parameter vorhandener Steuerkommandos ueberladen**." -#: sdk/playercontrols.xml:12(text) -msgid "Additional PlayerControls.txt files can be put in language packages to adapt the standard key mappings of different loaded languages to the keyboard of their respective country**." -msgstr "Zusaetzliche Dateien PlayerControls.txt koennen in Sprachpaketen abgelegt werden, um die Standardbelegungen der Tasten bei verschiedenen, geladenen Sprachen an die Tastaturen des jeweiligen Landes anzupassen**." - -#: sdk/playercontrols.xml:14(h) +#: sdk/playercontrols.xml:13(h) msgid "Section [ControlDefs]" msgstr "Sektion [ControlDefs]" -#: sdk/playercontrols.xml:19(caption) +#: sdk/playercontrols.xml:14(text) +msgid "Definition of possible player commands. Subordinated to this section:" +msgstr "Definition der moeglichen Spielerkommandos. Dieser Sektion untergeordnet:" + +#: sdk/playercontrols.xml:18(caption) msgid "Any number of sections [ControlDef]" msgstr "Beliebig viele Sektionen [ControlDef]" -#: sdk/playercontrols.xml:27(col) +#: sdk/playercontrols.xml:26(col) msgid "String (max. 96 chars)" msgstr "Zeichenfolge (Max. 96 Zeichen)" -#: sdk/playercontrols.xml:28(col) +#: sdk/playercontrols.xml:27(col) msgid "Internally used name for identification of the command. The command is referenced by that name in standard mappings and it is predefined in script as CON_Name. The name should therefore be a valid identifier in script, i.e. only consist of letters, numbers and _. Especially there should be no space characters or German umlauts. To avoid conflicts the same rules as for object IDs apply for definitions local to a certain scenario or object." msgstr "Intern benutzter Name zur Identifikation des Kommandos. Das Kommando wird unter diesem Namen in Standardbelegungen referenziert und im Script als CON_Name-Konstante vordefiniert. Der Name sollte folglich im Script gueltig sein, d.h. nur aus Buchstaben, Zahlen sowie _ bestehen. Insbesondere sollten keine Leerzeichen oder deutsche Umlaute verwendet werden. Zur Vermeidung von Konflikten gelten in szenarienlokalen sowie Objektpaketlokalen Definitionen dieselben Benennungsregeln wie zur Vergabe von Objekt-IDs." -#: sdk/playercontrols.xml:33(col) +#: sdk/playercontrols.xml:32(col) msgid "Name which is shown to the player in the control configuration dialog and in control tooltips. Localized strings from the corresponding string table can be used ($Name$)." msgstr "Name, der dem Spieler im Steuerungskonfigurationsdialog sowie in den Steuerungstooltips angezeigt wird. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$)." -#: sdk/playercontrols.xml:38(col) -msgid "Informative description which is displayed to the player in the control configuration dialog. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$)." -msgstr "Erlaeuternde Beschreibung, die dem Spieler im Steuerungskonfigurationsdialog angezeigt wird. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$)." +#: sdk/playercontrols.xml:37(col) +#, fuzzy +msgid "Informative description which is displayed to the player in the control configuration dialog. Localized strings from the corresponding string table can be used ($Desc$)." +msgstr "Name, der dem Spieler im Steuerungskonfigurationsdialog sowie in den Steuerungstooltips angezeigt wird. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$)." -#: sdk/playercontrols.xml:43(col) +#: sdk/playercontrols.xml:42(col) msgid "If true this is a global definition, i.e. not assigned to a particular player. See Global definitions." msgstr "Wenn wahr, ist dies eine globale, d.h. keinem Spieler zugeordnete Definition. Siehe Globale Definitionen." -#: sdk/playercontrols.xml:48(col) +#: sdk/playercontrols.xml:47(col) msgid "If true this command is interpreted as a held command. Such a command remembers whether the control key is pressed and generates another scripting event when it is released. See Held keys." msgstr "Wenn wahr, wird das Kommando als ein gehaltenes Kommando interpretiert. Ein solches Kommando speichert, ob die Steuerungstaste gedrueckt ist und generiert beim Loslassen ein zusaetzliches Scriptereignis. Siehe Gehaltene Tasten." -#: sdk/playercontrols.xml:53(col) +#: sdk/playercontrols.xml:52(col) msgid "Only valid if Hold is true. If greater than 0 then this key generates additional scripting events while pressed every that many number of frames. See Key repeats." msgstr "Nur gueltig wenn Hold wahr. Wenn groesser 0, generiert die Taste im gehaltenen Zustand im angegebenen Abstand (in Frames) weitere Scriptereignisse. Siehe Tastenwiederholungen." -#: sdk/playercontrols.xml:58(col) +#: sdk/playercontrols.xml:57(col) msgid "If specified then the delay of the first key repeat event can be changed. See Key repeats." msgstr "Wenn angegeben, kann die Wartezeit fuer das erste Tastenwiederholungsereignis geaendert werden. Siehe Tastenwiederholungen." -#: sdk/playercontrols.xml:63(col) +#: sdk/playercontrols.xml:62(col) msgid "If true then the command is deactivated in the normal case and needs to be activated by script first. This is useful for commands that are only required in special situations. See Deactivated commands." msgstr "Wenn wahr, ist das Kommando im Normalfall deaktiviert und muss erst per Script aktiviert werden. Nuetzlich fuer Kommandos, die nur in sehr speziellen Situationen benoetigt werden. Siehe Deaktivierte Kommandos." -#: sdk/playercontrols.xml:67(col) -#: sdk/definition/defcore.xml:165(col) -#: sdk/definition/defcore.xml:200(col) +#: sdk/playercontrols.xml:66(col) +#: sdk/definition/properties.xml:145(col) +#: sdk/definition/defcore.xml:170(col) msgid "C4ID" msgstr "C4ID" -#: sdk/playercontrols.xml:68(col) +#: sdk/playercontrols.xml:67(col) msgid "Optional ID that is passed to the script function. See ExtraData." msgstr "Optionale ID, die an die Scriptfunktion uebergeben wird. Siehe ExtraData." -#: sdk/playercontrols.xml:73(col) +#: sdk/playercontrols.xml:72(col) msgid "If true then the GUI mouse position at the time of triggering the command will be sent as a separate CON_CursorPos command. If the mouse is not activated then the cursor position in GUI coordinates is transmitted." msgstr "Wenn wahr, wird mit dem Kommando die GUI-Mausposition zum Zeitpunkt des Ausloesens des Kommandos als separates CON_CursorPos-Kommando gesendet. Ist keine Maus aktiviert, wird die Cursorposition in GUI-Koordinaten uebertragen." +#: sdk/playercontrols.xml:78(text) +msgid "Action to be executed for this command. Possible values:" +msgstr "Auszufuehrende Aktion bei diesem Kommando. Moegliche Werte:" + #: sdk/playercontrols.xml:88(col) msgid "No action." msgstr "Keine Aktion." @@ -13176,212 +13380,251 @@ msgid "Execution of the script function PlayerControl. See PlayerControl. Siehe Script-Callbacks." #: sdk/playercontrols.xml:96(col) +msgid "Zoom in one unit" +msgstr "Zoomt eine Einheit rein" + +#: sdk/playercontrols.xml:100(col) +msgid "Zoom out one unit" +msgstr "Zoomt eine Einheit raus" + +#: sdk/playercontrols.xml:104(col) msgid "Open the player menu (asynchronous command)." msgstr "Oeffnen des Spielermenues (asynchrones Kommando)." -#: sdk/playercontrols.xml:100(col) +#: sdk/playercontrols.xml:108(col) msgid "Confirmation of the selected item in the player menu (asynchronous command)." msgstr "Bestaetigen des ausgewaehlten Elementes im Spielermenue (asynchrones Kommando)." -#: sdk/playercontrols.xml:104(col) +#: sdk/playercontrols.xml:112(col) msgid "Close the player menu (asynchronous command)." msgstr "Schliessen des Spielermenues (asynchrones Kommando)." -#: sdk/playercontrols.xml:108(col) +#: sdk/playercontrols.xml:116(col) msgid "Navigation in the player menu (asynchronous command)." msgstr "Navigation im Spielermenu (asynchrones Kommando)." -#: sdk/playercontrols.xml:78(col) -msgid "Action to be executed for this command. Possible values: " -msgstr "Auszufuehrende Aktion bei diesem Kommando. Moegliche Werte: " +#: sdk/playercontrols.xml:120(col) +msgid "Confirmation of the selected item in a menu (synchronous command)." +msgstr "Bestätigen des ausgewählten Elements im Spielermenü (synchrones Kommando)." -#: sdk/playercontrols.xml:15(text) -msgid "Definition of possible player commands. Not valid in language packages. Subordinated to this section: " -msgstr "Definition der moeglichen Spielerkommandos. Nicht gueltig in Sprachpaketen. Dieser Sektion untergeordnet: " +#: sdk/playercontrols.xml:124(col) +msgid "Close a menu (synchronous command)." +msgstr "Schließen des Spielermenüs (synchrones Kommando)." -#: sdk/playercontrols.xml:119(h) +#: sdk/playercontrols.xml:128(col) +msgid "Navigation in a menu (synchronous command)." +msgstr "Navigation im Spielermenü (synchrones Kommando)." + +#: sdk/playercontrols.xml:135(h) msgid "Section [ControlSets]" msgstr "Sektion [ControlSets]" -#: sdk/playercontrols.xml:124(caption) +#: sdk/playercontrols.xml:136(text) +msgid "Definition of standard control mappings." +msgstr "Definition von Standard-Steuerungsbelegungen." + +#: sdk/playercontrols.xml:140(caption) msgid "Any number of sections [ControlSet]" msgstr "Beliebig viele Sektionen [ControlSet]" -#: sdk/playercontrols.xml:133(col) -msgid "Internal name for identification of otherwise equal control mappings. The names of the standard mappings are Keyboard1, Keyboard1Classic, Keyboard2, Keyboard2Classic, Gamepad. By using placeholders (*) keys can directly be defined in multiple mappings**." +#: sdk/playercontrols.xml:149(col) +#, fuzzy +msgid "Internal name for identification of otherwise equal control mappings. By using placeholders (*) keys can directly be defined in multiple mappings." msgstr "Interner Name zur Identifikation gleicher Steuerungsbelegungen. Die Namen der Standardbelegungen sind Keyboard1, Keyboard1Classic, Keyboard2, Keyboard2Classic, Gamepad. Ueber Platzhalter (*) koennen Tasten direkt in mehreren Belegungen definiert werden**." -#: sdk/playercontrols.xml:138(caption) +#: sdk/playercontrols.xml:154(col) +msgid "Name for the control assignment set which is shown to the player in the control configuration dialog." +msgstr "Name der Steuerung welche wie sie in den Optionen angezeigt wird." + +#: sdk/playercontrols.xml:159(col) +msgid "Whether this control assignment set uses the keyboard. Default 1." +msgstr "Ob diese Steuerung die Tastatur benutzt. Default 1." + +#: sdk/playercontrols.xml:164(col) +msgid "Whether this control assignment set uses the mouse. Default 1." +msgstr "Ob diese Steuerung die Maus benutzt. Default 1." + +#: sdk/playercontrols.xml:169(col) +msgid "Whether this control assignment set uses the gamepad. Default 0." +msgstr "Ob diese Steuerung ein Gamepad benutzt. Default 0." + +#: sdk/playercontrols.xml:173(caption) msgid "Any number of sections [Assignment]" msgstr "Beliebig viele Sektionen [Assignment]" -#: sdk/playercontrols.xml:147(col) +#: sdk/playercontrols.xml:182(col) msgid "Specifies the key(s) of this mapping or a reference to another mapping. See Key mappings." msgstr "Taste(n) dieser Belegung oder Referenz auf eine andere Belegung. Siehe Tastenbelegungen." -#: sdk/playercontrols.xml:152(col) +#: sdk/playercontrols.xml:187(col) msgid "If true then multiple keys are taken as a sequence, i.e. they need to be pressed one after the other instead of all at the same time. See Key mappings." msgstr "Wenn wahr, werden mehrfache Tasten als Sequenz interpretiert. Das heisst, sie muessen nacheinander statt gleichzeitig gedrueckt werden. Siehe Tastenbelegungen." -#: sdk/playercontrols.xml:157(col) +#: sdk/playercontrols.xml:192(col) msgid "Command that is combined with this mapping. The name should be equivalent to the Identifier of a command defined in a [ControlDef]." msgstr "Kommando, das mit dieser Belegung verknuepft wird. Der Name sollte dem Identifier eines in einer [ControlDef] definierten Kommandos entsprechen." -#: sdk/playercontrols.xml:162(col) +#: sdk/playercontrols.xml:197(col) +#, fuzzy +msgid "Name which is shown to the player in the control configuration dialog and in control tooltips. Localized strings from the corresponding string table can be used ($Name$). If unset, GUIName of the control def is used. If set to \"None\", the control is not displayed in the user customization dialog even if the control def has a name set." +msgstr "Name, der dem Spieler im Steuerungskonfigurationsdialog sowie in den Steuerungstooltips angezeigt wird. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$)." + +#: sdk/playercontrols.xml:202(col) +#, fuzzy +msgid "Informative description which is displayed to the player in the control configuration dialog. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$). If unset, GUIDesc of the control def is used." +msgstr "Erlaeuternde Beschreibung, die dem Spieler im Steuerungskonfigurationsdialog angezeigt wird. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$)." + +#: sdk/playercontrols.xml:207(col) +msgid "Control assignments in the same group are displayed grouped together in the control assignment dialog. The group with the lowest number is displayed at the top. Default 0." +msgstr "Tastenbelegungen in der gleichen Gruppe werden in den Optionen zusammen angezeigt. Die Gruppe mit der kleinsten Nummer erscheint ganz oben in der Liste." + +#: sdk/playercontrols.xml:212(col) +msgid "Whether this control assignment can not be changed in the control assignment dialog. Default 0." +msgstr "Ob diese Tastenbelegung nicht in den Optionen angepasst werden kann. Default 0." + +#: sdk/playercontrols.xml:217(col) msgid "Priority of the mapping. If more than once mapping is using the same keys then the key with the highest priority is executed first until a command is treated as handled." msgstr "Prioritaet der Belegung. Nutzen mehrere Belegungen die gleichen Tasten, so wird zunaechst die Taste mit der hoeheren Prioritaet ausgefuehrt, bis ein Kommando als behandelt gilt." -#: sdk/playercontrols.xml:166(col) +#: sdk/playercontrols.xml:221(col) msgid "bitmask" msgstr "Bitmaske" -#: sdk/playercontrols.xml:177(col) +#: sdk/playercontrols.xml:223(text) +msgid "Trigger mode of this mapping. Bitmask based on the following values:" +msgstr "Auslösemodus dieser Belegung. Bitmaske aus folgenden Werten:" + +#: sdk/playercontrols.xml:233(col) msgid "No particular action." msgstr "Keine besondere Aktion." -#: sdk/playercontrols.xml:181(col) +#: sdk/playercontrols.xml:237(col) msgid "The key changes the state of the command linked to to be held even if the key itself is pressed only shortly. Only valid if the Hold attribute is set for the command. This state remains until a corresponding mapping with trigger mode Release is being pressed. See Held keys." msgstr "Die Taste versetzt das verlinkte Kommando in den gedrueckten Zustand, selbst wenn die Taste selbst nur angeschlagen wird. Nur gueltig, wenn das Kommando das Hold-Attribut gesetzt hat. Dieser Zustand bleibt erhalten, bis eine entsprechende Belegung mit Ausloesemodus Release gedrueckt wird. Siehe Gehaltene Tasten." -#: sdk/playercontrols.xml:185(col) +#: sdk/playercontrols.xml:241(col) msgid "The key removes the held state. A key can have both Hold and Release set to toggle between the two states. See Held keys." msgstr "Die Taste entfernt den gedrueckten Zustand. Eine Taste kann auch sowohl Hold als auch Release setzen, um zwischen den Zustaenden hin und her zu schalten. Siehe Gehaltene Tasten." -#: sdk/playercontrols.xml:189(col) +#: sdk/playercontrols.xml:245(col) msgid "The key press is always passed to the mapping with the next lowest priority, independent of whether the previous command was executed successfully or not." msgstr "Der Tastendruck wird immer an die Belegung mit der naechstniedrigen Prioritaet weitergereicht, unabhaengig davon, ob das vorherige Kommando erfolgreich ausgefuehrt wurde." -#: sdk/playercontrols.xml:193(col) -msgid "The keypress is passed to the mapping with the next lower priority only if the previous command was executed successfully. This can be used to define macros. **" -msgstr "Der Tastendruck wird genau dann an die Belegung mit der naechstniedrigen Prioritaet weitergereicht, wenn das vorherige Kommando erfolgreich ausgefuehrt wurde. Hiermit lassen sich Makros definieren. **" - -#: sdk/playercontrols.xml:197(col) +#: sdk/playercontrols.xml:249(col) msgid "The assignment overwrites all other assignments for the same control with the same press/release trigger mode." msgstr "Die Zuweisung ueberschreibt alle weiteren Zuweisungen zum gleichen Control mit gleichem Press/Release-Triggermodus." -#: sdk/playercontrols.xml:167(col) -msgid "Trigger mode of this mapping. Bitmask based on the following values: " -msgstr "Ausloesmodus dieser Belegung. Bitmaske aus folgenden Werten: " - -#: sdk/playercontrols.xml:120(text) -msgid "Definition of standard control mappings. " -msgstr "Definition von Standard-Steuerungsbelegungen. " - -#: sdk/playercontrols.xml:210(h) +#: sdk/playercontrols.xml:257(h) msgid "Script callbacks" msgstr "Script-Callbacks" -#: sdk/playercontrols.xml:211(text) +#: sdk/playercontrols.xml:258(text) msgid "To initialize the player control the script function InitializePlayerControl is called for each player. This call might be delayed by a few frames with respect to InitializePlayer since the initialization of the control needs to be transmitted in the network. When continuing savegames InitalizePlayerControl will be called again. The chosen control might be different from the original one. The same can happen if a player chooses to change its controls during the game." msgstr "Zum Initialisieren der Spielersteuerung wird für jeden gesteuerten Spieler die Funktion InitializePlayerControl aufgerufen. Dieser Aufruf erfolgt gegebenenfalls einige Frames verspätet nach InitializePlayer, da die Initialisierung der Steuerung im Netzwerk übertragen werden muss. Beim Fortsetzen von Spielständen wird InitializePlayerControl wiederholt aufgerufen. Die gewählte Steuerung kann sich hier von der ursprünglichen Steuerung unterscheiden. Gleiches gilt, falls der Spieler mitten im Spiel die Steuerung wechselt." -#: sdk/playercontrols.xml:218(text) +#: sdk/playercontrols.xml:265(text) msgid "most commands (except for asynchronous commands in the player menu) call a global script function:" msgstr "Die meisten Kommandos (abgesehen von asyrnchronen Kommandos im Spielermenue), rufen eine globale Scriptfunktion auf:" -#: sdk/playercontrols.xml:220(text) +#: sdk/playercontrols.xml:267(text) msgid "For an explanation of the parameters see . Amongst others, the function receives the calling player in player as well as the command to be executed in control." msgstr "Fuer eine Erlaeuterung der Parameter siehe . Die Funktion erhaelt unter anderem den aufrufenden Spieler in player, sowie das ausgefuehrte Kommando in iControl." -#: sdk/playercontrols.xml:221(text) +#: sdk/playercontrols.xml:268(text) msgid "As a simple example let's assume that in the global PlayerControls.txt the following command has been defined:" msgstr "Fuer ein einfaches Beispiel sei in der globalen PlayerControls.txt folgendes Kommando definiert:" -#: sdk/playercontrols.xml:238(text) +#: sdk/playercontrols.xml:285(text) msgid "This defines a Jump key and the corresponding standard mapping on the keyboard for the first player. The following script is used to handle the control:" msgstr "Dies definiert eine Sprungtaste und die zugehoerige Standardbelegung auf der Tastatur fuer den ersten Spieler. Dazu folgendes Script zur Behandlung:" -#: sdk/playercontrols.xml:256(h) +#: sdk/playercontrols.xml:303(h) msgid "ExtraData" msgstr "ExtraData" -#: sdk/playercontrols.xml:257(text) +#: sdk/playercontrols.xml:304(text) msgid "Since not every object definition is able to overload the global PlayerControl function the ExtraData field can be used to distribute commands. As an example consider the following definition:" msgstr "Da nicht jede Objektdefinition die globale PlayerControl-Funktion ueberladen kann, gibt es das ExtraData-Feld zum Verteilen von Kommandos. Zum Beispiel fuer folgende Definition:" -#: sdk/playercontrols.xml:264(text) +#: sdk/playercontrols.xml:311(text) msgid "Let shovel be the ID of a shovel object. In the global script there could be the following, generic handling for unknown commands, for example:" msgstr "Dabei sei Shovel die ID eines Schaufelobjektes. Im globalen Script kann zum Beispiel folgende, allgemeine Behandlung fuer unbekannte Kommandos stehen:" -#: sdk/playercontrols.xml:274(text) +#: sdk/playercontrols.xml:321(text) msgid "And in the script of the shovel:" msgstr "Und im Script der Schaufel:" -#: sdk/playercontrols.xml:291(h) +#: sdk/playercontrols.xml:338(h) msgid "Held keys" msgstr "Gehaltene Tasten" -#: sdk/playercontrols.xml:292(text) +#: sdk/playercontrols.xml:339(text) msgid "If the Hold flag is set for a command then the engines saves the current key state for that key. These kind of keys have a few specialties:" msgstr "Wird fuer ein Kommando das Hold-Flag gesetzt, so speichert die Engine den gegenwaertigen Tastenzustand fuer diese Taste. Solche Tasten haben einige Besonderheiten:" -#: sdk/playercontrols.xml:295(li) +#: sdk/playercontrols.xml:342(li) msgid "When released they also generate calls in the script with the Release flag set." msgstr "Sie generieren auch beim Loslassen -Aufrufe mit gesetztem Release-Flag im Script." -#: sdk/playercontrols.xml:296(li) +#: sdk/playercontrols.xml:343(li) msgid "Mappings can emulate permanent key presses using the Hold/Release flags." msgstr "Belegungen koennen mit den Hold/Release-Flags dauerhafte Tastendruecke emulieren." -#: sdk/playercontrols.xml:297(li) +#: sdk/playercontrols.xml:344(li) msgid "Key repeats are generated." msgstr "Tastenwiederholungen werden erzeugt." -#: sdk/playercontrols.xml:298(li) +#: sdk/playercontrols.xml:345(li) msgid "The held state of the key can be queried in the script via ." msgstr "Der Haltezustand der Taste kann mit im Script abgefragt werden." -#: sdk/playercontrols.xml:301(text) +#: sdk/playercontrols.xml:348(text) msgid "A good example for this functionality is a directional command:" msgstr "Bestes Beispiel hierfuer ist ein Richtungskommando:" -#: sdk/playercontrols.xml:307(text) +#: sdk/playercontrols.xml:354(text) msgid "In the script the direction is transferred to the Clonk:" msgstr "Im Script wird die Richtung dann auf den Clonk uebertragen:" -#: sdk/playercontrols.xml:330(text) +#: sdk/playercontrols.xml:377(text) msgid "To achieve the behaviour of classic controls a mapping can emulate the Hold state:" msgstr "Um klassisches Steuerungsverhalten zu erreichen, kann eine Tastenbelegung den Hold-Zustand emulieren:" -#: sdk/playercontrols.xml:340(h) +#: sdk/playercontrols.xml:387(h) msgid "Global definitions" msgstr "Globale Definitionen" -#: sdk/playercontrols.xml:341(text) -#: sdk/playercontrols.xml:354(text) -#: sdk/playercontrols.xml:356(text) -#: sdk/playercontrols.xml:358(text) +#: sdk/playercontrols.xml:388(text) +#: sdk/playercontrols.xml:401(text) +#: sdk/playercontrols.xml:403(text) +#: sdk/playercontrols.xml:405(text) msgid "..." msgstr "..." -#: sdk/playercontrols.xml:342(h) +#: sdk/playercontrols.xml:389(h) msgid "Key repeats" msgstr "Tastenwiederholungen" -#: sdk/playercontrols.xml:343(text) +#: sdk/playercontrols.xml:390(text) msgid "If a command has RepeatDelay defined then repeated commands are generated while the key is pressed. For example for a throwing command:" msgstr "Hat ein Kommando ein RepeatDelay definiert, so werden wiederholte Kommandos beim Halten der Taste erzeugt. Zum Beispiel fuer ein Wurkommando:" -#: sdk/playercontrols.xml:351(text) +#: sdk/playercontrols.xml:398(text) msgid "In the example one could keep the key pressed after having it pressed for the first time. The Throw command then would be sent every 5 seconds automatically after an initial delay of 35 frames (about one second)." msgstr "Im Beispiel koennte man die Wurftaste nach einmal Druecken auch halten. Das Wurfkommando wuerde dann nach 35 Frames (ca. eine Sekunde) halten alle 5 Frames automatisch wiederholt." -#: sdk/playercontrols.xml:352(text) +#: sdk/playercontrols.xml:399(text) msgid "Repeats are only generated when the command also has the Hold flag set." msgstr "Wiederholungen werden nur erzeugt, wenn das Kommando ebenfalls das Hold-Flag gesetzt hat." -#: sdk/playercontrols.xml:353(h) +#: sdk/playercontrols.xml:400(h) msgid "Deactivated commands**" msgstr "Deaktivierte Kommandos**" -#: sdk/playercontrols.xml:355(h) +#: sdk/playercontrols.xml:402(h) msgid "Keyboard shortcuts" msgstr "Tastenbelegungen" -#: sdk/playercontrols.xml:360(em) -msgid "** - not yet implemented" -msgstr "** - noch nicht implementiert" - #: sdk/particle/index.xml:9(text) msgid "Particles are lightweight objects which are not synchronized in a network game. This means that on the one hand you can create huge amounts of particles without slowing down the game too much but on the other hand there are only limited options for control of particle behaviour. If the particles are not sufficient for a given effect you have in mind, you can always use true objects instead." msgstr "Partikel sind abgespeckte Objekte, die im Netzwerk nicht synchronisationsrelevant sind. Das heißt einerseits, dass man Partikel relativ problemlos in größeren Mengen erstellen kann, um interessante Effekte zu erzielen. Andererseits existieren nur sehr wenige Möglichkeiten, un das Verhalten von Partikeln zu steuern. Wenn die Möglichkeiten von Partikeln also für einen Effekt nicht ausreichen, sollten stattdessen reguläre Objekte verwenden, mit denen sich alle durch Partikel darstellbaren Effekte auch erzielen lassen." @@ -13788,7 +14031,7 @@ msgstr "Sektion [Material]" #: sdk/material/ocm.xml:165(col) #: sdk/material/ocm.xml:180(col) #: sdk/material/ocm.xml:200(col) -#: sdk/definition/defcore.xml:245(col) +#: sdk/definition/defcore.xml:215(col) msgid "String (max. 15)" msgstr "Zeichenfolge (max. 15)" @@ -14812,8 +15055,8 @@ msgid "Useful Hints" msgstr "Tipps zur Entwicklung" #: sdk/folder/foldermap.xml:161(text) -msgid "For testing purposes a folder map can be loaded from an unpacked scenario folder and reloaded an runtime using F5. If the classic scenario selection appears instead of the folder map, an error has occured in the folder map declaration, such as missing image files. With debug mode activated, there will also be an error message in Clonk.log." -msgstr "Zum Testen kann die FolderMap mit einem entpackten Rundenordner entworfen, und dann in der Szenarienauswahl mit Druck auf F5 jeweils neu geladen werden. Erscheint statt der FolderMap die klassische Szenarienauswahl, ist beim Laden der Definitionsdatei ein Fehler aufgetreten, oder zum Beispiel eine referenzierte Grafikdatei nicht gefunden worden. Bei aktiviertem Debugmodus findet sich in dem Fall eine Fehlermeldung in der Datei Clonk.log." +msgid "For testing purposes a folder map can be loaded from an unpacked scenario folder and reloaded an runtime using F5. If the classic scenario selection appears instead of the folder map, an error has occured in the folder map declaration, such as missing image files. With debug mode activated, there will also be an error message in OpenClonk.log." +msgstr "Zum Testen kann die FolderMap mit einem entpackten Rundenordner entworfen, und dann in der Szenarienauswahl mit Druck auf F5 jeweils neu geladen werden. Erscheint statt der FolderMap die klassische Szenarienauswahl, ist beim Laden der Definitionsdatei ein Fehler aufgetreten, oder zum Beispiel eine referenzierte Grafikdatei nicht gefunden worden. Bei aktiviertem Debugmodus findet sich in dem Fall eine Fehlermeldung in der Datei OpenClonk.log." #: sdk/files.xml:6(title) #: sdk/files.xml:7(h) @@ -14941,392 +15184,400 @@ msgstr "CreateContents" msgid "An object with this script will be given a rock right after it has been created. The Initialize function is called only when the object has reached full size (a building only when its construction has been completed and a living being only when it is fully grown)." msgstr "Ein Objekt mit diesem Script enthält sofort nach seiner Erschaffung einen Stein. Die Initialisierungsfunktion wird erst aufgerufen, nachdem das Objekt seine volle Größe erreicht hat. Bei Bauwerken also erst, nachdem sie vollständig gebaut wurden und bei Lebewesen erst, wenn sie voll ausgewachsen sind." -#: sdk/definition/script.xml:18(h) -msgid "TimerCall" -msgstr "TimerCall" - #: sdk/definition/script.xml:19(text) -msgid "Each object definition can define a timer call in its DefCore. The TimerCall is a function which will be called at regular intervals. The DefCore entry Timer determines the rate of calls. If no rate is specifed, the default value is 35 frames (roughly once per second)." -msgstr "Jede Objektdefinition kann im DefCore einen TimerCall bestimmen. Der TimerCall ist eine Funktion, die in regelmäßigen Abständen im Objektscript aufgerufen wird. Den Zeitabstand der Aufrufe bestimmt der DefCore-Eintrag Timer. Ohne spezielle Angabe für den Timer gilt der Vorgabewert von 35 Frames (also ca. einmal pro Sekunde)." - -#: sdk/definition/script.xml:21(text) msgid "An active object can also define activity script calls in its ActMap. The defined StartCall is made whenever an action begins (or repeats), an EndCall is made at the end of each activity. PhaseCall is called at each animation phase step and should only be used for very short animations. The call frequency of PhaseCalls is determined by the speed of the animation." msgstr "Ein aktives Objekt kann außerdem in seiner Aktivitätsdefinition Script-Aufrufe enthalten. Die als StartCall definierte Funktion wird immer dann aufgerufen wird, wenn die Aktivitätsschleife erneut startet. EndCall wird aufgerufen, wenn die Aktivitätsschleife endet. PhaseCall wird bei jedem Animationsschritt aufgerufen (da dies äußerst rechenintensiv ist, sollte PhaseCall nur bei seltenen und kurzzeitig ausgeführten Aktivitäten eingesetzt werden). Die Frequenz der Aufrufe bestimmt sich aus der Aktivitätsgeschwindigkeit." -#: sdk/definition/script.xml:22(h) +#: sdk/definition/script.xml:20(h) msgid "#include" msgstr "#include" -#: sdk/definition/script.xml:23(text) +#: sdk/definition/script.xml:21(text) msgid "An object script can also include the functionality of another script." msgstr "Ein Objektscript kann auf dem Script eines anderen Objekts basieren:" -#: sdk/definition/script.xml:25(text) +#: sdk/definition/script.xml:23(text) #, fuzzy msgid "At this position the complete script of the specified object definition (that of the clonk, in this case) is inserted, including all scripts that that script includes or got via #appendto. The only exception is that every script is included only once, so including both the Clonk script and a script that is included by the Clonk script doesn't include that script twice. Other Obviously, the included definition must be valid and loaded. Declared functions can be overloaded by functions of the same name that occur later in the script. Also see ()." msgstr "An dieser Position wird das komplette Script der jeweiligen Objektdefinition (hier des Clonks) eingefügt, die selbstverständlich vorhanden und geladen sein muss. Funktionen können durch später im Script folgende Funktionen gleichen Namens überladen werden. Siehe auch ()." -#: sdk/definition/script.xml:26(h) +#: sdk/definition/script.xml:24(h) #, fuzzy msgid "Interaction from other scripts" msgstr "Reaktionstyp 'Script'" -#: sdk/definition/script.xml:27(text) +#: sdk/definition/script.xml:25(text) msgid "Other scripts can call functions of an object obj with the -> and ->~ operators." msgstr "" -#: sdk/definition/script.xml:29(h) +#: sdk/definition/script.xml:27(h) msgid "Object calls made by the engine" msgstr "Objekt-Calls der Engine" -#: sdk/definition/script.xml:41(col) +#: sdk/definition/script.xml:39(col) msgid "When the object is completed (Con >= 100)." msgstr "Wenn das Objekt fertiggestellt wird (Con größer gleich 100)." -#: sdk/definition/script.xml:45(col) -#: sdk/definition/script.xml:115(col) -#: sdk/definition/script.xml:125(col) -#: sdk/definition/script.xml:130(col) -#: sdk/definition/script.xml:275(col) +#: sdk/definition/script.xml:43(col) +#: sdk/definition/script.xml:113(col) +#: sdk/definition/script.xml:123(col) +#: sdk/definition/script.xml:128(col) +#: sdk/definition/script.xml:278(col) msgid "object by_object" msgstr "object by_object" -#: sdk/definition/script.xml:46(col) +#: sdk/definition/script.xml:44(col) msgid "When the object is created. The parameter is a pointer to the object the script of which has created this object. Also see Construction" msgstr "Wenn das Objekt erzeugt wird. Als Parameter wird das Objekt übergeben, in dem das erzeugende Script steht. Siehe auch Construction" -#: sdk/definition/script.xml:51(col) +#: sdk/definition/script.xml:49(col) msgid "When the object is removed." msgstr "Wenn das Objekt gelöscht wird." -#: sdk/definition/script.xml:56(col) +#: sdk/definition/script.xml:54(col) msgid "When the object collides with the landscape or is collected at high velocity (>=15)." msgstr "Wenn das Objekt bei hoher Geschwindigkeit (>= 15) mit der Landschaft kollidiert oder aufgenommen wird (Collection)" -#: sdk/definition/script.xml:61(col) +#: sdk/definition/script.xml:59(col) msgid "Like Hit, with speeds >= 20 (see OCF_HitSpeed2)." msgstr "Wie Hit, bei Geschwindigkeiten >= 20 (siehe OCF_HitSpeed2)." -#: sdk/definition/script.xml:66(col) +#: sdk/definition/script.xml:64(col) msgid "Like Hit, with speeds >= 60 (see OCF_HitSpeed3)." msgstr "Wie Hit, bei Geschwindigkeiten >= 60 (siehe OCF_HitSpeed3)." -#: sdk/definition/script.xml:70(col) +#: sdk/definition/script.xml:68(col) msgid "object target, bool grab" msgstr "object target, bool grab" -#: sdk/definition/script.xml:71(col) +#: sdk/definition/script.xml:69(col) msgid "When the object grabs or lets go of another object." msgstr "Wenn das Objekt ein anderes Objekt anfasst oder loslässt." -#: sdk/definition/script.xml:75(col) +#: sdk/definition/script.xml:73(col) msgid "object by_object, bool grab" msgstr "object by_object, bool grab" -#: sdk/definition/script.xml:76(col) +#: sdk/definition/script.xml:74(col) msgid "When the object is grabbed or let go by another object." msgstr "Wenn das Objekt durch ein anderes Objekt angefasst oder losgelassen wird." -#: sdk/definition/script.xml:80(col) +#: sdk/definition/script.xml:78(col) msgid "object target" msgstr "object target" -#: sdk/definition/script.xml:81(col) +#: sdk/definition/script.xml:79(col) msgid "When the object takes another object from a container." msgstr "Wenn das Objekt ein Objekt aus einem anderen Objekt herausnimmt." -#: sdk/definition/script.xml:86(col) +#: sdk/definition/script.xml:84(col) msgid "When the object puts another object into a container." msgstr "Wenn das Objekt ein Objekt in einem anderen Objekt ablegt." -#: sdk/definition/script.xml:90(col) -msgid "int change, int by_player" -msgstr "int change, int by_player" +#: sdk/definition/script.xml:88(col) +msgid "int change, int cause, int by_player" +msgstr "int change, int cause, int by_player" -#: sdk/definition/script.xml:91(col) -msgid "When the object is damage." -msgstr "Wenn das Objekt beschädigt wird." +#: sdk/definition/script.xml:89(col) +msgid "When the object is damaged. See Fx*Damagefor cause values." +msgstr "Wenn das Objekt beschädigt wird. Siehe Fx*Damage für Werte von cause." -#: sdk/definition/script.xml:96(col) +#: sdk/definition/script.xml:94(col) msgid "When a living being surfaces after having used up more than half of its breath." msgstr "Wenn das Lebewesen nach dem Auftauchen mehr als die Hälfte seiner Atemkapazität auffüllt." -#: sdk/definition/script.xml:100(col) -#: sdk/definition/script.xml:105(col) -#: sdk/definition/script.xml:295(col) -#: sdk/definition/script.xml:300(col) +#: sdk/definition/script.xml:98(col) +#: sdk/definition/script.xml:103(col) +#: sdk/definition/script.xml:298(col) +#: sdk/definition/script.xml:303(col) msgid "int by_player" msgstr "int by_player" -#: sdk/definition/script.xml:101(col) +#: sdk/definition/script.xml:99(col) msgid "When the object is incinerated. Notice: with objects changing their definition via BurnTo, this call is made to the burned version!" msgstr "Wenn das Objekt entzündet wird. Achtung: Bei Objekten, die ihre Definition mit BurnTo ändern, findet der Aufruf im verbrannten Objekt statt!" -#: sdk/definition/script.xml:106(col) +#: sdk/definition/script.xml:104(col) msgid "When the object is incinerated in and immediately extinguished by a surrounding liquid. Otherwise as Incineration." msgstr "Wenn das Objekt in einer löschenden Flüssigkeit gesprengt, und damit nicht angezündet wird. Aufruf analog zu Incineration." -#: sdk/definition/script.xml:111(col) +#: sdk/definition/script.xml:109(col) msgid "When a living being dies." msgstr "Wenn ein Lebwesen stirbt." -#: sdk/definition/script.xml:116(col) +#: sdk/definition/script.xml:114(col) msgid "Activation by double dig. Only applies to collected items or directly controlled crew objects. Called after internal handling of the double dig command has been completed (e.g. chopping of trees etc.)" msgstr "Aktivierung durch einen Doppelklick auf Graben. Nur getragene Objekte und direkt spielergesteuerte Objekte. Wird aufgerufen, nachdem die interne Befehlskette (z.B. Bäume fällen) abgearbeitet wurde." -#: sdk/definition/script.xml:121(col) +#: sdk/definition/script.xml:119(col) msgid "When the object collides with the landscape. See CNAT - Contact Attachment." msgstr "Wenn das Objekt die Landschaft berührt. Siehe CNAT - Contact Attachment." -#: sdk/definition/script.xml:126(col) +#: sdk/definition/script.xml:124(col) msgid "When the object is controlled from the outside. See Control Functions." msgstr "Wenn das Objekt von außen gesteuert wird. Siehe Control-Funktionen." -#: sdk/definition/script.xml:131(col) +#: sdk/definition/script.xml:129(col) msgid "When the object is controlled from the inside. See Control Functions." msgstr "Wenn das Objekt von innen gesteuert wird. Siehe Control-Funktionen." -#: sdk/definition/script.xml:135(col) +#: sdk/definition/script.xml:133(col) msgid "string command, object target, int x, int y, object target2, int data, object command_object" msgstr "string command, object target, int x, int y, object target2, int data, object command_object" -#: sdk/definition/script.xml:136(col) +#: sdk/definition/script.xml:134(col) msgid "When the object has received a command to be independently executed. See Control functions." msgstr "Wenn dem Objekt durch den Spieler ein selbständig auszuführender Befehl gegeben wurde. Siehe Control-Funktionen." -#: sdk/definition/script.xml:140(col) +#: sdk/definition/script.xml:138(col) msgid "string command, object target, int x, int y, object target2, any Data" msgstr "string command, object target, int x, int y, object target2, any Data" -#: sdk/definition/script.xml:141(col) +#: sdk/definition/script.xml:139(col) msgid "When the object has completed a command or execution of a command has failed." msgstr "Wenn das Objekt einen selbständigen auszuführenden Befehl vollendet hat oder die Ausführung des Befehls fehlgeschlagen ist." -#: sdk/definition/script.xml:145(col) +#: sdk/definition/script.xml:143(col) msgid "object obj, int x, int y" msgstr "object obj, int x, int y" -#: sdk/definition/script.xml:146(col) +#: sdk/definition/script.xml:144(col) msgid "When an object (obj) using the internal pathfinding algorithm is trying to pass the transfer zone of this object on its way to point x/y. The transfer function can then help the object along by giving special script commands and returning true. Also see SetTransferZone()." msgstr "Wenn ein durch die Wegfindungsroutine gesteuertes Objekt (obj) die Transferzone dieses Objekts zum Zielpunkt x/y passieren möchte. Die Transferfunktion kann dem Objekt entsprechende Kommandos geben und sollte bei erfolgreicher Bearbeitung true zurückliefern. Siehe auch SetTransferZone()." -#: sdk/definition/script.xml:151(col) +#: sdk/definition/script.xml:149(col) msgid "When an object is loaded from a savegame or network synchronization is performed. Objects with a transfer zone should reset the zone in this call. Also see SetTransferZone()." -msgstr "Wenn ein Objekt geladen oder synchronisiert wird. Objekte mit einer TransferZone sollten diese bei jedem Aufruf von UpdateTransferZone neu setzen. Siehe auch SetTransferZone()." +msgstr "Wenn ein Objekt geladen oder synchronisiert wird. Objekte mit einer TransferZone sollten diese bei jedem Aufruf von OnSynchronized neu setzen. Siehe auch SetTransferZone()." -#: sdk/definition/script.xml:155(col) +#: sdk/definition/script.xml:153(col) msgid "int selection, object menu_object" msgstr "int selection, object menu_object" -#: sdk/definition/script.xml:156(col) +#: sdk/definition/script.xml:154(col) msgid "When the player wants to close a user defined object menu. Return value true will keep the menu open." msgstr "Wird in einem Objekt aufgerufen, wenn der Spieler ein benutzerdefiniertes Menu schließen will. Bei Rückgabewert true bleibt das Menu geöffnet." -#: sdk/definition/script.xml:161(col) +#: sdk/definition/script.xml:159(col) msgid "Only in game goal objects. A return value true indicates that this goal is fulfilled." msgstr "Nur bei Spielziel-Objekten. Bei Rückgabewert true ist das Spielziel erfüllt." -#: sdk/definition/script.xml:165(col) +#: sdk/definition/script.xml:163(col) msgid "id target" msgstr "id target" -#: sdk/definition/script.xml:166(col) +#: sdk/definition/script.xml:164(col) msgid "When a new inventory object is selected. See Control Functions." msgstr "Wenn ein neues Inhaltsobjekt angewählt wird. Siehe Control-Funktionen." -#: sdk/definition/script.xml:170(col) -#: sdk/definition/script.xml:260(col) -#: sdk/definition/script.xml:270(col) +#: sdk/definition/script.xml:168(col) +#: sdk/definition/script.xml:263(col) +#: sdk/definition/script.xml:273(col) msgid "object container" msgstr "object container" -#: sdk/definition/script.xml:171(col) +#: sdk/definition/script.xml:169(col) msgid "When the object is selected in an inventory change. If you are processing this event, the function should play its own selection sound." msgstr "Wenn das Objekt durch einen Inventarwechsel ausgewählt wird. Wenn die Funktion abgefangen wird, sollte ein eigener Auswahlsound abgespielt werden." -#: sdk/definition/script.xml:175(col) +#: sdk/definition/script.xml:173(col) msgid "int level, object by" msgstr "int level, object by" -#: sdk/definition/script.xml:176(col) +#: sdk/definition/script.xml:174(col) msgid "When the object is hit or punched by another object." msgstr "Wenn das Objekt von einem anderen Objekt geschlagen oder getroffen wird." -#: sdk/definition/script.xml:180(col) +#: sdk/definition/script.xml:178(col) msgid "object by" msgstr "object by" -#: sdk/definition/script.xml:181(col) +#: sdk/definition/script.xml:179(col) msgid "Called before the object is hit or punched by another object. By returning true, QueryCatchBlow can reject physical blows." msgstr "Bevor das Objekt von einem anderen Objekt geschlagen oder getroffen wird. Wenn QueryCatchBlow true zurückgibt, können damit physikalische Treffer abgefangen werden." -#: sdk/definition/script.xml:185(col) +#: sdk/definition/script.xml:183(col) msgid "int cause" msgstr "int cause" -#: sdk/definition/script.xml:186(col) +#: sdk/definition/script.xml:184(col) msgid "When a line object is broken. cause: 0 by movement, 1 because of a missing or incomplete target object." msgstr "Wenn ein Leitungsobjekt unterbrochen wird. cause: 0 durch Bewegung, 1 durch fehlendes oder unvollständiges Zielobjekt." -#: sdk/definition/script.xml:190(col) +#: sdk/definition/script.xml:188(col) msgid "id material_definition, int amount" msgstr "id material_definition, int amount" -#: sdk/definition/script.xml:191(col) +#: sdk/definition/script.xml:189(col) msgid "When the object is building another object and building material is required. The parameters are the type and amount of the first needed material. If this function returns true, no material message is displayed above the object." msgstr "Wenn das Objekt ein anderes Objekt baut und noch Baumaterial benötigt wird. Parameter sind Typ und Menge des ersten noch benötigten Baustoffs. Durch Rückgabewert true kann die Textmeldung über fehlendes Material abgefangen werden." -#: sdk/definition/script.xml:196(col) +#: sdk/definition/script.xml:194(col) msgid "When the object is in an ATTACH action and has lost its action target. At this time, the object's action has already been reset." msgstr "Wenn das Objekt eine ATTACH-Aktivität besessen hatte, aber das Actiontarget verloren hat. Die Aktivität ist beim Aufruf bereits zurückgesetzt." -#: sdk/definition/script.xml:200(col) +#: sdk/definition/script.xml:198(col) msgid "bool deselect, bool cursor_only" msgstr "bool deselect, bool cursor_only" -#: sdk/definition/script.xml:201(col) +#: sdk/definition/script.xml:199(col) msgid "When crew selection is changed. cursor_only specifies whether only that crew member has been selected which is also the cursor." msgstr "Bei Änderung der Crewauswahl. cursor_only gibt an, ob nur das Mannschaftsmitglied angewählt wurde, welches den Cursor hat." -#: sdk/definition/script.xml:205(col) +#: sdk/definition/script.xml:203(col) msgid "object for_collection_of_object" msgstr "object for_collection_of_object" -#: sdk/definition/script.xml:206(col) +#: sdk/definition/script.xml:204(col) msgid "Called to determine the least needed inventory object when a clonk tries to collect a new object and his inventory is full. The function should return the object to be dropped to gain space, or nil if none." msgstr "Zur Ermittlung des am wenigsten gebrauchten Objekts, wenn der Clonk versucht, ein neues aufzunehmen. Die Funktion sollte das abzulegende Objekt zurückliefern, oder nil für keins." -#: sdk/definition/script.xml:210(col) +#: sdk/definition/script.xml:208(col) msgid "int index, object menu_object" msgstr "int index, object menu_object" -#: sdk/definition/script.xml:211(col) +#: sdk/definition/script.xml:209(col) msgid "When an object menu entry is selected." msgstr "Wenn ein Menueintrag ausgewählt wurde." -#: sdk/definition/script.xml:215(col) -#: sdk/definition/script.xml:220(col) +#: sdk/definition/script.xml:213(col) +#: sdk/definition/script.xml:218(col) msgid "object in_base, int for_player" msgstr "object in_base, int for_player" -#: sdk/definition/script.xml:216(col) +#: sdk/definition/script.xml:214(col) msgid "Calculates the value of an object. Also see GetValue()." msgstr "Ermittelt den Wert eines Objekts. Siehe auch GetValue()." -#: sdk/definition/script.xml:221(col) +#: sdk/definition/script.xml:219(col) msgid "Calculates the value of an object type available to buy. Also see GetValue()." msgstr "Ermittelt den Wert eines (noch nicht gekauften) Objekttyps. Siehe auch GetValue()." -#: sdk/definition/script.xml:225(col) +#: sdk/definition/script.xml:223(col) msgid "id item, int value" msgstr "id item, int value" -#: sdk/definition/script.xml:226(col) +#: sdk/definition/script.xml:224(col) msgid "Returns the buying price of the object type." msgstr "Rückgabewert ist Einkaufspreis des Objekttyps." -#: sdk/definition/script.xml:230(col) +#: sdk/definition/script.xml:228(col) msgid "object obj, int object_value" msgstr "object obj, int object_value" -#: sdk/definition/script.xml:231(col) +#: sdk/definition/script.xml:229(col) msgid "Returns the selling price of the object type." msgstr "Rückgabewert ist Verkaufspreis des Objekttyps." -#: sdk/definition/script.xml:236(col) +#: sdk/definition/script.xml:234(col) msgid "When an object with LIFT action lifts its action target to the height specified in its DefCore or above." msgstr "Wenn das Objekt bei einer LIFT-Aktivität ein anderes Objekt höher angehoben hat als in der DefCore angegeben." -#: sdk/definition/script.xml:241(col) +#: sdk/definition/script.xml:239(col) msgid "When the action target of the object's PUSH or LIFT action is stuck." msgstr "Wird aufgerufen, wenn das Ziel einer PUSH- oder LIFT-Aktivität festhängt." -#: sdk/definition/script.xml:246(col) +#: sdk/definition/script.xml:244(col) msgid "When the action target of the object's PUSH or PULL action is lost." msgstr "Wenn das Ziel einer PUSH- oder PULL-Aktion verloren geht." -#: sdk/definition/script.xml:250(col) +#: sdk/definition/script.xml:248(col) msgid "object obj, bool put" msgstr "object obj, bool put" -#: sdk/definition/script.xml:251(col) +#: sdk/definition/script.xml:249(col) msgid "When the object has collected another object (obj) (by ingame collection or grabbing and getting)." msgstr "Wenn das Objekt ein anderes Objekt (obj) aufgenommen hat (nur durch einsammeln oder anfassen und ablegen)." -#: sdk/definition/script.xml:255(col) -#: sdk/definition/script.xml:265(col) +#: sdk/definition/script.xml:253(col) +#: sdk/definition/script.xml:268(col) msgid "object obj" msgstr "object obj" -#: sdk/definition/script.xml:256(col) +#: sdk/definition/script.xml:254(col) msgid "When the object has collected another object (obj) (in all cases, even in script controlled collection or entering)." msgstr "Wenn das Objekt ein anderes Objekt (obj) aufgenommen hat (immer, auch durch Scriptbefehl Enter)" -#: sdk/definition/script.xml:261(col) +#: sdk/definition/script.xml:258(col) +msgid "object destroyed" +msgstr "object destroyed" + +#: sdk/definition/script.xml:259(col) +msgid "When an object contained in the object has been destroyed/removed. The object still exists when the callback is called, but will be destroyed afterwards." +msgstr "Wenn ein Inhaltsobjekt dieses Objekts zerstört wird. Zum Aufrufzeitpunkt existiert das Objekt noch und wird erst danach zerstört." + +#: sdk/definition/script.xml:264(col) msgid "When this object has left another object (container)." msgstr "Wenn das Objekt ein anderes Objekt (container) verlassen hat." -#: sdk/definition/script.xml:266(col) +#: sdk/definition/script.xml:269(col) msgid "When another object (obj) has left the contents of this object (also see script command Exit)." msgstr "Wenn ein Objekt (obj) dieses Objekt verlassen hat (auch durch Scriptbefehl Exit)." -#: sdk/definition/script.xml:271(col) +#: sdk/definition/script.xml:274(col) msgid "When the object has entered another object (container)." msgstr "Wenn das Objekt ein anderes Objekt (container) betreten hat." -#: sdk/definition/script.xml:276(col) +#: sdk/definition/script.xml:279(col) msgid "When another object is trying to enter this object through the entrance." msgstr "Wenn ein anderes Objekt versucht, das Objekt durch Entrance zu betreten." -#: sdk/definition/script.xml:280(col) +#: sdk/definition/script.xml:283(col) msgid "id def, object obj" msgstr "id def, object obj" -#: sdk/definition/script.xml:281(col) +#: sdk/definition/script.xml:284(col) msgid "Called before Collection. If RejectCollect returns true, the collection of the other object is prevented." msgstr "Wird vor Collection aufgerufen. Wenn RejectCollect true zurückgibt, kann damit die Aufnahme des anderen Objekts verhindert werden." -#: sdk/definition/script.xml:285(col) +#: sdk/definition/script.xml:288(col) msgid "object into_object" msgstr "object into_object" -#: sdk/definition/script.xml:286(col) +#: sdk/definition/script.xml:289(col) msgid "Called before Entrance. If RejectEntrance returns true, then entrance of the other object is prevented." msgstr "Wird vor Entrance aufgerufen. Wenn RejectEntrance true zurückgibt, kann damit das Hineinversetzen in das andere Objekt verhindert werden." -#: sdk/definition/script.xml:291(col) +#: sdk/definition/script.xml:294(col) msgid "Called in game goals, rules, or environment objects after the joining of a new player and before the corresponding call in the scenario script." msgstr "Aufruf in Spielziel, -regel und Umweltobjekten nach der Platzierung eines beitretenden Spielers, und vor dem entsprechenden Aufruf im Szenarioscript." -#: sdk/definition/script.xml:296(col) +#: sdk/definition/script.xml:299(col) msgid "When the object is sold. Should return nil or the id of the object type which is actually added to the player's homebase material." msgstr "Wenn das Objekt verkauft wird. Rückgabewert nil oder die ID des Objekts, welches dem Heimatbasismaterial hinzugefügt wird." -#: sdk/definition/script.xml:301(col) +#: sdk/definition/script.xml:304(col) msgid "When the object is sold." msgstr "Wenn das Objekt verkauft wird." -#: sdk/definition/script.xml:305(col) +#: sdk/definition/script.xml:308(col) msgid "int by_player, object buy_object" msgstr "int by_player, object buy_object" -#: sdk/definition/script.xml:306(col) +#: sdk/definition/script.xml:309(col) msgid "When the object is bought." msgstr "Wenn das Objekt gekauft wird." -#: sdk/definition/script.xml:311(col) +#: sdk/definition/script.xml:314(col) msgid "When the objet is added to the crew of a player." msgstr "Wenn das Objekt der Crew eines Spielers hinzugefügt wird." -#: sdk/definition/script.xml:316(col) +#: sdk/definition/script.xml:319(col) msgid "Callback in game goal, rule, and environment objects and in the scenario script. If RejectTeamSwitch returns true, the team switch of a player can be prevented (see )." msgstr "Aufruf in Spielziel, -regel und Umweltobjekten und dem Szenarioscript. Wenn RejectTeamSwitch true zurückgibt, kann der Teamwechsel eines Spielers (durch ) verhindert werden." -#: sdk/definition/script.xml:321(col) +#: sdk/definition/script.xml:324(col) msgid "Callback in game goal, rule, and environment objects and in the scenario script. Called when a player has successfully switch from old_team to new_team (see )." msgstr "Aufruf in Spielziel, -regel und Umweltobjekten und dem Szenarioscript. Wenn ein Spieler erfolgreich von old_team zu new_team transferiert wurde (durch )." -#: sdk/definition/script.xml:30(text) +#: sdk/definition/script.xml:329(col) +msgid "When object is selected in editor. Use this callback to display extra information for scenario designers." +msgstr "" + +#: sdk/definition/script.xml:334(col) +msgid "When object is deselected in editor. Use this callback to hide any information previously shown in EditCursorSelection." +msgstr "" + +#: sdk/definition/script.xml:28(text) msgid "The engine calls the following functions is objects at the given time. " msgstr "Die Engine ruft zu Zeiten die folgenden Funktionen in Objektscripten auf. " @@ -15355,14 +15606,32 @@ msgid "The Objects's major Z-Position. See ." msgstr "Die hauptsächliche Z-Position des Objekts. Siehe auch ." #: sdk/definition/properties.xml:131(col) -#, fuzzy msgid "The Object's minor Z-Position. Negative values are behind the landscape, positive values before it. Use 1-399 for stuff behind Clonks, 401-999 for stuff before Clonks, and 1000+ for GUI objects." -msgstr "Die sekundäre Z-Position des Objekts. Negative Werte sind hinter der Landschaft, positive vor ihr." +msgstr "Die sekundäre Z-Position des Objekts. Negative Werte sind hinter der Landschaft, positive vor ihr. Benutze 1-399 für Dinge hinter Clonks, 401-999 für Dinge vor Clonks, und 1000+ für GUI-Objekte." + +#: sdk/definition/properties.xml:136(col) +msgid "Placement: 0 land surface, 1 in liquid, 2 in mid-air, 3 underground, 4 land surface and underground." +msgstr "Platzierung: 0 Oberfläche, 1 in Flüssigkeit, 2 in der Luft, 3 im Untergrund, 4 An der Oberfläche und im Untergrund." + +#: sdk/definition/properties.xml:141(col) +msgid "Incineration by explosion: 0 none, otherwise the damage level of incineration." +msgstr "Explosionsentzündlichkeit: 0 keine, sonst bei angegebenem Schadenswert" + +#: sdk/definition/properties.xml:146(col) +msgid "Definition change upon incineration." +msgstr "Definitionswechsel bei Entzündung." + +#: sdk/definition/properties.xml:151(col) +msgid "0 or 1. If 1, the object does not decompose if burning." +msgstr "0 oder 1. Bei Wert 1 verbrennt das Objekt nicht." + +#: sdk/definition/properties.xml:156(col) +msgid "Probability of incineration by contact: 0 none, or 1 (high) to 5 (low)." +msgstr "Kontaktentzündlichkeit: 0 keine, 1 (hoch) bis 5 (niedrig)" #: sdk/definition/procedures.xml:8(text) -#, fuzzy msgid "For object activity the engine offers various standard procedures which perform typical physical behaviour. In procedure WALK, for instance, the activity automatically changes to \"Jump\" if the ground under the feet is lost." -msgstr "Für Objekt-Aktivitäten bietet die Engine diverse Standardprozeduren an, die verschiedene typische Verhaltensweisen steuern. Durch die Standardprozedur WALK wechselt z.B. die Aktivität Walk automatisch nach Jump, sobald der Boden unter den Füßen verloren wurde." +msgstr "Für Objekt-Aktivitäten bietet die Engine diverse Standardprozeduren an, die verschiedene typische Verhaltensweisen steuern. Die Standardprozedur WALK wechselt z.B. automatisch nach \"Jump\", sobald der Boden unter den Füßen verloren wurde." #: sdk/definition/procedures.xml:15(col) #: sdk/definition/cnat.xml:14(col) @@ -15399,9 +15668,8 @@ msgstr "Laufen" #: sdk/definition/procedures.xml:50(col) #: sdk/definition/procedures.xml:62(col) #: sdk/definition/procedures.xml:92(col) -#, fuzzy msgid "According to current ComDir." -msgstr "Baut das Zielobjekt." +msgstr "Verhalten nach derzeitiger ComDir." #: sdk/definition/procedures.xml:27(col) #: sdk/definition/procedures.xml:39(col) @@ -15858,382 +16126,347 @@ msgid "Maximal allowed count when placed in the menu system." msgstr "Maximale Anzahl beim Platzieren des Objekts im Menüsystem." #: sdk/definition/defcore.xml:46(col) -msgid "Regularly called timer function in the object script." -msgstr "Regelmäßig aufgerufene Funktion des Objektscripts. Siehe Objektscripte." - -#: sdk/definition/defcore.xml:51(col) -msgid "Time interval between TimerCalls in frames. Default is 35." -msgstr "Zeitabstand der TimerCalls in Frames. Ohne Angabe gilt der Vorgabewert 35." - -#: sdk/definition/defcore.xml:56(col) msgid "0 or 1. If 1, Contactcalls are called in the object script." msgstr "0 oder 1. Legt fest, ob Kontaktaufrufe im Objektscript getätigt werden." -#: sdk/definition/defcore.xml:61(col) +#: sdk/definition/defcore.xml:51(col) msgid "Width of the object." msgstr "Breite des Objekts." -#: sdk/definition/defcore.xml:66(col) +#: sdk/definition/defcore.xml:56(col) msgid "Height of the object." msgstr "Höhe des Objekts." -#: sdk/definition/defcore.xml:71(col) +#: sdk/definition/defcore.xml:61(col) msgid "Coordinate offset of the top left corner to the object center." msgstr "Koordinatenabstand der linken oberen Ecke zur Objektmitte." -#: sdk/definition/defcore.xml:76(col) +#: sdk/definition/defcore.xml:66(col) msgid "Value of the object in money points." msgstr "Wert des Objekts in Geldpunkten." -#: sdk/definition/defcore.xml:81(col) +#: sdk/definition/defcore.xml:71(col) msgid "Weight of the object. Rock 10, clonk 50, hut 1000, castle 10000." msgstr "Gewicht des Objekts. Stein 10, Clonk 50, Hütte 1000, Burg 10000." -#: sdk/definition/defcore.xml:86(col) +#: sdk/definition/defcore.xml:76(col) msgid "Elements from which the object is composed. Uncompleted or half grown objects will only have the respective fraction of the components." msgstr "Elemente, aus denen das Objekt zusammen gesetzt ist. Im Bau oder Wachstum befindliche Objekte enthalten nur anteilige Komponenten." -#: sdk/definition/defcore.xml:91(col) +#: sdk/definition/defcore.xml:81(col) msgid "Solid areas of the object. Target rectangle from the source graphics onto the object." msgstr "Massivbereiche des Objekts. Zielrechteck aus der Graphics.png aufs Objekt." -#: sdk/definition/defcore.xml:96(col) +#: sdk/definition/defcore.xml:86(col) msgid "Covering layer of the object graphics. Target rectangle from the source graphics onto the object." msgstr "Verdeckende Oberflächen. Zielrechteck aus Graphics.png aufs Objekt." -#: sdk/definition/defcore.xml:101(col) +#: sdk/definition/defcore.xml:91(col) msgid "Representative image of the object. Rectangle from the source graphics." msgstr "Repräsentativgrafik des Objekts. Rechteck aus Graphics.png." -#: sdk/definition/defcore.xml:106(col) +#: sdk/definition/defcore.xml:96(col) msgid "Number of vertices of the object. 1 to 30." msgstr "Anzahl der Eckpunkte des Objekts. 1 bis 30." +#: sdk/definition/defcore.xml:100(col) +#: sdk/definition/defcore.xml:105(col) #: sdk/definition/defcore.xml:110(col) #: sdk/definition/defcore.xml:115(col) -#: sdk/definition/defcore.xml:120(col) -#: sdk/definition/defcore.xml:125(col) msgid "up to 30 integers" msgstr "bis zu 30 Integer" -#: sdk/definition/defcore.xml:111(col) +#: sdk/definition/defcore.xml:101(col) msgid "List of horizontal vertex coordinates of the object. See vertices." msgstr "Liste der horizontalen Koordinaten der Eckpunkte des Objekts. Siehe Vertices." -#: sdk/definition/defcore.xml:116(col) +#: sdk/definition/defcore.xml:106(col) msgid "List of vertical coordinates of the object vertices." msgstr "Liste der vertikalen Koordinaten der Eckpunkte des Objekts." -#: sdk/definition/defcore.xml:121(col) +#: sdk/definition/defcore.xml:111(col) msgid "List of direction indicators of the object vertices. See CNAT." msgstr "Liste der Ausrichtungsbestimmungen der Eckpunkte. Siehe CNAT." -#: sdk/definition/defcore.xml:126(col) +#: sdk/definition/defcore.xml:116(col) msgid "List of friction values of the object vertices, each 1 to 100." msgstr "Liste der Reibungswerte der Eckpunkte, jeweils 1 bis 100." -#: sdk/definition/defcore.xml:131(col) +#: sdk/definition/defcore.xml:121(col) msgid "Position of the entrance region relative to the object centre." msgstr "Koordinaten des Eingangsbereichs des Objekts relativ zur Objektmitte." -#: sdk/definition/defcore.xml:136(col) +#: sdk/definition/defcore.xml:126(col) msgid "Position of the intake region relative to the object centre." msgstr "Koordinaten des Aufnahmebereichs des Objekts relativ zur Objektmitte." -#: sdk/definition/defcore.xml:141(col) +#: sdk/definition/defcore.xml:131(col) msgid "Flame distance to the object's bottom line." msgstr "Flammenabstand zur Objektunterkante." -#: sdk/definition/defcore.xml:146(col) -msgid "Placement: 0 land surface, 1 in liquid, 2 in mid-air, 3 underground, 4 land surface and underground." -msgstr "Platzierung: 0 Oberfläche, 1 in Flüssigkeit, 2 in der Luft, 3 im Untergrund, 4 An der Oberfläche und im Untergrund." - -#: sdk/definition/defcore.xml:151(col) +#: sdk/definition/defcore.xml:136(col) msgid "0 or 1. Determines whether the object blocks objects behind it." msgstr "0 oder 1. Legt fest, ob das Objekt dahinterliegende Objekte blockiert." -#: sdk/definition/defcore.xml:156(col) -msgid "Probability of incineration by contact: 0 none, or 1 (high) to 5 (low)." -msgstr "Kontaktentzündlichkeit: 0 keine, 1 (hoch) bis 5 (niedrig)" - -#: sdk/definition/defcore.xml:161(col) -msgid "Incineration by explosion: 0 none, otherwise the damage level of incineration." -msgstr "Explosionsentzündlichkeit: 0 keine, sonst bei angegebenem Schadenswert" - -#: sdk/definition/defcore.xml:166(col) -msgid "Definition change upon incineration." -msgstr "Definitionswechsel bei Entzündung." - -#: sdk/definition/defcore.xml:171(col) +#: sdk/definition/defcore.xml:141(col) msgid "0 or 1. Determines whether the building can be a home base." msgstr "0 oder 1. Legt fest, ob das Objekt Heimatbasis sein kann." -#: sdk/definition/defcore.xml:176(col) +#: sdk/definition/defcore.xml:146(col) msgid "0 or 1. If 1 the object is a line and exhibits special behaviour." msgstr "0 oder 1. Bei 1 ist das Objekt eine Leitung und wird speziell behandelt" -#: sdk/definition/defcore.xml:181(col) +#: sdk/definition/defcore.xml:151(col) msgid "0 or 1. If 1, the object is added to the player's crew upon purchase. Objects created using CreateObject have to be added to a player's crew manually using MakeCrewMember." msgstr "0 oder 1. Wenn 1, wird das Objekt beim Kauf der Mannschaft hinzugefügt. Mit CreateObject erzeugte CrewMember-Objekte müssen mit MakeCrewMember der Mannschaft eines Spielers hinzugefügt werden." -#: sdk/definition/defcore.xml:186(col) +#: sdk/definition/defcore.xml:156(col) msgid "Growth of the object. Trees 1-4, living beings 15." msgstr "Wachstum des Objekts. Baum 1-4, Lebewesen 15." -#: sdk/definition/defcore.xml:191(col) +#: sdk/definition/defcore.xml:161(col) msgid "0 or 1. Determines whether the object can be bought back after selling it." msgstr "0 oder 1. Legt fest, ob das Objekt nach Verkauf zurückgekauft werden kann." -#: sdk/definition/defcore.xml:196(col) +#: sdk/definition/defcore.xml:166(col) msgid "0 or 1. Determines whether the object can be built." msgstr "0 oder 1. Legt fest, ob das Objekt als Baustelle gebaut werden kann." -#: sdk/definition/defcore.xml:201(col) +#: sdk/definition/defcore.xml:171(col) msgid "Definition change upon building." msgstr "Definitionswechsel beim Bau." -#: sdk/definition/defcore.xml:206(col) +#: sdk/definition/defcore.xml:176(col) msgid "0 no grabbing, 1 grab and push, 2 grab only." msgstr "0 kein Anfassen, 1 Anfassen und Verschieben, 2 nur Anfassen." -#: sdk/definition/defcore.xml:211(col) +#: sdk/definition/defcore.xml:181(col) msgid "Bit mask: bit 0 (value 1) putting possible, bit 1 (value 2) getting possible." msgstr "Bitmaske: Bit 0 (Wert 1) Grab und Put, Bit 1 (Wert 2) Grab und Get" -#: sdk/definition/defcore.xml:216(col) +#: sdk/definition/defcore.xml:186(col) msgid "0 or 1. Determines whether the object can be collected." msgstr "0 oder 1. Legt fest, ob das Objekt eingesammelt werden kann." -#: sdk/definition/defcore.xml:221(col) +#: sdk/definition/defcore.xml:191(col) msgid "0 no rotation, 1 full rotation, 2-360 limited rotation." msgstr "0 keine Rotation, 1 volle Rotation, 2-360 eingeschränkte Rotation" -#: sdk/definition/defcore.xml:226(col) +#: sdk/definition/defcore.xml:196(col) msgid "0 or 1. Determines whether the object can be chopped." msgstr "0 oder 1. Legt fest, ob das Objekt gefällt werden kann." -#: sdk/definition/defcore.xml:231(col) +#: sdk/definition/defcore.xml:201(col) msgid "Floatation in liquids: 0 no floatation, otherwise floatation height above the object center." msgstr "Auftrieb in Flüssigkeiten: 0 kein Auftrieb, sonst Auftriebshöhe über Mitte" -#: sdk/definition/defcore.xml:236(col) +#: sdk/definition/defcore.xml:206(col) msgid "0 or 1. Determines whether explosions in the object's contents affect other objects outside." msgstr "0 oder 1. Legt fest, ob Explosionen im Inneren nach außen wirken." -#: sdk/definition/defcore.xml:241(col) +#: sdk/definition/defcore.xml:211(col) msgid "0 or 1. If 1, the specified sections of the object's graphcis are colored by the player color." msgstr "0 oder 1. Bei Wert 1 wird das Ausgangsblau, bzw. die Overlay.png, nach dem Besitzer gefärbt." -#: sdk/definition/defcore.xml:246(col) +#: sdk/definition/defcore.xml:216(col) msgid "The object is colored by the color of the specified material." msgstr "Name des Materials, nach dem das Objekt gefärbt wird." -#: sdk/definition/defcore.xml:251(col) +#: sdk/definition/defcore.xml:221(col) msgid "0 or 1. If 1, the object can only move vertically." msgstr "0 oder 1. Bei Wert 1 kann das Objekt sich nur vertikal bewegen." -#: sdk/definition/defcore.xml:256(col) +#: sdk/definition/defcore.xml:226(col) msgid "Bit mask: bit 0 (value 1) stop at the sides, bit 1 (value 2) stop at the top, bit 2 (value 4) stop at the bottom." msgstr "Bitmaske: Bit 0 (1) Stop an Seiten, Bit 1 (2) Stop oben, Bit 2 (4) Stop unten" -#: sdk/definition/defcore.xml:261(col) +#: sdk/definition/defcore.xml:231(col) msgid "If not 0, the unrotated object attaches to solid areas (attachment directions 8-10)." msgstr "Wenn ungleich 0 (8-10) sitzt das Objekt aufgerichtet auf Massivbereichen auf." -#: sdk/definition/defcore.xml:266(col) +#: sdk/definition/defcore.xml:236(col) msgid "0 or 1. If 1, the uncomplete object (see GetCon) is scaled, not sliced from the bottom like a construction site." msgstr "0 oder 1. Bei Wert 1 wird das Objekt wie ein Lebewesen vergrößert (abhängig von der Fertigstellung. Siehe GetCon)" -#: sdk/definition/defcore.xml:271(col) +#: sdk/definition/defcore.xml:241(col) msgid "0 no basement, 1 normal basement, other values reserved." msgstr "0 kein Fundament, 1 Fundament, andere Werte speziell" -#: sdk/definition/defcore.xml:276(col) -msgid "0 or 1. If 1, the object does not decompose if burning." -msgstr "0 oder 1. Bei Wert 1 verbrennt das Objekt nicht." - -#: sdk/definition/defcore.xml:281(col) +#: sdk/definition/defcore.xml:246(col) msgid "0 or 1. If 1, the object can have activities set even if it's not complete." msgstr "0 oder 1. Wert 1 für Lebewesen, die auch im Wachstum aktiv sein können." -#: sdk/definition/defcore.xml:286(col) +#: sdk/definition/defcore.xml:251(col) msgid "0 or 1. The object can be scaled over 100% using DoCon." msgstr "0 oder 1. Das Objekt kann mit DoCon auf Übergröße vergrößert werden." -#: sdk/definition/defcore.xml:291(col) +#: sdk/definition/defcore.xml:256(col) msgid "0 or 1. The object attracts lightning." msgstr "0 oder 1. Das Objekt zieht Blitze an." -#: sdk/definition/defcore.xml:296(col) +#: sdk/definition/defcore.xml:261(col) msgid "0 or 1. The object should not be thrown." msgstr "0 oder 1. Objekt sollte nicht geworfen werden." -#: sdk/definition/defcore.xml:301(col) +#: sdk/definition/defcore.xml:266(col) msgid "0 or 1. The object can not be pushed into another object's entrance (e.g. elevator case)." msgstr "0 oder 1. Das Objekt kann nicht durch Anfassen und Steuerung Rauf in andere Objekte hineingeschoben werden (z.B. Fahrstuhlkorb)." -#: sdk/definition/defcore.xml:306(col) +#: sdk/definition/defcore.xml:271(col) msgid "Bit mask: bit 0 (value 1) object can be controlled by grabbing from the outside and/or bit 1 (value 2) from the inside. With active VehicleControl, clonk orders (commands) are also passed to the grabbed object as ControlCommand calls and can be processed and/or overloaded by the controlled object's script. See Control-Funktionen." msgstr "Bitmaske: Bit 0 (Wert 1) das Objekt kann durch Anfassen von außen und/oder Bit 1 (Wert 2) von innen gesteuert werden. Bei aktiviertem VehicleControl werden die selbständig auszuführenden Befehle (Commands) eines Clonks als ControlCommand-Aufrufe an das Script des entsprechenden Fahrzeugs weitergeleitet und können von diesem ausgewertet und abgefangen werden. Siehe Control-Funktionen." -#: sdk/definition/defcore.xml:311(col) +#: sdk/definition/defcore.xml:276(col) msgid "1 - 10. Determines search depth of the pathfinder algorithm (default 1). Warning: higher values may slow down the game. By setting this value you can also enable non-CrewMember objects to use pathfinding when executing commands." msgstr "1 - 10. Beeinflusst die Suchtiefe des Wegfindungsalgorithmus (Standard: 1). Vorsicht: hohe Werte sind sehr rechenintensiv. Mit diesem Wert setzen auch Objekte ohne CrewMember-Wert bei der Ausführung von Kommandos (z.B. MoveTo) den internen Wegfindungsalgorithmus ein." -#: sdk/definition/defcore.xml:316(col) +#: sdk/definition/defcore.xml:281(col) msgid "0 or 1. If 1, the object's contents is not added to the object's total mass. This can be used to prevent small container objects from turning into killer throwing items." msgstr "0 oder 1. Bei 1 zählt der Inhalt des Objekts nicht mit zur Gesamtmasse. Dadurch lässt sich zum Beispiel verhindern, dass Rucksäcke oder Köcher durch ihren Inhalt mörderische Wurfwaffen werden." -#: sdk/definition/defcore.xml:321(col) +#: sdk/definition/defcore.xml:286(col) msgid "0 or 1. If 1, the object will not straighten itself to 0° if within a certain upright range." msgstr "0 oder 1. Bei 1 richtet sich das Objekt nicht automatisch auf 0° Drehung auf, wenn es nur sehr leicht gedreht ist." -#: sdk/definition/defcore.xml:326(col) +#: sdk/definition/defcore.xml:291(col) msgid "0 or 1. If 1, clonks inside this object can not lighten the Fog of War outside." msgstr "0 oder 1. Bei 1 können enthaltene Clonks bei aktiviertem Fog Of War nicht herausschauen." -#: sdk/definition/defcore.xml:331(col) +#: sdk/definition/defcore.xml:296(col) msgid "0 or 1. Can be used to prevent failure messages caused by failed commands." msgstr "0 oder 1. Bei 1 werden bei fehlgeschlagenen Commands keine Meldungen ausgegeben." -#: sdk/definition/defcore.xml:336(col) -msgid "0 or 1. If 1, the object does not take damage when burning." -msgstr "0 oder 1. Bei 1 wird dem Objekt kein Schaden zugefügt, wenn es brennt." - -#: sdk/definition/defcore.xml:341(col) +#: sdk/definition/defcore.xml:301(col) msgid "0 or 1. If 1, the object is not stored in the permanent crew of a player." msgstr "0 oder 1. Bei 1 wird das Objekt nicht in die Dauerhafte Crew des Spielers eingetragen." -#: sdk/definition/defcore.xml:346(col) -msgid "0 to 200: determines the amount of smoke caused by the burning object. 0 for no smoke, 100 is default. If other than 0, the object will always generate maximum smoke when traveling at high velocity (e.g. a fire arrow)." -msgstr "0 bis 200: Gibt die Rauchmenge an, die das Objekt im Brandfall verursacht. 0 ist kein Rauch, 100 ist die Standardmenge. Bei Werten ungleich 0 wird allerdings immer die Maximalmenge Rauch produziert, wenn das Objekt in schneller Bewegung ist (zum Beispiel Brandpfeile)." - -#: sdk/definition/defcore.xml:351(col) +#: sdk/definition/defcore.xml:306(col) msgid "0 or 1. Value 1 for addtive drawing." msgstr "0 oder 1. Bei 1 wird das Objekt additiv gezeichnet." -#: sdk/definition/defcore.xml:356(col) +#: sdk/definition/defcore.xml:311(col) msgid "0 or 1. If 1, the object does not need oxygen, even if it's a living being." msgstr "0 oder 1. Bei 1 atmet das Objekt nicht, selbst wenn es ein Lebewesen ist." -#: sdk/definition/defcore.xml:361(col) +#: sdk/definition/defcore.xml:316(col) msgid "Values grater than 0 are deducted from the top of necessary construction space." msgstr "Wert >=0. Abzug des benötigten Bauplatzes von oben." -#: sdk/definition/defcore.xml:366(col) +#: sdk/definition/defcore.xml:321(col) msgid "0 or 1. If 1 the object can not be sold." msgstr "0 oder 1. Bei 1 kann das Objekt nicht verkauft werden." -#: sdk/definition/defcore.xml:371(col) +#: sdk/definition/defcore.xml:326(col) msgid "0 or 1. If 1 the object can not be taken from containers by a clonk." msgstr "0 oder 1. Bei 1 kann das Objekt nicht manuell aus anderen Objekten heraus genommen werden.01." -#: sdk/definition/defcore.xml:376(col) +#: sdk/definition/defcore.xml:331(col) msgid "If an object with Action procedure \"LIFT\" lifts its target to this value above object center the function LiftTop is called in the object script." msgstr "Wird ein Objekt bei einer Action mit der Procedure \"LIFT\" mehr als die angegebene Höhe über der Objektmitte angehoben, wird die Funktion LiftTop im Script aufgerufen." -#: sdk/definition/defcore.xml:381(col) +#: sdk/definition/defcore.xml:336(col) msgid "0 entrance is open if the object is upright only; 1 entrance is always open; 2-360 entrance is open within the specified object rotation in degrees." msgstr "0 Eingang ist nur bei aufgerichtetem Objekt geöffnet, 1 Eingang ist immer geöffnet, 2-360 Eingang ist innerhalb des entsprechenden Bereichs geöffnet." -#: sdk/definition/defcore.xml:386(col) +#: sdk/definition/defcore.xml:341(col) msgid "Maximum range at which the waypoint of a movement command can be touched for a successful hit. Default value 5." msgstr "Maximale Distanz, mit der ein Bewegungskommando einen Zielpunkt treffen muss, damit das Bewegungskommando als erfüllt gilt. Vorgabewert 5." -#: sdk/definition/defcore.xml:391(col) +#: sdk/definition/defcore.xml:346(col) msgid "0 or 1. If 1 the object's pathfinding will ignore any transfer zones." msgstr "0 oder 1. Bei 1 berücksichtigt die Wegfindung des Objekts keine Transferzonen an Gebäuden." -#: sdk/definition/defcore.xml:396(col) +#: sdk/definition/defcore.xml:351(col) msgid "0 or 1. If 1, the building's context menu will open automatically upon entry." msgstr "0 oder 1. Bei 1 wird für dieses Gebäude beim Betreten automatisch das Kontextmenü geöffnet." -#: sdk/definition/defcore.xml:402(caption) +#: sdk/definition/defcore.xml:357(caption) msgid "Section [Physical]" msgstr "Sektion [Physical]" -#: sdk/definition/defcore.xml:411(col) +#: sdk/definition/defcore.xml:366(col) msgid "0-100000. Maximum life energy." msgstr "0-100000. Maximale Lebensenergie." -#: sdk/definition/defcore.xml:416(col) +#: sdk/definition/defcore.xml:371(col) msgid "0-100000. Maximum breath." msgstr "0-100000. Maximaler Atem." -#: sdk/definition/defcore.xml:421(col) +#: sdk/definition/defcore.xml:376(col) msgid "0-100000. Walking speed." msgstr "0-100000. Laufgeschwindigkeit." -#: sdk/definition/defcore.xml:426(col) +#: sdk/definition/defcore.xml:381(col) msgid "0-100000. Jump force." msgstr "0-100000. Sprungkraft." -#: sdk/definition/defcore.xml:431(col) +#: sdk/definition/defcore.xml:386(col) msgid "0-100000. Scaling speed." msgstr "0-100000. Klettergeschwindigkeit." -#: sdk/definition/defcore.xml:436(col) +#: sdk/definition/defcore.xml:391(col) msgid "0-100000. Hangling speed." msgstr "0-100000. Hangelgeschwindigkeit." -#: sdk/definition/defcore.xml:441(col) +#: sdk/definition/defcore.xml:396(col) msgid "0-100000. Digging speed." msgstr "0-100000. Grabgeschwindigkeit." -#: sdk/definition/defcore.xml:446(col) +#: sdk/definition/defcore.xml:401(col) msgid "0-100000. Swimming speed." msgstr "0-100000. Schwimmgeschwindigkeit." -#: sdk/definition/defcore.xml:451(col) +#: sdk/definition/defcore.xml:406(col) msgid "0-100000. Throwing force." msgstr "0-100000. Wurfkraft." -#: sdk/definition/defcore.xml:456(col) +#: sdk/definition/defcore.xml:411(col) msgid "0-100000. Push power." msgstr "0-100000. Schiebekraft." -#: sdk/definition/defcore.xml:461(col) +#: sdk/definition/defcore.xml:416(col) msgid "0-100000. Maximal magic energy." msgstr "0-100000. Maximale Zauberenergie." -#: sdk/definition/defcore.xml:466(col) +#: sdk/definition/defcore.xml:421(col) msgid "0-100. Flight speed." msgstr "0-100. Fluggeschwindigkeit." -#: sdk/definition/defcore.xml:471(col) +#: sdk/definition/defcore.xml:426(col) msgid "0 or 1. Scale." msgstr "0 oder 1. Klettern." -#: sdk/definition/defcore.xml:476(col) +#: sdk/definition/defcore.xml:431(col) msgid "0 or 1. Brachiation." msgstr "0 oder 1. Hangeln." -#: sdk/definition/defcore.xml:481(col) +#: sdk/definition/defcore.xml:436(col) msgid "0 or 1. Dig." msgstr "0 oder 1. Graben." -#: sdk/definition/defcore.xml:486(col) +#: sdk/definition/defcore.xml:441(col) msgid "0 or 1. Construct. If greater than 1, percentage construction speed. (100 normal, 50 half, etc.)" msgstr "0 oder 1. Bauen. Bei Werten größer 1: Prozentuale Baugeschwindigkeit (100 entspricht dem Standard; 50 ist halbe Standardgeschwindigkeit). Erweitert" -#: sdk/definition/defcore.xml:491(col) +#: sdk/definition/defcore.xml:446(col) msgid "0 or 1. Determines wether the object resists acid." msgstr "0 oder 1. Legt fest, ob das Objekt Säure widersteht." -#: sdk/definition/defcore.xml:496(col) +#: sdk/definition/defcore.xml:451(col) msgid "0 object breathes air, 1 object breathes water." msgstr "0 Objekt atmet Luft, 1 Objekt atmet Wasser." -#: sdk/definition/defcore.xml:500(h) +#: sdk/definition/defcore.xml:455(h) msgid "Note:" msgstr "Hinweis:" -#: sdk/definition/defcore.xml:501(text) +#: sdk/definition/defcore.xml:456(text) msgid "When a crew member is created, it gets an own physical section in it's Objectinfo (oci). In there, the individual changes to the physicals (for example because of training) are saved and restored when an object enters a player's crew. The physical section of the defcore is only used for new crew members and normal objects." msgstr "Sobald ein Mannschaftsmitglied erschaffen wird, wird für dieses eine eigenständige Physical-Sektion erschaffen, die zusammen mit dem Mannschaftsmitglied in der Objektinfo (oci) gespeichert wird. Jedes Mannschaftsmitglied behält seine eigene Physical-Sektion, da hier alle individuellen Veränderungen (z.B. erweiterte Fähigkeiten durch Beförderung) vorgenommen werden. Die Physical-Sektion der Objektdefinition wird also nur bei der Erschaffung des Objekts verwendet und nicht etwa bei ChangeDef." #: sdk/definition/cnat.xml:8(text) -msgid "In multiple places the engine uses ContactAttachment values (a bitmask) to manage the orientation of objects and processes. For example, a vertex of an object can have the CNAT bit left. If that object has ContactCalls activated, the engine calls on every contact of that vertex with the landscape the object script function ContactLeft. CNAT values are composed of the following bits:" +#, fuzzy +msgid "In multiple places the engine uses ContactAttachment values (a bitmask) to manage the orientation of objects and processes. For example, a vertex of an object can have the CNAT bit left. If that object has ContactCalls activated, the engine calls on every contact of that vertex with the landscape the object script function ContactLeft. CNAT values are composed of the following bits:" msgstr "An zahlreichen Stellen benutzt die Engine ContactAttachment-Werte (DWord-Bitmasken), um Ausrichtungen von Objekten und Vorgängen zu verwalten. So kann z.B. einem Objekt-Vertex ein CNAT-Wert zugewiesen werden, der die Ausrichtung Links enthält. Sind für dieses Objekt ContactCalls aktiviert (siehe DefCore.txt), so ruft die Engine bei jedem Kontakt dieses Vertex mit der Landschaft die Objektscript-Funktion ContactLeft auf. CNAT-Werte setzen sich aus folgenden Bits zusammen:" #: sdk/definition/cnat.xml:20(col) @@ -16260,10 +16493,6 @@ msgstr "Richtung: Oben" msgid "Direction: Down" msgstr "Richtung: Unten" -#: sdk/definition/cnat.xml:43(col) -msgid "16" -msgstr "16" - #: sdk/definition/cnat.xml:44(col) msgid "CNAT_Center" msgstr "CNAT_Center" @@ -16298,8 +16527,8 @@ msgid "Object Categories" msgstr "Objektkategorien" #: sdk/definition/category.xml:9(text) -msgid "An object's category specifies parts of its behavior. For a definition it is set by the Category entry in the DefCore.txt file. Multiple categories can be combined using the binary OR operator." -msgstr "Die Kategorie eines Objekts legt Teile seines Verhaltens fest. Sie wird für eine Definition durch den Eintrag Category in der DefCore.txt festgelegt. Dabei können verschiedene Kategorien mit einem binären oder-Operator kombiniert werden." +msgid "An object's category specifies parts of its behavior. For a definition it is set by the Category entry in the DefCore.txt file. Multiple categories can be combined using the binary OR operator." +msgstr "Die Kategorie eines Objekts legt Teile seines Verhaltens fest. Sie wird für eine Definition durch den Eintrag Category in der DefCore.txt festgelegt. Dabei können verschiedene Kategorien mit einem binären oder-Operator kombiniert werden." #: sdk/definition/category.xml:17(col) msgid "C4D_StaticBack" @@ -16410,7 +16639,7 @@ msgstr "C4D_IgnoreFoW" msgid "Object is drawn above fog of war. Useful for creating status displays or gui elements using objects." msgstr "Objekt wird auch dann gezeichnet, wenn es eigentlich vom Kriegsnebel bedeckt ist. Nützlich beispielsweise für Statusanzeigen und Kontrollelemente." -#: sdk/definition/category.xml:79(text) +#: sdk/definition/category.xml:78(text) msgid "Category for a rule." msgstr "Kategorie für eine Regel." @@ -16479,34 +16708,39 @@ msgid "Linear with Y position. When the object moves upwards the animation plays msgstr "Linear mit der Y-Position. Bewegung des Objekts nach Oben spielt die Animation in die entgegengesetzte Richtung ab. Kann verwendet werden falls die Animation eines Objekts synchron zu seiner vertikalen Bewegung stattfinden soll." #: sdk/definition/animations.xml:45(col) +#, fuzzy +msgid "Linear with rotation. When the object rotates counter-clockwise the animation plays backwards. Can be used if the animation of an object should be synchronized to its rotation." +msgstr "Linear mit der X-Position. Bewegung des Objekts nach Links spielt die Animation in die entgegengesetzte Richtung ab. Kann verwendet werden falls die Animation eines Objekts synchron zu seiner horizontalen Bewegung stattfinden soll." + +#: sdk/definition/animations.xml:49(col) msgid "Linear with X position. However, the animation is always played in the same direction, not taking into account whether the object moves left or right." msgstr "Linear mit der X-Position, allerdings spielt die Animation immer in die gleiche Richtung, egal ob sich das Objekt nach rechts oder nach links bewegt." -#: sdk/definition/animations.xml:49(col) +#: sdk/definition/animations.xml:53(col) msgid "Linear with Y position. However, the animation is always played in the same direction, not taking into account whether the object moves upwards or downwards." msgstr "Linear mit der Y-Position, allerdings spielt die Animation immer in die gleiche Richtung, egal ob sich das Objekt nach oben oder nach unten bewegt." -#: sdk/definition/animations.xml:53(col) +#: sdk/definition/animations.xml:57(col) msgid "Proportional to the horizontal speed of the object." msgstr "Proportional zur X-Geschwindigkeit eines Objekts." -#: sdk/definition/animations.xml:57(col) +#: sdk/definition/animations.xml:61(col) msgid "Proportional to the vertical speed of the object." msgstr "Proportional zur Y-Geschwindigkeit eines Objekts." -#: sdk/definition/animations.xml:61(col) +#: sdk/definition/animations.xml:65(col) msgid "Proportional to the phase of the currently executed action." msgstr "Proportional zur Phase der aktuell ausgeführten Aktivität." -#: sdk/definition/animations.xml:65(text) +#: sdk/definition/animations.xml:69(text) msgid "For examples to the individual AVPs see the documentation of their respective script functions." msgstr "Für Beispiele zu den einzelnen AVPs siehe die Dokumentation zu den entsprechenden Scriptfunktion." -#: sdk/definition/animations.xml:66(h) +#: sdk/definition/animations.xml:70(h) msgid "ActMap animations" msgstr "Animationen der ActMap" -#: sdk/definition/animations.xml:67(text) +#: sdk/definition/animations.xml:71(text) msgid "Individual activities specified in the ActMap can be assigned an animation. These animations are always played in slot 0. This means that, amongst others, at most one animation can be played in slot 0, animations cannot be combined. Also it is not possible to modify these animations via script functions such as or . However it is allowed to query properties of ActMap animations, such as with . Negative slot numbers do also exist so that own animations can be assigned a smaller priority than ActMap animations." msgstr "Einzelnen Aktivitäten in der ActMap kann eine Animation zugeordnet werden. Diese Animationen werden immer in Slot 0 abgespielt. Das bedeutet unter anderem, dass in Slot 0 höchstens eine Animation abgespielt wird, es gibt keine Kombinationen. Es ist auch nicht möglich, diese durch Scriptfunktionen wie oder zu beeinflussen. Es ist jedoch sehr wohl möglich, Eigenschaften von ActMap-Animationen abzufragen, zum Beispiel mit . Es existieren auch negative Slotnummern, sodass man eigene Animationen eine geringere Priorität als ActMap-Animationen zuweisen kann." @@ -16567,66 +16801,80 @@ msgid "Attachment to surfaces: CNAT Value< msgstr "Festhalten an Oberflächen: CNAT-Wert, also z.B. Wert 8 für Boden. Wird nur ausgewertet, wenn Procedure NONE ist." #: sdk/definition/actmap.xml:76(col) -msgid "Animation graphics: Target rectangle from Graphics.png relative to upper left corner of unrotated object shape." -msgstr "Animationsgrafik: Zielrechteck aus Graphics.png auf Objektposition." +msgid "Animation graphics: X coordinate from Graphics.png." +msgstr "" #: sdk/definition/actmap.xml:81(col) +msgid "Animation graphics: Y coordinate from Graphics.png." +msgstr "" + +#: sdk/definition/actmap.xml:86(col) +#, fuzzy +msgid "Width of the animation graphic from Graphics.png." +msgstr "Breite des neuen Grafikrechtecks" + +#: sdk/definition/actmap.xml:91(col) +#, fuzzy +msgid "Height of the animation graphic from Graphics.png." +msgstr "Höhe des neuen Grafikrechtecks" + +#: sdk/definition/actmap.xml:96(col) msgid "0 or 1. If 1, the default facet (i.e., the facet shown if the object has no action) will be drawn behind the action facet." msgstr "0 oder 1. Bei Wert 1 wird Facet mit der Standardobjektgrafik unterlegt." -#: sdk/definition/actmap.xml:86(col) +#: sdk/definition/actmap.xml:101(col) msgid "0 or 1. If 1, the TopFace (see DefCore.txt) will be drawn using the animated facet." msgstr "0 oder 1. Bei 1 wird das TopFace (siehe DefCore.txt) aus der animierten Facet verwendet." -#: sdk/definition/actmap.xml:91(col) +#: sdk/definition/actmap.xml:106(col) msgid "0 or 1. If 1, the graphics will be stretched down towards the upper border of the ActionTarget. Used e.g. for the elevator line." msgstr "0 oder 1. Bei 1 wird die Grafik vertikal bis zur oberen Kante des ActionTarget gestretcht." -#: sdk/definition/actmap.xml:96(col) +#: sdk/definition/actmap.xml:111(col) msgid "Next action being set after the current one has reached its end." msgstr "Nächste Aktivität nach Ablauf der Animationsphasen." -#: sdk/definition/actmap.xml:101(col) +#: sdk/definition/actmap.xml:116(col) msgid "0 or 1. If 1, no other action can be set after this one (used e.g. for death or destruction)." msgstr "0 oder 1. Bei 1 ist keine Aktivität nach dieser möglich (z.B. Tod, Zerstörung)." -#: sdk/definition/actmap.xml:106(col) +#: sdk/definition/actmap.xml:121(col) msgid "Object script function which is called when the activity is started." msgstr "Objektscriptfunktion, die beim Start der Aktivität aufgerufen wird." -#: sdk/definition/actmap.xml:111(col) +#: sdk/definition/actmap.xml:126(col) msgid "Called when an activity reaches the end of its animation." msgstr "Wird am Ende der Aktivität aufgerufen." -#: sdk/definition/actmap.xml:116(col) +#: sdk/definition/actmap.xml:131(col) msgid "Called whenever the animation phase changes." msgstr "Wird bei jedem Phasenschritt aufgerufen." -#: sdk/definition/actmap.xml:121(col) +#: sdk/definition/actmap.xml:136(col) msgid "Called if an activity is being replaced by another before its regular end; i.e. not by a transition through NextAction. Parameters are the previous animation phase, previous ActionTarget and previous ActionTarget2." msgstr "Wird aufgerufen, wenn die Aktivität vor ihrem Ende durch eine andere ersetzt wird. Parameter sind letzte Animationsphase, letztes ActionTarget und ActionTarget2." -#: sdk/definition/actmap.xml:126(col) +#: sdk/definition/actmap.xml:141(col) msgid "Action to be set if the object plunges into water." msgstr "Auszuführende Aktion, wenn das Objekt in Flüssigkeiten eintaucht." -#: sdk/definition/actmap.xml:131(col) +#: sdk/definition/actmap.xml:146(col) msgid "Permanent sound being played during this action." msgstr "Dauerhaftes Geräusch dieser Aktivität." -#: sdk/definition/actmap.xml:136(col) +#: sdk/definition/actmap.xml:151(col) msgid "0 or 1. Restricted control of the object during this action." msgstr "0 oder 1. Eingeschränkte Fähigkeit des Objekts während dieser Aktion." -#: sdk/definition/actmap.xml:141(col) +#: sdk/definition/actmap.xml:156(col) msgid "Area that is dug free during this action. If 1, the area covered by the object shape is freed (like the elevator case); otherwise, the value is taken as the radius of a circular area (like a digging Clonk)." msgstr "Freigraben während dieser Aktion. Objektrechteck 1, sonst Kreisradius." -#: sdk/definition/actmap.xml:146(col) +#: sdk/definition/actmap.xml:161(col) msgid "Specifies the animation to be played in the mesh of the object. Works only if the object uses a mesh for its graphics. If given all of Facet, FacetBase, FacetTopFace and FacetTargetStretch are ignored. The Length times Delay possible animation phases are mapped linearly on the animation length. If Delay equals 0 only Length will be used and the animation does not play automatically. See Animationen for further documentation on animations." msgstr "Bestimmt die auszuführende Animation im Mesh des Objekts. Funktioniert nur wenn ein solches vorhanden ist. Wenn gegeben werden Facet, FacetBase, FacetTopFace und FacetTargetStretch ignoriert. Die Length mal Delay verschiedenen Animationsphasen werden linear auf die Länge der Animation abgebildet. Wenn Delay 0 ist wird nur Length verwendet und die Animation spielt nicht automatisch. Siehe Animationen für weitergehende Dokumentation zu Animationen." -#: sdk/definition/actmap.xml:151(text) +#: sdk/definition/actmap.xml:166(text) msgid "The ActMap is defined in the script, an example definition looks like this:" msgstr "Die ActMap wird im Script definiert, eine Beispiel-Definition sieht so aus:" @@ -16731,12 +16979,12 @@ msgid "Ctrl-W, Ctrl-M, Ctrl-T, Ctrl-I, +/- : Change settings in landscape drawin msgstr "Ctrl-W, Ctrl-M, Ctrl-T, Ctrl-I, +/- : Einstellungen im Zeichenmodus" #: sdk/cmdline.xml:8(text) -msgid "The installation directory of Clonk contains various executable program files. Usually programs are started with a double click or from a start menu without additional parameters. When starting programs from a command line shell or script file (batch file), additional command line parameters can be specified." -msgstr "Das Installationsverzeichnis von Clonk enthält die unten beschriebenen Programmdateien. Durch einen Start per Doppelklick oder Startmenü werden Programme ohne zusätzliche Parameter ausgeführt. Innerhalb einer Konsole (Eingabeaufforderung) oder Script-Datei (Batch-Datei) lassen sich die Programme jedoch mit zusätzlichen Kommandozeilenparametern starten, die hier ausführlich erklärt werden." +msgid "The installation directory of OpenClonk contains various executable program files. Usually programs are started with a double click or from a start menu without additional parameters. When starting programs from a command line shell or script file (batch file), additional command line parameters can be specified." +msgstr "Das Installationsverzeichnis von OpenClonk enthält die unten beschriebenen Programmdateien. Durch einen Start per Doppelklick oder Startmenü werden Programme ohne zusätzliche Parameter ausgeführt. Innerhalb einer Konsole (Eingabeaufforderung) oder Script-Datei (Batch-Datei) lassen sich die Programme jedoch mit zusätzlichen Kommandozeilenparametern starten, die hier ausführlich erklärt werden." #: sdk/cmdline.xml:10(h) -msgid "Clonk.exe (Windows) clonk (Linux) Clonk (Mac)" -msgstr "Clonk.exe (Windows) clonk (Linux) Clonk (Mac)" +msgid "openclonk.exe (Windows) openclonk (Linux) Openclonk (Mac)" +msgstr "openclonk.exe (Windows) openclonk (Linux) Openclonk (Mac)" #: sdk/cmdline.xml:11(text) msgid "The engine. The main program of the game. Without startup parameters, the game starts in fullscreen (player mode) and shows the startup menu. The following command line parameters are recognized:" @@ -16891,8 +17139,8 @@ msgid "--recdump=<Filename>" msgstr "--recdump=<Dateiname>" #: sdk/cmdline.xml:85(text) -msgid "Only for replay of recorded games: Before the replay is started, all replay data (player controls) are dumped into a file called <File name> in the Clonk folder. If the file name extension is .txt, the controls will be dumped in text mode, otherwise binary. The replay file must be specified separately as a scenario file (e.g. Clonk.exe Records.ocf/Record001.ocs --recdump=CtrlRec.txt)." -msgstr "Nur für die Wiedergabe von Aufnahmen: Vor dem Start der Wiedergabe werden die Wiedergabedaten (Spielerkommandos) in eine Datei mit dem Namen <Dateiname> im Clonkverzeichnis geschrieben. Endet der Dateiname auf .txt, werden die Daten als Text geschrieben; sonst binär. Die abzuspielende Aufnahme muss trotzdem als Szenariendatei angegeben werden (Zum Beispiel Clonk.exe Aufnahmen.ocf/Record001.ocs --recdump=CtrlRec.txt)." +msgid "Only for replay of recorded games: Before the replay is started, all replay data (player controls) are dumped into a file called <File name> in the Clonk folder. If the file name extension is .txt, the controls will be dumped in text mode, otherwise binary. The replay file must be specified separately as a scenario file (e.g. openclonk.exe Records.ocf/Record001.ocs --recdump=CtrlRec.txt)." +msgstr "Nur für die Wiedergabe von Aufnahmen: Vor dem Start der Wiedergabe werden die Wiedergabedaten (Spielerkommandos) in eine Datei mit dem Namen <Dateiname> im Clonkverzeichnis geschrieben. Endet der Dateiname auf .txt, werden die Daten als Text geschrieben; sonst binär. Die abzuspielende Aufnahme muss trotzdem als Szenariendatei angegeben werden (Zum Beispiel openclonk.exe Aufnahmen.ocf/Record001.ocs --recdump=CtrlRec.txt)." #: sdk/cmdline.xml:87(dt) msgid "--startup=<Name>" @@ -16931,8 +17179,92 @@ msgid "c4group.exe (Windows) c4group (Linux) c4group (Mac)" msgstr "c4group.exe (Windows) c4group (Linux) c4group (Mac)" #: sdk/cmdline.xml:111(text) -msgid "This command line program is used for processing group files. A list of command line options is available by starting the program without parameters via command line (not by double clicking)." -msgstr "Dieses Kommandozeilen-Programm dient zum Bearbeiten von Gruppendateien. Es kann nicht per Doppelklick, sondern nur per Kommandozeile (Eingabeaufforderung) gestartet werden. Auskunft über alle verfügbaren Kommandozeilenparameter erhält man, indem man das Programm ohne weitere Parameter über die Kommandozeile startet." +msgid "This command line program is used for processing group files. A list of command line options is available by starting the program without parameters via command line (not by double clicking)." +msgstr "Dieses Kommandozeilen-Programm dient zum Bearbeiten von Gruppendateien. Es kann nicht per Doppelklick, sondern nur per Kommandozeile (Eingabeaufforderung) gestartet werden. Auskunft über alle verfügbaren Kommandozeilenparameter erhält man, indem man das Programm ohne weitere Parameter startet." + +#~ msgid "Calls the local function function. If \"~\" is prepended to the function name then the call does not fail if the function does not exist." +#~ msgstr "Ruft die lokale Funktion function auf. Wird \"~\" vor den Funktionsnamen gesetzt, wird der Aufruf failsafe durchgeführt." + +#~ msgid "Animation graphics: Target rectangle from Graphics.png relative to upper left corner of unrotated object shape." +#~ msgstr "Animationsgrafik: Zielrechteck aus Graphics.png auf Objektposition." + +#~ msgid "X position of the pixel to be set; relative coordinates in local calls" +#~ msgstr "X-Position des Pixels, das umgefärbt werden soll; relative Koordinaten bei objektlokalem Aufruf" + +#~ msgid "Y position of the pixel to be set; relative coordinates in local calls" +#~ msgstr "Y-Position des Pixels, das umgefärbt werden soll; relative Koordinaten bei objektlokalem Aufruf" + +#~ msgid "32 bit color value of the pixel" +#~ msgstr "32Bit-Farbwert des Pixels." + +#~ msgid "Sets a pixel in the landscape. Not available in the old 8 bit graphics system." +#~ msgstr "Färbt ein Pixel in der Landschaft ein. Diese Funktion ist nicht im 8Bit-Grafiksystem verfügbar." + +#~ msgid "Colors the landscape pixel directly behind the calling object brown." +#~ msgstr "Färbt das Landschaftspixel direkt hinter dem aufrufenden Objekt braun." + +#~ msgid "New gravity: value -300 til 300 (in percent)" +#~ msgstr "Neue Schwerkraft: Werte -300 bis 300 (in Prozent)" + +#~ msgid "Sets the gravity. Normal gravity is 100% and results in an acceleration of 0.2 pixels per Tick. (increasing YDir by 2 per Tick with precision=10)." +#~ msgstr "Setzt die Schwerkraft. Dabei entspricht die Standardgravitation (100%) einer Beschleunigung von 0.2 Pixeln pro Tick. (Zunahme der YDir um 2 pro Tick bei precision=10)" + +#~ msgid "Additional PlayerControls.txt files can be put in language packages to adapt the standard key mappings of different loaded languages to the keyboard of their respective country**." +#~ msgstr "Zusaetzliche Dateien PlayerControls.txt koennen in Sprachpaketen abgelegt werden, um die Standardbelegungen der Tasten bei verschiedenen, geladenen Sprachen an die Tastaturen des jeweiligen Landes anzupassen**." + +#~ msgid "The keypress is passed to the mapping with the next lower priority only if the previous command was executed successfully. This can be used to define macros. **" +#~ msgstr "Der Tastendruck wird genau dann an die Belegung mit der naechstniedrigen Prioritaet weitergereicht, wenn das vorherige Kommando erfolgreich ausgefuehrt wurde. Hiermit lassen sich Makros definieren. **" + +#~ msgid "** - not yet implemented" +#~ msgstr "** - noch nicht implementiert" + +#~ msgid "id of the definition in the script of which to call the function." +#~ msgstr "ID der Definition, in dessen Script die Funktion aufgerufen wird" + +#~ msgid "Additional parameters to be passed to the function." +#~ msgstr "Zusätzliche Parameter, die an die Funktion übergeben werden" + +#~ msgid "Calls a function in a script without object context. returns in this case (comparable to scenario scripts)." +#~ msgstr "Ruft eine Funktion in einem Script ohne zugehöriges Objekt auf. Der ()-Zeiger gibt in einem solchen Aufruf zurück (Vergleichbar mit dem Szenarioscript)." + +#~ msgid "TimerCall" +#~ msgstr "TimerCall" + +#~ msgid "Each object definition can define a timer call in its DefCore. The TimerCall is a function which will be called at regular intervals. The DefCore entry Timer determines the rate of calls. If no rate is specifed, the default value is 35 frames (roughly once per second)." +#~ msgstr "Jede Objektdefinition kann im DefCore einen TimerCall bestimmen. Der TimerCall ist eine Funktion, die in regelmäßigen Abständen im Objektscript aufgerufen wird. Den Zeitabstand der Aufrufe bestimmt der DefCore-Eintrag Timer. Ohne spezielle Angabe für den Timer gilt der Vorgabewert von 35 Frames (also ca. einmal pro Sekunde)." + +#~ msgid "When the object is damage." +#~ msgstr "Wenn das Objekt beschädigt wird." + +#~ msgid "Regularly called timer function in the object script." +#~ msgstr "Regelmäßig aufgerufene Funktion des Objektscripts. Siehe Objektscripte." + +#~ msgid "Time interval between TimerCalls in frames. Default is 35." +#~ msgstr "Zeitabstand der TimerCalls in Frames. Ohne Angabe gilt der Vorgabewert 35." + +#~ msgid "0 or 1. If 1, the object does not take damage when burning." +#~ msgstr "0 oder 1. Bei 1 wird dem Objekt kein Schaden zugefügt, wenn es brennt." + +#~ msgid "0 to 200: determines the amount of smoke caused by the burning object. 0 for no smoke, 100 is default. If other than 0, the object will always generate maximum smoke when traveling at high velocity (e.g. a fire arrow)." +#~ msgstr "0 bis 200: Gibt die Rauchmenge an, die das Objekt im Brandfall verursacht. 0 ist kein Rauch, 100 ist die Standardmenge. Bei Werten ungleich 0 wird allerdings immer die Maximalmenge Rauch produziert, wenn das Objekt in schneller Bewegung ist (zum Beispiel Brandpfeile)." + +#~ msgid "Makes a rectangular hole in semi-solid materials." +#~ msgstr "Gräbt ein rechteckiges Loch in halbfesten Materialien." + +#~ msgid "Makes a circular hole in semi-solid materials." +#~ msgstr "Gräbt ein kreisrundes Loch in halbfesten Materialien." + +#~ msgid "Rain" +#~ msgstr "Rain" + +#~ msgid "0-100 with tolerance. Precipitation amount." +#~ msgstr "0-100 und Abweichung. Regenwahrscheinlichkeit." + +#~ msgid "Precipitation" +#~ msgstr "Precipitation" + +#~ msgid "Simple material definition precipitation." +#~ msgstr "Einfache Materialdefinition Niederschlag." #~ msgid "New value for the script counter. The next scenario script function called will be ScriptXXX." #~ msgstr "Neue Position des Skriptzählers. Der nächste ScriptXXX-Aufruf wird bei diesem Zählerwert getätigt." @@ -17552,9 +17884,6 @@ msgstr "Dieses Kommandozeilen-Programm dient zum Bearbeiten von Gruppendateien. #~ msgid "Displays \"Ich benötige ein besseres Beispiel\" for German users." #~ msgstr "Gibt \"Ich benötige ein besseres Beispiel\" auf dem Bildschirm aus." -#~ msgid "[opt] variable in which the red value is to be stored" -#~ msgstr "[opt] Variable, in der der Rotanteil gespeichert werden soll" - #~ msgid "[opt] variable in which the green value is to be stored" #~ msgstr "[opt] Variable, in der der Grünanteil gespeichert werden soll" @@ -18083,8 +18412,8 @@ msgstr "Dieses Kommandozeilen-Programm dient zum Bearbeiten von Gruppendateien. #~ msgid "Animation" #~ msgstr "Animation" -#~ msgid "UpdateTransferZone" -#~ msgstr "UpdateTransferZone" +#~ msgid "OnSynchronized" +#~ msgstr "OnSynchronized" #~ msgid "CatchBlow" #~ msgstr "CatchBlow" diff --git a/docs/doku.css b/docs/doku.css index 60240b9bb..a65d8b0ea 100644 --- a/docs/doku.css +++ b/docs/doku.css @@ -1,3 +1,9 @@ +@font-face{ + font-family: Endeavour; + src: url('/Endeavour.eot'); + src: local('Endeavour'),url('/Endeavour.ttf') format("truetype"); +} + body { margin: 0; font-size: small; @@ -74,6 +80,7 @@ color:#222222; } h1 { + font-family: Endeavour, Verdana, Sans-serif; font-size: 2em; font-weight: normal; margin-top: 1.32em; @@ -243,4 +250,6 @@ ul.nav li.switchlang img { margin: 0; } - +a { + color: rgb(0, 102, 153); +} diff --git a/docs/header.xml b/docs/header.xml index 100ed2b8c..c3fd8f95a 100644 --- a/docs/header.xml +++ b/docs/header.xml @@ -3,68 +3,56 @@ Unfortunately, xml documents can only have one root, so there needs to be a dumm header is an appropiate html element, so it's arbitrarily chosen. clonk.xsl also uses it to match the processing for it. -->
            + + -
            diff --git a/docs/sdk/cmdline.xml b/docs/sdk/cmdline.xml index afcf98ab9..2aee1aa62 100644 --- a/docs/sdk/cmdline.xml +++ b/docs/sdk/cmdline.xml @@ -5,9 +5,9 @@ Command Line Parameters Command Line Parameters - The installation directory of Clonk contains various executable program files. Usually programs are started with a double click or from a start menu without additional parameters. When starting programs from a command line shell or script file (batch file), additional command line parameters can be specified. + The installation directory of OpenClonk contains various executable program files. Usually programs are started with a double click or from a start menu without additional parameters. When starting programs from a command line shell or script file (batch file), additional command line parameters can be specified. - Clonk.exe (Windows) clonk (Linux) Clonk (Mac) + openclonk.exe (Windows) openclonk (Linux) Openclonk (Mac) The engine. The main program of the game. Without startup parameters, the game starts in fullscreen (player mode) and shows the startup menu. The following command line parameters are recognized:
            --editor
            @@ -82,7 +82,7 @@
            --recdump=<Filename>
            - Only for replay of recorded games: Before the replay is started, all replay data (player controls) are dumped into a file called <File name> in the Clonk folder. If the file name extension is .txt, the controls will be dumped in text mode, otherwise binary. The replay file must be specified separately as a scenario file (e.g. Clonk.exe Records.ocf/Record001.ocs --recdump=CtrlRec.txt). + Only for replay of recorded games: Before the replay is started, all replay data (player controls) are dumped into a file called <File name> in the Clonk folder. If the file name extension is .txt, the controls will be dumped in text mode, otherwise binary. The replay file must be specified separately as a scenario file (e.g. openclonk.exe Records.ocf/Record001.ocs --recdump=CtrlRec.txt).
            --startup=<Name>
            @@ -108,7 +108,7 @@ c4group.exe (Windows) c4group (Linux) c4group (Mac) - This command line program is used for processing group files. A list of command line options is available by starting the program without parameters via command line (not by double clicking). + This command line program is used for processing group files. A list of command line options is available by starting the program without parameters via command line (not by double clicking). Sven22007-02 Günther2011 diff --git a/docs/sdk/content.xml.in b/docs/sdk/content.xml.in index f6e87ca7a..5e144315d 100644 --- a/docs/sdk/content.xml.in +++ b/docs/sdk/content.xml.in @@ -87,6 +87,7 @@
          • Scenario
          • Multiplayer
          • Map Generator
          • +
          • Map Scripts
          • Scripts
        • diff --git a/docs/sdk/definition/actmap.xml b/docs/sdk/definition/actmap.xml index 0abf9fac3..42e2efe79 100644 --- a/docs/sdk/definition/actmap.xml +++ b/docs/sdk/definition/actmap.xml @@ -1,4 +1,4 @@ - + @@ -15,6 +15,11 @@ Data type Description + + Prototype + proplist + Must be Action. See below in the example. + Name String @@ -43,7 +48,7 @@ Directions Integer - Number of animation directions. Animation directions are arranged vertically in Graphics.png. + Number of animation directions. Animation directions are arranged vertically in Graphics.png. Default 1. FlipDir @@ -53,7 +58,7 @@ Length Integer - Number of animation phases for this activity (arranged horizontally in Graphics.png) + Number of animation phases for this activity (arranged horizontally in Graphics.png). Default 1. Reverse @@ -66,14 +71,44 @@ Time difference in frames (ticks) between two animation phases. - Attach + Step Integer - Attachment to surfaces: CNAT Value, e.g. value 8 if the object should attach to the floor like a walking clonk does; or 4 for attachment to the ceiling like a hangling clonk. Only evaluated if the procedure is NONE. + How many animation phases the animation should advance after Delay frames. Default 1. - Facet - 6 integers - Animation graphics: Target rectangle from Graphics.png relative to upper left corner of unrotated object shape. + Attach + Integer + A bitmask for the attachment to surfaces. See CNAT Values for a documentation of possible values. Only evaluated if the procedure is NONE. + + + X + Integer + Animation graphics: X coordinate from Graphics.png. + + + Y + Integer + Animation graphics: Y coordinate from Graphics.png. + + + Wdt + Integer + Width of the animation graphic from Graphics.png. + + + Hgt + Integer + Height of the animation graphic from Graphics.png. + + + OffX + Integer + X-Offset at which to display the animation graphics. + + + OffY + Integer + Y-Offset at which to display the animation graphics. FacetBase @@ -87,13 +122,13 @@ FacetTargetStretch - Boolean + Integer 0 or 1. If 1, the graphics will be stretched down towards the upper border of the ActionTarget. Used e.g. for the elevator line. NextAction String - Next action being set after the current one has reached its end. + Next action being set after the current one has reached its end. If it is not specified, the action will be kept and the animation phase resets to 0 and the animation begins anew. If it is "Hold", the action will also be kept but stops at the last animation frame. If it is "Idle", the object will have no action after this one. NoOtherAction @@ -102,22 +137,22 @@ StartCall - String (max. 30 chars) + String Object script function which is called when the activity is started. EndCall - String (max. 30 chars) + String Called when an activity reaches the end of its animation. PhaseCall - String (max. 30 chars) + String Called whenever the animation phase changes. AbortCall - String (max. 30 chars) + String Called if an activity is being replaced by another before its regular end; i.e. not by a transition through NextAction. Parameters are the previous animation phase, previous ActionTarget and previous ActionTarget2. @@ -127,8 +162,8 @@ Sound - String (max. 30 chars) - Permanent sound being played during this action. + String + Permanent sound being played during this action. The same can be achieved with Sound which is the more flexible solution. ObjectDisabled @@ -143,7 +178,7 @@ Animation String - Specifies the animation to be played in the mesh of the object. Works only if the object uses a mesh for its graphics. If given all of Facet, FacetBase, FacetTopFace and FacetTargetStretch are ignored. The Length times Delay possible animation phases are mapped linearly on the animation length. If Delay equals 0 only Length will be used and the animation does not play automatically. See Animationen for further documentation on animations. + Specifies the animation to be played in the mesh of the object. Works only if the object uses a mesh for its graphics. If given all of Facet, FacetBase, FacetTopFace and FacetTargetStretch are ignored. The Length times Delay possible animation phases are mapped linearly on the animation length. If Delay equals 0 only Length will be used and the animation does not play automatically. See Animations for further documentation on animations. diff --git a/docs/sdk/definition/animations.xml b/docs/sdk/definition/animations.xml index 5af078b42..065d5cf84 100644 --- a/docs/sdk/definition/animations.xml +++ b/docs/sdk/definition/animations.xml @@ -40,6 +40,10 @@ Anim_Y Linear with Y position. When the object moves upwards the animation plays backwards. Can be used if the animation of an object should be synchronized to its vertical movement. + + Anim_R + Linear with rotation. When the object rotates counter-clockwise the animation plays backwards. Can be used if the animation of an object should be synchronized to its rotation. + Anim_AbsX Linear with X position. However, the animation is always played in the same direction, not taking into account whether the object moves left or right. diff --git a/docs/sdk/definition/category.xml b/docs/sdk/definition/category.xml index e4e25d340..56ddd13a7 100644 --- a/docs/sdk/definition/category.xml +++ b/docs/sdk/definition/category.xml @@ -6,82 +6,96 @@ Object Categories Object Categories - An object's category specifies parts of its behavior. For a definition it is set by the Category entry in the DefCore.txt file. Multiple categories can be combined using the binary OR operator. + An object's category specifies parts of its behavior. For a definition it is set by the Category entry in the DefCore.txt file. Multiple categories can be combined using the binary OR operator. + A category also specifies the default plane an object is drawn in if it doesn't specify this property itself. The higher the plane number, the further in the front an object is drawn. See Properties. CategoryDescription + Default plane C4D_StaticBackImmovable object. + 100 C4D_Structure - Unused. + Structures. + 200 C4D_Vehicle - Unused. + Vehicles. + 300 C4D_LivingA living being. + 400 C4D_ObjectAn item that can hit alive objects. + 500 C4D_GoalGame goal. + C4D_EnvironmentEnvironmental control object. + C4D_RuleRule control object. + C4D_Background - Object is behind the landscape. + Object is behind the landscape. Can be combined with any of the first 5 categories. + -600 (combined with C4D_StaticBack) to -100 (C4D_Object) C4D_ParallaxObject moves parallax according to the Parallaxity property. For more information see C4D_Parallax. + C4D_MouseSelectObject can be clicked with the mouse, causing a MouseSelection(int player) callback in the object. + C4D_ForegroundObject is always in the foreground, even before global particles. + +1100 (combined with C4D_StaticBack) to +1500 (C4D_Object) C4D_MouseIgnoreObject cannot be selected with the mouse. + C4D_IgnoreFoWObject is drawn above fog of war. Useful for creating status displays or gui elements using objects. +
          - Example - - - - Category=C4D_StaticBack|C4D_Rule - Category for a rule. - - - + Example + + + Category=C4D_StaticBack|C4D_Rule + Category for a rule. + +
          Sven22006-05 - Newton2005-01 Günther2005, 2011 + 2013-11 diff --git a/docs/sdk/definition/cnat.xml b/docs/sdk/definition/cnat.xml index 4a143820a..ade8b47be 100644 --- a/docs/sdk/definition/cnat.xml +++ b/docs/sdk/definition/cnat.xml @@ -5,61 +5,45 @@ CNAT - Contact Attachment CNAT - Contact Attachment - In multiple places the engine uses ContactAttachment values (a bitmask) to manage the orientation of objects and processes. For example, a vertex of an object can have the CNAT bit left. If that object has ContactCalls activated, the engine calls on every contact of that vertex with the landscape the object script function ContactLeft. CNAT values are composed of the following bits: + In multiple places the engine uses ContactAttachment values (a bitmask) to manage the orientation of objects and processes. For example, a vertex of an object can have the CNAT bit left. If that object has ContactCalls activated, the engine calls on every contact of that vertex with the landscape the object script function ContactLeft. CNAT values are composed of the following bits: - Bit - ValueCNATDescription - 0 - 1CNAT_LeftDirection: Left - 1 - 2CNAT_RightDirection: Right - 2 - 4CNAT_TopDirection: Up - 3 - 8CNAT_BottomDirection: Down - 4 - 16CNAT_CenterDirection: Center (not for attachment) - 5 - 32CNAT_MultiAttachSpecial flag: new attachment behaviour for objects with the same direction value at several vertices. - 6 - 64CNAT_NoCollisionExtra flag: non-colliding vertexCNAT
          - Sven22002-04 - Newton & Günther2005-01 - Matthes2005-08 + A vertex can have multiple CNAT values, they can be combined them with the | operator. Example: + Attach = CNAT_Bottom | CNAT_Left + Newton2013-11
          diff --git a/docs/sdk/definition/defcore.xml b/docs/sdk/definition/defcore.xml index 9815879c3..de714d9d1 100644 --- a/docs/sdk/definition/defcore.xml +++ b/docs/sdk/definition/defcore.xml @@ -25,31 +25,16 @@ 3 Integers Minimal engine version required by the object. Should be always the current engine version at the time of the last change.
          - - Name - String (max. 30 chars) - Name of the object. Will be overwritten by the applicable one in the Names.txt. - + + RequireDef + Definition IDs + List of definition IDs this object depends upon. + Category Integer Category of the object. Also see object categories. - - MaxUserSelect - Integer - Maximal allowed count when placed in the menu system. - - - TimerCall - String (max. 30 chars) - Regularly called timer function in the object script. - - - Timer - Integer - Time interval between TimerCalls in frames. Default is 35. - ContactCalls Integer @@ -88,7 +73,7 @@ SolidMask 6 integers - Solid areas of the object. Target rectangle from the source graphics onto the object. + Solid areas of the object. Target rectangle from the SolidMask.png graphics onto the object. TopFace @@ -140,36 +125,11 @@ Integer Flame distance to the object's bottom line. - - Placement - Integer - Placement: 0 land surface, 1 in liquid, 2 in mid-air, 3 underground, 4 land surface and underground. - Exclusive Integer 0 or 1. Determines whether the object blocks objects behind it. - - ContactIncinerate - Integer - Probability of incineration by contact: 0 none, or 1 (high) to 5 (low). - - - BlastIncinerate - Integer - Incineration by explosion: 0 none, otherwise the damage level of incineration. - - - BurnTo - C4ID - Definition change upon incineration. - - - Base - Integer - 0 or 1. Determines whether the building can be a home base. - Line Integer @@ -180,16 +140,6 @@ Integer 0 or 1. If 1, the object is added to the player's crew upon purchase. Objects created using CreateObject have to be added to a player's crew manually using MakeCrewMember. - - Growth - Integer - Growth of the object. Trees 1-4, living beings 15. - - - Rebuy - Integer - 0 or 1. Determines whether the object can be bought back after selling it. - Construction Integer @@ -200,31 +150,16 @@ C4ID Definition change upon building. - - Grab - Integer - 0 no grabbing, 1 grab and push, 2 grab only. - GrabPutGet Integer Bit mask: bit 0 (value 1) putting possible, bit 1 (value 2) getting possible. - - Collectible - Integer - 0 or 1. Determines whether the object can be collected. - Rotate Integer 0 no rotation, 1 full rotation, 2-360 limited rotation. - - Chop - Integer - 0 or 1. Determines whether the object can be chopped. - Float Integer @@ -240,11 +175,6 @@ Integer 0 or 1. If 1, the specified sections of the object's graphcis are colored by the player color. - - ColorByMaterial - String (max. 15) - The object is colored by the color of the specified material. - HorizontalFix Integer @@ -265,16 +195,6 @@ Integer 0 or 1. If 1, the uncomplete object (see GetCon) is scaled, not sliced from the bottom like a construction site. - - Basement - Integer - 0 no basement, 1 normal basement, other values reserved. - - - NoBurnDecay - Integer - 0 or 1. If 1, the object does not decompose if burning. - IncompleteActivity Integer @@ -330,25 +250,15 @@ Integer 0 or 1. Can be used to prevent failure messages caused by failed commands. - - NoBurnDamage - Integer - 0 or 1. If 1, the object does not take damage when burning. - TemporaryCrew Integer 0 or 1. If 1, the object is not stored in the permanent crew of a player. - - SmokeRate - Integer - 0 to 200: determines the amount of smoke caused by the burning object. 0 for no smoke, 100 is default. If other than 0, the object will always generate maximum smoke when traveling at high velocity (e.g. a fire arrow). - BlitMode Integer - 0 or 1. Value 1 for addtive drawing. + 0 or 1. Value 1 for addtive drawing. Use SetObjectBlitMode for more flexibility. NoBreath @@ -360,11 +270,6 @@ Integer Values grater than 0 are deducted from the top of necessary construction space. - - NoSell - Integer - 0 or 1. If 1 the object can not be sold. - NoGet Integer @@ -390,115 +295,8 @@ Integer 0 or 1. If 1 the object's pathfinding will ignore any transfer zones. - - AutoContextMenu - Integer - 0 or 1. If 1, the building's context menu will open automatically upon entry. - - - - - - Value - Data type - Description - - - Energy - Integer - 0-100000. Maximum life energy. - - - Breath - Integer - 0-100000. Maximum breath. - - - Walk - Integer - 0-100000. Walking speed. - - - Jump - Integer - 0-100000. Jump force. - - - Scale - Integer - 0-100000. Scaling speed. - - - Hangle - Integer - 0-100000. Hangling speed. - - - Dig - Integer - 0-100000. Digging speed. - - - Swim - Integer - 0-100000. Swimming speed. - - - Throw - Integer - 0-100000. Throwing force. - - - Push - Integer - 0-100000. Push power. - - - Magic - Integer - 0-100000. Maximal magic energy. - - - Float - Integer - 0-100. Flight speed. - - - CanScale - Integer - 0 or 1. Scale. - - - CanHangle - Integer - 0 or 1. Brachiation. - - - CanDig - Integer - 0 or 1. Dig. - - - CanConstruct - Integer - 0 or 1. Construct. If greater than 1, percentage construction speed. (100 normal, 50 half, etc.) - - - CorrosionResist - Integer - 0 or 1. Determines wether the object resists acid. - - - BreatheWater - Integer - 0 object breathes air, 1 object breathes water. - -
          Section [Physical]
          -
          - Note: - When a crew member is created, it gets an own physical section in it's Objectinfo (oci). In there, the individual changes to the physicals (for example because of training) are saved and restored when an object enters a player's crew. The physical section of the defcore is only used for new crew members and normal objects. - Sven22002-04 + Newton2013-11 diff --git a/docs/sdk/definition/index.xml b/docs/sdk/definition/index.xml index 0c13f018c..a1e589f81 100644 --- a/docs/sdk/definition/index.xml +++ b/docs/sdk/definition/index.xml @@ -38,6 +38,10 @@
          Graphics*.png/Overlay*.png
          Objects can also contain alternative sets of graphics which can be selected ingame using the script command SetGraphics(). The name corresponds to the file name portion following "Graphics". The matching overlay is automatically selected. For more information see SetGraphics(). +
          +
          SolidMask.png
          +
          + Image describing areas in this object that are solid, so vertices of other objects will collide with it. Pixels are made solid if they are 50% or less transparent in this image. Source rectangle within this graphic and target position on the object must be set in DefCore.txt property "SolidMask" or using the script function SetSolidMask.
          3D Graphics diff --git a/docs/sdk/definition/meshes.xml b/docs/sdk/definition/meshes.xml index 3e1fee505..9f955de8a 100644 --- a/docs/sdk/definition/meshes.xml +++ b/docs/sdk/definition/meshes.xml @@ -6,7 +6,7 @@ Meshes Meshes - It is possible to directly use 3D models (meshes) as object graphics. To do so they need to be in OGRE format. For most modeling tools there exist exporter tools, a list can be found on the OGRE Wiki. Both the OGRE binary format (*.mesh) and the OGRE XML format(*.mesh.xml) are supported, however it is recommended to always use the binary format whenever possible since it is smaller in size and can be loaded more quickly by the engine. The tool OgreXMLConverter can convert between the two formats. + It is possible to directly use 3D models (meshes) as object graphics. To do so they need to be in OGRE format. For most modeling tools there exist exporter tools, a list can be found on the OGRE Wiki. Both the OGRE binary format (*.mesh) and the OGRE XML format(*.mesh.xml) are supported, however it is recommended to always use the binary format whenever possible since it is smaller in size and can be loaded more quickly by the engine. The tool OgreXMLConverter can convert between the two formats. The exporter normally creates a mesh file (*.mesh or *.mesh.xml), a skeleton file (*.skeleton or *.skeleton.xml) if the mesh contains bones, a material script (*.material) and potentially used textures. To use the mesh as a Clonk object all generated files need to be copied into the object definition and the mesh file needs to be renamed to Graphics.mesh or Graphics.mesh.xml, respectively. Textures are supported in PNG, JPG and BMP format. The mesh is not automatically scaled to the shape (i.e. the width and height values specified in DefCore.txt) of the object. Instead one unit in the modeling tool corresponds to one pixel in Clonk. This simplifies using the same magnitude of object sizes for all objects which is especially helpful for attaching meshes (see below). Also pay attention to the coordinate frame: The X axis in the mesh coordinate frame points out of the screen in Clonk, the Y axis points to the right and the Z axis points upwards. Material scripts diff --git a/docs/sdk/definition/procedures.xml b/docs/sdk/definition/procedures.xml index 590e178e6..a9857634a 100644 --- a/docs/sdk/definition/procedures.xml +++ b/docs/sdk/definition/procedures.xml @@ -21,91 +21,91 @@ Action.Attach
          - WALK + DFA_WALK Walking According to current ComDir. CNAT_Bottom - FLIGHT + DFA_FLIGHT Free fall Only gravitational effects CNAT_None - KNEEL + DFA_KNEEL Getting up Behaviour according to activity. CNAT_Bottom - - SCALE + + DFA_SCALE Scaling a wall According to current ComDir. CNAT_Left/Right - HANGLE + DFA_HANGLE Climbing on the ceiling According to current ComDir. CNAT_Top - DIG + DFA_DIG Dig According to current ComDir. With Data=1 material chunks are dug free. CNAT_None - SWIM + DFA_SWIM Swimming According to current ComDir. CNAT_None - THROW + DFA_THROW Throw Behaviour according to activity. CNAT_Bottom - BRIDGE + DFA_BRIDGE Bridge building According to ComDir. Bridge material is a material number in Data. CNAT_Bottom - PUSH + DFA_PUSH Pushing Pushes the target object according to ComDir. CNAT_Bottom - LIFT + DFA_LIFT Lifting Lifts the target object according to ComDir. CNAT_None - FLOAT + DFA_FLOAT Floating in mid-air According to current ComDir. CNAT_None - ATTACH + DFA_ATTACH Attachment to another object Adjusts object position at vertex a to the position of vertex b of the target object. a and b are the two low bytes of ActionData (see SetActionData for an example). CNAT_None - CONNECT + DFA_CONNECT Line connections - Only line objects. Connects target object 1 and target object 2. + Only line objects. Connects target object 1 and target object 2. If property LineMaxDistance is a nonzero integer, the line breaks when the target objects are further apart than the given distance. CNAT_None - PULL + DFA_PULL Pulling Pulls the target object according to ComDir. CNAT_Bottom diff --git a/docs/sdk/definition/properties.xml b/docs/sdk/definition/properties.xml index 7822ffccb..0d8b5ca8d 100644 --- a/docs/sdk/definition/properties.xml +++ b/docs/sdk/definition/properties.xml @@ -33,22 +33,22 @@ Stand = { Name string - + Name of the object. This string should be internationalized. Collectible - - + bool + Whether the object can be picked up. Touchable - - + int + 1 the object can be grabbed, 2 the object can be grabbed and pushed ActMap proplist - + See the detailed description of the ActMap Visibility @@ -57,68 +57,73 @@ Stand = { LineColors - - + array + An array of two integers. The first denotes the color of the line and the second the color of the endpoints if the object is drawn as a line. LineAttach - - - + array + An array of two integers. Denotes the position of where the endpoint of the line is located relative to the object center. + PictureTransformation - - + array + If the object is a mesh, the picture graphic of the object can be transformed with this property. See Trans_Mul for an example. MeshTransformation - - - - - MouseDragImage - - + array + If the object is a mesh, the ingame graphic of the object can be transformed with this property. See Trans_Mul for an example. MouseDrag - - + bool + Whether the object can be dragged with the mouse. What exactly happens when an object is dragged onto another is defined in script. - Animation - - + MouseDragImage + id / object + The object or object id of which the picture should be displayed below the cursor while dragging. + + + Tooltip + string + A tooltip that is displayed for objects of the category C4D_MouseSelect. This string should be internationalized. Action proplist - + The current action of the object as a proplist. BreatheWater - - + bool + Whether the object breathes in water rather than air. CorrosionResist - - + bool + Whether the alive object does not loose energy when in corrosive material. MaxEnergy int - + Maximum life energy in a precision of 100. MaxBreath int - + Maximum breath. ThrowSpeed int - + Throwing speed in a precision of 100. + + + JumpSpeed + int + Jump speed in a precision of 100. Parallaxity @@ -129,6 +134,31 @@ Stand = { Plane int The Object's minor Z-Position. Negative values are behind the landscape, positive values before it. Use 1-399 for stuff behind Clonks, 401-999 for stuff before Clonks, and 1000+ for GUI objects. + + + Placement + Integer + Placement: 0 land surface, 1 in liquid, 2 in mid-air, 3 underground, 4 land surface and underground. + + + BlastIncinerate + Integer + Incineration by explosion: 0 none, otherwise the damage level that has to be reached until the object is incinerated. + + + BurnTo + C4ID + Definition change upon incineration. + + + NoBurnDecay + Integer + 0 or 1. If 1, the object does not decompose if burning. + + + ContactIncinerate + Integer + Probability of incineration by contact: 0 none, or 1 (high) to 5 (low). diff --git a/docs/sdk/definition/script.xml b/docs/sdk/definition/script.xml index e92637e32..2ee6f6901 100644 --- a/docs/sdk/definition/script.xml +++ b/docs/sdk/definition/script.xml @@ -15,8 +15,6 @@ }
          An object with this script will be given a rock right after it has been created. The Initialize function is called only when the object has reached full size (a building only when its construction has been completed and a living being only when it is fully grown). - TimerCall - Each object definition can define a timer call in its DefCore. The TimerCall is a function which will be called at regular intervals. The DefCore entry Timer determines the rate of calls. If no rate is specifed, the default value is 35 frames (roughly once per second). ActMap An active object can also define activity script calls in its ActMap. The defined StartCall is made whenever an action begins (or repeats), an EndCall is made at the end of each activity. PhaseCall is called at each animation phase step and should only be used for very short animations. The call frequency of PhaseCalls is determined by the speed of the animation. #include @@ -87,8 +85,8 @@ Damage - int change, int by_player - When the object is damage. + int change, int cause, int by_player + When the object is damaged. See Fx*Damagefor cause values. DeepBreath @@ -145,8 +143,8 @@ object obj, int x, int y When an object (obj) using the internal pathfinding algorithm is trying to pass the transfer zone of this object on its way to point x/y. The transfer function can then help the object along by giving special script commands and returning true. Also see SetTransferZone(). - - UpdateTransferZone + + OnSynchronized When an object is loaded from a savegame or network synchronization is performed. Objects with a transfer zone should reset the zone in this call. Also see SetTransferZone(). @@ -325,12 +323,211 @@ int player, int new_team, int old_team Callback in game goal, rule, and environment objects and in the scenario script. Called when a player has successfully switch from old_team to new_team (see SetPlayerTeam). + + EditCursorSelection + + When object is selected in editor. Use this callback to display extra information for scenario designers. + + + EditCursorDeselection + + When object is deselected in editor. Use this callback to hide any information previously shown in EditCursorSelection. + + + SaveScenarioObject + proplist props + Called when scenario is saved from the editor. Object should write creation of itself and properties to the buffer props. Return true if the object should be saved and false if saving of this object should be omitted. See Scenario saving. + + Scenario saving + When the user chooses the "Save Scenario" option from the editor menu, the engine calls a global function SaveScenarioObjects defined in System.ocg/SaveScenario.c. This function writes all objects to the Objects.c file in their current state. The function stores all objects except the crew of currently joined human players and objects of a type that starts with GUI_. By default, objects are recreated using a call to CreateObject followed by setting a number of default properties like position, rotation, speed, action, if they are not in their default state. + For most object, the default saving method should be fine. However, it is possible to override the SaveScenarioObject callback to control how objects are created and which properties are set. + For example if a switch wants to save its target which is stored in a local variable called "target", the switch definition can override the callback: + +local target; + +func SetTarget(object new_target) { target = new_target; return true; } + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (target) props->AddCall("Target", this, "SetTarget", target); + return true; +} + As a result, the generated Objects.c file will include the call to SetTarget if the switch is saved. Dependent objects should always either be passed to the AddCall function or stored as a string from the MakeScenarioSaveName function. If this is done, that object is marked as a dependency. The saving mechanism will ensure that any object this object depends on will be created before. In case of circular dependencies, the object property setting script is detached from object creation script. + If an object should not be saved in scenarios - for example, because it is just the helper of another object - the SaveScenarioObject callback should be overloaded to return false. + The object creation procedure can also be adjusted. For example, the waterfall object (defined in Objects.ocd/Environment.ocd/Waterfall.ocd) is created using the global functions CreateWaterfall and CreateLiquidDrain, which create a Waterfall object and attach an effect to it. To generate the creation functions from the effects, the waterfall overrides SaveScenarioObject: +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + var fx_waterfall = GetEffect("IntWaterfall", this); + if (fx_waterfall) + { + props->RemoveCreation(); + props->Add(SAVEOBJ_Creation, "CreateWaterfall(%d,%d,%d,%v)",fx_waterfall.X, fx_waterfall.Y, fx_waterfall.Strength, fx_waterfall.Material); + } + return true; +} + The call to RemoveCreation removes the existing object creation using CreateObject. + If you need access to one of the objects created in the editor, you can set its "StaticSaveVar" property to the name of a static variable. The InitializeObjects() function will then save the object in that variable. + The following table lists standard properties that are saved if their value is different from the default and if it is not removed using a props->Remove call. + + + Property name + Default value + Description + + + Alive + true + Category C4D_Living only: If object is not alive, a call to SetKill is stored. See GetAlive and Kill. + + + Action + this.DefaultAction + Action as retrieved using GetAction and set using SetAction. Includes ActionTargets. Not stored by default but only if SaveScenarioObjectAction is called. + + + Phase + 0 + Action phase (see GetPhase and SetPhase). Not stored by default but only if SaveScenarioObjectAction is called. + + + Dir + DIR_Left + Animation direction (see GetDir and SetDir) + + + ComDir + COMD_Stop + Commanded movement direction (see GetComDir and SetComDir) + + + Con + 100 + Construction percentage, i.e. object size (see GetCon and SetCon) + + + Category + GetID()->GetCategory() + Object category (see GetCategory and SetCategory) + + + R + 0 + Rotation (see GetR and SetR) + + + XDir + 0 + Horizontal speed (see GetXDir and SetXDir) + + + YDir + 0 + Vertical speed (see GetYDir and SetYDir). Vertical speed is not saved it is very small and the object touches the ground to avoid saving of speed on idle objects. + + + RDir + 0 + Rotation speed (see GetRDir and SetRDir) + + + Color + 0, 0xffffffff + Object color of ColorByOwner-surfaces (see GetColo and SetColor) + + + ClrModulation + 0, 0xffffffff + Object color modulation of all surfaces (see GetClrModulation and SetClrModulation) + + + BlitMode + 0 + Object drawing mode (see GetObjectBlitMode and SetObjectBlitMode) + + + Name + GetID()->GetName() + Object name (see GetName and SetName) + + + MaxEnergy + GetID().MaxEnergy + Maximum energy (see Properties) + + + Energy + GetID().MaxEnergy/1000 + Current energy level (see GetEnergy and DoEnergy) + + + Visibility + VIS_All + Object visibility (see Properties) + + + Plane + GetID().Plane + Object plane, i.e. z-order (see Properties) + + + Position + + Object position. This is only set if the object has a rotation and could not be created directly at the correct offset (see SetPosition) + + + Command + None + Stores only the topmost command of the chain (see GetCommand and SetCommand) + + + Fire + + Fire effect. + +
          +
          + By default, effects are not saved in scenarios. To force saving of an effect, define the Fx*SaveScen callback. For example, the fire effect saves itself like this: +global func FxFireSaveScen(object obj, proplist fx, proplist props) +{ + // this is burning. Save incineration to scenario. + props->AddCall("Fire", obj, "Incinerate", fx.strength, fx.caused_by, fx.blasted, fx.incinerating_object); + return true; +} + obj and fx refer to the object and effect proplist as for any effect call. save_name is the variable name of the effected object and is unset for global effects. + + Scenario saving reference + The following functions are available to call on the "props" parameter passed to SaveScenarioObject callbacks: + + AddCall + bool AddCall(string id, object target, string function, any par1, any par2, ...); + Adds a new call of format target->Function(par1, par2, ...) to the stored object script. Object parameters may be passed as is; strings must be quoted explicitely. + The id parameter is an identifier which can be used by derived objects to remove the property again. + + Add + bool AddCall(string id, string script, any par1, any par2, ...); + Adds a custom script snippet of any format. script may contain format characters and parameters are formatted into the string using Format(). + + Remove + int Remove(string id); + Remove all strings added previously using AddCall or Add with the given ID. Can also be used to remove default properties. Returns number of script lines removed. + + RemoveCreation + bool RemoveCreation(); + Remove all strings added previously using with IDs SAVEOBJ_Creation or SAVEOBJ_ContentsCreation. + + Clear + bool Clear(); + Remove all creation and property setting strings. + +
          sulai2003-11 - Sven22004-02 matthes2004-07 Clonkonaut2008-04 + Sven22013-12 diff --git a/docs/sdk/folder/foldermap.xml b/docs/sdk/folder/foldermap.xml index 217892b3e..19811c231 100644 --- a/docs/sdk/folder/foldermap.xml +++ b/docs/sdk/folder/foldermap.xml @@ -158,7 +158,7 @@ The image is always stretched to the full available screen area. All coordinates given for section elements are relative to the unstretched background image. Useful Hints - For testing purposes a folder map can be loaded from an unpacked scenario folder and reloaded an runtime using F5. If the classic scenario selection appears instead of the folder map, an error has occured in the folder map declaration, such as missing image files. With debug mode activated, there will also be an error message in Clonk.log. + For testing purposes a folder map can be loaded from an unpacked scenario folder and reloaded an runtime using F5. If the classic scenario selection appears instead of the folder map, an error has occured in the folder map declaration, such as missing image files. With debug mode activated, there will also be an error message in OpenClonk.log. Sven22006-09 diff --git a/docs/sdk/material/ocm.xml b/docs/sdk/material/ocm.xml index 43936ba6e..3ede32e05 100644 --- a/docs/sdk/material/ocm.xml +++ b/docs/sdk/material/ocm.xml @@ -23,7 +23,7 @@ ColorAnimation Integer - 0 oder 1. Color animation. + 0 or 1. Color animation. Shape @@ -33,7 +33,7 @@ Density Integer - Density: 50 solid, 25 liquid (other values not allowed). + A density of 25 and above is liquid. 50 and above is solid. BlastFree offers a parameter to only blast solid materials of a given density or lower. Friction @@ -43,12 +43,12 @@ DigFree Integer - 0 oder 1. Determines wether the material can be dug into. + 0 or 1. Determines wether the material can be dug into. BlastFree Integer - 0 oder 1. Determines whether the material can be blasted away. + 0 or 1. Determines whether the material can be blasted away. Blast2Object @@ -83,7 +83,7 @@ Instable Integer - 0 oder 1. Stability. + 0 or 1. Stability. MaxAirSpeed diff --git a/docs/sdk/particle/index.xml b/docs/sdk/particle/index.xml index 7e2161d0a..9a772599f 100644 --- a/docs/sdk/particle/index.xml +++ b/docs/sdk/particle/index.xml @@ -7,7 +7,7 @@ Particle Particles are lightweight objects which are not synchronized in a network game. This means that on the one hand you can create huge amounts of particles without slowing down the game too much but on the other hand there are only limited options for control of particle behaviour. If the particles are not sufficient for a given effect you have in mind, you can always use true objects instead. - If a particle is defined in a ocd group, any object definition located in the same group is ignored. This used to be a way to allow loading of placeholder options in the old graphics system which didn't support particles. + If a particle is defined in a ocd group, any object definition located in the same group is ignored. Particles are not stored in savegames and are designed for temporary visual effects only. Particle Components (ocd)
          @@ -34,190 +34,120 @@ Name String (max. 30 chars) - Name of the particle definition. This name is also used to refer to this particle type in scripts. For multi-language display in the menu system you should use the Names.txt component. - - - MaxCount - Integer - Maximum number of instances of this particle type. See instance control. - - - MinLifetime - Integer - Only for smoke particles: lower limit for the lifetime, which ranges from MinLifetime to MaxLifetime. - - - MaxLifetime - Integer - Only for smoke particles: upper limit for the lifetime, which ranges from MinLifetime to MaxLifetime. - - - InitFn - String (max. 30 chars) - Identifier for the function used to initialize the particle. For valid functions see section particle functions. - - - ExecFn - String (max. 30 chars) - Identifier for the function used to execute the particle each frame. For valid functions see section particle functions. - - - DrawFn - String (max. 30 chars) - Identifier for the function used to draw the particle. For valid functions see section drawing functions. - - - CollisionFn - String (max. 30 chars) - Identifier for the function called upon collision with the landscape. Also see collision checking. + Name of the particle definition. This name is also used to refer to this particle type in scripts. Face - 6 integers + 4 integers Target rectangle for the graphics within Graphics.png. See particle graphics. - - YOff - Integer - Upper spatial limit for the particle. At this limit the particles will be deleted as if the landscape would end here. Only StdExec. - - - Delay - Integer - Delay between two animation phases. If Delay = 0 one randomly chosen phase is permanently displayed. - - - Repeats - Integer - Number of animation runs until the particle is destroyed. - - - Reverse - Integer - 0 or 1. If 1 every seconds animation is played backwards. - - - FadeOutLen - Integer - If specified, this number of animation phases is truncated from the end and reserved for a death animation which is displayed after all repetitions of the standard animation. - - - FadeOutDelay - Integer - Delay between two animation phases of the death animation. - - - RByV - Integer - 0 to 3. 0 for no particle rotation. If 1 the particle will be aligned to its direction of travel; the particle's up-side will be in front. If 2 the speed parameters only determine rotation; the particle will not move. If 3 a random rotation is applied. - - - GravityAcc - Integer - Effects of gravity. At 0 the particle is not affected by gravity, at 100 it is fully affected. Negative values are also possible. - - - WindDrift - Integer - Horizontal drift by wind. Same as the material property of the same name. - - - VertexCount - Integer - 0 or 1. If 1, collision detection is done. - - - VertexY - Integer - Y offset of the collision checking point in percent. Also see collision detection. - - - Additive - Integer - 0 or 1. If 1, the particle is drawn additively. - - - AlphaFade - Integer - 0 to 40. Rate of fade out per FadeDelay. A fully faded particle is removed. - - - FadeDelay - Integer - The default is 1. - - - Parallaxity - 2 Integer - Parallaxity in x and y directions. 0 is locked with the viewport; 100 is default (locked with the landscape). - - - Attach - Integer - 0 or 1. If 1 the particle is moving relative to its target object's position. - - Properties - Each particle has a position (x, y), horizontal and vertical impulse (xdir and ydir), life time (life), and two extra parameters (a and b). These are initialized by script and then processed by the particle functions. For more information see particle functions and drawing functions. - Graphics - The coordinates for the source rectangle within Graphics.png of a particle are comparable to the Face entry in an object's ActMap. The coordinates only specify the first animation phase. All following animation phases should be located on the right (with smoke also below) of the initial phase. The animation length is then automatically determined from the image size. For the drawing offset you should usually specify half the particle size. An offset 0/0 would cause the particle graphics to be drawn below actual particle position. - If Delay = 0, a random animation phase is chosen on startup and maintained. The particle will exist until is falls out of the landscape. - Particle Amounts - For each particle type a maximum count is defined which is then also adjusted by the configuration setting for effect levels in the graphics options. As soon as half of the maximum amount of particles is created, new particles are only created based on random selected and the closer you get to the maximum value, the smaller the chance of new particle generation. This ensures a smooth approach to the actual limit. - Collision Detection - Particles can collide with the landscape. This is not very exact, however. Fast moving particles might pass through very thin layers of solid materials. If you need more precision, you should use objects instead. - Collision detection is only done in StdExec (i.e. not with smoke particles). For valid functions see particle functions. Collision detection is done at the particle center and only if VertexCount is specified. The point of detection can be shifted using VertexY. The specified values are in percent of the particle size, meaning VertexY=100 would check at the bottom of the particle. The visual size specified in Face doesn't affect this. - Particle Functions - The behaviour of particles can be controlled by predefined particle functions. These are executed for initialization, then at each fram, and in case of collision with the landscape. -
          -
          StdExec
          -
          - Standard function ExecFn for almost all particle types. The particle runs through an animation defined by Face, Delay, Repeats, Reverse, FadeOutLen, and FadeOutDelay and is then destroyed. The extra parameter defines the size of the particle in 1/10 pixels. b defines color modulation; if b = 0 no modulation is applied. aa as well as b are not modified by this function and will preserve the initial values. Also, the particle moves according to xdir and ydir while ydir is affected by gravity if GravityAcc is enabled. -
          -
          StdInit
          -
          - Standard function for InitFn to be used with StdExec. -
          -
          Bounce
          -
          - Collision function: the particle will bounce back into the exact opposite direction. -
          -
          BounceY
          -
          - Collision function: the particle will bounce back vertically. -
          -
          Stop
          -
          - Collision function: the particle will stop. -
          -
          Die
          -
          - Collision function: the particle will be destroyed. -
          -
          SmokeExec
          -
          - Hard coded processing function for smoke particles. a is puff size; b is color modulation. Smoke graphics must be defined in 4 x 4 animation phases in Graphics.png of which the one on the lower right is used only rarely. The other animation phases are used evenly. Smoke always rises continuously until it collides with the landscape. If the life time has passed, the smoke particle fades out until it is deleted. -
          -
          SmokeInit
          -
          - Hard coded initialization function for smoke to be used in conjunction with SmokeExec. -
          -
          - Drawing Functions - Functions that can be assigned to DrawFn. -
          -
          Std
          -
          - Standard function for most particles except smoke. The particle is drawn at position x/y with size a/5 x a/5 and color modulated with b. -
          -
          Smoke
          -
          - Drawing function for smoke. -
          -
          - Control - External control of particles is very limited and only allows creation, global offset, and global removal. This is necessary as particles are not synchronized on computers throughout a network game and any deviation in particle handling would cause sync loss. Particles are created using CreateParticle. + Graphics + The coordinates for the source rectangle within Graphics.png of a particle specify the first phase of the particle graphics the other phases should follow to the right and can be continued in the next row. The animation length is then automatically determined from the image size. + Properties + Each particle has different attributes like position, lifetime, size and more. These are set by script when creating the particle. + The following properties can be contained in a proplist passed to CreateParticle. For an example, see CreateParticle + You can assign either constants to the properties (f.e. R = 200) or use certain value provider functions (f.e. R = PV_Linear(200, 0)). Available value provider functions are: + PV_Linear + PV_Direction + PV_Random + PV_Step + PV_Speed + PV_KeyFrames + PV_Wind + PV_Gravity + + + + + + Name + Values + Description + + + R + 0 to 255 + Red part of the color modulation. + + + G + 0 to 255 + Green part of the color modulation. + + + B + 0 to 255 + Blue part of the color modulation. + + + Alpha + 0 to 255 + Alpha part of the color modulation. + + + Size + pixels + Size of the particle in pixels. + + + Stretch + factor + The vertical stretch of the particle. 1000 equals no stretch. + + + Phase + Index of phase + The displayed phase of the particle from the Graphics.png. The index starts at 0 and will be wrapped. + + + Rotation + 0 to 360 + Rotation of the particle. + + + ForceX + Integer + Force in x-direction that is constantly applied to the particle's speed. Can f.e. simulate wind. + + + ForceY + Integer + Force in y-direction that is constantly applied to the particle's speed. Ca f.e. simulate gravity. + + + DampingX + 0 to 1000 + Damping of the particle's speed in x-direction. 1000 means no damping, 0 means instant stop. + + + DampingY + 0 to 1000 + Damping of the particle's speed in y-direction. 1000 means no damping, 0 means instant stop. + + + BlitMode + 0 or GFX_BLIT_Additive + The particle's blit mode. Currently only additive blitting is supported. + + + CollisionVertex + 0 to 1000 + The offset of the particle's hit point relative to its width. When set, the particle will collide with the landscape. 0 means the particle will collide with its center. + + + OnCollision + PC_Die, PC_Bounce, PC_Stop + Defines what happens when the particle collides with the landscape. + + + Attach + bit mask + Defines the attachment of the particles to the calling object. Can be a combination of ATTACH_Front, ATTACH_Back, and ATTACH_MoveRelative. For example ATTACH_Front | ATTACH_MoveRelative + +
          Particle definition proplist
          +
          - Sven22002-04 + Zapper2013-10 diff --git a/docs/sdk/playercontrols.xml b/docs/sdk/playercontrols.xml index 3da1f10de..1ea97470d 100644 --- a/docs/sdk/playercontrols.xml +++ b/docs/sdk/playercontrols.xml @@ -8,204 +8,256 @@ The engine allows to define control commands completely arbitrarily. Own keyboard commands can be added and modified. All supported input devices such as mouse, keyboard and gamepads can be mapped freely and commands can consist of any key combinations or sequences. PlayerControls.txt - All control commands which a player can send to the game are defined in the file PlayerControls.txt. The standard keys as well as their standard mapping for various input devices are contained in the global definition file in the Systems.ocg folder. Object definitions and scenarios can add more keys or overload the parameters of existing commands in their local Systems.ocg folder**. - Additional PlayerControls.txt files can be put in language packages to adapt the standard key mappings of different loaded languages to the keyboard of their respective country**. + All control commands which a player can send to the game are defined in the file PlayerControls.txt. The standard keys as well as their standard mapping for various input devices are contained in the global definition file in the Systems.ocg folder. Object definitions and scenarios can add more keys or overload the parameters of existing commands in their local Systems.ocg folder. Section [ControlDefs] - Definition of possible player commands. Not valid in language packages. Subordinated to this section: - - - - - Value - Data type - Description - - - Identifier - String (max. 96 chars) - Internally used name for identification of the command. The command is referenced by that name in standard mappings and it is predefined in script as CON_Name. The name should therefore be a valid identifier in script, i.e. only consist of letters, numbers and _. Especially there should be no space characters or German umlauts. To avoid conflicts the same rules as for object IDs apply for definitions local to a certain scenario or object. - - - GUIName - String - Name which is shown to the player in the control configuration dialog and in control tooltips. Localized strings from the corresponding string table can be used ($Name$). - - - GUIDesc - String - Informative description which is displayed to the player in the control configuration dialog. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$). - - - Global - Boolean - If true this is a global definition, i.e. not assigned to a particular player. See Global definitions. - - - Hold - Boolean - If true this command is interpreted as a held command. Such a command remembers whether the control key is pressed and generates another scripting event when it is released. See Held keys. - - - RepeatDelay - Integer - Only valid if Hold is true. If greater than 0 then this key generates additional scripting events while pressed every that many number of frames. See Key repeats. - - - InitialRepeatDelay - Integer - If specified then the delay of the first key repeat event can be changed. See Key repeats. - - - DefaultDisabled - Boolean - If true then the command is deactivated in the normal case and needs to be activated by script first. This is useful for commands that are only required in special situations. See Deactivated commands. - - - ExtraData - C4ID - Optional ID that is passed to the script function. See ExtraData. - - - SendCursorPos - Boolean - If true then the GUI mouse position at the time of triggering the command will be sent as a separate CON_CursorPos command. If the mouse is not activated then the cursor position in GUI coordinates is transmitted. - - - Action - String - - Action to be executed for this command. Possible values: - -
          Any number of sections [ControlDef]
          - - Value - Description - - - None - No action. - - - Script - Execution of the script function PlayerControl. See Script callbacks. (Default value) - - - Menu - Open the player menu (asynchronous command). - - - MenuOK - Confirmation of the selected item in the player menu (asynchronous command). - - - MenuCancel - Close the player menu (asynchronous command). - - - MenuLeft / MenuUp / MenuRight / MenuDown - Navigation in the player menu (asynchronous command). - -
          -
          - - - - -
          - + Definition of possible player commands. Subordinated to this section: - Section [ControlSets] - - Definition of standard control mappings. - - - - - Value - Data type - Description - - - Name - String - Internal name for identification of otherwise equal control mappings. The names of the standard mappings are Keyboard1, Keyboard1Classic, Keyboard2, Keyboard2Classic, Gamepad. By using placeholders (*) keys can directly be defined in multiple mappings**. - -
          Any number of sections [ControlSet]
          - + + + + Value + Data type + Description + + + Identifier + String (max. 96 chars) + Internally used name for identification of the command. The command is referenced by that name in standard mappings and it is predefined in script as CON_Name. The name should therefore be a valid identifier in script, i.e. only consist of letters, numbers and _. Especially there should be no space characters or German umlauts. To avoid conflicts the same rules as for object IDs apply for definitions local to a certain scenario or object. + + + GUIName + String + Name which is shown to the player in the control configuration dialog and in control tooltips. Localized strings from the corresponding string table can be used ($Name$). + + + GUIDesc + String + Informative description which is displayed to the player in the control configuration dialog. Localized strings from the corresponding string table can be used ($Desc$). + + + Global + Boolean + If true this is a global definition, i.e. not assigned to a particular player. See Global definitions. + + + Hold + Boolean + If true this command is interpreted as a held command. Such a command remembers whether the control key is pressed and generates another scripting event when it is released. See Held keys. + + + RepeatDelay + Integer + Only valid if Hold is true. If greater than 0 then this key generates additional scripting events while pressed every that many number of frames. See Key repeats. + + + InitialRepeatDelay + Integer + If specified then the delay of the first key repeat event can be changed. See Key repeats. + + + DefaultDisabled + Boolean + If true then the command is deactivated in the normal case and needs to be activated by script first. This is useful for commands that are only required in special situations. See Deactivated commands. + + + ExtraData + C4ID + Optional ID that is passed to the script function. See ExtraData. + + + SendCursorPos + Boolean + If true then the GUI mouse position at the time of triggering the command will be sent as a separate CON_CursorPos command. If the mouse is not activated then the cursor position in GUI coordinates is transmitted. + + + Action + String + + + Action to be executed for this command. Possible values: +
          Any number of sections [ControlDef]
          - Value - Data typeDescription - Key - String - Specifies the key(s) of this mapping or a reference to another mapping. See Key mappings. + None + No action. - ComboIsSequence - Boolean - If true then multiple keys are taken as a sequence, i.e. they need to be pressed one after the other instead of all at the same time. See Key mappings. + Script + Execution of the script function PlayerControl. See Script callbacks. (Default value) - Control - String - Command that is combined with this mapping. The name should be equivalent to the Identifier of a command defined in a [ControlDef]. + ZoomIn + Zoom in one unit - Priority - Integer - Priority of the mapping. If more than once mapping is using the same keys then the key with the highest priority is executed first until a command is treated as handled. + ZoomOut + Zoom out one unit - TriggerMode - bitmask - - Trigger mode of this mapping. Bitmask based on the following values: - -
          Any number of sections [Assignment]
          - - Value - Description - - - Default value - No particular action. - - - Hold - The key changes the state of the command linked to to be held even if the key itself is pressed only shortly. Only valid if the Hold attribute is set for the command. This state remains until a corresponding mapping with trigger mode Release is being pressed. See Held keys. - - - Release - The key removes the held state. A key can have both Hold and Release set to toggle between the two states. See Held keys. - - - AlwaysUnhandled - The key press is always passed to the mapping with the next lowest priority, independent of whether the previous command was executed successfully or not. - - - ToggleUnhandled - The keypress is passed to the mapping with the next lower priority only if the previous command was executed successfully. This can be used to define macros. ** - - - OverrideAssignments - The assignment overwrites all other assignments for the same control with the same press/release trigger mode. - -
          -
          - - + Menu + Open the player menu (asynchronous command). + + + MenuOK + Confirmation of the selected item in the player menu (asynchronous command). + + + MenuCancel + Close the player menu (asynchronous command). + + + MenuLeft / MenuUp / MenuRight / MenuDown + Navigation in the player menu (asynchronous command). + + + ObjectMenuOK / ObjectMenuSelect / ObjectMenuOKAll + Confirmation of the selected item in a menu (synchronous command). + + + ObjectMenuCancel + Close a menu (synchronous command). + + + ObjectMenuLeft / ObjectMenuUp / ObjectMenuRight / ObjectMenuDown + Navigation in a menu (synchronous command). -
          -
          + + + + Section [ControlSets] + + Definition of standard control mappings. + + + + Value + Data type + Description + + + Name + String + Internal name for identification of otherwise equal control mappings. By using placeholders (*) keys can directly be defined in multiple mappings. + + + GUIName + String + Name for the control assignment set which is shown to the player in the control configuration dialog. + + + Keyboard + Boolean + Whether this control assignment set uses the keyboard. Default 1. + + + Mouse + Boolean + Whether this control assignment set uses the mouse. Default 1. + + + Gamepad + Boolean + Whether this control assignment set uses the gamepad. Default 0. + +
          Any number of sections [ControlSet]
          + + + + Value + Data type + Description + + + Key + String + Specifies the key(s) of this mapping or a reference to another mapping. See Key mappings. + + + ComboIsSequence + Boolean + If true then multiple keys are taken as a sequence, i.e. they need to be pressed one after the other instead of all at the same time. See Key mappings. + + + Control + String + Command that is combined with this mapping. The name should be equivalent to the Identifier of a command defined in a [ControlDef]. + + + GUIName + String + Name which is shown to the player in the control configuration dialog and in control tooltips. Localized strings from the corresponding string table can be used ($Name$). If unset, GUIName of the control def is used. If set to "None", the control is not displayed in the user customization dialog even if the control def has a name set. + + + GUIDesc + String + Informative description which is displayed to the player in the control configuration dialog. Lokalisierte Zeichenketten koennen aus dem zugehoerigen StringTable refeenziert werden ($Name$). If unset, GUIDesc of the control def is used. + + + GUIGroup + Integer + Control assignments in the same group are displayed grouped together in the control assignment dialog. The group with the lowest number is displayed at the top. Default 0. + + + GUIDisabled + Boolean + Whether this control assignment can not be changed in the control assignment dialog. Default 0. + + + Priority + Integer + Priority of the mapping. If more than once mapping is using the same keys then the key with the highest priority is executed first until a command is treated as handled. + + + TriggerMode + bitmask + + + Trigger mode of this mapping. Bitmask based on the following values: + +
          Any number of sections [Assignment]
          + + Value + Description + + + Default value + No particular action. + + + Hold + The key changes the state of the command linked to to be held even if the key itself is pressed only shortly. Only valid if the Hold attribute is set for the command. This state remains until a corresponding mapping with trigger mode Release is being pressed. See Held keys. + + + Release + The key removes the held state. A key can have both Hold and Release set to toggle between the two states. See Held keys. + + + AlwaysUnhandled + The key press is always passed to the mapping with the next lowest priority, independent of whether the previous command was executed successfully or not. + + + ClearRecentKeys + When the assignment is triggered, all recent keys are deleted and the trigger key is not added to the recent list. This means no future key combos can be triggered with any keys including and preceding the current. + +
          + + + + + OverrideAssignments + Boolean + The assignment overwrites all other assignments for the same control with the same press/release trigger mode. + +
          Script callbacks To initialize the player control the script function InitializePlayerControl is called for each player. This call might be delayed by a few frames with respect to InitializePlayer since the initialization of the control needs to be transmitted in the network. When continuing savegames InitalizePlayerControl will be called again. The chosen control might be different from the original one. The same can happen if a player chooses to change its controls during the game. @@ -357,6 +409,5 @@ global func UpdateControlDir(int player) Priorities ...
          - ** - not yet implemented Sven22009-06 diff --git a/docs/sdk/scenario/index.xml b/docs/sdk/scenario/index.xml index bc516778d..adb518d50 100644 --- a/docs/sdk/scenario/index.xml +++ b/docs/sdk/scenario/index.xml @@ -25,6 +25,10 @@
          Landscape.txt
          Advanced scenario designers can use this component to define highly complex, fully random generated dynamic landscapes. This does require certain mathematical skill and some patience, however. +
          +
          Map.c
          +
          + Script for dynamic generation of map. See map script documentation.
          @@ -104,10 +108,14 @@ US:Attack of the Killer Wipfs
          Stores the material table used in this scenario. The materials listed here are used by the exact landscape and have to be available in the loaded Material.ocg group.
          -
          Objects.txt
          +
          Game.txt
          This component is generated by the engine and stores runtime object data of a savegame.
          +
          Objects.c
          +
          + This component is generated by the engine if the game is stored as a scenario. Contains an InitializeObjects() function to recreate all objects placed during editing before. See Object saving. +
          Overloading Rules Various system components (graphics, loader screens, materials, music, or objects) can be overloaded in scenarios. In doing this, parent scenario folders (ocf) are searched. Also, components located in child groups will always overload the same components located in parent groups. diff --git a/docs/sdk/scenario/scenario.xml b/docs/sdk/scenario/scenario.xml index cf290c414..a84feb004 100644 --- a/docs/sdk/scenario/scenario.xml +++ b/docs/sdk/scenario/scenario.xml @@ -218,7 +218,7 @@ BottomOpen Integer - 0 or 1. Determines wether the bottom of the game world should be open. + 0, 1 or 2. Determines wether the bottom of the game world should be open. 0=Bottom is closed, 1=Bottom is open, 2=Bottom is closed if the corresponding map pixel in the bottom row has tunnel background and open otherwise. TopOpen @@ -330,6 +330,11 @@ Integer Granularity of the Fog of War. Default: 64. Warning: smaller values will improve the looks of the FoW but will also severely increase processing times. + + FlatChunkShapes + Integer + 0 or 1. If 1, all landscape chunks are drawn flat when the map is zoomed to draw the landscape. Set this while drawing a static map in console mode to fix small gaps of lower order materials hidden behind materials of chunky shape. + diff --git a/docs/sdk/script/BreakContinue.xml b/docs/sdk/script/BreakContinue.xml index 81496a942..e9e83913e 100644 --- a/docs/sdk/script/BreakContinue.xml +++ b/docs/sdk/script/BreakContinue.xml @@ -9,8 +9,8 @@ The keywords break and continue are used for finer control of loops:
            -
          • break ends the enclosing loop. Execution is continued after the end of the loop.
          • -
          • continue ends the current loop execution and continues with the next loop item from the beginning of the loop.
          • +
          • break ends the enclosing loop. Execution is continued after the end of the loop.
          • +
          • continue ends the current loop execution and continues with the next loop item from the beginning of the loop.
          Example: diff --git a/docs/sdk/script/Effects.xml b/docs/sdk/script/Effects.xml index 50cd5923a..bcf376d57 100644 --- a/docs/sdk/script/Effects.xml +++ b/docs/sdk/script/Effects.xml @@ -1,4 +1,4 @@ - + @@ -71,12 +71,12 @@ func Activate(object caster, object caster2) func FxInvisPSpellStart(object target, proplist effect) { - // Vorherige Sichtbarkeit des Zauberers speichern + // Save the casters previous visibility effect.visibility = target.Visibility; effect.old_mod = target->GetClrModulation(); - // Zauberer unsichtbar machen + // Make the caster invisible target.Visibility = VIS_Owner | VIS_Allies | VIS_God; - // Halbdurchsichtig bläulich für den Besitzer und Verbündete + // Semitransparent and slightly blue for owner and allies target->SetClrModulation(ModulateColor(effect.old_mod, RGBa(127,127,255,127))); // Fertig return true; @@ -505,26 +505,32 @@ global func FxExplodeOnDeathCurseStop(object target, proplist effect, int reason + Script constantreasonMeaning + FX_Call_Normal0Normal removal + FX_Call_Temp1Temporary removal (temporary is 1). + FX_Call_TempAddForRemoval2Not used + FX_Call_RemoveClear3The target object has been deleted + FX_Call_RemoveDeath4The target object has died @@ -551,7 +557,7 @@ global func FxExplodeOnDeathCurseStop(object target, proplist effect, int reason Fx*Damageint Fx*Damage (object target, proplist effect, int damage, int cause);Every effect receives this callback whenever the energy or damage value of the target object is to change. If the function is defined, it should then return whether to allow the change. - This callback is made upon life energy changes in living beings and damage value changes in non-livings - but not vice versa. cause contains the value change and reason: + This callback is made upon life energy changes in living beings and damage value changes in non-livings - but not vice versa. cause contains the value change and reason:
          diff --git a/docs/sdk/script/FuncCall.xml b/docs/sdk/script/FuncCall.xml index 035251767..f0bf8343d 100644 --- a/docs/sdk/script/FuncCall.xml +++ b/docs/sdk/script/FuncCall.xml @@ -41,7 +41,7 @@ func MyCall() The function Activate() in the script of object B will first search for the closest object of type A (definition ID TestObjectA) and store a reference to this object in the variable "obj". Then the function Activate() is called in the script of object A. To do this we first specifiy the variable containing the pointer to the object, followed by an arrow, then the function name including the parameter list (no parameters in this case). Calling Activate() in object B will cause the closest object of type A to be blown up. You may consider this a very primitive type of remote control. By the way, this script will cause an error if no object of type A can be found. To prevent this, first check whether obj is not nil before calling Activate(). Remarks - You don't have to store the object pointer in a variable as done in this example. You could also continue calling the function directly on the search result as in this case: + You don't have to store the object pointer in a variable as done in this example. You could also continue calling the function directly on the search result as in this case: func Activate() { FindObject(Find_Id(TestObjectA), Sort_Distance())->Activate(); diff --git a/docs/sdk/script/Funcs.xml b/docs/sdk/script/Funcs.xml index 65da170dd..77f66eb62 100644 --- a/docs/sdk/script/Funcs.xml +++ b/docs/sdk/script/Funcs.xml @@ -48,8 +48,8 @@ func Bar() { this == self: true this == self: false this == self: true - The last call to Foo shows the reason for this: Most of the functions in an object need that object to do something with it, and passing the object to every function would result in a lot of repetetive code. - Note for everyone familiar with previous versions of C4Script: When calling a function in a definition like Flint->Hit();, the definition is returned from this. In the Flint->Hit(); example, that will probably result in an error message from the engine like "passed proplist, but expected object". + The last call to Foo shows the reason for this: Most of the functions in an object need that object to do something with it, and passing the object to every function would result in a lot of repetitive code. + Note for everyone familiar with previous versions of C4Script: When calling a function in a definition like Flint->Hit();, the definition is returned from this. In the Flint->Hit(); example, that will probably result in an error message from the engine like "passed proplist, but expected object", because the Hit function of the Flint is not designed to be called like that. Parameter Types You can specify the data type that is to be accepted for a given parameter. To do this, simply write the desired type name before the parameter name: func TypeParameterFunction(object myClonk, id def, int count, string msg) diff --git a/docs/sdk/script/MapScript.xml b/docs/sdk/script/MapScript.xml new file mode 100644 index 000000000..e493af035 --- /dev/null +++ b/docs/sdk/script/MapScript.xml @@ -0,0 +1,502 @@ + + + + + Map script + Map script + + Map scripts provide a powerful method to generate diverse, dynamic maps with just a few lines of simple script code. Map scripts can be used to generate new maps, as well as modify existing maps defined as static Map.bmp or dynamic Landscape.txt. + Introduction + A map script is simply a script file called Map.c placed in a scenario. On scenario initialization, the engine calls the local function called InitializeMap in this script. If the function returns true, the map will be used by the engine. If false is returned, the map is discarded and the regular fallback map is created. + Here an example of a simple map script: + /* A simple map */ + +#include Library_Map + +func InitializeMap(proplist map) +{ + // Create a big map + Resize(150,150); + // Draw earth + DrawRegularGround(); + // Draw some resources into the ground + DrawWaterVeins(3, [0,map.Hgt/3,map.Wdt,map.Hgt*2/3]); + DrawCoal(6); + DrawSulphur(4); + DrawRock(15); + DrawOre(4); + DrawGold(2*GetStartupPlayerCount()); // amount of gold depends on player count! + // Make sure liquids don't border tunnel or sky sideways + FixLiquidBorders(); + // Done. Use this map. + return true; +} + This draws a pretty boring standard map with basic resources. It makes use of some high-level helper functions such as DrawRegularGround or DrawCoal. which are included in the definition named Library_Map in Objects.ocd/Libraries.ocd. All map scripts should include this definition. + + Layers + + All map draw functions work on layers, which are simply 8 bit image surfaces. The map itself is a layer, but additional layers can be created as temporary buffers using the CreateLayer or Duplicate script functions. Additional layers are bound to the map they were created from and destroyed alongside with it when map drawing is complete. + In C4Script, map layers are represented as prop lists. They have the implicit properties Wdt and Hgt, which contain the width and height of the surface respectively. To resize a map or layer, use the Resize() function. Do not modify Wdt or Hgt directly. + For example, the following code: + var layer = CreateLayer("Earth"); +layer->DrawCoal(); +Blit(layer, [0,0,layer.Wdt/2,layer.Hgt]); + would create a secondary layer filled with earth. It would then draw coal onto the layer and finally copy only the left half of its contents to the main map. + + + Algorithms + + Algorithms are the core concept of dynamic map creation to point drawing operations to specific subregions of the map only. An algorithm is a function that maps a position (int x, int y) to either a pixel color (int) or a mask value (bool). + Algorithms are defined as prop list with the Algo property set to one of the MAPALGO_* constants and additional algorithm parameters set as properties. They can then be passed to one of the drawing functions (Draw or Blit), which will evaluate the algorithm at all positions and draw pixel values accordingly. + For example, the following code would draw rectangles of earth in a checkerboard pattern: + Draw("Earth", {Algo=MAPALGO_RndChecker, Wdt=5, Hgt=5}); + In addition to pattern-generating algorithms, there are also modifier algorithms that take other algorithms as parameters. For example, the Turbulence algorithm jumbles all pixels of the underlying algorithm around to create a noisy pattern: + var checkerboard = {Algo=MAPALGO_RndChecker, Wdt=10, Hgt=10}; +var jumbled_checkerboard = {Algo=MAPALGO_Turbulence, Amplitude=10, Scale=10}; +Draw("Earth", jumbled_checkerboard); + Modifier algorithms can also be applied to layer contents directly. For example, to flip the contents of the current map, one could write: + // Backup contents of current map +var copy_layer = Duplicate(); +// Redraw flipped horizontally +Blit({Algo=MAPALGO_Scale, OffX=Wdt/2, X=-100, Op=copy_layer}); + + Note: If you are using the target layer in a drawing command, always draw from a copy. Otherwise, the result is undefined. + MAPALGO_Layer + Returns the pixel value at the x,y position of the given layer. Instead of passing a MAPALGO_Layer prop list, layers can also be passed directly as algorithms. +
          ParameterDefaultMeaning + + Layer + + The layer from which pixel values are taken. + +
          + MAPALGO_RndChecker + Returns values from a checkerboard pattern of rectangles that are filled with ones or zeros. + ParameterDefaultMeaning + + Seed + Random(65536) + If nonzero, the checkerboard pattern is generated from a fixed seed. + + Ratio + 50 + Percentage of checkerboard fields that are one. + + Wdt + 10 + Width of rectangles. + + Hgt + 10 + Height of rectangles + + FixedOffset + false + If true, the pattern always starts at position (0,0). Otherwise, it is offset by a random phase. + +
          + MAPALGO_Rect + Returns one if the position is in a given rectangle and zero otherwise. + ParameterDefaultMeaning + + X + 0 + Left side of rectangle (pixel is included). + + Y + 0 + Top side of rectangle (pixel is included). + + Wdt + 0 + Width of rectangle. + + Hgt + 0 + Height of rectangle. + +
          + MAPALGO_Ellipsis + Returns one if the position is in a given ellipsis and zero otherwise. + ParameterDefaultMeaning + + X + 0 + Horizontal center of ellipsis. + + Y + 0 + Vertical center of ellipsis. + + Wdt + 10 + Horizontal radius of ellipsis. + + Hgt + 10 + Vertical radius of ellipsis + +
          + MAPALGO_Polygon + Returns one if the position is in a given polygon or on its border and zero otherwise. + ParameterDefaultMeaning + + X + + Array of x coordinates of polygon points. + + Y + + Array of y coordinates of polygon points. + + Wdt + 1 + Width of border lines of polygon. + + Empty + false + If true, the polygon is not filled and only the border is drawn. + + Open + false + If true, the last segment of the polygon is not drawn. Useful to draw lines. Only valid if Empty is true. + +
          + MAPALGO_Lines + Returns one if the point is on regular stripes and zero otherwise. + Vector (X,Y) determines both width and direction of the stripes. So, for instance, if you want to draw vertical stripes of 10 pixels width and a gap of 5 pixels between them, you would set X=10, Y=0, Distance=15. + ParameterDefaultMeaning + + X + 0 + X size of vector that points perpendicular to stripes. + + Y + 0 + Y size of vector that points perpendicular to stripes. + + OffX + 0 + Offset of stripes. If unspecified, stripes begin at (0,0). + + OffY + 0 + Offset of stripes. + + Distance + 2*Sqrt(X*X+Y*Y) + Distance between two stripes. Includes the stripe width! + +
          + MAPALGO_And + Returns zero if any of the operands is zero. Otherwise, returns the value of the last operand. If there are zero operands, always returns zero. + ParameterDefaultMeaning + + Op + + Array of algorithms that are tested. + +
          + MAPALGO_Or + Returns the first operand that is nonzero. If all operands are zero, returns zero. If there are zero operands, always returns zero. + ParameterDefaultMeaning + + Op + + Array of algorithms that are tested. + +
          + MAPALGO_Not + Returns one if the operand is zero. Returns zero otherwise. + ParameterDefaultMeaning + + Op + + Algorithms that is negated. + +
          + MAPALGO_Xor + If exactly one of the two operands is nonzero, returns that operand. Otherwise, returns zero. + ParameterDefaultMeaning + + Op + + Array of two algorithms that are tested. + +
          + MAPALGO_Offset + Moves its operand by an offset. + ParameterDefaultMeaning + + Op + + Algorithms that is being manipulated. + + OffX + 0 + Horizontal offset to the right. + + OffY + + Vertical offset downwards. + +
          + MAPALGO_Scale + Scales its operand by a point. + ParameterDefaultMeaning + + Op + + Algorithms that is being manipulated. + + X + 100 + Horizontal scaling in percent. Values smaller than zero flip the operand horizontally. + + Y + 100 + Vertical scaling in percent. Values smaller than zero flip the operand vertically. + + OffX + 0 + X position of fixed point that remains in position. + + OffY + 0 + Y position of fixed point that remains in position. + +
          + MAPALGO_Rotate + Rotates its operand around a point. + ParameterDefaultMeaning + + Op + + Algorithms that is being manipulated. + + R + 0 + Rotation angle in degrees (0 to 360). Positive values rotate counter-clockwise. + + OffX + 0 + X position of fixed point that remains in position. + + OffY + 0 + Y position of fixed point that remains in position. + +
          + MAPALGO_Turbulence + Jumbles its operand around by moving points by a randomized offset. + ParameterDefaultMeaning + + Seed + Random(65536) + If nonzero, the offset map is generated from a fixed seed. + + Amplitude + 10 + Maximum range by which pixels may be moved in a single step. Movement in any direction is half of the amplitude. Can be an single integer for equal movement in both dimensions or an array of two integers for separate amplitudes for horizontal and vertical movement. + + Scale + 10 + Distance of points for which the amplitude is randomized. A large scale relative to the amplitude creates more broadly scaled, regular turbulence, while a small scale can cause borders to look more jumpey. Can be an single integer for equal scale in both dimensions or an array of two integers for separate scales horizontally and vertically. + + Iterations + 2 + Number of times each point is pushed around. The amplitude of the n'th successive push is reduced by 1/n. + +
          + MAPALGO_Border + Returns true for positions that lie on an inner or outer border of an operand. An inner border is defined as a position where the operand is nonzero and a position where it is zero lies within inner border width range. An outer border is defined as a position where the operand is zero and a position where it is nonzero lies within outer border width range. Note that borders are only searched in four directions (left, right, upwards, downwards) and not diagonally. This means that for a square, outer borders to not catch the corners. + ParameterDefaultMeaning + + Op + + Algorithm of which the border is to be determined. + + Wdt + 1 + Border width in all directions. Positive integer for inner border; negative integer for outer border. Can also be an array of two integers of opposing signs for inner and outer borders. + + Left + + Border width to the left side. Definition like Wdt. Falls back to Wdt if not specified. + + Top + + Border width upwards. Definition like Wdt. Falls back to Wdt if not specified. + + Right + + Border width to the right side. Definition like Wdt. Falls back to Wdt if not specified. + + Bottom + + Border width downwards. Definition like Wdt. Falls back to Wdt if not specified. + +
          + MAPALGO_Filter + Return only pixel values of the operand that match the mask specification. Returns zero for other pixels. + ParameterDefaultMeaning + + Op + + Operand algorithm that is being filtered. + + Filter + + Mask specification (see section "Material-texture masks" below) + +
          + + + Script function parameters + + Map drawing functions follow a common syntax for passing certain structures: + Rectangles (array rect) + All rectangles are given in the format [left, top, width, height], where the left and top pixel rows are included and left+width and top+height pixel rows are excluded. Unless otherwise specified, rect can always be nil, in which case the area defaults to the whole map or layer ([0,0,this.Wdt,this.Hgt]). + Material-texture definitions (string mattex) + When a material is specified for the drawing functions, the following definitions are valid: + + + + String + Example + Meaning + + + Material + Earth + Draws the given material in its default texture as underground (tunnel background) material. + + + Material-Texture + Earth-earth_topSoil + Draws the given material with the given texture as underground material. + + + ^Material + ^Water + Draws the given material with its default texture as overground (sky background) material. + + + ^Material-Texture + ^Earth-earth_rough + Draws the given material with the given texture as overground material. + + + Sky + Sky + Draws a sky material. Within the map generator, explicit sky is drawn as IFT (0x80), which is converted to index zero on map drawing. That way, sky can be blitted to other layers without being transparent. + + + Transparent + Transparent + Draws with index 0. + +
          +
          + Material-texture masks (string mask_spec) + When a material is specified as a masking function, the following definitions are valid: + + + + String + Example + Meaning + + + Material + Earth + True for given material with any texture and any (sky or tunnel) background. + + + Material-Texture + Earth-earth_topSoil + True for the given material with the given texture and any (sky or tunnel) background. + + + Sky + Sky + True for explicit sky material (0x80) only. Not true for transaprent (0) pixels. + + + Transparent + Transparent + True for transparent pixels (index 0) only. + + + Background + Background + True for all background materials (e.g. Tunnel, BrickBack and Sky). + + + Liquid + Liquid + True for all liquids (e.g. Water, Acid, Lava and DuroLava). + + + Solid + Solid + True for solid materials (e.g. Earth, Rock, Brick, etc.). + + + * + * + True for all materials. + + + ^Definition + ^Rock-rock_cracked + True for the definition if overground (sky background) only. + + + &Definition + &Liquid + True for the definition if underground (tunnel background) only. The example would match all underground liquids. + + + ~Definition + ~^* + Inverts the definition, i.e. true only if the definition would originally be false. The example would match all underground materials. + +
          +
          +
          + + Script functions + + All drawing functions are defined in the MapLayer static prop list. Because the Map.c script file is also evaluated in this context with the current map as this pointer, all drawing functions can be called directly by name in that script (e.g.: Resize(150,150)). In other script contexts or if the function is to be executed on a layer instead of on the main map, the base object must be given explicitely (e.g.: map->Resize(150,150), where map is the parameter passed to InitializeMap). + Because layers derive from the MapLayer prop list, all script functions defined in the Map.c and included script files are also available on any layer. + Internal engine functions + + bool Draw(string mattex, proplist mask_algo, array rect); + Draws the material given by mattex on all pixels within rect if the algorithm given by mask_algo returns a value other than zero. Returns true on success. + bool Blit(proplist mask_algo, array rect); + Same as draw, but draws the result of evaluation of mask_algo directly instead of a material given by mattex. Because mask_algo can also be a layer, this function can be used to copy layer contents onto other layers or the map. If mask_algo evaluates to zero, nothing is drawn and the original pixel value is kept. + proplist CreateLayer(string mattex_fill, int width, int height); + Creates a new layer of size width,height. If no size is given, the layer is created in the same size as the calling context layer or map. The new layer is filled with the pixel color given by mattex_fill, or with zeroes if mattex_fill is nil. Returns the newly created layer. + bool Resize(int new_width, int new_height); + Recreates the calling layer or map surface in the given size. All contents are deleted and the layer is filled with zeroes. Use functions Duplicate and Blit to backup and restore any old layer contents if you want to extent the map without losing its contents. Returns true on success. + proplist Duplicate(any mask_spec, array rect); + Creates a new layer with the same size and surface contents as this layer. If a rect is given, the new layer is smaller and contains only the portion included in rect. If mask_spec is given, only pixels passing the mask are set and all other pixels in the new layer are zero. + int GetPixel(int x, int y); + Gets the pixel color at the given position in this layer. If x,y is outside the layer, zero is returned. + bool SetPixel(int x, int y, int new_color); + Sets the pixel at position x,y in this layer to new_color. Returns true on success. + int GetPixelCount(any mask_spec, array rect); + Returns number of pixels on this layer or map within rect that fulfill mask_spec. + bool FindPosition(proplist out_pos, mask_spec, array rect, int max_tries); + Tries to find a position on this layer for which the pixel color matches mask_spec. If a position is found, true is returned and the position is set as X and Y parameters in the out_pos prop list. If no position is found after max_tries, the function will walk through all pixels of the layer starting from a random starting position to find a point. If still no position is found, false is returned and out_pos is not changed. max_tries defaults to 500. + array CreateMatTexMask(any mask_spec); + Returns mask_spec as an array of 256 bools to be used e.g. in conjunction with the return value of GetPixel. + + + + + + Sven22013-03 + diff --git a/docs/sdk/script/fn/AddMenuItem.xml b/docs/sdk/script/fn/AddMenuItem.xml index c784635fe..6095f22f5 100644 --- a/docs/sdk/script/fn/AddMenuItem.xml +++ b/docs/sdk/script/fn/AddMenuItem.xml @@ -32,7 +32,7 @@ Numeric value to be displayed next to the menu entry (such as counts and amounts). - int + any parameter Second parameter to the function specified in command (see remark). diff --git a/docs/sdk/script/fn/Anim_AbsX.xml b/docs/sdk/script/fn/Anim_AbsX.xml index 82942afdb..a0d1ecfe4 100644 --- a/docs/sdk/script/fn/Anim_AbsX.xml +++ b/docs/sdk/script/fn/Anim_AbsX.xml @@ -48,6 +48,7 @@ Anim_Linear Anim_X Anim_Y + Anim_R Anim_AbsY Anim_XDir Anim_YDir diff --git a/docs/sdk/script/fn/Anim_AbsY.xml b/docs/sdk/script/fn/Anim_AbsY.xml index a15bc6436..9c70d1134 100644 --- a/docs/sdk/script/fn/Anim_AbsY.xml +++ b/docs/sdk/script/fn/Anim_AbsY.xml @@ -48,6 +48,7 @@ Anim_Linear Anim_X Anim_Y + Anim_R Anim_AbsX Anim_XDir Anim_YDir diff --git a/docs/sdk/script/fn/Anim_Action.xml b/docs/sdk/script/fn/Anim_Action.xml index e042a171d..496ce08d0 100644 --- a/docs/sdk/script/fn/Anim_Action.xml +++ b/docs/sdk/script/fn/Anim_Action.xml @@ -27,6 +27,7 @@ Anim_Linear Anim_X Anim_Y + Anim_R Anim_AbsX Anim_AbsY Anim_XDir diff --git a/docs/sdk/script/fn/Anim_Const.xml b/docs/sdk/script/fn/Anim_Const.xml index e2d60e34c..d00c99e17 100644 --- a/docs/sdk/script/fn/Anim_Const.xml +++ b/docs/sdk/script/fn/Anim_Const.xml @@ -32,6 +32,7 @@ Anim_Linear Anim_X Anim_Y + Anim_R Anim_AbsX Anim_AbsY Anim_XDir diff --git a/docs/sdk/script/fn/Anim_Linear.xml b/docs/sdk/script/fn/Anim_Linear.xml index e5a0d835f..8143f32c5 100644 --- a/docs/sdk/script/fn/Anim_Linear.xml +++ b/docs/sdk/script/fn/Anim_Linear.xml @@ -71,6 +71,7 @@ else Anim_Const Anim_X Anim_Y + Anim_R Anim_AbsX Anim_AbsY Anim_XDir diff --git a/docs/sdk/script/fn/Anim_R.xml b/docs/sdk/script/fn/Anim_R.xml new file mode 100644 index 000000000..9f0f983a6 --- /dev/null +++ b/docs/sdk/script/fn/Anim_R.xml @@ -0,0 +1,49 @@ + + + + + + Anim_R + Animations + 5.3 OC + + array + + + int + begin + Start of the interval. + + + int + end + End of the interval. If end is chosen to be greater than begin then the value increases with clockwise rotation, otherwise it decreases. + + + + The value depends on the rotation of the object. Upward rotation (0 degrees) is mapped to the value given by begin, and moves toward end when the object rotates clockwise, up to end after one revolution (360 degrees). + See the animation documentation for further explanations of the animation system. + + + PlayAnimation("Turn", 5, Anim_R(0, GetAnimationLength("Turn")), Anim_Const(1000)); + Plays the animation "Turn" in slot 5 and superimposes any other potential animations in slot 5. The animation is synchronized to the object's rotation so that the full animation is played once per revolution. + + + + PlayAnimation + SetAnimationPosition + SetAnimationWeight + Anim_Const + Anim_Linear + Anim_X + Anim_Y + Anim_AbsX + Anim_AbsY + Anim_XDir + Anim_YDir + Anim_Action + + + Clonk-Karl2012-04 + diff --git a/docs/sdk/script/fn/Anim_X.xml b/docs/sdk/script/fn/Anim_X.xml index 0968e5413..501aa2471 100644 --- a/docs/sdk/script/fn/Anim_X.xml +++ b/docs/sdk/script/fn/Anim_X.xml @@ -47,6 +47,7 @@ Anim_Const Anim_Linear Anim_Y + Anim_R Anim_AbsX Anim_AbsY Anim_XDir diff --git a/docs/sdk/script/fn/Anim_XDir.xml b/docs/sdk/script/fn/Anim_XDir.xml index 31a3255c1..80860f3e3 100644 --- a/docs/sdk/script/fn/Anim_XDir.xml +++ b/docs/sdk/script/fn/Anim_XDir.xml @@ -43,6 +43,7 @@ Anim_Linear Anim_X Anim_Y + Anim_R Anim_AbsX Anim_AbsY Anim_YDir diff --git a/docs/sdk/script/fn/Anim_Y.xml b/docs/sdk/script/fn/Anim_Y.xml index d9e804828..47ba3e718 100644 --- a/docs/sdk/script/fn/Anim_Y.xml +++ b/docs/sdk/script/fn/Anim_Y.xml @@ -47,6 +47,7 @@ Anim_Const Anim_Linear Anim_X + Anim_R Anim_AbsX Anim_AbsY Anim_XDir diff --git a/docs/sdk/script/fn/Anim_YDir.xml b/docs/sdk/script/fn/Anim_YDir.xml index ee6ee9d7b..61135cf7f 100644 --- a/docs/sdk/script/fn/Anim_YDir.xml +++ b/docs/sdk/script/fn/Anim_YDir.xml @@ -43,6 +43,7 @@ Anim_Linear Anim_X Anim_Y + Anim_R Anim_AbsX Anim_AbsY Anim_XDir diff --git a/docs/sdk/script/fn/BlastFree.xml b/docs/sdk/script/fn/BlastFree.xml new file mode 100644 index 000000000..b95cc1935 --- /dev/null +++ b/docs/sdk/script/fn/BlastFree.xml @@ -0,0 +1,54 @@ + + + + + + BlastFree + Landscape + 5.1 OC + + int + + + int + x + X coordinate + + + int + y + Y coordinate + + + int + radius + Radius + + + int + caused_by + The controller of objects that are created by the blast. See Blast2Objects in material definitions. If not set, the controller is the owner of the calling object. + + + + int + max_density + Only materials of the given density or lower are blasted by this explosion. If not specified, any material is blasted. + + + + + Blasts a hole in solid materials. + + + BlastFree(300, 300, 40, nil, 70); + Blasts a hole into the landscape with the center of the blast being 300,300. Additionally, only materials of a density of 70 or lower are blasted, so this blast does not blast granite. + + + + Explode + + + 2014-01 + diff --git a/docs/sdk/script/fn/Call.xml b/docs/sdk/script/fn/Call.xml index c1afb3dba..da070d460 100644 --- a/docs/sdk/script/fn/Call.xml +++ b/docs/sdk/script/fn/Call.xml @@ -7,12 +7,12 @@ Call Script Function call - 5.1 OC + 5.1 OC5.4 OC any - string + string or function function Function to be called. @@ -23,11 +23,12 @@ - Calls the local function function. If "~" is prepended to the function name then the call does not fail if the function does not exist. + Calls the specified function. If given a string, the function is looked up in the context object (this). For example, obj->Call("Foo") is the same as obj->Foo(). Using Call like this is primarily useful when the name of the function can vary. If "~" is prepended to the function name then the call does not fail if the function does not exist. GameCall eval jwk2002-04 + Günther2012 diff --git a/docs/sdk/script/fn/CanInsertMaterial.xml b/docs/sdk/script/fn/CanInsertMaterial.xml new file mode 100644 index 000000000..6c7a21e88 --- /dev/null +++ b/docs/sdk/script/fn/CanInsertMaterial.xml @@ -0,0 +1,46 @@ + + + + + + CanInsertMaterial + Landscape + Material + 5.4 OC + + bool + + + int + material_index + Material to test to be inserted (see Material()). + + + int + x + X insert position or offset + + + + int + y + Y insert position or offset + + + + proplist + out_insertpos + If a writeable proplist is passed, members x and y are filled with the position at which the material would be inserted. + + + + + Tests if a material pixel at the given position can be inserted. + If the target position already contains material of the same density as the inserted material, the engine will search upwards for a proper insertion position. + + Material + + + Sven22001-11 + diff --git a/docs/sdk/script/fn/CastParticles.xml b/docs/sdk/script/fn/CastParticles.xml deleted file mode 100644 index 238a34f7f..000000000 --- a/docs/sdk/script/fn/CastParticles.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - CastParticles - Particle - 5.1 OC - - bool - - - string - name - Name of the particle type. - - - int - amount - Amount of particles. - - - int - level - Velocity at which to cast the particles. - - - int - x - X coordinate of the particle. Offset in local calls. - - - int - y - Y coordinate of the particle. Offset in local calls. - - - int - a0 - Lower limit for the first extra parameter. This is usually the size of the particles in 1/5 pixels. - - - int - a1 - Upper limit for the first extra parameter. - - - int - b0 - Lower limit for the second extra parameter. This is usually the color modulation of the particles. - - - int - b1 - Upper limit for the second extra parameter. - - - object - obj - Target object for object local particles. Object local particles are drawn directly on top of the object and are removed when the object is deleted. - - - - - Casts the specified amount of particles of the specified type. The extra parameters are set randomly in the range from a0/b0 to a1/b1. - This function returns false if the particle definition was not found, otherwise true. There is no return value indicating whether the particle has actually been created. This must be so to prevent synchronization problems in network games, as particles may be handled differently on each computer in the network. - - - CastParticles("MagicSpark", 10,100, 0,0, 100, 200, RGBa(128,128,255,0), RGBa(255,255,255,127)); - Creates some sparks. - - - - CreateParticle - CastObjects - CastPXS - - - Sven22002-05 - diff --git a/docs/sdk/script/fn/CheckVisibility.xml b/docs/sdk/script/fn/CheckVisibility.xml index da03d5a96..8ac120c29 100644 --- a/docs/sdk/script/fn/CheckVisibility.xml +++ b/docs/sdk/script/fn/CheckVisibility.xml @@ -21,7 +21,7 @@ Checks whether this object is visible for the given player. - Visibility-Property + Visibility Property Newton2009-07 diff --git a/docs/sdk/script/fn/FreeRect.xml b/docs/sdk/script/fn/ClearFreeRect.xml similarity index 69% rename from docs/sdk/script/fn/FreeRect.xml rename to docs/sdk/script/fn/ClearFreeRect.xml index a46502bad..fb1fd364d 100644 --- a/docs/sdk/script/fn/FreeRect.xml +++ b/docs/sdk/script/fn/ClearFreeRect.xml @@ -4,7 +4,7 @@ - FreeRect + ClearFreeRect Landscape 5.1 OC @@ -13,12 +13,12 @@ int x - Left limit of the rectangle + Left limit of the rectangle. Always global coordinates. int y - Top limit of the rectangle + Top limit of the rectangle. Always global coordinates. int @@ -30,27 +30,21 @@ height Height of the rectangle - - int - density - If specified, material of the specified density is removed. - Removes all material within the specified rectangle. Coordinates are always global. Excluding the right and lower limits of the rectangle. This call may take quite a while for large rectangles. - FreeRect(0, 0, LandscapeWidth(), LandscapeHeight()); + ClearFreeRect(0, 0, LandscapeWidth(), LandscapeHeight()); Empties the complete landscape. DigFree DigFreeRect - Explode + BlastFree - Sven22001-11 - Clonkonaut2008-04 + 2014-01 diff --git a/docs/sdk/script/fn/ClearParticles.xml b/docs/sdk/script/fn/ClearParticles.xml index 1d1a8ce84..1b9094ffe 100644 --- a/docs/sdk/script/fn/ClearParticles.xml +++ b/docs/sdk/script/fn/ClearParticles.xml @@ -5,36 +5,23 @@ ClearParticles - Particle + Particles 5.1 OC bool - - - string - name - Name of the particle definition of which you want to delete all particles. If not specified, all particles of all types will be removed. - - - - object - obj - If specified, only the particles local to that object are removed. - - - - Removes all particles of the specified type. + Removes all particles associated with the calling object or the global particles if not called from object context. - ClearParticles("Smoke"); - Removes all smoke. + +GetCursor(0)->ClearParticles(); +Scenario->ClearParticles(); + Removes all particles belonging to the first player's Clonk and all global particles. CreateParticle - PushParticles - Sven22002-04 + Zapper2013-12 diff --git a/docs/sdk/script/fn/CreateParticle.xml b/docs/sdk/script/fn/CreateParticle.xml index 179cf0727..b24a7bceb 100644 --- a/docs/sdk/script/fn/CreateParticle.xml +++ b/docs/sdk/script/fn/CreateParticle.xml @@ -5,72 +5,91 @@ CreateParticle - Particle - 5.1 OC + Particles + 5.3.4 OC bool string - szName - Name of the particle + particle_name + Name of the particle definition. int x - X coordinate of the particle. Offset in local calls. + X-coordinate of the new particle (relative to object for local calls) int y - Y coordinate of the particle. Offset in local calls. + Y-coordinate of the new particle (relative to object for local calls) int - xdir - Initial horizontal velocity of the particle. + speed_x + Starting speed of the particle in x-direction. Can also be a value provider function. int - ydir - Initial vertical velocity of the particle. + speed_y + Starting speed of the particle in y-direction. Can also be a value provider function. - + int - a - Extra parameter. This is usually the size of the particle in 1/5 pixels. + lifetime + Time in frames that the particle will be alive before it is removed. Can also be a value provider function. - + + proplist + properties + PropList with the particle attributes (see the particle documentation). + + int - b - Extra parameter. This is usually the color modulation of the particle. - - - object - target - Target object for object local particles. Object local particles are drawn directly on top of the object and are removed when the object is deleted. - - - - bool - behind_target - If specified and not false, the particle is drawn directly behind the target object. - + amount + Amount of particles to create. Defaults to 1. - Creates a particle. The named particle definition must be loaded. For more information see the particle documentation. - This function returns false if the particle definition was not found, otherwise true. There is no return value indicating whether the particle has actually been created. This must be so to prevent synchronization problems in network games, as particles may be handled differently on each computer in the network. - - - CreateParticle("Blast", 0,0, 0,0, 100, RGB(128,128,255)); - Creates a blue explosion at the position of the calling object. - - - - PushParticles - ClearParticles + Creates a new particle with the given properties. Note that particle creation is not necessarily synchronized over the network and thus, the return value is not whether the particle was actually created but whether the particle definition was found. + See the particle documentation for further explanations. + + + +var particles = +{ + Size = PV_KeyFrames(0, 0, 0, 200, 50, 1000, 0), + DampingX = 900, + DampingY = 900, + R = 255, + G = PV_Linear(255, 0), + B = PV_Linear(128, 0), + Alpha = PV_Linear(255, 0), + Rotation = PV_Direction(), + Stretch = PV_Speed(5 * 1000), + ForceY = PV_KeyFrames(0, 0, 0, 900, 0, 1000, -20), + ForceX = PV_Random(-5, 5, 15), + Phase = PV_Step(1, 0, 10) +}; +CreateParticle("Fire", 0, 0, PV_Random(-200, 200), PV_Random(-200, 200), PV_Random(18, 38 * 5), particles, 100); + + Casts 100 particles with a previously defined behavior. + + + + PV_Linear + PV_Direction + PV_Random + PV_Step + PV_Speed + PV_KeyFrames + PV_Wind + PV_Gravity + PC_Die + PC_Bounce + PC_Stop - Sven22002-04 + Zapper2013-10 diff --git a/docs/sdk/script/fn/CreateParticleAtBone.xml b/docs/sdk/script/fn/CreateParticleAtBone.xml new file mode 100644 index 000000000..21106b00b --- /dev/null +++ b/docs/sdk/script/fn/CreateParticleAtBone.xml @@ -0,0 +1,74 @@ + + + + + + CreateParticleAtBone + Particles + 5.4 OC + + bool + + + string + szName + Name of the particle + + + string + szBoneName + Name of the bone at which to create the particle + + + array + pos + Vector of three elements with the X,Y and Z coordinates of the particle relative to the bone position and orientation. + + + array + dir + Vector of three elements with the X,Y and Z components of the velocity of theparticle relative to the bone orientation. + + + int + lifetime + Time in frames that the particle will be alive before it is removed. Can also be a value provider function. + + + proplist + properties + PropList with the particle attributes (see the particle documentation). + + + int + amount + Amount of particles to create. Defaults to 1. + + + + Creates a particle relative to a bone of the calling object's skeleton. The named particle definition must be loaded. For more information see the particle documentation. + This function returns false if the particle definition was not found, or the function is called for an object which does not have a mesh graphics, or the skeleton of the mesh does not have a bone called szBoneName. Otherwise, true is returned. There is no return value indicating whether the particle has actually been created. This must be so to prevent synchronization problems in network games, as particles may be handled differently on each computer in the network. + + + func InitializePlayer(int plr) +{ + AddEffect("IntColorize", 0, 1, 1); +} + +global func FxIntColorizeTimer() +{ + FindObject(Find_ID(Clonk))->CreateParticleAtBone("SphereSpark", "skeleton_body", [0, 0, 0], [0, 0, 0], PV_Random(20, 30), Particles_Spark()); + FindObject(Find_ID(Clonk))->CreateParticleAtBone("Fire", "pos_hand1", [0, 0, 0], [0, 0, 0], PV_Random(5, 10), Particles_Fire()); + FindObject(Find_ID(Clonk))->CreateParticleAtBone("Fire", "pos_hand2", [0, 0, 0], [0, 0, 0], PV_Random(5, 10), Particles_Fire()); + return(0); +} + Scenario script. Creates an effect which traces a Clonk's body, left hand and right hand with differently colored sparks. + + + + CreateParticle + + + Clonk-Karl2012-12 + diff --git a/docs/sdk/script/fn/CreateScriptPlayer.xml b/docs/sdk/script/fn/CreateScriptPlayer.xml index 16a670474..5c63098dd 100644 --- a/docs/sdk/script/fn/CreateScriptPlayer.xml +++ b/docs/sdk/script/fn/CreateScriptPlayer.xml @@ -45,7 +45,7 @@ 1 CSPF_NoScenarioInit - If true, the scenario initialization (i.e. placement of home base material, clonks, setting of build knowledge, etc.) is not performed for this player. Also, the global callbacks PreInitializePlayer and InitializePlayer to the scenario script and to goal, rule, and environment objects are not performed. Instead, the callback InitializeScriptPlayer(Player number, Team) is made to the object definition specified in extra_data. The call is made as DefinitionCall (without this object). Using this parameter you can create script-controlled AI players which do not receive the same standard treatment as user-controlled players. + If true, the scenario initialization (i.e. placement of home base material, clonks, setting of build knowledge, etc.) is not performed for this player. Also, the global callbacks PreInitializePlayer and InitializePlayer to the scenario script and to goal, rule, and environment objects are not performed. Instead, the callback InitializeScriptPlayer(Player number, Team) is made to the object definition specified in extra_data. Using this parameter you can create script-controlled AI players which do not receive the same standard treatment as user-controlled players. 2 diff --git a/docs/sdk/script/fn/DIR_Left.xml b/docs/sdk/script/fn/DIR_Left.xml index f70b28ae2..ca0b9fe6b 100644 --- a/docs/sdk/script/fn/DIR_Left.xml +++ b/docs/sdk/script/fn/DIR_Left.xml @@ -13,7 +13,7 @@ GetCursor(0)->SetComDir(COMD_None); -GetCursor()->SetDir(DIR_Left); +GetCursor()->SetDir(DIR_Left);
          The selected clonk stops and looks to the left. diff --git a/docs/sdk/script/fn/DefinitionCall.xml b/docs/sdk/script/fn/DefinitionCall.xml deleted file mode 100644 index 8e619826c..000000000 --- a/docs/sdk/script/fn/DefinitionCall.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - DefinitionCall - Script - Function call - 5.1 OC - - any - - - id - definition - id of the definition in the script of which to call the function. - - - string - function - Function to call - - - any - ... - Additional parameters to be passed to the function. - - - - - Calls a function in a script without object context. this returns nil in this case (comparable to scenario scripts). - - GameCall - - - Sven22001-11 - diff --git a/docs/sdk/script/fn/DigFree.xml b/docs/sdk/script/fn/DigFree.xml index c94108da7..c07f29e0b 100644 --- a/docs/sdk/script/fn/DigFree.xml +++ b/docs/sdk/script/fn/DigFree.xml @@ -25,10 +25,17 @@ radius Radius - + bool no_dig2objects Prevent objects from being dug out + + + + bool + no_instability_check + Does not perform instability checks around dug pixels, i.e. prevents surrounding single pixels and liquids from becoming loose. + @@ -41,8 +48,7 @@ DigFreeRect - Explode - jwk2002-04 + 2013-03 diff --git a/docs/sdk/script/fn/DigFreeRect.xml b/docs/sdk/script/fn/DigFreeRect.xml index 1671a0016..0a4ceb5f1 100644 --- a/docs/sdk/script/fn/DigFreeRect.xml +++ b/docs/sdk/script/fn/DigFreeRect.xml @@ -30,10 +30,17 @@ height Height - + bool no_dig2objects Prevent objects from being dug out + + + + bool + no_instability_check + Does not perform instability checks around dug pixels, i.e. prevents surrounding single pixels and liquids from becoming loose. + @@ -47,5 +54,5 @@ DigFree - jwk2002-04 + 2013-03 diff --git a/docs/sdk/script/fn/DrawMaterialQuad.xml b/docs/sdk/script/fn/DrawMaterialQuad.xml index 5a9adac19..91b247ee6 100644 --- a/docs/sdk/script/fn/DrawMaterialQuad.xml +++ b/docs/sdk/script/fn/DrawMaterialQuad.xml @@ -72,7 +72,6 @@ InsertMaterial - SetLandscapePixel Sven22002-05 diff --git a/docs/sdk/script/fn/DrawParticleLine.xml b/docs/sdk/script/fn/DrawParticleLine.xml index 4bc8498ce..e020be58d 100644 --- a/docs/sdk/script/fn/DrawParticleLine.xml +++ b/docs/sdk/script/fn/DrawParticleLine.xml @@ -5,7 +5,7 @@ DrawParticleLine - Particle + Particles 5.1 OC int diff --git a/docs/sdk/script/fn/Explode.xml b/docs/sdk/script/fn/Explode.xml index a9df7fece..ba000801d 100644 --- a/docs/sdk/script/fn/Explode.xml +++ b/docs/sdk/script/fn/Explode.xml @@ -41,7 +41,8 @@ RemoveObject BlastObjects - + BlastFree + Sven22001-11 Clonkonaut2008-04 diff --git a/docs/sdk/script/fn/FatalError.xml b/docs/sdk/script/fn/FatalError.xml index 2517c8d82..571f53dca 100644 --- a/docs/sdk/script/fn/FatalError.xml +++ b/docs/sdk/script/fn/FatalError.xml @@ -11,10 +11,10 @@ bool - string message Error message to be displayed + @@ -42,6 +42,9 @@ }
          + + LogCallStack + Newton2011-09 diff --git a/docs/sdk/script/fn/FileWrite.xml b/docs/sdk/script/fn/FileWrite.xml new file mode 100644 index 000000000..efd7d1743 --- /dev/null +++ b/docs/sdk/script/fn/FileWrite.xml @@ -0,0 +1,40 @@ + + + + + + FileWrite + System + 5.3 OC + + bool + + + int + fid + ID of file to be written to. + + + string + data + String to be written to the file. + + + + Adds a text string to an open file. Currently, this function is only used to write to the Objects.c file in the SaveScenarioObjects callback defined in System.ocg/SaveScenario.c (See Scenario objects saving). + + + global func SaveScenarioObjects(f) +{ + FileWrite(f, "func InitializeObjects() { return true; }\n"); +} + When the user presses "Save scenario" in the editor, he won't save any objects. + + + + Scenario objects saving + + + Sven22013-12 + diff --git a/docs/sdk/script/fn/FinishCommand.xml b/docs/sdk/script/fn/FinishCommand.xml index 794b10faf..490c7ce9a 100644 --- a/docs/sdk/script/fn/FinishCommand.xml +++ b/docs/sdk/script/fn/FinishCommand.xml @@ -24,7 +24,7 @@ - Ends a command in the command stack of an object. + Ends a command in the command stack of an object. A finished command stays in the stack until it would be time for it to be executed and is removed only then. SetCommand GetCommand @@ -33,4 +33,5 @@ Günther2004-04 + Newton2013-12 diff --git a/docs/sdk/script/fn/GameCall.xml b/docs/sdk/script/fn/GameCall.xml index f1e46e7e7..93ea708dc 100644 --- a/docs/sdk/script/fn/GameCall.xml +++ b/docs/sdk/script/fn/GameCall.xml @@ -34,7 +34,6 @@ GameCallEx Call - DefinitionCall Günther2002-04 diff --git a/docs/sdk/script/fn/GameCallEx.xml b/docs/sdk/script/fn/GameCallEx.xml index a50728480..f07900d25 100644 --- a/docs/sdk/script/fn/GameCallEx.xml +++ b/docs/sdk/script/fn/GameCallEx.xml @@ -34,7 +34,6 @@ GameCall Call - DefinitionCall Newton2011-07 diff --git a/docs/sdk/script/fn/GetAverageTextureColor.xml b/docs/sdk/script/fn/GetAverageTextureColor.xml new file mode 100644 index 000000000..13f0ac27e --- /dev/null +++ b/docs/sdk/script/fn/GetAverageTextureColor.xml @@ -0,0 +1,27 @@ + + + + + + GetAverageTextureColor + Landscape + Material + 5.4 OC + + int + + + string + texture_name + Name of the texture for which to retrieve the average color. + + + + Returns the average color of the given material texture. + + GetTexture + + + 2014-01 + diff --git a/docs/sdk/script/fn/GetColor.xml b/docs/sdk/script/fn/GetColor.xml index a0498ff39..407e2216e 100644 --- a/docs/sdk/script/fn/GetColor.xml +++ b/docs/sdk/script/fn/GetColor.xml @@ -9,7 +9,7 @@ Display 5.1 OC int - Gets the RGB color value of the ColorByOwner areas of an object. These are controlled by SetOwner, SetColor or . + Gets the RGB color value of the ColorByOwner areas of an object. These are controlled by SetOwner or SetColor. otherclonk->SetColor(GetColor()); diff --git a/docs/sdk/script/fn/GetContact.xml b/docs/sdk/script/fn/GetContact.xml index 571896d56..700903b9f 100644 --- a/docs/sdk/script/fn/GetContact.xml +++ b/docs/sdk/script/fn/GetContact.xml @@ -19,7 +19,7 @@ int dwCNAT - Bit mask of CNAT values which determine which directions to check. If not specified, all directions are checked. + Bit mask of CNAT values which determine which directions to check. If not specified, defaults to the vertices own CNAT mode, i.e. usually the one specified in VertexCNAT in the definition DefCore.txt file. If the vertex does not have any CNAT value, no direction is checked. diff --git a/docs/sdk/script/fn/GetDefBottom.xml b/docs/sdk/script/fn/GetDefBottom.xml index bf7ad722d..5e786948d 100644 --- a/docs/sdk/script/fn/GetDefBottom.xml +++ b/docs/sdk/script/fn/GetDefBottom.xml @@ -9,7 +9,7 @@ Status 5.1 OC int - Determines the lower limit of an object. This corresponds to y position + DefCore OffsetY + DefCore Height. Object rotation is not taken into consideration. + Determines the lower limit of an object. This corresponds to the bottom vertex on objects that have vertices and y position + DefCore OffsetY + DefCore Height for objects without vertices. Contents()->Exit(0, GetDefBottom()-GetY()); diff --git a/docs/sdk/script/fn/GetGravity.xml b/docs/sdk/script/fn/GetGravity.xml index 18d2a1dba..83f16e8a0 100644 --- a/docs/sdk/script/fn/GetGravity.xml +++ b/docs/sdk/script/fn/GetGravity.xml @@ -8,11 +8,11 @@ Global 5.1 OC int - Returns the current gravity in percent. + Returns the current gravity in 1/100 pixel/tick². for (var obj in FindObjects(Find_Distance(100))) - obj->SetYDir(obj->GetYDir(500) - GetGravity(), 500); + obj->SetYDir(obj->GetYDir(100) - GetGravity(), 100); Makes the gravitation within a radius of 100 pixels vanish if called every frame. diff --git a/docs/sdk/script/fn/GetID.xml b/docs/sdk/script/fn/GetID.xml index 97c6b6add..0a463533c 100644 --- a/docs/sdk/script/fn/GetID.xml +++ b/docs/sdk/script/fn/GetID.xml @@ -6,9 +6,9 @@ GetID Objects - 5.1 OC - id - Returns the object definition id of an object. + 5.1 OC5.4 OC + proplist + Returns the definition of an object. This is most often a def, but can also be a proplist deriving from a def. CreateObject(GetID()) @@ -17,4 +17,5 @@ jwk2002-04 + Günther2013 diff --git a/docs/sdk/script/fn/GetIndexOf.xml b/docs/sdk/script/fn/GetIndexOf.xml new file mode 100644 index 000000000..bd628b669 --- /dev/null +++ b/docs/sdk/script/fn/GetIndexOf.xml @@ -0,0 +1,29 @@ + + + + + + GetIndexOf + Script + Arrays + 5.1 OC + + int + + + array + array2search + Array in which the element should be searched. The array can be zero, in which case the element is never found and -1 is returned. + + + any + needle + The value to which every element of the array is to be compared. + + + + Finds the first occurrence of a value in an array and returns its zero-based index. If the element is not found, -1 is returned. The usual rules for comparison using the ==-operator apply. + + Sven22012-12 + diff --git a/docs/sdk/script/fn/GetMatAdjust.xml b/docs/sdk/script/fn/GetMatAdjust.xml new file mode 100644 index 000000000..6454da2cf --- /dev/null +++ b/docs/sdk/script/fn/GetMatAdjust.xml @@ -0,0 +1,24 @@ + + + + + + GetMatAdjust + Landscape + 5.1 OC + + int + + Returns the material modulation as set by SetMatAdjust. + + SetMatAdjust + SetSkyAdjust + GetSkyAdjust + SetGamma + RGB + RGBa + + + Sven22003-06 + diff --git a/docs/sdk/script/fn/GetPlrColor.xml b/docs/sdk/script/fn/GetPlayerColor.xml similarity index 82% rename from docs/sdk/script/fn/GetPlrColor.xml rename to docs/sdk/script/fn/GetPlayerColor.xml index 2265ad67b..3da2fe07d 100644 --- a/docs/sdk/script/fn/GetPlrColor.xml +++ b/docs/sdk/script/fn/GetPlayerColor.xml @@ -4,7 +4,7 @@ - GetPlrColor + GetPlayerColor Player 5.1 OC @@ -20,7 +20,7 @@ Determines the player color. The player color is used to identify various owned objects such as flags or clonks as well as his text messages. - Log("<c %x>%s</c> has a score of %d.", GetPlrColor(0), GetPlayerName(0), GetScore(0)); + Log("<c %x>%s</c> has a score of %d.", GetPlayerColor(0), GetPlayerName(0), GetScore(0)); Returns status information about the first player, highlighting the player's name in the player color. @@ -29,5 +29,5 @@ SetColor - Sven22003-10 + Sven22013-12 diff --git a/docs/sdk/script/fn/GetPlayerControlAssignment.xml b/docs/sdk/script/fn/GetPlayerControlAssignment.xml new file mode 100644 index 000000000..3dfde18d4 --- /dev/null +++ b/docs/sdk/script/fn/GetPlayerControlAssignment.xml @@ -0,0 +1,45 @@ + + + + + + GetPlayerControlAssignment + Player + 5.1 OC + + string + + + int + player + Number of the player for whom the control set is queried. + + + int + control + Control to query. A CON_* constant should be used here. + + + bool + human_readable + If true, some internal names such as JOY_* for joystick buttons are replaced by variants suitable for display to the player. + + + bool + short_name + If true, short names are preferred if available. Currently effects Mac builds only. + + + + Returns the name of the key, mouse of joystick button assigned to a control for a player. If the player number is invalid, nil is returned. For unassigned or invalid controls, "" is returned. + For network games and replays, the returned value is not synchronized. If the function is called for a remote player or during replay, "" is always returned for valid player numbers. + + + Message("Press <c ffff00>%s</c> to walk left!", GetPlayerControlAssignment(GetPlayerByIndex(0, C4PT_User), CON_Left, true, true)); + Tells the first player how to walk left. + + + + Sven22012-04 + diff --git a/docs/sdk/script/fn/GetPlayerCount.xml b/docs/sdk/script/fn/GetPlayerCount.xml index 2d7ce1df6..1406e1b75 100644 --- a/docs/sdk/script/fn/GetPlayerCount.xml +++ b/docs/sdk/script/fn/GetPlayerCount.xml @@ -26,6 +26,7 @@ + GetStartupPlayerCount GetPlayerName GetPlayerByIndex EliminatePlayer diff --git a/docs/sdk/script/fn/GetProperties.xml b/docs/sdk/script/fn/GetProperties.xml new file mode 100644 index 000000000..fcefaecfb --- /dev/null +++ b/docs/sdk/script/fn/GetProperties.xml @@ -0,0 +1,34 @@ + + + + + + GetProperties + Objects + Properties + 5.3 OC + + array + + + proplist + object + Object to request property from, nil in local calls. + + + + + Returns the names of all properties of object. + + + GetProperties({foo = 1, bar = 2}) == ["bar", "foo"] + + + + SetProperty + GetProperty + + + Günther2012 + diff --git a/docs/sdk/script/fn/GetProperty.xml b/docs/sdk/script/fn/GetProperty.xml index 38eab2b8e..ea475e75f 100644 --- a/docs/sdk/script/fn/GetProperty.xml +++ b/docs/sdk/script/fn/GetProperty.xml @@ -26,7 +26,10 @@ Returns the property key of object. - SetProperty + + SetProperty + GetProperties + Günther2009-05 diff --git a/docs/sdk/script/fn/GetStartupPlayerCount.xml b/docs/sdk/script/fn/GetStartupPlayerCount.xml new file mode 100644 index 000000000..3a077d5cd --- /dev/null +++ b/docs/sdk/script/fn/GetStartupPlayerCount.xml @@ -0,0 +1,21 @@ + + + + + + GetStartupPlayerCount + Player + 5.4 OC + + int + + Returns the number of players scheduled to join the game when it intiially started. This value is determined before game start, so it can be used in early scenario initialization functions such as Initialize or InitializeMap. + The startup player count is not updated when a savegame is resumed with a different number of players. + The number of players actually joining the game might be lower due to clients disconnecting at game start or players trying to join with invalid player files. To get a reliable number of players, handle player joins and leaves directly in InitializePlayer and RemovePlayer callbacks or call GetPlayerByCount shortly after game start. + + GetPlayerCount + + + Sven22013-03 + diff --git a/docs/sdk/script/fn/GetTexture.xml b/docs/sdk/script/fn/GetTexture.xml new file mode 100644 index 000000000..fc28af307 --- /dev/null +++ b/docs/sdk/script/fn/GetTexture.xml @@ -0,0 +1,44 @@ + + + + + + GetTexture + Landscape + Material + 5.4 OC + + string + + + int + x + X coordinate at which to check the texture. Offset in local calls. + + + int + y + Y coordinate at which to check the texture. Offset in local calls. + + + + Returns the name of the texture used for the material at the given position. + + + func ControlUse(object clonk)
          +{
          + var tex_name = clonk->GetTexture(0,0);
          + var tex_color = GetAverageTextureColor();
          + clonk->SetColor(tex_color); + clonk->PlayerMessage(clonk->GetOwner(), "Camoflaging Clonk to look like %s", tex_name);
          +}
          + A script for a carmoflage item. When used, the clonk's overlay color is set to the average color of the texture where he is currently standing and he announces the name of the texture he is carmoflaging as. +
          +
          + + GetAverageTextureColor + +
          + 2014-01 +
          diff --git a/docs/sdk/script/fn/InsertMaterial.xml b/docs/sdk/script/fn/InsertMaterial.xml index 98b07838c..4393a3c10 100644 --- a/docs/sdk/script/fn/InsertMaterial.xml +++ b/docs/sdk/script/fn/InsertMaterial.xml @@ -1,52 +1,58 @@ - - - - - - InsertMaterial - Landscape - Material - 5.1 OC - - bool - - - int - material_index - Material to be inserted (see Material()). - - - int - x - X insert position or offset - - - - int - y - Y insert position or offset - - - - int - xdir - horizontal speed of material pixel to be inserted - - - - int - ydir - vertical speed of material pixel to be inserted - - - - - Inserts a material pixel at the given position and given speed. - - Material - InsertMaterialAmount - - - Sven22001-11 - + + + + + + InsertMaterial + Landscape + Material + 5.1 OC + + bool + + + int + material_index + Material to be inserted (see Material()). + + + int + x + X insert position or offset + + + + int + y + Y insert position or offset + + + + int + xdir + horizontal speed of material pixel to be inserted + + + + int + ydir + vertical speed of material pixel to be inserted + + + + proplist + out_insertpos + If a writeable proplist is passed, members x and y are filled with the actual insertion position. + + + + + Inserts a material pixel at the given position and given speed. + If the target position already contains material of the same density as the inserted material, the engine will search upwards for a proper insertion position. + + Material + + + Sven22001-11 + diff --git a/docs/sdk/script/fn/LaunchVolcano.xml b/docs/sdk/script/fn/LaunchVolcano.xml index 482f4d578..52013af57 100644 --- a/docs/sdk/script/fn/LaunchVolcano.xml +++ b/docs/sdk/script/fn/LaunchVolcano.xml @@ -18,8 +18,7 @@ int y - Y target position. Default: Bottom of the landscape. - + Y position int @@ -33,6 +32,12 @@ Name of the material. The default is "Lava" + + int + angle + Direction into which to erupt. 0 (default) is straight up. + + Launches a volcano at the specified position. @@ -41,5 +46,5 @@ LaunchEarthquake
          - Newton2009-07 + Newton2013-12 diff --git a/docs/sdk/script/fn/MakeScenarioSaveName.xml b/docs/sdk/script/fn/MakeScenarioSaveName.xml new file mode 100644 index 000000000..d793f1533 --- /dev/null +++ b/docs/sdk/script/fn/MakeScenarioSaveName.xml @@ -0,0 +1,32 @@ + + + + + + MakeScenarioSaveName + System + 5.3 OC + + string + + Returns the name under which an object is stored in an Objects.c file if it is saved with the "Save scenario" option (See Scenario objects saving). + + + local target; + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (target) props->Add("Target", "SetTarget(%s)", target->MakeScenarioSaveName()); + return false; +} + Stores a call to SetTarget using a reference to an object stored in the target variable. + + + + Scenario objects saving + + + Sven22013-12 + diff --git a/docs/sdk/script/fn/Music.xml b/docs/sdk/script/fn/Music.xml index b82b35a7c..2546dd378 100644 --- a/docs/sdk/script/fn/Music.xml +++ b/docs/sdk/script/fn/Music.xml @@ -26,6 +26,8 @@ Plays a music track. The corresponding music file must be available in the active music group. If the loaded scenario contains music files, the scenario file will be the music group. Otherwise, the global file Music.ocg will be used. SetPlayList - + Sound + SoundAt + jwk2002-08 diff --git a/docs/sdk/script/fn/PC_Bounce.xml b/docs/sdk/script/fn/PC_Bounce.xml new file mode 100644 index 000000000..64ec784da --- /dev/null +++ b/docs/sdk/script/fn/PC_Bounce.xml @@ -0,0 +1,34 @@ + + + + + + PC_Bounce + Particles + 5.3.3 OC + + array + + + int + bouncyness + Factor to multiply the new speed with. 1000 equals a factor of 1.0. Defaults to 1000. + + + + A particle collision function. The particle will bounce off the ground on collision. If your particles get stuck instead of bouncing, you might need to increase the CollisionVertex value a bit. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Random + PV_KeyFrames + PV_Step + PV_Speed + PC_Die + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PC_Die.xml b/docs/sdk/script/fn/PC_Die.xml new file mode 100644 index 000000000..b7ebb94a6 --- /dev/null +++ b/docs/sdk/script/fn/PC_Die.xml @@ -0,0 +1,27 @@ + + + + + + PC_Die + Particles + 5.3.3 OC + + array + + A particle collision function. The particle will die on collision. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Random + PV_KeyFrames + PV_Step + PV_Speed + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PC_Stop.xml b/docs/sdk/script/fn/PC_Stop.xml new file mode 100644 index 000000000..560658eae --- /dev/null +++ b/docs/sdk/script/fn/PC_Stop.xml @@ -0,0 +1,29 @@ + + + + + + PC_Stop + Particles + 5.3.3 OC + + array + + A particle collision function. The particle will set its velocity to zero on collision. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Random + PV_KeyFrames + PV_Step + PV_Speed + PV_Wind + PC_Bounce + PC_Die + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_Direction.xml b/docs/sdk/script/fn/PV_Direction.xml new file mode 100644 index 000000000..5fc11d0bf --- /dev/null +++ b/docs/sdk/script/fn/PV_Direction.xml @@ -0,0 +1,35 @@ + + + + + + PV_Direction + Particles + 5.3.3 OC + + array + + + int + factor + Factor to multiply the angle with. The factor of 1000 is equal to a real factor of 1.0. + + + + + The value depends on the current angle of movement of the particle. Usually the factor-parameter can be left out, since the original purpose of this function is to be used for the rotation-property. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Random + PV_Step + PV_Speed + PV_KeyFrames + PC_Die + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_KeyFrames.xml b/docs/sdk/script/fn/PV_KeyFrames.xml new file mode 100644 index 000000000..9af2bbd9a --- /dev/null +++ b/docs/sdk/script/fn/PV_KeyFrames.xml @@ -0,0 +1,54 @@ + + + + + + PV_KeyFrames + Particles + 5.3.3 OC + + array + + + int + smoothing + Smoothing of the curve. 0 means linear interpolation. + + + int + position1 + Position relative to the particle age of value1 (0 to 1000). + + + int + value1 + Value at position1. + + + int + position2 + Position relative to the particle age of value2 (0 to 1000). + + + int + value2 + Value at position2. + + + + The value returned will be an interpolated value of the (smoothed) curve between the up to 4 key frames. PV_KeyFrames(0, 0, X, 1000, Y) is equivalent to PV_Linear(X, Y). + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Random + PV_Speed + PV_Step + PC_Die + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_Linear.xml b/docs/sdk/script/fn/PV_Linear.xml new file mode 100644 index 000000000..02f078070 --- /dev/null +++ b/docs/sdk/script/fn/PV_Linear.xml @@ -0,0 +1,39 @@ + + + + + + PV_Linear + Particles + 5.3.3 OC + + array + + + int + start_value + Begin of the interval. + + + int + end_value + End of the interval. + + + + The value will go linearly from start_value to end_value over the life of the particle. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Direction + PV_Random + PV_Step + PV_Speed + PV_KeyFrames + PC_Die + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_Random.xml b/docs/sdk/script/fn/PV_Random.xml new file mode 100644 index 000000000..d9ad69b83 --- /dev/null +++ b/docs/sdk/script/fn/PV_Random.xml @@ -0,0 +1,47 @@ + + + + + + PV_Random + Particles + 5.3.3 OC + + array + + + int + start_value + Begin of the interval to draw the random number from. + + + + int + end_value + End of the interval to draw the random number from. + + + + int + reroll_interval + Interval in frames after which a new random number will be drawn. + + + + + The value will be a random number in the interval from start_value to (not including) end_value. The values in between are not whole integers, but are also in fraction of integers. This means that PV_Random(0, 1) can not only return one value (the 0) but a lot of different values in the interval between 0 and 1. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Step + PV_Speed + PV_KeyFrames + PC_Die + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_Speed.xml b/docs/sdk/script/fn/PV_Speed.xml new file mode 100644 index 000000000..23f18d721 --- /dev/null +++ b/docs/sdk/script/fn/PV_Speed.xml @@ -0,0 +1,39 @@ + + + + + + PV_Speed + Particles + 5.3.3 OC + + array + + + int + factor + Factor to multiply the speed with. 1000 is equal to a factor of 1.0. Defaults to 1000. + + + int + start_value + Base value to add to the calculated speed-value. + + + + The value will depend on the speed of the particle. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Random + PV_KeyFrames + PV_Step + PC_Die + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_Step.xml b/docs/sdk/script/fn/PV_Step.xml new file mode 100644 index 000000000..c09d3ba31 --- /dev/null +++ b/docs/sdk/script/fn/PV_Step.xml @@ -0,0 +1,46 @@ + + + + + + PV_Step + Particles + 5.3.3 OC + + array + + + int + step + Increase per each step (usually one frame, see the delay-parameter). + + + int + start_value + Value that will be added to the current step-value. + + + + int + delay + Delay in frames for every step (defaults to 1). + + + + + PV_Step can be used for values that do not depend on the particle age (unlike f.e. PV_Linear). + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Linear + PV_Direction + PV_Random + PV_Speed + PV_KeyFrames + PC_Die + PC_Bounce + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/PV_Wind.xml b/docs/sdk/script/fn/PV_Wind.xml new file mode 100644 index 000000000..9d46cb648 --- /dev/null +++ b/docs/sdk/script/fn/PV_Wind.xml @@ -0,0 +1,40 @@ + + + + + + PV_Wind + Particles + 5.3.3 OC + + array + + + int + factor + Factor for the speed. 1000 is a factor of 1.0. + + + int + constant_value + Value that is added to the result. + + + + The value will depend on the wind at the current position of the particle. + See the particle documentation for further explanations of the particle system. + + CreateParticle + PV_Direction + PV_Random + PV_Step + PV_Speed + PV_KeyFrames + PC_Die + PC_Bounce + PC_Stop + + + Zapper2013-10 + diff --git a/docs/sdk/script/fn/Particles_Colored.xml b/docs/sdk/script/fn/Particles_Colored.xml new file mode 100644 index 000000000..b6469559f --- /dev/null +++ b/docs/sdk/script/fn/Particles_Colored.xml @@ -0,0 +1,44 @@ + + + + + + Particles_Colored + Particles + 5.3.3 OC + + proplist + + + proplist + prototype + Particle prototype of which a colored version is returned. + + + int + color1 + RGB color in format 0xRRGGBB + + + int + color2 + Secondary color. If given, particles are created with a random color between color and color2. + + + + + Creates a colored version of another particle definition. + + + CreateParticle("MagicSpark", 0,0, PV_Random(-10,10), PV_Random(-10,10), PV_Random(10,50), Particles_Colored(Particles_Spark(),0xff0000,0x00ff00), 15); + Creates 15 particles with coloration varying between red and green. + + + See the particle documentation for further explanations of the particle system. + + CreateParticle + + + Sven22013-12 + diff --git a/docs/sdk/script/fn/PlayAnimation.xml b/docs/sdk/script/fn/PlayAnimation.xml index 7925abc86..2e138be96 100644 --- a/docs/sdk/script/fn/PlayAnimation.xml +++ b/docs/sdk/script/fn/PlayAnimation.xml @@ -53,6 +53,7 @@ var swim_comb = swim_down + 1;
          + TransformBone StopAnimation SetAnimationPosition SetAnimationWeight diff --git a/docs/sdk/script/fn/PushParticles.xml b/docs/sdk/script/fn/PushParticles.xml index 6037fac9a..218052144 100644 --- a/docs/sdk/script/fn/PushParticles.xml +++ b/docs/sdk/script/fn/PushParticles.xml @@ -5,7 +5,7 @@ PushParticles - Particle + Particles 5.1 OC bool diff --git a/docs/sdk/script/fn/Random.xml b/docs/sdk/script/fn/Random.xml index bf2160339..6d87ff3dc 100644 --- a/docs/sdk/script/fn/Random.xml +++ b/docs/sdk/script/fn/Random.xml @@ -13,7 +13,7 @@ int max - Maximum value + Maximum value. Must be zero or greater. The bevaviour for negative values is undefined. diff --git a/docs/sdk/script/fn/SaveScenarioObjectAction.xml b/docs/sdk/script/fn/SaveScenarioObjectAction.xml new file mode 100644 index 000000000..71e72cc04 --- /dev/null +++ b/docs/sdk/script/fn/SaveScenarioObjectAction.xml @@ -0,0 +1,37 @@ + + + + + + SaveScenarioObjectAction + System + 5.3 OC + + bool + + + proplist + props + Handle to proplist for storage of this object. + + + + Stores object action and phase for Objects.c scenario saving (See Scenario objects saving). + + + func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (!ActIdle())SaveScenarioObjectAction(props); + return false; +} + In addition to default properties, this object also saved its current action unless it is idle. + + + + Scenario objects saving + + + Sven22013-12 + diff --git a/docs/sdk/script/fn/Schedule.xml b/docs/sdk/script/fn/Schedule.xml index 18a874968..6fa1985e3 100644 --- a/docs/sdk/script/fn/Schedule.xml +++ b/docs/sdk/script/fn/Schedule.xml @@ -37,11 +37,11 @@ Accordingly, the specified script can be a single command only. It may not contain multiple commands separated by ";". - Schedule("Explode(50)", 1000, 0, FindObject(Find_ID(Clonk))); + Schedule(FindObject(Find_ID(Clonk)), "Explode(50)", 1000); Makes a clonk explode after 1000 ticks delay. - Schedule("SetWealth(GetPlayerByIndex(0), GetWealth(GetPlayerByIndex(0)) + 1)", 1, 100); + Schedule(nil, "DoWealth(GetPlayerByIndex(0), 1)", 1, 100); Gives one unit of money per frame to the first player for 100 frames. Notice that if the first player is eliminated, the donations will continue for the next (first) player, since the receiving player is determined anew in each execution. diff --git a/docs/sdk/script/fn/SetAnimationBoneTransform.xml b/docs/sdk/script/fn/SetAnimationBoneTransform.xml new file mode 100644 index 000000000..289a92d6a --- /dev/null +++ b/docs/sdk/script/fn/SetAnimationBoneTransform.xml @@ -0,0 +1,46 @@ + + + + + + SetAnimationBoneTransform + Animations + 5.4 OC + + int + + + int + animation_number + Animation number of the animation whose bone transformation to change. The animation must have been created with TransformBone. + + + array + transformation + An array with 12 entries representing a 3x4 transformation matrix in row-major order. These matrices can be created via Trans_Identity, Trans_Translate, Trans_Rotate and Trans_Scale or they can be combined via Trans_Mul. + + + int + attach_number + If given, refers to the number of the attached mesh whose animation to change. + + + + + This function can be used to change the transformation of a bone set with TransformBone. This allows to create dynamic animations by script. Returns true if the new transformation was set or false if there is no such animation node or it was not created with TransformBone. + See the animation documentation for further explanations of the animation system. + The transformation passed to this function is not completely arbitrary, in particular it must not have components which skew the mesh along one of the axes. Skewing is not supported by the animation blending system. Skew matrices cannot be produced with one of the Trans_* functions directly, but it can result of the multiplication of a rotation matrix with a rotated scale matrix, e.g. Trans_Mul(Trans_Rotate(...), Trans_Scale(...), Trans_Rotate(...)). Skewing cannot occur by combining translation and rotation matrices only. + + + SetAnimationBoneTransform(animation_number, Trans_Rotate(FrameCounter() % 360, 0, 1, 0)); + Script for a timer to be called each frame: The bone for which the animation with animation_number was started is turning with one revolution per 360 frames. + + + + TransformBone + StopAnimation + + + Clonk-Karl2013-05 + diff --git a/docs/sdk/script/fn/SetAnimationPosition.xml b/docs/sdk/script/fn/SetAnimationPosition.xml index a182d295d..d5e7ad1b4 100644 --- a/docs/sdk/script/fn/SetAnimationPosition.xml +++ b/docs/sdk/script/fn/SetAnimationPosition.xml @@ -20,6 +20,12 @@ position Specifies how to compute the position of the animation. The value needs to be created with one of the "Anim_" animation functions. + + int + attach_number + If given, refers to the number of the attached mesh whose animation to change. + + Sets a new position for the given animation. Returns true if the new AVP was set or false if there is no such animation with the given number or the number refers to a combination node. diff --git a/docs/sdk/script/fn/SetAnimationWeight.xml b/docs/sdk/script/fn/SetAnimationWeight.xml index 4c02a3c8b..f3fc4ec11 100644 --- a/docs/sdk/script/fn/SetAnimationWeight.xml +++ b/docs/sdk/script/fn/SetAnimationWeight.xml @@ -20,6 +20,12 @@ weight Specifies how to compute the weight of the animation in case the animation is combined with another animation in the given slot. The value needs to be created with one of the "Anim_" animation functions. + + int + attach_number + If given, refers to the number of the attached mesh whose animation to change. + + Sets a new weight for the given animation. Returns true if the new AVP was set or false if there is no such animation with the given number or the refernced node is an animation node. diff --git a/docs/sdk/script/fn/SetDir.xml b/docs/sdk/script/fn/SetDir.xml index e8d437bf7..3b0973882 100644 --- a/docs/sdk/script/fn/SetDir.xml +++ b/docs/sdk/script/fn/SetDir.xml @@ -18,7 +18,7 @@ - Sets the direction of the object. + Sets the direction of the object. If the object defines an action named "Turn", this action is executed after the call of this function. SetDir affects the visual direction of an active object; to modify object motion use SetComDir. If the object's action has more than two directions (see the ActMap), you can also use values other than just DIR_Right and DIR_Left. @@ -28,5 +28,5 @@ SetAction - jwk2002-08 + Newton2013-11 diff --git a/docs/sdk/script/fn/SetGamma.xml b/docs/sdk/script/fn/SetGamma.xml index 45696d0d9..98a3f1086 100644 --- a/docs/sdk/script/fn/SetGamma.xml +++ b/docs/sdk/script/fn/SetGamma.xml @@ -78,7 +78,7 @@ SetGamma(RGB(50,0,0), RGB(140,100,100), RGB(255,220,220)); - Adds a light blue hue to the game. + Adds a light red hue to the game. diff --git a/docs/sdk/script/fn/SetGravity.xml b/docs/sdk/script/fn/SetGravity.xml index c32d2d36b..1f4f3a337 100644 --- a/docs/sdk/script/fn/SetGravity.xml +++ b/docs/sdk/script/fn/SetGravity.xml @@ -13,11 +13,11 @@ int gravity - New gravity: value -300 til 300 (in percent) + New gravity in 1/100 pixel/tick² - Sets the gravity. Normal gravity is 100% and results in an acceleration of 0.2 pixels per Tick. (increasing YDir by 2 per Tick with precision=10). + Sets the gravity. It is usually a good idea to set this to a multiple or a fraction of the previous value. GetGravity jwk2002-08 diff --git a/docs/sdk/script/fn/SetLandscapePixel.xml b/docs/sdk/script/fn/SetLandscapePixel.xml deleted file mode 100644 index 3334eaebd..000000000 --- a/docs/sdk/script/fn/SetLandscapePixel.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - SetLandscapePixel - Landscape - 5.1 OC - - bool - - - int - x - X position of the pixel to be set; relative coordinates in local calls - - - int - y - Y position of the pixel to be set; relative coordinates in local calls - - - int - dwValue - 32 bit color value of the pixel - - - - Sets a pixel in the landscape. Not available in the old 8 bit graphics system. - - - SetLandscapePixel(0, 0, RGB(185, 127, 0)); - Colors the landscape pixel directly behind the calling object brown. - - - RGB - - Sven22002-04 - diff --git a/docs/sdk/script/fn/SetObjectBlitMode.xml b/docs/sdk/script/fn/SetObjectBlitMode.xml index 29a73a5e2..51ef94ab3 100644 --- a/docs/sdk/script/fn/SetObjectBlitMode.xml +++ b/docs/sdk/script/fn/SetObjectBlitMode.xml @@ -53,10 +53,15 @@ GFX_BLIT_ClrSfc_Mod2 8 The overlay (owner color) is drawn using additive modulation. This flag might have to be set independently of bit 2. +
          + + GFX_BLIT_Wireframe + 16 + Draws the mesh as a wireframe. Only works with meshes! 5-7 - 16, 32, 64 + 32, 64 reserved diff --git a/docs/sdk/script/fn/SetShape.xml b/docs/sdk/script/fn/SetShape.xml index e026434bf..59945d07b 100644 --- a/docs/sdk/script/fn/SetShape.xml +++ b/docs/sdk/script/fn/SetShape.xml @@ -33,7 +33,7 @@ Changes the bounding rectangle of the object. This rectangle is used e.g. for collision or overlap detection. It does not affect object drawing. - In various situations the engine will reset the object's shape to the definition value. This might overwrite changes made with SetShape. This will happen e.g. during object rotation but also when resuming a saved game. So this function should only be used for mainly static, unchanging objects and you should readjust the shape manually in synchronization calls like UpdateTransferZone. + In various situations the engine will reset the object's shape to the definition value. This might overwrite changes made with SetShape. This will happen e.g. during object rotation but also when resuming a saved game. So this function should only be used for mainly static, unchanging objects and you should read just the shape manually in synchronization calls like OnSynchronized. FindObject(Find_ID(Tree_Coniferous))->SetShape(-200,-300,400,600); diff --git a/docs/sdk/script/fn/SetSolidMask.xml b/docs/sdk/script/fn/SetSolidMask.xml index 9ae2b956a..8172177b4 100644 --- a/docs/sdk/script/fn/SetSolidMask.xml +++ b/docs/sdk/script/fn/SetSolidMask.xml @@ -14,22 +14,22 @@ int x - X position of the top left corner of the new SolidMask rectangle within the definition graphic. + X position of the top left corner of the new SolidMask rectangle within the definition's SolidMask.png image. int y - Y position of the top left corner of the new SolidMask rectangle within the definition graphic. + Y position of the top left corner of the new SolidMask rectangle within the definition's SolidMask.png image. int width - Width of the new SolidMask rectangle within the definition graphic. + Width of the new SolidMask rectangle within the definition's SolidMask.png image. int height - Height of the new SolidMask rectangle within the definition graphic. + Height of the new SolidMask rectangle within the definition's SolidMask.png image. int @@ -43,7 +43,7 @@ - Sets the solid area of an object. The source rectangle determines which pixels from the definition graphic should be used. All pixels within the rectangle of less than 50% transparency will be solid. Also see the SolidMask entry in DefCore.txt. + Sets the solid area of an object. The source rectangle determines which pixels from the definition's SolidMask.png graphic should be used. All pixels within the rectangle of less than 50% transparency will be solid. Also see the SolidMask entry in DefCore.txt. Solid areas will internally be drawn in the landscape using the "Vehicle" material. @@ -52,5 +52,5 @@ - Sven22003-06 + Sven22014-01 diff --git a/docs/sdk/script/fn/SetTransferZone.xml b/docs/sdk/script/fn/SetTransferZone.xml index 7811a9e4c..64363cac1 100644 --- a/docs/sdk/script/fn/SetTransferZone.xml +++ b/docs/sdk/script/fn/SetTransferZone.xml @@ -34,12 +34,12 @@ Sets the transfer zone of the object. If the pathfinding trail of another object leads through this transfer zone (a transfer zone is always considered completely passable in pathfinding) ControlTransfer calls will be made to the transfer zone object for the passing clonk. In these calls, the necessary script commands should be given to the clonk so he can pass the object and reach his destination. - Transfer zones have to be set anew when the object has moved. Also, they should be set anew in response to a UpdateTransferZone callback made by the engine. + Transfer zones have to be set anew when the object has moved. Also, they should be set anew in response to a OnSynchronized callback made by the engine. - protected func Initialize() { return UpdateTransferZone(); } + protected func Initialize() { return OnSynchronized(); } -protected func UpdateTransferZone() { return SetTransferZone(-GetX(), -GetY(), LandscapeWidth(), LandscapeHeight()); +protected func OnSynchronized() { return SetTransferZone(-GetX(), -GetY(), LandscapeWidth(), LandscapeHeight()); protected func ControlTransfer(clonk, endx, endy) { diff --git a/docs/sdk/script/fn/SortArray.xml b/docs/sdk/script/fn/SortArray.xml new file mode 100644 index 000000000..834541fdf --- /dev/null +++ b/docs/sdk/script/fn/SortArray.xml @@ -0,0 +1,33 @@ + + + + + + SortArray + Script + Arrays + 5.4 OC + + bool + + + array + array2sort + Array that is to be sorted + + + bool + descending + If true, elements are sorted in descending (highest to lowest) order. Otherwise ascending order. + + + + Sorts an array by its elements. Elements should be either all strings or all integers. + + SortArrayByProperty + SortArrayByArrayElement + + + Sven22012-12 + diff --git a/docs/sdk/script/fn/SortArrayByArrayElement.xml b/docs/sdk/script/fn/SortArrayByArrayElement.xml new file mode 100644 index 000000000..f614a1825 --- /dev/null +++ b/docs/sdk/script/fn/SortArrayByArrayElement.xml @@ -0,0 +1,38 @@ + + + + + + SortArrayByArrayElement + Script + Arrays + 5.4 OC + + bool + + + array + array2sort + Array that is to be sorted + + + int + element_index + Index of element in sub-array by which sorting should happen + + + bool + descending + If true, elements are sorted in descending (highest to lowest) order. Otherwise ascending order. + + + + Sorts an array of arrays by a subarray element. All elements must be arrays of at least element_index+1 size. Subarray elements should be either all strings or all integer. + + SortArray + SortArrayByProperty + + + Sven22012-12 + diff --git a/docs/sdk/script/fn/SortArrayByProperty.xml b/docs/sdk/script/fn/SortArrayByProperty.xml new file mode 100644 index 000000000..9fc5a056b --- /dev/null +++ b/docs/sdk/script/fn/SortArrayByProperty.xml @@ -0,0 +1,38 @@ + + + + + + SortArrayByProperty + Script + Arrays + 5.4 OC + + bool + + + array + array2sort + Array that is to be sorted + + + string + property_name + Name of property by which the array is to be sorted + + + bool + descending + If true, elements are sorted in descending (highest to lowest) order. Otherwise ascending order. + + + + Sorts an array of proplists by a property. All elements must be proplists. Properties should be either all strings or all integer. If a property is not assigned, it is assumed to be integer zero. + + SortArray + SortArrayByArrayElement + + + Sven22012-12 + diff --git a/docs/sdk/script/fn/Sort_Random.xml b/docs/sdk/script/fn/Sort_Random.xml index 3d1d1d85d..41ef4fcf2 100644 --- a/docs/sdk/script/fn/Sort_Random.xml +++ b/docs/sdk/script/fn/Sort_Random.xml @@ -10,7 +10,7 @@ 5.1 OC array Sort criterion: Sorts the found objects randomly. - Sort_Random should not be used together with to find a random, matching object. Instead the first object of a search with a SortRandom parameter can be used for instance. + Sort_Random should not be used together with FindObject to find a random, matching object. Instead the first object of a FindObjects search with a SortRandom parameter can be used for instance. For additional information on the use of this function see FindObjects. FindObjects diff --git a/docs/sdk/script/fn/Sound.xml b/docs/sdk/script/fn/Sound.xml index 4ede96a6e..25b060411 100644 --- a/docs/sdk/script/fn/Sound.xml +++ b/docs/sdk/script/fn/Sound.xml @@ -39,7 +39,13 @@ Increases or decreases the number of sounds running in a continuous loop. Value +1 will play this sound indefinitely until it is stopped by calling this function again with value -1. Value 0 will play the sound once normally. - + + int + custom_falloff_distance + The further away the sound effect from the player, the more quiet it is played. By default, the sound will not be hearable anymore in a distance of 700 pixels. A custom distance can be specified here. + + + Plays a sound. The specified sound file has to be available in the group Sound.ocg, in the active scenario file, or in any loaded object definition. The audibility of object local sounds will depend on the position of the object relative to the visible viewports. @@ -48,6 +54,7 @@ Plays a 'Fanfare' sound next to the first found wind generator at half volume. + SoundAt Music Sven22002-08 diff --git a/docs/sdk/script/fn/SoundAt.xml b/docs/sdk/script/fn/SoundAt.xml new file mode 100644 index 000000000..6ebd975ef --- /dev/null +++ b/docs/sdk/script/fn/SoundAt.xml @@ -0,0 +1,53 @@ + + + + + + SoundAt + Effects + 5.4 OC + + bool + + + string + name + Name of the sound effect (without .wav/.ogg extension). Wildcards as used by WildcardMatch are used. + + + int + x + X-Position of the sound effect. An offset if called from object-context. + + + int + y + Y-Position of the sound effect. An offset if called from object-context. + + + int + volume + 0-100: volume for playback of the sound. A volume value of nil means playback at 100. + + + + int + player + Player number of the player for which the sound is to be played. In network games, the sound will thus not be audible for the other players. If nil (or not specified), the sound will be played for all players. + + + + int + custom_falloff_distance + The further away the sound effect from the player, the more quiet it is played. By default, the sound will not be hearable anymore in a distance of 700 pixels. A custom distance can be specified here. + + + + + Plays a sound at the specified position. The specified sound file has to be available in the group Sound.ocg, in the active scenario file, or in any loaded object definition. + Sound + Music + + Sven22002-08 + diff --git a/docs/sdk/script/fn/TransformBone.xml b/docs/sdk/script/fn/TransformBone.xml new file mode 100644 index 000000000..89244428b --- /dev/null +++ b/docs/sdk/script/fn/TransformBone.xml @@ -0,0 +1,57 @@ + + + + + + TransformBone + Animations + 5.4 OC + + int + + + string + bone + Name of the bone to be transformed. + + + array + transformation + An array with 12 entries representing a 3x4 transformation matrix in row-major order. These matrices can be created via Trans_Identity, Trans_Translate, Trans_Rotate and Trans_Scale or they can be combined via Trans_Mul. + + + int + slot + Slot in the animation stack in which the animation should be inserted. See Animations. + + + array + weight + Specifies how to compute the weight of the bone transformation in case it is combined with another animation in the given slot. The value needs to be created with one of the "Anim_" animation functions. + + + int + sibling + If the bone transformation is combined with another animation then this refers to the node with which the new node is combined. If not given or nil then the animation is combined with the animation at the top of the slot as returned by GetRootAnimation. + + + + + This function is very similar to PlayAnimation. Instead of playing an animation which is pre-defined in the skeleton of the mesh, it allows individual bones to be transformed arbitrarily. The transformation is inserted as a leaf node into the animation tree for the given slot. The return value of this function is the animation number of the animation node inserted which can be used to manipulate or remove the animation later. If there are already animations in the given slot then additionally a combination node is created. This combination node is assigned the returned number plus 1. + See the animation documentation for further explanations of the animation system. + The transformation passed to this function is not completely arbitrary, in particular it must not have components which skew the mesh along one of the axes. Skewing is not supported by the animation blending system. Skew matrices cannot be produced with one of the Trans_* functions directly, but it can result of the multiplication of a rotation matrix with a rotated scale matrix, e.g. Trans_Mul(Trans_Rotate(...), Trans_Scale(...), Trans_Rotate(...)). Skewing cannot occur by combining translation and rotation matrices only. + + + TransformBone("skeleton_arm_upper.R", Trans_Rotate(90, 0, 1, 0), 5, Anim_Const(1000)); + Rotates the right arm of a Clonk by 90 degrees around the Y axis (in bone coordinates). + + + + PlayAnimation + StopAnimation + SetAnimationBoneTransform + + + Clonk-Karl2013-05 + diff --git a/docs/sdk/script/operatoren.xml b/docs/sdk/script/operatoren.xml index ed28db338..46fce6bb9 100644 --- a/docs/sdk/script/operatoren.xml +++ b/docs/sdk/script/operatoren.xml @@ -21,28 +21,28 @@ 15 - ++ + ++ Increases the value of the following variable by 1. prefix reference, reference 15 - -- + -- Decreases the value of the following variable by 1. prefix reference, reference 15 - ~ + ~ Bitwise negation of the following value. prefix int, int 15 - ! + ! Logical negation of the following value. prefix bool, bool @@ -77,70 +77,70 @@ 14l - ** + ** Yields the power of a to b. postfix int, int/int 13l - / + / Divides a by b. postfix int, int/int 13l - * + * Multiplies a by b. postfix int, int/int 13l - % + % Yields the remainder of the devision of a by b. postfix int, int/int 12l - - + - Subtracts b from a. postfix int, int/int 12l - + + + Adds a to b. postfix int, int/int 11l - << + << Performs a bit shift operation to the left. postfix int, int/int 11l - >> + >> Performs a bit shift operation to the right. postfix int, int/int 10l - < + < Returns whether a is less than b. postfix bool, int/int 10l - <= + <= Returns whether a is less than or equal to b. postfix bool, int/int @@ -148,104 +148,125 @@ 10l > - Returns whether a is greater than b. + Returns whether a is greater than b. postfix bool, int/int 10l - >= + >= Returns whether the first value is greater than or equal to the second. postfix bool, int/int 9l - == + == Returns whether a equals b. postfix bool, any/any 9l - != + != Returns whether a is unequal to b. postfix bool, any/any + + 9l + === + Returns whether a and b refer to the same thing. + postfix + bool, any/any + + + 9l + !== + Returns whether a and b do not refer to the same thing. + postfix + bool, any/any + 8l - & + & Performs a bitwise AND operation. postfix int, int/int 6l - ^ + ^ Performs a bitwise XOR operation. postfix int, int/int 6l - | + | Performs a bitwise OR operation. postfix int, int/int 5l - && + && Performs a logical AND operation. postfix any, any/any 4l - || + || Performs a logical OR operation. postfix any, any/any + + 3l + ?? + Returns the left-hand operand if the operand is not nil, or the right-hand operand otherwise. + postfix + any, any/any + 2r - *= + *= Multiplies the preceeding variables by the following value. postfix reference, reference/int 2r - /= + /= Divides the preceeding variable by the following value. postfix reference, reference/int 2r - %= + %= Sets the preceeding variable to the remainder of the devision of that variable by the following value. postfix reference, reference/int 2r - += + += Increases the preceeding variable by the following value. postfix reference, reference/int 2r - -= + -= Decreases the preeceding variable by the following value. postfix reference, reference/int 2r - = + = Assigns the following value to the preceeding variable. postfix reference, reference/any @@ -292,13 +313,21 @@ while(++somevar < 10) Yet there is an important difference between the two versions: when using the postfix version, the previous value of the variable is returned. The first example will result in a count from 1 to 10, since at beginning of the last loop repetition is value of somevar is 9. It is then increased by one (somevar is now 10) but the previous value of 9 is returned and compared to 10. Thus the loop will be repeated one more time and then the value of 10 is printed. In the second example, on the other hand, the loop runs from 1 to 9. When somevar is 9 and is increased, the new value of 10 is returned immediately. The result is not less than 10 and the loop ends. - The Operators && and || + The Short-Circuiting Operators &&, || and ?? - These two operators are special. If the result can be determined by the first parameter alone, the second parameter is not computed at all. For example, this script does not explode an object, because the overall result would be false, regardless of the result of Explode: + These operators are special. If the result can be determined by the first parameter alone, the second parameter is not computed at all. For example, this script does not explode an object, because the overall result would be false, regardless of the result of Explode: 0 && Explode(20); Further, the result is the value of the first or second parameter, depending on whether one or both were evaluated. For example, one can create a knight if possible or else a Clonk: CreateObject(Knight,0,0,GetOwner()) || CreateObject(Clonk,0,0,GetOwner()) + The operator ?? + + The ?? operator is called the nil-coalescing operator. It can be used to specify a default value for an expression or function call that may evaluate to nil. + + The equality operators ==, !=, === and !== + + The shorter operators basically consider more things equal. For example, two arrays with the same contents are equal, but === only returns true when both sides of the operator contain the same array. This matters mostly when arrays or proplists are modified. Modification can change the return value of the ==/!= operators, but not of the ===/!== operators. + Priority and Associating This subject shows how operator priority is evaluated in detail. diff --git a/docs/search.php b/docs/search.php index 2dc13d3bc..0499f9138 100644 --- a/docs/search.php +++ b/docs/search.php @@ -107,11 +107,7 @@ text-decoration: none;
          diff --git a/include/c4script/c4script.h b/include/c4script/c4script.h index 5ad4f8a03..3d522ae7e 100644 --- a/include/c4script/c4script.h +++ b/include/c4script/c4script.h @@ -1,19 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2012 Günther Brammer + * Copyright (c) 2012-2013, The OpenClonk Team and contributors * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * "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. */ #ifndef C4SCRIPTSTANDALONE_H diff --git a/licenses/clonk-source.txt b/licenses/clonk-source.txt deleted file mode 100644 index 722c93363..000000000 --- a/licenses/clonk-source.txt +++ /dev/null @@ -1,36 +0,0 @@ -Clonk Source Code License - -Clonk source code is distributed through the OpenClonk project -at http://www.openclonk.org under the following license: - -------------------------------------------------------------------------------- - -Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -------------------------------------------------------------------------------- - -Third party library code is included for convenience only and is -covered by their respective licenses. List of libraries: - -zlib: Jean-loup Gailly, Mark Adler -libpng: Glenn Randers-Pehrson -jpeglib: Independent JPEG Group -FMOD: Firelight Multimedia -Freetype: The FreeType Project -Allegro: Shawn Hargreaves -GTK+: see LGPL.txt -SDL: see LGPL.txt -SDL_mixer: see LGPL.txt -getopt: see getopt.txt diff --git a/licenses/isc_license.txt b/licenses/isc_license.txt deleted file mode 100644 index 2d764625c..000000000 --- a/licenses/isc_license.txt +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/licenses/open_clonk_header.txt b/licenses/open_clonk_header.txt deleted file mode 100644 index 449e968aa..000000000 --- a/licenses/open_clonk_header.txt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ diff --git a/masterserver/web/index.php b/masterserver/web/index.php index 178dbbda6..1f2f91b8e 100644 --- a/masterserver/web/index.php +++ b/masterserver/web/index.php @@ -20,10 +20,9 @@ require_once('frontend.php'); OpenClonk Masterserver - - +

          Masterserver

          cleanUp(true); //Cleanup old stuff + + // register new release if (ParseINI::parseValue('oc_enable_update', $config) == 1 && isset($_REQUEST['action']) && $_REQUEST['action'] == 'release-file' && isset($_REQUEST['file']) && isset($_REQUEST['hash']) && isset($_REQUEST['new_version']) && isset($_REQUEST['platform'])) { $absolutefile = ParseINI::parseValue('oc_update_path', $config) . $_REQUEST['file']; if (file_exists($absolutefile)) { @@ -72,7 +74,8 @@ if ($link && $db) { } else { C4Network::sendAnswer(C4Network::createError('Specified file not found.')); } - } else if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) { //data sent from engine? + // prepare data for the engine + } else if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) { $input = $GLOBALS['HTTP_RAW_POST_DATA']; $action = ParseINI::parseValue('Action', $input); $csid = ParseINI::parseValue('CSID', $input); @@ -83,17 +86,17 @@ if ($link && $db) { switch ($action) { case 'Start': //start a new round if (ParseINI::parseValue('LeagueAddress', $reference)) { - C4Network::sendAnswer(C4Network::createError('League not supported!')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_LEAGUENOTSUPPORTED')); } else { $csid = $server->addReference($reference); if ($csid) { $answer = array('Status' => 'Success', 'CSID' => $csid); if(!testHostConn($input)) - $answer['Message'] = 'Your network failed to pass certain tests. It is unlikely that are you able to host for the public.|To fix that, you need port forwarding in your router.'; + $answer['Message'] = 'IDS_MSG_MASTERSERVNATERROR'; C4Network::sendAnswer(C4Network::createAnswer($answer)); unset($answer); } else { - C4Network::sendAnswer(C4Network::createError('Round signup failed. (To many tries?)')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_MATERSERVSIGNUPFAIL')); } } break; @@ -101,26 +104,26 @@ if ($link && $db) { if ($server->updateReference($csid, $reference)) { C4Network::sendAnswer(C4Network::createAnswer(array('Status' => 'Success'))); } else { - C4Network::sendAnswer(C4Network::createError('Round update failed.')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_MASTERSERVUPDATEFAIL')); } break; case 'End': //remove a round if ($server->removeReference($csid)) { C4Network::sendAnswer(C4Network::createAnswer(array('Status' => 'Success'))); } else { - C4Network::sendAnswer(C4Network::createError('Round end failed.')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_MASTERSERVENDFAIL')); } break; default: if (!empty($action)) { - C4Network::sendAnswer(C4Network::createError('Unknown action.')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_MASTERSERVNOOP')); } else { - C4Network::sendAnswer(C4Network::createError('No action defined.')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_MASTERSERVNOOP')); } break; } } else { - C4Network::sendAnswer(C4Network::createError('Wrong engine, "' . ParseINI::parseValue('Game', $input) . '" expected.')); + C4Network::sendAnswer(C4Network::createError('IDS_MSG_MASTERSERVWRONGENGINE')); } } else { //list availabe games $list = array(); @@ -140,6 +143,17 @@ if ($link && $db) { $version = $row['new_version']; if ($version) { $message .= 'Version=' . $version . PHP_EOL; + // strip build version from client request + $n = 0; + for($i=0;$i=3){ + break; + } + } + } + $client_version = substr($client_version,0,$i); if (version_compare($client_version, $version) < 0) { //We need to update $result = mysql_query('SELECT `file` FROM `' . $prefix . 'update` WHERE `old_version` = \'' . $client_version . '\' AND `platform` = \'' . $platform . '\''); $row = mysql_fetch_assoc($result); diff --git a/clonk.desktop b/openclonk.desktop similarity index 89% rename from clonk.desktop rename to openclonk.desktop index 71ca23ba7..edc50102f 100644 --- a/clonk.desktop +++ b/openclonk.desktop @@ -4,7 +4,7 @@ Name=OpenClonk Comment=An action-packed game of strategy, tactics, and skill. Comment[de]=Ein actiongeladenes Taktikspiel. GenericName=Multiplayer action, tactics and skill game -Icon=clonk -Exec=clonk +Icon=openclonk +Exec=openclonk Categories=Game;ActionGame; StartupNotify=true diff --git a/planet/.gitattributes b/planet/.gitattributes new file mode 100644 index 000000000..343394605 --- /dev/null +++ b/planet/.gitattributes @@ -0,0 +1,3 @@ +* -crlf + +* text=auto diff --git a/planet/Arena.ocf/DescDE.rtf b/planet/Arena.ocf/DescDE.rtf new file mode 100644 index 000000000..9e2de74d0 Binary files /dev/null and b/planet/Arena.ocf/DescDE.rtf differ diff --git a/planet/Arena.ocf/DescUS.rtf b/planet/Arena.ocf/DescUS.rtf new file mode 100644 index 000000000..b5315eb84 Binary files /dev/null and b/planet/Arena.ocf/DescUS.rtf differ diff --git a/planet/Arena.ocf/Folder.txt b/planet/Arena.ocf/Folder.txt new file mode 100644 index 000000000..1487bf532 --- /dev/null +++ b/planet/Arena.ocf/Folder.txt @@ -0,0 +1,2 @@ +[Head] +Index=5 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/DescDE.rtf b/planet/Arena.ocf/FrozenFortress.ocs/DescDE.rtf similarity index 52% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/DescDE.rtf rename to planet/Arena.ocf/FrozenFortress.ocs/DescDE.rtf index 240fb56cb..007034170 100644 Binary files a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/DescDE.rtf and b/planet/Arena.ocf/FrozenFortress.ocs/DescDE.rtf differ diff --git a/planet/Arena.ocf/FrozenFortress.ocs/DescUS.rtf b/planet/Arena.ocf/FrozenFortress.ocs/DescUS.rtf new file mode 100644 index 000000000..b6892a963 Binary files /dev/null and b/planet/Arena.ocf/FrozenFortress.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/DefCore.txt b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/DefCore.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/FlagCarry.skeleton b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/FlagCarry.skeleton similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/FlagCarry.skeleton rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/FlagCarry.skeleton diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/FlagIce.png b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/FlagIce.png similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/FlagIce.png rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/FlagIce.png diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/FlagSnow.png b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/FlagSnow.png similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/FlagSnow.png rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/FlagSnow.png diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/Graphics.mesh b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/Graphics.mesh similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/Graphics.mesh rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/Graphics.mesh diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/Scene.material b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/Scene.material rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/Scene.material diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/Script.c similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Script.c rename to planet/Arena.ocf/FrozenFortress.ocs/Flag.ocd/Script.c diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Icon.png b/planet/Arena.ocf/FrozenFortress.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Icon.png rename to planet/Arena.ocf/FrozenFortress.ocs/Icon.png diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Map.bmp b/planet/Arena.ocf/FrozenFortress.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Map.bmp rename to planet/Arena.ocf/FrozenFortress.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Brick.ocm b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Brick.ocm similarity index 87% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Brick.ocm rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Brick.ocm index 3853cb926..f40acac0c 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Brick.ocm +++ b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Brick.ocm @@ -1,7 +1,7 @@ [Material] Name=Brick Shape=Flat -Density=50 +Density=90 Friction=15 Placement=80 TextureOverlay=brick1 diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/BrickSoft.ocm b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/BrickSoft.ocm similarity index 88% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/BrickSoft.ocm rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/BrickSoft.ocm index bd6d5d8e2..70faef15a 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/BrickSoft.ocm +++ b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/BrickSoft.ocm @@ -1,7 +1,7 @@ [Material] Name=BrickSoft Shape=Flat -Density=50 +Density=90 Friction=15 Placement=60 TextureOverlay=brick1 diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Ice.ocm b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Ice.ocm similarity index 92% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Ice.ocm rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Ice.ocm index 132261619..4a8097d66 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Ice.ocm +++ b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Ice.ocm @@ -1,7 +1,7 @@ [Material] Name=Ice Shape=TopFlat -Density=50 +Density=60 Friction=15 BlastFree=1 Blast2Object=Ice diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Snow.ocm b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Snow.ocm similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Snow.ocm rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Snow.ocm diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/TEXMAP.TXT b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/TEXMAP.TXT similarity index 97% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/TEXMAP.TXT rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/TEXMAP.TXT index f64a4a527..6459ff199 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/TEXMAP.TXT +++ b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/TEXMAP.TXT @@ -38,7 +38,7 @@ OverloadTextures 51=Rock-rock_cracked 52=Rock-rock -53=Sulphur-sulphur +53=Firestone-firestone 54=Coal-coal diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Water.ocm b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Water.ocm similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/Water.ocm rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/Water.ocm diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/brick1.jpg b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/brick1.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/brick1.jpg rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/brick1.jpg diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/brickback.jpg b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/brickback.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/brickback.jpg rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/brickback.jpg diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/tunnel.jpg b/planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/tunnel.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Material.ocg/tunnel.jpg rename to planet/Arena.ocf/FrozenFortress.ocs/Material.ocg/tunnel.jpg diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scenario.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scenario.txt similarity index 96% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scenario.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scenario.txt index 207644f45..177c1f827 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scenario.txt +++ b/planet/Arena.ocf/FrozenFortress.ocs/Scenario.txt @@ -3,7 +3,7 @@ Icon=13 Title=FrozenFortress Version=5,2,0,1 MinPlayer=2 -MaxPlayer=8 +Difficulty=80 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/Script.c similarity index 94% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Script.c rename to planet/Arena.ocf/FrozenFortress.ocs/Script.c index 3341745ea..1df0ec180 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Script.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/Script.c @@ -14,14 +14,14 @@ protected func Initialize() var time=CreateObject(Environment_Time); time->SetTime(); time->SetCycleSpeed(); - FindObject(Find_ID(Moon))->SetPhase(3); + FindObject(Find_ID(Moon))->SetMoonPhase(3); FindObject(Find_ID(Moon))->SetCon(150); FindObject(Find_ID(Moon))->SetPosition(LandscapeWidth()/2,150); // Goal: Capture the flag, with bases in both hideouts. var goal = CreateObject(Goal_CaptureTheFlag, 0, 0, NO_OWNER); - goal->SetFlagBase(1, 135, 264); - goal->SetFlagBase(2, LandscapeWidth() - 135, 264); + goal->SetFlagBase(1, 135, 266); + goal->SetFlagBase(2, LandscapeWidth() - 135, 266); CreateObject(Rule_KillLogs); var gate = CreateObject(StoneDoor, 345, 272, NO_OWNER); @@ -34,16 +34,21 @@ protected func Initialize() // Chests with weapons. var chest; chest = CreateObject(Chest, 60, 220, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 7 * 36,nil,nil,false); chest = CreateObject(Chest, 150, 370, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 7 * 36,nil,nil,true); chest = CreateObject(Chest, LandscapeWidth() - 60, 220, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 7 * 36,nil,nil,false); chest = CreateObject(Chest, LandscapeWidth() - 150, 370, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 7 * 36,nil,nil,true); chest = CreateObject(Chest, LandscapeWidth()/2, 320, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillOtherChest", chest, 100, 5 * 36); AddEffect("SnowyWinter", nil, 100, 1); @@ -94,12 +99,11 @@ global func FxGeysirExplosionTimer(object target, effect) y-=3; for(var i=0; i<(45); i++)InsertMaterial(Material("Water"),x+RandomX(-9,9),y-Random(5),RandomX(-10,10)+RandomX(-5,5)+RandomX(-10,10),-(10+Random(50)+Random(30)+Random(60))); for(var i=0; i<(25); i++)InsertMaterial(Material("Water"),x+RandomX(-16,16),y-Random(5),RandomX(-10,10)+RandomX(-15,15)+RandomX(-20,20),-(10+Random(50))); - CreateParticle("Air",x+RandomX(-6,6),y-Random(3),-RandomX(-15,15),RandomX(-86,-2),100+Random(130)); + CreateParticle("Air", PV_Random(x-6, x+6), PV_Random(y-3, y), PV_Random(-15, 15), PV_Random(-90, -5), PV_Random(20, 100), Particles_Air()); if(effect.counter>2072) effect.counter=0; for(var obj in FindObjects(Find_InRect(x-30,y-200,60,210))) { obj->SetYDir(Max(obj->GetYDir()-15,-50)); - } } @@ -127,13 +131,6 @@ global func FxSnowyWinterTimer(object target, effect, int time) { obj->~DoEnergy(-1); } - - for(var dead in FindObjects(Find_ID(Clonk),Find_Not(Find_OCF(OCF_Alive)))) - { - CastParticles("Air",100,50,dead->GetX(),dead->GetY(),50+Random(30)); - CastParticles("AirIntake",50,30,dead->GetX(),dead->GetY(),70+Random(60)); - dead->RemoveObject(); - } } global func PlaceEdges() diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/DefCore.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/DefCore.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Fireball.ogg b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Fireball.ogg similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Fireball.ogg rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Fireball.ogg diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/GlassShatter.ogg b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/GlassShatter.ogg similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/GlassShatter.ogg rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/GlassShatter.ogg diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Graphics.8.png b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Script.c similarity index 57% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Script.c rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Script.c index ed89f2170..d860770da 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Script.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/Script.c @@ -6,9 +6,14 @@ --*/ +func Initialize() +{ + return _inherited(); +} + public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("Frostbolt", 0, 100, 1, 0, GetID(), pClonk->GetOwner(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); + AddEffect("Frostbolt", nil, 100, 1, nil, GetID(), pClonk->GetOwner(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); Sound("Fireball"); Sound("Fireball"); RemoveObject(); @@ -26,6 +31,23 @@ public func FxFrostboltStart(pTarget, effect, iTemp, owner, angle, x, y) effect.angle=angle; effect.x=x; effect.y=y; + + effect.air_particles = + { + Prototype = Particles_Air(), + R = PV_Random(100, 150), + G = PV_Random(100, 150), + B = PV_Random(200, 255), + BlitMode = GFX_BLIT_Additive, + Size = PV_Random(5, 10) + }; + effect.fire_particles = + { + Prototype = Particles_Fire(), + R = PV_Random(100, 150), + G = PV_Random(100, 150), + B = PV_Random(200, 255), + }; } public func FxFrostboltTimer(pTarget, effect, iEffectTime) @@ -45,32 +67,27 @@ public func FxFrostboltTimer(pTarget, effect, iEffectTime) ) { CreateObject(Dynamite,x,y,effect.owner)->BlueExplode(); - CreateObject(Star,x,y,-1)->Sound("GlassShatter"); + var dummy = CreateObject(Dummy,x,y,-1); + dummy->Sound("GlassShatter"); + ScheduleCall(dummy, "RemoveObject", 36); for(var i=0; i<=60;i++) { var r=Random(10)+Random(18); DoBlueExplosion(x+Sin(i*6 ,r),y-Cos(i*6 ,r), 2+Random(3), nil, effect.owner, nil); - } + } return -1; } else if(iEffectTime < 70) { - for(var i=0; i<3; i++) - CreateParticle("Air",x+Sin(angle,-i*2),y-Cos(angle,-i*2),Sin(Random(360),4),Cos(Random(360),4),RandomX(120,180),RGBa(100,100,100,70)); - CreateParticle("AirIntake",x,y,Sin(Random(360),RandomX(5,13)),Cos(Random(360),RandomX(5,13)),RandomX(30,70),RGB(255,255,255)); angle+=Sin(iEffectTime*50,2)*8; x+=Sin(angle, 9); y+=-Cos(angle, 9); effect.x=x; effect.y=y; - for(var i=0;i<6;++i) - { - var c=HSL(128+Random(40), 200+Random(25), Random(100)); - var rx=RandomX(-3, 3); - var ry=RandomX(-3, 3); - CreateParticle("Air", x+rx, y+ry, Sin(angle+180,6)+ry, -Cos(angle+180,6)+rx, 80+Random(20), c); - CreateParticle("MagicFire", x+rx, y+ry, Sin(angle+180,6)+ry, -Cos(angle+180,6)+rx, 20+Random(10), HSL(0,0,255)); - } + + CreateParticle("Air", PV_Random(x - 3, x + 3), PV_Random(y - 3, y + 3), PV_Random(-10, 10), PV_Random(-10, 10), 5, effect.air_particles, 10); + CreateParticle("MagicFire", PV_Random(x - 3, x + 3), PV_Random(y - 3, y + 3), PV_Random(-10, 10), PV_Random(-10, 10), 10, effect.air_particles, 10); + } return 1; diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/authors.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/authors.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/FrostboltScroll.ocd/authors.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/DefCore.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/DefCore.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Graphics.8.png b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Script.c similarity index 71% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Script.c rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Script.c index 11bbb4776..5bee60ce1 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Script.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/Script.c @@ -8,7 +8,7 @@ public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("HardeningSpell", 0, 100, 1, 0, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); + AddEffect("HardeningSpell", nil, 100, 1, nil, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); RemoveObject(); return 1; } @@ -30,13 +30,9 @@ public func FxHardeningSpellTimer(pTarget, effect, iEffectTime) var ydir = effect.ydir; var x = effect.x; var y = effect.y; - for(var i=0; i<4; i++) - { - var r = Random(360); - var d = Random(8) + Random(5) + Random(6) + Random(6); - CreateParticle("AirIntake", Sin(r,d) + x, -Cos(r,d) + y, xdir, ydir,16); - CreateParticle("Air", Sin(r,d) + x, -Cos(r,d) + y, xdir, ydir,16); - } + + CreateParticle("Air", PV_Random(x - 10, x + 10), PV_Random(y - 10, y + 10), xdir, ydir, PV_Random(20, 40), Particles_Air(), 4); + if(!GBackSolid(x,y)) { effect.x+=effect.xdir; @@ -52,7 +48,7 @@ public func FxHardeningSpellTimer(pTarget, effect, iEffectTime) if(GetMaterial(x,y) == Material("Snow")) { DrawMaterialQuad("Ice",x,y,x+1,y,x+1,y+1,x,y+1); - CreateParticle("Air",x ,y ,xdir/3 ,ydir/3 ,35); + CreateParticle("Air", x , y, xdir/3, ydir/3, PV_Random(20, 40), Particles_Air()); } } if(iEffectTime > 360) { return -1; } diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/HardeningScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Script.c similarity index 72% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Script.c rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Script.c index 9a8ac7ff5..f905923e7 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Script.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/Script.c @@ -8,7 +8,7 @@ public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("WindScrollStorm", 0, 100, 1, 0, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); + AddEffect("WindScrollStorm", nil, 100, 1, nil, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); RemoveObject(); return 1; } @@ -23,7 +23,11 @@ public func FxWindScrollStormStart(pTarget, effect, iTemp, angle, x, y) effect.x=x+Sin(angle,43); effect.y=y-Cos(angle,43); - + effect.particles = + { + Prototype = Particles_Air(), + Size = PV_Random(2, 5) + }; } public func FxWindScrollStormTimer(pTarget, effect, iEffectTime) @@ -35,20 +39,14 @@ public func FxWindScrollStormTimer(pTarget, effect, iEffectTime) if(iEffectTime<36) { - var r=Random(360); - var d=Random(40); - CreateParticle("AirIntake",Sin(r,d)+x,-Cos(r,d)+y,xdir/3,ydir/3 +2,64,RGB(Random(80),100+Random(50),255)); - return 1; + var r=Random(360); + var d=Random(40); + CreateParticle("Air", Sin(r,d)+x,-Cos(r,d)+y, xdir/3, ydir/3, PV_Random(10, 30), effect.particles, 1); + return 1; } else if(iEffectTime<180 ) { - for(var i=0; i<5; i++) - { - var r=Random(360); - var d=Random(40); - CreateParticle("AirIntake",Sin(r,d)+x,-Cos(r,d)+y,xdir/2,ydir/2 +2,64,RGB(Random(80),100+Random(50),255)); - } - + CreateParticle("Air", PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), xdir/2, ydir/2, PV_Random(10, 30), effect.particles, 5); for(var obj in FindObjects(Find_Distance(40,x,y),Find_Not(Find_Category(C4D_Structure)))) { if(PathFree(x,y,obj->GetX(),obj->GetY())) diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/StringTblDE.txt b/planet/Arena.ocf/FrozenFortress.ocs/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/StringTblDE.txt rename to planet/Arena.ocf/FrozenFortress.ocs/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/StringTblUS.txt b/planet/Arena.ocf/FrozenFortress.ocs/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/StringTblUS.txt rename to planet/Arena.ocf/FrozenFortress.ocs/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/Explode.c b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/Explode.c similarity index 85% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/Explode.c rename to planet/Arena.ocf/FrozenFortress.ocs/System.ocg/Explode.c index 0c341470a..7f44e114a 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/Explode.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/Explode.c @@ -63,25 +63,35 @@ global func DoBlueExplosion(int x, int y, int level, object inobj, int cause_plr global func BlueExplosionEffect(int level, int x, int y) { - // Blast particle. - CreateParticle("Blast", x, y, 0, 0, level * 10, RGB(0,25,255)); - if(!GBackLiquid(x,y)) CastParticles("Spark", 3, 40 + level, x, y, 20, 30, RGB(0,0,255), RGB(0,30,255)); - if(GBackLiquid(x,y)) CastObjects(Fx_Bubble, level * 4 / 10, level, x, y); - //CastParticles("FSpark", level/5+1, level, x,y, level*5+10,level*10+10, 0x00ef0000,0xffff1010)); - - /*// Smoke trails. - var i = 0, count = 1 + level / 16, angle = Random(360); - while (count > 0 && ++i < count * 10) + var glimmer = { - angle += RandomX(40, 80); - var smokex = Sin(angle, RandomX(level / 4, level / 2)); - var smokey = -Cos(angle, RandomX(level / 4, level / 2)); - if (GBackSolid(x + smokex, y + smokey)) - continue; - //var lvl = 16 * level / 10; - CreateSmokeTrail(level, angle, x + smokex, y + smokey); - count--; - }*/ + Prototype = Particles_Glimmer(), + R = PV_Random(100, 150), + G = PV_Random(100, 150), + B = PV_Random(200, 255) + }; + var fire = + { + Prototype = Particles_Fire(), + R = PV_Random(100, 150), + G = PV_Random(100, 150), + B = PV_Random(200, 255), + Size = PV_Random(level/2, level/3) + }; + var smoke = + { + Prototype = Particles_SmokeTrail(), + R = PV_Linear(PV_Random(100, 150), 0), + G = PV_Linear(PV_Random(100, 150), 0), + B = PV_Linear(PV_Random(200, 255), 0), + Size = PV_Random(level - 5, level + 5) + }; + // Blast particle. + CreateParticle("SmokeDirty", x, y, PV_Random(-2, 2), PV_Random(-2, 2), PV_Random(20, 40), smoke, 10); + CreateParticle("MagicFire", x, y, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 10), fire, 20); + if(!GBackLiquid(x,y)) CreateParticle("SphereSpark", x, y, PV_Random(-100, 100), PV_Random(-100, 100), PV_Random(5, 36 * 3), glimmer, level); + + if(GBackLiquid(x,y)) CastObjects(Fx_Bubble, level * 4 / 10, level, x, y); return; } diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/Script.c b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/Flag.c similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/Script.c rename to planet/Arena.ocf/FrozenFortress.ocs/System.ocg/Flag.c diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/LessBubbles.c b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/LessBubbles.c similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/LessBubbles.c rename to planet/Arena.ocf/FrozenFortress.ocs/System.ocg/LessBubbles.c diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/StoneDoor.c b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/StoneDoor.c similarity index 86% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/StoneDoor.c rename to planet/Arena.ocf/FrozenFortress.ocs/System.ocg/StoneDoor.c index ae399c0f7..de51c1059 100644 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/StoneDoor.c +++ b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/StoneDoor.c @@ -2,8 +2,6 @@ #appendto StoneDoor -private func GetStrength() { return 300; } - protected func Damage() { // Destroy if damage above strength. diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/UnUseableRopeLadders.c b/planet/Arena.ocf/FrozenFortress.ocs/System.ocg/UnUseableRopeLadders.c similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/System.ocg/UnUseableRopeLadders.c rename to planet/Arena.ocf/FrozenFortress.ocs/System.ocg/UnUseableRopeLadders.c diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Teams.txt b/planet/Arena.ocf/FrozenFortress.ocs/Teams.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Teams.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Teams.txt diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Title.txt b/planet/Arena.ocf/FrozenFortress.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/FrozenFortress.ocs/Title.txt rename to planet/Arena.ocf/FrozenFortress.ocs/Title.txt diff --git a/planet/Arena.ocf/Hideout.ocs/DescDE.rtf b/planet/Arena.ocf/Hideout.ocs/DescDE.rtf new file mode 100644 index 000000000..db8ec638b Binary files /dev/null and b/planet/Arena.ocf/Hideout.ocs/DescDE.rtf differ diff --git a/planet/Arena.ocf/Hideout.ocs/DescUS.rtf b/planet/Arena.ocf/Hideout.ocs/DescUS.rtf new file mode 100644 index 000000000..4b64c7a16 Binary files /dev/null and b/planet/Arena.ocf/Hideout.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/DefCore.txt b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/DefCore.txt rename to planet/Arena.ocf/Hideout.ocs/Flag.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/FlagAmetyst.png b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/FlagAmetyst.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/FlagAmetyst.png rename to planet/Arena.ocf/Hideout.ocs/Flag.ocd/FlagAmetyst.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/FlagCarry.skeleton b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/FlagCarry.skeleton similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/FlagCarry.skeleton rename to planet/Arena.ocf/Hideout.ocs/Flag.ocd/FlagCarry.skeleton diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/FlagRuby.png b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/FlagRuby.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/FlagRuby.png rename to planet/Arena.ocf/Hideout.ocs/Flag.ocd/FlagRuby.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/Graphics.mesh b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/Graphics.mesh similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/Graphics.mesh rename to planet/Arena.ocf/Hideout.ocs/Flag.ocd/Graphics.mesh diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/Scene.material b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/Scene.material rename to planet/Arena.ocf/Hideout.ocs/Flag.ocd/Scene.material diff --git a/planet/Arena.ocf/Hideout.ocs/Flag.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/Flag.ocd/Script.c new file mode 100644 index 000000000..e69de29bb diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Breathing.wav b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Breathing.wav similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Breathing.wav rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Breathing.wav diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/DefCore.txt b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/DefCore.txt similarity index 90% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/DefCore.txt rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/DefCore.txt index 5e3c15f94..8c51408ef 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/DefCore.txt +++ b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/DefCore.txt @@ -11,6 +11,5 @@ VertexY=0,-4,0,4 VertexFriction=70,70,70,70 Value=5 Mass=10 -Components=Sulphur=1 Rotate=1 Projectile=1 diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Graphics.8.png b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Graphics.8.png rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/GraphicsE.8.png b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/GraphicsE.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/GraphicsE.8.png rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/GraphicsE.8.png diff --git a/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Script.c new file mode 100644 index 000000000..905adb436 --- /dev/null +++ b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/Script.c @@ -0,0 +1,90 @@ +/*--- Life Gem ---*/ + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; + +// does not fade out. Who wants to leave it lying around anyway! +func HasNoFadeOut(){return true;} + +func Initialize() +{ + AddEffect("Sparkle", this, 1, 30 + RandomX(-3, 3), this); + return 1; +} + +func FxSparkleStart(target, effect, temp) +{ + if (temp) return; + var color = this->~GetGemColor() ?? RGB(255, 20, 20); + effect.particles = + { + Prototype = Particles_MagicRing(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + }; +} + +func FxSparkleTimer(target, effect, effect_time) +{ + if(this()->Contained() || !Random(2)) return FX_OK; + CreateParticle("MagicRing", 0, 0, 0, 0, effect.Interval, effect.particles, 1); + return FX_OK; +} + +public func ControlUse(object clonk, int ix, int iy) +{ + // applies the healing effect even when the Clonk is at full HP + // does this because you can block one source of damage + AddEffect("GemHealing", clonk, 10, 4, nil, this->GetID()); + clonk->Sound("Breathing", false, 50, nil); + this->RemoveObject(); + return true; +} + +func FxGemHealingStart(target, effect, temp) +{ + if (temp) return; + effect.glimmer_particles = + { + Prototype = Particles_Glimmer(), + R = 255, + G = 200, + B = 200 + }; + + effect.sparks = + { + Prototype = Particles_Spark(), + Size = PV_Random(1, 3), + R = 255, + G = PV_Random(180, 220), + B = PV_Random(180, 220) + }; +} + +func FxGemHealingTimer(target, effect, effect_time) +{ + if(target->GetEnergy() >= target->GetMaxEnergy()) + { + if(effect_time < 36) return 0; + return -1; + } + + target->DoEnergy(500, true); + + target->CreateParticle("Magic", PV_Random(-5, +5), PV_Random(-8, 8), PV_Random(-1, 1), PV_Random(-10, -5), PV_Random(10, 20), effect.glimmer_particles, 3); + if(!Random(10)) effect.switcher = !effect.switcher; + if(effect.switcher) + target->CreateParticle("MagicSpark", PV_Random(-3, 3), PV_Random(0, 8), PV_Random(-1, 1), PV_Random(-2, -1), PV_Random(20, 30), effect.sparks, 2); +} + +func FxGemHealingDamage(target, effect, damage, cause) +{ + if(damage >= 0) return damage; + RemoveEffect(nil, target, effect); + + // can actually block one source of damage - use wisely + return 0; +} diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/StringTblDE.txt b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/StringTblDE.txt rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/StringTblUS.txt b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/StringTblUS.txt rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/authors.txt b/planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/authors.txt rename to planet/Arena.ocf/Hideout.ocs/LifeGem.ocd/authors.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Map.bmp b/planet/Arena.ocf/Hideout.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Map.bmp rename to planet/Arena.ocf/Hideout.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ametyst.jpg b/planet/Arena.ocf/Hideout.ocs/Material.ocg/Ametyst.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ametyst.jpg rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/Ametyst.jpg diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ametyst.ocm b/planet/Arena.ocf/Hideout.ocs/Material.ocg/Ametyst.ocm similarity index 93% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ametyst.ocm rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/Ametyst.ocm index 6bfdc53f0..5c618534a 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ametyst.ocm +++ b/planet/Arena.ocf/Hideout.ocs/Material.ocg/Ametyst.ocm @@ -1,7 +1,7 @@ [Material] Name=Ametyst Shape=Rough -Density=50 +Density=70 Friction=15 BlastFree=1 Blast2Object=Ice diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ruby.jpg b/planet/Arena.ocf/Hideout.ocs/Material.ocg/Ruby.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ruby.jpg rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/Ruby.jpg diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ruby.ocm b/planet/Arena.ocf/Hideout.ocs/Material.ocg/Ruby.ocm similarity index 92% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ruby.ocm rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/Ruby.ocm index 777a001f4..efa9f8c9d 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/Ruby.ocm +++ b/planet/Arena.ocf/Hideout.ocs/Material.ocg/Ruby.ocm @@ -1,7 +1,7 @@ [Material] Name=Ruby Shape=Rough -Density=50 +Density=70 Friction=15 BlastFree=1 Blast2Object=Ice diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/TEXMAP.TXT b/planet/Arena.ocf/Hideout.ocs/Material.ocg/TEXMAP.TXT similarity index 97% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/TEXMAP.TXT rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/TEXMAP.TXT index 8848a3f8f..22b499c87 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/TEXMAP.TXT +++ b/planet/Arena.ocf/Hideout.ocs/Material.ocg/TEXMAP.TXT @@ -40,7 +40,7 @@ OverloadTextures 51=Rock-rock_cracked 52=Rock-rock -53=Sulphur-sulphur +53=Firestone-firestone 54=Coal-coal diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/tunnelAmethyst.jpg b/planet/Arena.ocf/Hideout.ocs/Material.ocg/tunnelAmethyst.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/tunnelAmethyst.jpg rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/tunnelAmethyst.jpg diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/tunnelRuby.jpg b/planet/Arena.ocf/Hideout.ocs/Material.ocg/tunnelRuby.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Material.ocg/tunnelRuby.jpg rename to planet/Arena.ocf/Hideout.ocs/Material.ocg/tunnelRuby.jpg diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/DefCore.txt b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/DefCore.txt similarity index 86% rename from planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/DefCore.txt rename to planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/DefCore.txt index d9c34da5e..320faecee 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/DefCore.txt +++ b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/DefCore.txt @@ -11,9 +11,7 @@ VertexY=0,-4,0,4 VertexFriction=70,70,70,70 Value=5 Mass=10 -Components=Sulphur=1 Rotate=1 Projectile=1 Fragile=1 -Explosive=1 diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/Graphics.8.png b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/Graphics.8.png rename to planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/GraphicsE.8.png b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/GraphicsE.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/GraphicsE.8.png rename to planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/GraphicsE.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/Script.c similarity index 74% rename from planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/Script.c rename to planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/Script.c index f97c14b54..dc7837a90 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/Script.c @@ -52,6 +52,23 @@ global func FxGemPyreStart(object target, effect, int temporary, c, e, owner,thr effect.thrower=thrower; effect.owner=owner; effect.objects=[]; + + effect.particles = + { + Prototype = Particles_Air(), + Size = PV_Linear(2, 0), + R = PV_Random(120, 140), + G = PV_Random(20, 30), + G = PV_Random(90, 110), + BlitMode = GFX_BLIT_Additive + }; + + if (e) + { + effect.particles.R = PV_Random(190, 200); + effect.particles.G = 0; + effect.particles.B = PV_Random(20, 40); + } } global func FxGemPyreTimer(object target, effect, int time) { @@ -68,8 +85,9 @@ global func FxGemPyreTimer(object target, effect, int time) if(!PathFree(x,y,x + Sin(r,d), y - Cos(r,d))) continue; var clr=RGB(122+Random(20),18+Random(10),90+Random(20)); if(e)clr=RGB(190+Random(10),0,20+Random(20)); - if(Random(2))CreateParticle("AirIntake", x + Sin(r,d), y - Cos(r,d),RandomX(-5,5),RandomX(-5,-10),BoundBy((30-time),1,25)*2 + 10 + Random(10),clr); - else CreateParticle("Magic", x + Sin(r,d), y - Cos(r,d),0,0,BoundBy((40-time),1,25) + 5 + Random(10),clr); + var xoff = Sin(r, d); + var yoff = -Cos(r, d); + CreateParticle("Air", x + xoff, y + yoff, PV_Random(xoff - 3, xoff + 3), PV_Random(yoff - 3, yoff + 3), PV_Random(5, 10), effect.particles, 2); } for(var obj in FindObjects(Find_NoContainer(), Find_OCF(OCF_Alive), Find_Distance(((time/2)+1)*6,x,y),Find_Not(Find_Distance((time/2)*4,x,y)),Find_ID(Clonk))) @@ -81,8 +99,7 @@ global func FxGemPyreTimer(object target, effect, int time) if(PathFree(x,y,obj->GetX(),obj->GetY())) { obj->DoEnergy((-BoundBy((30-time),1,26)*3)/5,0,0,effect.thrower); - obj->CastParticles("MagicFire",20 + (BoundBy((30-time),1,26)*2),(BoundBy((30-time),6,26)*2),0,0,26,50,clr,clr); - obj->CastParticles("Air",10 + BoundBy((30-time),1,26),10,0,0,16,30,clr,clr); + obj->CreateParticle("MagicFire", 0, 0, PV_Random(-15, 15), PV_Random(-15, 15), PV_Random(5, 10), effect.particles, 20); obj->Fling(RandomX(-2,2),-2-(BoundBy((30-time),10,30)/10)); effect.objects[GetLength(effect.objects)] = obj; } diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/StringTblDE.txt b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/StringTblDE.txt rename to planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/StringTblUS.txt b/planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/PyreGem.ocd/StringTblUS.txt rename to planet/Arena.ocf/Hideout.ocs/PyreGem.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Scenario.txt b/planet/Arena.ocf/Hideout.ocs/Scenario.txt similarity index 95% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Scenario.txt rename to planet/Arena.ocf/Hideout.ocs/Scenario.txt index 03aa06f37..894a99de4 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Scenario.txt +++ b/planet/Arena.ocf/Hideout.ocs/Scenario.txt @@ -3,7 +3,7 @@ Icon=13 Title=Hideout Version=5,2,0,1 MinPlayer=2 -MaxPlayer=8 +Difficulty=90 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Script.c b/planet/Arena.ocf/Hideout.ocs/Script.c similarity index 78% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Script.c rename to planet/Arena.ocf/Hideout.ocs/Script.c index 8577778d8..c236705c3 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/Script.c @@ -14,52 +14,67 @@ protected func Initialize() // Goal: Capture the flag, with bases in both hideouts. var goal = CreateObject(Goal_CaptureTheFlag, 0, 0, NO_OWNER); - goal->SetFlagBase(1, 120, 504); - goal->SetFlagBase(2, LandscapeWidth() - 120, 504); + goal->SetFlagBase(1, 120, 506); + goal->SetFlagBase(2, LandscapeWidth() - 120, 506); // Rules CreateObject(Rule_Restart); CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); + + var lwidth = LandscapeWidth(); // Doors and spinwheels. var gate, wheel; - gate = CreateObject(StoneDoor, 365, 448, NO_OWNER); + gate = CreateObject(StoneDoor, 364, 448, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", 360, 446, 360, 448, 368, 448, 368, 446); gate->DoDamage(50); // Upper doors are easier to destroy gate->SetAutoControl(1); - gate = CreateObject(StoneDoor, 341, 584, NO_OWNER); + gate = CreateObject(StoneDoor, 340, 584, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", 336, 582, 336, 584, 344, 584, 344, 582); gate->SetAutoControl(1); - gate = CreateObject(StoneDoor, 693, 544, NO_OWNER); + gate = CreateObject(StoneDoor, 692, 544, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", 688, 542, 688, 544, 696, 544, 696, 542); gate->DoDamage(80); // Middle doors even easier wheel = CreateObject(SpinWheel, 660, 552, NO_OWNER); wheel->SetStoneDoor(gate); - gate = CreateObject(StoneDoor, LandscapeWidth() - 364, 448, NO_OWNER); + gate = CreateObject(StoneDoor, lwidth - 364, 448, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", lwidth - 361, 446, lwidth - 361, 448, lwidth - 365, 448, lwidth - 365, 446); gate->DoDamage(50); // Upper doors are easier to destroy gate->SetAutoControl(2); - gate = CreateObject(StoneDoor, LandscapeWidth() - 340, 584, NO_OWNER); + gate = CreateObject(StoneDoor, lwidth - 340, 584, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", lwidth - 337, 582, lwidth - 337, 584, lwidth - 345, 584, lwidth - 345, 582); gate->SetAutoControl(2); - gate = CreateObject(StoneDoor, LandscapeWidth() - 692, 544, NO_OWNER); + gate = CreateObject(StoneDoor, lwidth - 692, 544, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", lwidth - 689, 542, lwidth - 689, 544, lwidth - 697, 544, lwidth - 697, 542); gate->DoDamage(80); // Middle doors even easier - wheel = CreateObject(SpinWheel, LandscapeWidth() - 660, 552, NO_OWNER); + wheel = CreateObject(SpinWheel, lwidth - 660, 552, NO_OWNER); wheel->SetStoneDoor(gate); // Chests with weapons. var chest; chest = CreateObject(Chest, 110, 592, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 6 * 36,nil,nil,true); chest = CreateObject(Chest, 25, 464, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 6 * 36,nil,nil,false); chest = CreateObject(Chest, 730, 408, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillOtherChest", chest, 100, 6 * 36); - chest = CreateObject(Chest, LandscapeWidth() - 110, 592, NO_OWNER); + chest = CreateObject(Chest, lwidth - 110, 592, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 6 * 36,nil,nil,true); - chest = CreateObject(Chest, LandscapeWidth() - 25, 464, NO_OWNER); + chest = CreateObject(Chest, lwidth - 25, 464, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillBaseChest", chest, 100, 6 * 36,nil,nil,false); - chest = CreateObject(Chest, LandscapeWidth() - 730, 408, NO_OWNER); + chest = CreateObject(Chest, lwidth - 730, 408, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillOtherChest", chest, 100, 6 * 36); - - chest = CreateObject(Chest, LandscapeWidth()/2, 512, NO_OWNER); + chest = CreateObject(Chest, lwidth/2, 512, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillSpecialChest", chest, 100, 4 * 36); /* @@ -70,7 +85,7 @@ protected func Initialize() cannon->SetDir(DIR_Right); cannon->SetR(15); cannon->CreateContents(PowderKeg); - cannon = CreateObject(Cannon, LandscapeWidth() - 429, 444, NO_OWNER); + cannon = CreateObject(Cannon, lwidth - 429, 444, NO_OWNER); cannon->SetDir(DIR_Left); cannon->SetR(-15); cannon->CreateContents(PowderKeg); @@ -190,11 +205,6 @@ global func FxFillSpecialChestTimer(object target) for(var i=0; i < GetLength(w_list); i++) if (FindObject(Find_ID(w_list[i]))) return 1; target->CreateChestContents(w_list[r]); - - var clr = RGB(0,255,0); - if (r == 1) clr = RGB(255,0,0); - if (r == 2) clr = RGB(255,128,0); - CastParticles("AnouncingFire",75,60,target->GetX(),target->GetY(),100,150,clr); return 1; } diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/DefCore.txt b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/DefCore.txt similarity index 86% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/DefCore.txt rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/DefCore.txt index cf058732c..c826406dc 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/DefCore.txt +++ b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/DefCore.txt @@ -11,9 +11,7 @@ VertexY=0,-4,0,4 VertexFriction=70,70,70,70 Value=5 Mass=10 -Components=Sulphur=1 Rotate=1 Projectile=1 Fragile=1 -Explosive=1 diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/Graphics.8.png b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/Graphics.8.png rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/GraphicsE.8.png b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/GraphicsE.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/GraphicsE.8.png rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/GraphicsE.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/Script.c similarity index 68% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/Script.c rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/Script.c index 1b451952e..3d4666ce3 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/Script.c @@ -45,7 +45,22 @@ global func FxGemShieldCreationStart(object target, effect, int temporary, x, y, return 1; effect.x=x; effect.var1=y; - effect.var2=e; + effect.var2=e; + + effect.particles = + { + Prototype = Particles_Spark(), + R = PV_Random(120, 140), + G = PV_Random(20, 30), + B = PV_Random(90, 110) + }; + + if (e) + { + effect.particles.R = PV_Random(190, 200); + effect.particles.G = 0; + effect.particles.B = PV_Random(20, 40); + } } global func FxGemShieldCreationTimer(object target, effect, int time) { @@ -55,15 +70,16 @@ global func FxGemShieldCreationTimer(object target, effect, int time) var e=effect.var2; var clr=RGB(122+Random(20),18+Random(10),90+Random(20)); if(e)clr=RGB(190+Random(10),0,20+Random(20)); + var shield=CreateObject(CrystalShield,x+Sin(time*7,35),y+Cos(time*7,35)); shield->SetR(-time*7); shield->SetClrModulation(clr); - CastParticles("MagicSpark",10+Random(10),20,x+Sin(time*7,39),y+Cos(time*7,39),20,28,shield->GetClrModulation(),shield->GetClrModulation()); + CreateParticle("MagicSpark", x+Sin(time*7,39),y+Cos(time*7,39), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(10, 20), effect.particles, 10); + var shield=CreateObject(CrystalShield,x-Sin(-7+time*7,35),y+Cos(-7+time*7,35)); shield->SetR(-7 + time*7); shield->SetClrModulation(clr); - CastParticles("MagicSpark",10+Random(10),20,x-Sin(-7+time*7,39),y+Cos(-7+time*7,39),20,28,shield->GetClrModulation(),shield->GetClrModulation()); - + CreateParticle("MagicSpark", x-Sin(-7+time*7,39),y+Cos(-7+time*7,39), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(10, 20), effect.particles, 10); return 1; } diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/DefCore.txt b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/DefCore.txt rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Graphics.png b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Graphics.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Graphics.png rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Graphics.png diff --git a/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Script.c new file mode 100644 index 000000000..f6cde819a --- /dev/null +++ b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Script.c @@ -0,0 +1,38 @@ +/*-- CrystalShield --*/ + + +protected func Initialize() +{ + AddEffect("Selfdestruction",this,100,4+Random(2),this,this->GetID()); + return; +} + +func SetClrModulation(int color, int overlay_id) +{ + inherited(color, overlay_id, ...); + var effect = GetEffect("Selfdestruction", this); + if (effect) + { + effect.particles.R = (color >> 16) & 0xff; + effect.particles.G = (color >> 8) & 0xff; + effect.particles.B = (color >> 0) & 0xff; + } +} + +func FxSelfdestructionStart(target, effect, temp) +{ + if (temp) return; + effect.particles = + { + Prototype = Particles_Spark(), + Size = PV_Random(1, 3) + }; +} + +func FxSelfdestructionTimer(object target, effect, int timer) +{ + CreateParticle("Magic", PV_Random(-4, 4), PV_Random(-4, 4), PV_Random(-3, 3), PV_Random(-3, 3), PV_Random(10, 30), effect.particles, 3); + if(timer>175) target->RemoveObject(); + return 1; +} + diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblDE.txt b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblDE.txt rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblUS.txt b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblUS.txt rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/StringTblDE.txt b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/StringTblDE.txt rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/StringTblUS.txt b/planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/StringTblUS.txt rename to planet/Arena.ocf/Hideout.ocs/ShieldGem.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/DefCore.txt b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/DefCore.txt similarity index 86% rename from planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/DefCore.txt rename to planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/DefCore.txt index c294e0787..20b237ba9 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/DefCore.txt +++ b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/DefCore.txt @@ -11,9 +11,7 @@ VertexY=0,-4,0,4 VertexFriction=70,70,70,70 Value=5 Mass=10 -Components=Sulphur=1 Rotate=1 Projectile=1 Fragile=1 -Explosive=1 diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/Graphics.8.png b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/Graphics.8.png rename to planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/GraphicsE.8.png b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/GraphicsE.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/GraphicsE.8.png rename to planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/GraphicsE.8.png diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/Script.c similarity index 73% rename from planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/Script.c rename to planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/Script.c index db206a633..d82777bfe 100644 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/Script.c +++ b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/Script.c @@ -46,7 +46,26 @@ global func FxGemSlowFieldStart(object target, effect, int temporary, x, y, e) return 1; effect.x=x; effect.var1=y; - effect.var2=e; + effect.var2=e; + + effect.particles = + { + Prototype = Particles_Spark(), + Size = PV_Linear(3, 0), + ForceY = PV_Gravity(-40), + R = PV_Random(120, 140), + G = PV_Random(20, 30), + B = PV_Random(90, 110), + OnCollision = PC_Die(), + CollisionVertex = 1000 + }; + + if (e) + { + effect.particles.R = PV_Random(190, 210); + effect.particles.G = 0; + effect.particles.B = PV_Random(20, 40); + } } global func FxGemSlowFieldTimer(object target, effect, int time) { @@ -59,10 +78,7 @@ global func FxGemSlowFieldTimer(object target, effect, int time) var r=Random(360); var d=Min(Random(20)+Random(130),62); if(!PathFree(x,y,x + Sin(r,d), y - Cos(r,d))) continue; - var clr=RGB(122+Random(20),18+Random(10),90+Random(20)); - if(e)clr=RGB(190+Random(10),0,20+Random(20)); - if(Random(2))CreateParticle("MagicSpark", x + Sin(r,d), y - Cos(r,d),0,0,10+Random(12),clr); - else CreateParticle("Magic", x + Sin(r,d), y - Cos(r,d),0,0,10+Random(6),clr); + CreateParticle("MagicFire", x + Sin(r,d), y - Cos(r,d), PV_Random(-2, 2), PV_Random(0, 4), PV_Random(10, 40), effect.particles, 2); } for(var obj in FindObjects(Find_Distance(62,x,y))) { diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/StringTblDE.txt b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/StringTblDE.txt rename to planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/StringTblUS.txt b/planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/SlowGem.ocd/StringTblUS.txt rename to planet/Arena.ocf/Hideout.ocs/SlowGem.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/StringTblDE.txt b/planet/Arena.ocf/Hideout.ocs/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/StringTblDE.txt rename to planet/Arena.ocf/Hideout.ocs/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/StringTblUS.txt b/planet/Arena.ocf/Hideout.ocs/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/StringTblUS.txt rename to planet/Arena.ocf/Hideout.ocs/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/Script.c b/planet/Arena.ocf/Hideout.ocs/System.ocg/Flag.c similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/Script.c rename to planet/Arena.ocf/Hideout.ocs/System.ocg/Flag.c diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/System.ocg/PowderKeg.c b/planet/Arena.ocf/Hideout.ocs/System.ocg/PowderKeg.c similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/System.ocg/PowderKeg.c rename to planet/Arena.ocf/Hideout.ocs/System.ocg/PowderKeg.c diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/System.ocg/UnUseableRopeLadders.c b/planet/Arena.ocf/Hideout.ocs/System.ocg/UnUseableRopeLadders.c similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/System.ocg/UnUseableRopeLadders.c rename to planet/Arena.ocf/Hideout.ocs/System.ocg/UnUseableRopeLadders.c diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Teams.txt b/planet/Arena.ocf/Hideout.ocs/Teams.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Teams.txt rename to planet/Arena.ocf/Hideout.ocs/Teams.txt diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Title.txt b/planet/Arena.ocf/Hideout.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Hideout.ocs/Title.txt rename to planet/Arena.ocf/Hideout.ocs/Title.txt diff --git a/planet/Arena.ocf/HotIce.ocs/DescDE.rtf b/planet/Arena.ocf/HotIce.ocs/DescDE.rtf new file mode 100644 index 000000000..d54cedbbd Binary files /dev/null and b/planet/Arena.ocf/HotIce.ocs/DescDE.rtf differ diff --git a/planet/Arena.ocf/HotIce.ocs/DescUS.rtf b/planet/Arena.ocf/HotIce.ocs/DescUS.rtf new file mode 100644 index 000000000..f5f3dd84c Binary files /dev/null and b/planet/Arena.ocf/HotIce.ocs/DescUS.rtf differ diff --git a/planet/Arena.ocf/HotIce.ocs/Landscape.txt b/planet/Arena.ocf/HotIce.ocs/Landscape.txt new file mode 100644 index 000000000..5caab56bc --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Landscape.txt @@ -0,0 +1,31 @@ +/* Hot ice */ + +overlay Ice { + mat=Ice; tex=ice2; + overlay { + algo=rndchecker; a=0; + zoomX=-100; zoomY=-100; + turbulence=100; lambda=3; + mat=Ice; tex=ice3; + }; +}; + +map HotIce { + overlay { algo=sin; ox=21; oy=65; zoomX=-100; zoomY=-100; invert=1; turbulence=10; } & + Ice { algo=poly; + point {x=12%; y=58%; }; + point {x=88%; y=58%; }; + point {x=70%; y=68%; }; + point {x=30%; y=68%; }; + }; + + overlay { algo=random; a=50; } & + Ice { algo=poly; + point {x=30%; y=5%; }; + point {x=70%; y=5%; }; + point {x=88%; y=50%; }; + point {x=12%; y=50%; }; + }; + + overlay { mat=DuroLava; tex=lava_red; y=80; sub=0; }; +}; diff --git a/planet/Arena.ocf/HotIce.ocs/Material.ocg/Ice.ocm b/planet/Arena.ocf/HotIce.ocs/Material.ocg/Ice.ocm new file mode 100644 index 000000000..fe4ee5b97 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Material.ocg/Ice.ocm @@ -0,0 +1,20 @@ +[Material] +Name=Ice +Shape=TopFlat +Density=60 +Friction=15 +DigFree=1 +BlastFree=1 +Blast2Object=Ice +Dig2Object=Ice +Dig2ObjectRatio=200 +Blast2ObjectRatio=220 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +TempConvStrength=3 +AboveTempConvert=10 +AboveTempConvertDir=1 +AboveTempConvertTo=Water +Placement=21 +TextureOverlay=ice3 diff --git a/planet/Tests.ocf/Materials.ocs/Material.ocg/TEXMAP.TXT b/planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT similarity index 54% rename from planet/Tests.ocf/Materials.ocs/Material.ocg/TEXMAP.TXT rename to planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT index 58a404087..5387973f1 100644 --- a/planet/Tests.ocf/Materials.ocs/Material.ocg/TEXMAP.TXT +++ b/planet/Arena.ocf/HotIce.ocs/Material.ocg/TEXMAP.TXT @@ -1,48 +1,72 @@ -# Automatically generated texture map -# Contains material-texture-combinations added at runtime -# Import materials from global file as well OverloadMaterials -# Import textures from global file as well OverloadTextures -1=SandDry-sand_rough -2=Vehicle-Smooth -3=BigRock-BigRock +# Static Map Material/Texture Table +# Index +128 for underground materials 10=Tunnel-tunnel 11=Tunnel-tunnel 12=Tunnel-brickback 13=BrickSoft-brick1 19=DuroLava-lava_red -20=Water-water +20=Water-water1-water2-water3-water1-water3-water2 +#21=Oil-Liquid 22=Acid-acid 23=Lava-lava_red 24=DuroLava-lava_red 25=Water-water +#26=Oil-Smooth 27=Acid-acid 28=Lava-lava_red 29=Earth-earth_dry 30=Earth-earth_rough -31=Earth-earth -32=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes +#34=Ashes-Rough +#35=Ashes-Ridge + 36=Ore-ore 37=Ore-ore 38=Ore-ore + 40=Granite-granite 41=Granite-granite 42=Granite-rock + 45=Gold-gold + 50=Rock-rock 51=Rock-rock_cracked 52=Rock-rock -53=Sulphur-sulphur + +53=Firestone-firestone + 54=Coal-coal + 55=Sand-sand_rough +56=Sand-sand_smooth +#57=Sand-Smooth3 + + + +#59=FlyAshes-Smooth + +#60=Crystal-Flare +#61=Crystal-Structure +#62=Crystal-Structure2 + 65=Ice-ice2 66=Ice-ice2 67=Ice-ice3 68=Ice-ice3 + 70=Snow-snow1 71=Snow-snow1 72=Snow-snow1 73=Brick-brick1 -74=BigRock-BigRock + +#80=FlySand-Smooth2 +#81=FlySand-Smooth3 +#82=FlySand-Smooth + + diff --git a/planet/Arena.ocf/HotIce.ocs/Scenario.txt b/planet/Arena.ocf/HotIce.ocs/Scenario.txt new file mode 100644 index 000000000..d4b640989 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Scenario.txt @@ -0,0 +1,20 @@ +[Head] +Title=HotIce +Version=5,3,2 +MinPlayer=2 +MaxPlayer=20 +Icon=21 + +[Game] +Goals=Goal_Melee=1; +Rules=Rule_KillLogs=1;Rule_Gravestones=1; + +[Landscape] +MapWidth=20 +MapHeight=20 +TopOpen=1 +BottomOpen=1 +MapZoom=18,0,0,18 + +[Weather] +Climate=0 diff --git a/planet/Arena.ocf/HotIce.ocs/Script.c b/planet/Arena.ocf/HotIce.ocs/Script.c new file mode 100644 index 000000000..1b4b29918 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Script.c @@ -0,0 +1,48 @@ +/* Hot ice */ + +func Initialize() +{ + // Materials: Chests + var i,pos; + var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight(); + for (i=0; i<6; ++i) + if (pos=FindLocation(Loc_InRect(0,0,ls_wdt,ls_hgt/2-100), Loc_Wall(CNAT_Bottom))) // Loc_Wall adds us 100 pixels... + { + var chest = CreateObject(Chest,pos.x,pos.y); + if (chest) + { + chest->CreateContents(Firestone,5); + chest->CreateContents(Bread,2); + var bonus = [[Bow,Arrow],[Shield,Sword]][Random(2)]; + for (var obj in bonus) chest->CreateContents(obj); + } + } + // Materials: Firestones + for (i=0; i<30; ++i) + if (pos=FindLocation(Loc_InRect(0,0,ls_wdt,ls_hgt/2), Loc_Solid())) + if (GBackSolid(pos.x,pos.y-1)) + CreateObject(Firestone,pos.x,pos.y-1); + // Some firestones in lower half + for (i=0; i<30; ++i) + if (pos=FindLocation(Loc_InRect(0,ls_hgt/2,ls_wdt,ls_hgt/3), Loc_Solid())) + if (GBackSolid(pos.x,pos.y-1)) + CreateObject(Firestone,pos.x,pos.y-1); + return true; +} + +func InitializePlayer(int plr) +{ + // player positioning + var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight(); + var crew = GetCrew(plr); + var start_pos = FindLocation(Loc_InRect(ls_wdt/5,ls_hgt/2,ls_wdt*3/5,ls_hgt/3), Loc_Wall(CNAT_Bottom), Loc_Space(20), Loc_Space(20,true)); + if (!start_pos) start_pos = {x=Random(ls_wdt*6/10)+ls_wdt*2/10, y=ls_hgt*58/100}; + crew->SetPosition(start_pos.x, start_pos.y-10); + // initial material + crew->CreateContents(Shovel); + crew->CreateContents(Club); + crew->CreateContents(Firestone); + crew.MaxEnergy = 120000; + crew->DoEnergy(1000); + return true; +} diff --git a/planet/Arena.ocf/HotIce.ocs/Title.txt b/planet/Arena.ocf/HotIce.ocs/Title.txt new file mode 100644 index 000000000..5ff0d0686 --- /dev/null +++ b/planet/Arena.ocf/HotIce.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Heißes Eis +US:Hot ice \ No newline at end of file diff --git a/planet/Arena.ocf/MoltenMonarch.ocs/DescDE.rtf b/planet/Arena.ocf/MoltenMonarch.ocs/DescDE.rtf new file mode 100644 index 000000000..3f7b614b7 --- /dev/null +++ b/planet/Arena.ocf/MoltenMonarch.ocs/DescDE.rtf @@ -0,0 +1,35 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\froman\fprq0\fcharset128 Times New Roman;}{\f6\fnil\fprq2\fcharset128 Droid Sans;}{\f7\fnil\fprq2\fcharset128 Lohit Hindi;}{\f8\fnil\fprq0\fcharset128 Lohit Hindi;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\hich\af6\dbch\af7\afs28\loch\f4\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af8 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3500}}\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b\rtlch \ltrch\loch\fs20\lang1043\loch\f5 +Geschmolzener Monarch} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch\lang1043 +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +Erlange die Herrschaft im inneren des Vulkans und erringe die meisten Punkte.} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch\lang1043 +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +Ziel: King of the Hill (nur der K\uc2 \u246\'c3\'b6nig bekommt Punkte f\u252\'c3\'bcr Kills oder andere Spieler f\u252\'c3\'bcr einen K\u246\'c3\'b6nigsmord)\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch\lang1043 +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +- Erlange die Herrschaft \uc2 \u252\'c3\'bcber diese Monarchie zur\u252\'c3\'bcck, indem zu 6 Punkte erreichst.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +- Du wirst der K\uc2 \u246\'c3\'b6nig, indem du entweder den Kreis aus Sternen erreichst oder dern momentanen K\u246\'c3\'b6nig t\u246\'c3\'b6test.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +- Als K\uc2 \u246\'c3\'b6nig werden deine Waffen aufgewertet, was dich noch st\u228\'c3\'a4rker macht.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +- Punkte sammelst du, indem du den K\uc2 \u246\'c3\'b6nig t\u246\'c3\'b6test, oder als K\u246\'c3\'b6nig andere t\u246\'c3\'b6test.\uc1 } +\par } \ No newline at end of file diff --git a/planet/Arena.ocf/MoltenMonarch.ocs/DescUS.rtf b/planet/Arena.ocf/MoltenMonarch.ocs/DescUS.rtf new file mode 100644 index 000000000..d391bdad1 Binary files /dev/null and b/planet/Arena.ocf/MoltenMonarch.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/DefCore.txt b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/DefCore.txt rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Graphics.mesh b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Graphics.mesh similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Graphics.mesh rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Graphics.mesh diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingClub.png b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingClub.png similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingClub.png rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingClub.png diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingSword2.png b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingSword2.png similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingSword2.png rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/KingSword2.png diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingjavelin.png b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingjavelin.png similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingjavelin.png rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingjavelin.png diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingmusket.png b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingmusket.png similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingmusket.png rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Kingmusket.png diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Musket.skeleton b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Musket.skeleton similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Musket.skeleton rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Musket.skeleton diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Scene.material b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Scene.material rename to planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Scene.material diff --git a/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Script.c b/planet/Arena.ocf/MoltenMonarch.ocs/KingsWeapons.ocd/Script.c new file mode 100644 index 000000000..e69de29bb diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Map.bmp b/planet/Arena.ocf/MoltenMonarch.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Map.bmp rename to planet/Arena.ocf/MoltenMonarch.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Scenario.txt b/planet/Arena.ocf/MoltenMonarch.ocs/Scenario.txt similarity index 95% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Scenario.txt rename to planet/Arena.ocf/MoltenMonarch.ocs/Scenario.txt index 63d29000b..cd9be1b54 100644 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Scenario.txt +++ b/planet/Arena.ocf/MoltenMonarch.ocs/Scenario.txt @@ -3,7 +3,7 @@ Title=MoltenMonarch Version=5,2,0,1 Icon=23 MinPlayer=2 -MaxPlayer=8 +Difficulty=70 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Script.c b/planet/Arena.ocf/MoltenMonarch.ocs/Script.c similarity index 74% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Script.c rename to planet/Arena.ocf/MoltenMonarch.ocs/Script.c index 2baeee4ae..559b4107e 100644 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Script.c +++ b/planet/Arena.ocf/MoltenMonarch.ocs/Script.c @@ -17,17 +17,18 @@ protected func Initialize() // Objects fade after 7 seconds. CreateObject(Rule_ObjectFade)->DoFadeTime(7 * 36); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); //make lava collapse CreateObject(Firestone,625,480); // Chests with weapons. - CreateObject(Chest, 320, 80, NO_OWNER); - CreateObject(Chest, 720, 192, NO_OWNER); - CreateObject(Chest, 668, 336, NO_OWNER); - CreateObject(Chest, 320, 440, NO_OWNER); - CreateObject(Chest, 48, 256, NO_OWNER); - AddEffect("IntFillChests", nil, 100, 5 * 36, this); + CreateObject(Chest, 320, 80, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 720, 192, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 668, 336, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 320, 440, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 48, 256, NO_OWNER)->MakeInvincible(); + AddEffect("IntFillChests", nil, 100, 5 * 36); // Moving bricks. var brick; @@ -49,26 +50,17 @@ protected func Initialize() AddEffect("LavaBrickReset", brick, 100, 10); AddEffect("DeathByFire",nil,100,2,nil); - AddEffect("RemoveCorpses",nil,100,2,nil); return; } - -global func FxRemoveCorpsesTimer() +global func FxBlessTheKingStart(target, effect, temp) { - //uber effect abuse - - for(var dead in FindObjects(Find_ID(Clonk),Find_Not(Find_OCF(OCF_Alive)))) + if (temp) return; + effect.particles = { - CastParticles("MagicFire",100,50,dead->GetX(),dead->GetY(),50+Random(30)); - CastParticles("MagicFire",50,30,dead->GetX(),dead->GetY(),70+Random(60)); - dead->RemoveObject(); - } - for(var burning in FindObjects(Find_ID(Clonk),Find_OCF(OCF_OnFire))) - { - burning->DoEnergy(-3); //lava hurts a lot - } - + Prototype = Particles_Fire(), + Attach = ATTACH_Back + }; } global func FxBlessTheKingTimer(object target, effect, int timer) @@ -81,26 +73,24 @@ global func FxBlessTheKingTimer(object target, effect, int timer) if(king->Contents(0)) king->Contents(0)->~MakeKingSize(); if(king->Contents(1)) king->Contents(1)->~MakeKingSize(); - for(var i=0; i<25; i++) - CreateParticle("MagicFire",king->GetX()+RandomX(-3,3),king->GetY()+RandomX(-11,8),RandomX(-6,6),RandomX(-10,3),Random(30),RGBa(255,255-Random(50),255-Random(160),20+Random(160))); - for(; i<45; i++) - CreateParticle("MagicFire2",king->GetX()+RandomX(-4,4),king->GetY()+RandomX(-7,8),RandomX(-6,6),RandomX(-10,3),30+Random(30),RGBa(255,255-Random(100),255-Random(100),10+Random(20))); + king->CreateParticle("Fire", PV_Random(-4, 4), PV_Random(-11, 8), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(10, 30), effect.particles, 10); return 1; } global func FxDeathByFireTimer(object target, effect, int timer) { + for(var burning in FindObjects(Find_ID(Clonk),Find_OCF(OCF_OnFire))) + { + burning->DoEnergy(-3); //lava hurts a lot + } + for(var obj in FindObjects(Find_InRect(55,0,50,70),Find_OCF(OCF_Alive))) obj->~Kill(); for(var obj in FindObjects(Find_InRect(55,0,50,30),Find_OCF(OCF_Alive),Find_Not(Find_ID(MovingBrick)))) obj->RemoveObject(); - for(var i=0; i<20; i++) - { - CreateParticle("MagicFire",50+Random(60),Random(60),RandomX(-3,3),RandomX(-1,10)+ Random(3)*10,150+Random(50),HSLa(-30+Random(60),200+Random(50),255,128+Random(100))); - CreateParticle("MagicFire",50+Random(60),Random(30),RandomX(-3,3),Random(60),150+Random(50),HSLa(-30+Random(60),200+Random(50),255,128+Random(100))); - } + CreateParticle("Fire", PV_Random(55, 90), PV_Random(0, 40), PV_Random(-1, 1), PV_Random(0, 20), PV_Random(10, 40), Particles_Fire(), 20); } global func FxLavaBrickResetTimer(object target, effect, int timer) diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/CheatArrow.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/CheatArrow.c similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/CheatArrow.c rename to planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/CheatArrow.c diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Bow.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Bow.c similarity index 90% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Bow.c rename to planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Bow.c index c4d644b43..a87a26cb0 100644 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Bow.c +++ b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Bow.c @@ -37,7 +37,7 @@ public func FinishedAiming(object clonk, int angle) public func FxExplosiveArrowTimer(pTarget, effect, iEffectTime) { - CastParticles("Spark",1,20,pTarget->GetX()-GetX(),pTarget->GetY()-GetY(),8+(effect.timer/2),12+(effect.timer/2),RGB(255,200,0),RGB(255,255,150)); + pTarget->CreateParticle("Fire", 0, 0, PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(10, 20), Particles_Glimmer(), 5); effect.timer++; if(!pTarget->GetXDir() && !pTarget->GetYDir()) effect.timer = Max(effect.timer,65); if(effect.timer>90) pTarget->Explode(15+Random(7)); diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Club.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Club.c similarity index 97% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Club.c rename to planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Club.c index 6f0e8fa22..d80ebba4f 100644 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Club.c +++ b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Club.c @@ -43,7 +43,7 @@ func DoStrike(clonk, angle) obj->SetXDir((obj->GetXDir(100) + Sin(angle, speed)) / 2, div); obj->SetYDir((obj->GetYDir(100) - Cos(angle, speed)) / 2, div); } - AddEffect(en, obj, 1, 15, 0); + AddEffect(en, obj, 1, 15, nil); found=true; break; } diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Javelin.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Javelin.c similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Javelin.c rename to planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Javelin.c diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Musket.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Musket.c similarity index 78% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Musket.c rename to planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Musket.c index e7ae08fcc..9415c14ee 100644 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Musket.c +++ b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Musket.c @@ -46,12 +46,10 @@ private func FireWeapon(object clonk, int angle) if(Abs(Normalize(angle,-180)) > 90) IY=Cos(180-angle,MuskDown)+MuskOffset; - for(var i=0; i<10; ++i) - { - var speed = RandomX(0,10); - var r = angle; - CreateParticle("ExploSmoke",IX,IY,+Sin(r,speed)+RandomX(-2,2),-Cos(r,speed)+RandomX(-2,2),RandomX(100,400),RGBa(255,255,255,50)); - } - CreateParticle("MuzzleFlash",IX,IY,+Sin(angle,500),-Cos(angle,500),450,RGB(255,255,255),clonk); - CreateParticle("Flash",0,0,0,0,800,RGBa(255,255,64,150)); + var x = Sin(angle, 20); + var y = -Cos(angle, 20); + CreateParticle("Smoke", IX, IY, PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), PV_Random(40, 60), Particles_Smoke(), 20); + clonk->CreateMuzzleFlash(IX, IY, angle, 20); + + CreateParticle("Flash", 0, 0, 0, 0, 8, Particles_Flash()); } diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_MusketBullet.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_MusketBullet.c similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_MusketBullet.c rename to planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_MusketBullet.c diff --git a/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Sword.c b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Sword.c new file mode 100644 index 000000000..35c1a92bc --- /dev/null +++ b/planet/Arena.ocf/MoltenMonarch.ocs/System.ocg/King_Sword.c @@ -0,0 +1,14 @@ +#appendto Sword + +local king_size; + +public func MakeKingSize() { king_size = true; SetMeshMaterial("KingSword2",0); } +public func MakeNormalSize() { king_size = false; SetMeshMaterial("Sword2",0); } +public func Departure() { MakeNormalSize(); } + +func SwordDamage(int shield) +{ + var damage = _inherited(shield, ...); + if(king_size) damage+=3000+Random(3000); + return damage; +} diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Title.txt b/planet/Arena.ocf/MoltenMonarch.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/MoltenMonarch.ocs/Title.txt rename to planet/Arena.ocf/MoltenMonarch.ocs/Title.txt diff --git a/planet/Arena.ocf/Overcast.ocs/DescDE.rtf b/planet/Arena.ocf/Overcast.ocs/DescDE.rtf new file mode 100644 index 000000000..4d9672a25 --- /dev/null +++ b/planet/Arena.ocf/Overcast.ocs/DescDE.rtf @@ -0,0 +1,26 @@ +{\rtf1\ansi\deff1\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset128 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\froman\fprq0\fcharset128 Times New Roman;}{\f6\fnil\fprq2\fcharset0 SimSun;}{\f7\fnil\fprq2\fcharset128 Lohit Hindi;}{\f8\fnil\fprq0\fcharset128 Lohit Hindi;}{\f9\fnil\fprq2\fcharset0 Mangal;}{\f10\fnil\fprq0\fcharset0 Mangal;}{\f11\fswiss\fprq2\fcharset128 Droid Sans;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s1\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\loch\fs24\lang1033\snext1 Normal;} +{\s2\sb240\sa120\keepn\rtlch\af9\afs28\lang1081\ltrch\dbch\af6\langfe1081\hich\f2\fs28\lang1033\loch\f2\fs28\lang1033\sbasedon1\snext3 Heading;} +{\s3\sa120\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\loch\fs24\lang1033\sbasedon1\snext3 Body Text;} +{\s4\sa120\rtlch\afs24\lang1081\ltrch\dbch\af8\langfe2052\hich\fs24\lang1031\loch\fs24\lang1031\sbasedon8\snext4 List;} +{\s5\sb120\sa120\rtlch\af10\afs24\lang1081\ai\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\i\loch\fs24\lang1033\i\sbasedon1\snext5 caption;} +{\s6\rtlch\af10\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\loch\fs24\lang1033\sbasedon1\snext6 Index;} +{\s7\sb240\sa120\keepn\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe2052\hich\f4\fs28\lang1031\loch\f4\fs28\lang1031\sbasedon1\snext8 Heading;} +{\s8\sa120\rtlch\af1\afs24\lang1081\ltrch\dbch\af1\langfe2052\hich\fs24\lang1031\loch\fs24\lang1031\sbasedon1\snext8 Text body;} +{\s9\sb120\sa120\rtlch\af1\afs24\lang1081\ai\ltrch\dbch\af8\langfe2052\hich\fs24\lang1031\i\loch\fs24\lang1031\i\sbasedon1\snext9 Caption;} +{\s10\rtlch\af1\afs24\lang1081\ltrch\dbch\af8\langfe2052\hich\fs24\lang1031\loch\fs24\lang1031\sbasedon1\snext10 Index;} +} +{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern3300}}\deftab720 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pard\plain \ltrpar\s1\rtlch\af11\afs24\lang1081\ab\ltrch\dbch\af7\langfe1081\hich\f5\fs20\lang1033\b\loch\f5\fs20\lang1033\b {\rtlch \ltrch\loch\f5\fs20\lang1033\i0\b Bedeckt} +\par \pard\plain \ltrpar\s1\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\loch\fs24\lang1033 +\par \pard\plain \ltrpar\s1\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\f5\fs16\lang1033\loch\f5\fs16\lang1033 {\rtlch \ltrch\loch\f5\fs16\lang1033\i0\b0 Hoch oben in den Wolken befinden sich - entgegen jeder Vernunft - schwebende Gesteinsbrocken. Mutige Forscher machten sich auf, um die dortige Gegend zu erkunden, und trafen dort auf an Schriftrollen gebundene Zauber. Getrieben von der Gier nach diesen Sch +riftrollen beginnt ein Kampf, bei dem auch selbige zu Einsatz kommen. Schau blo\u223\'3f nicht runter!} +\par \pard\plain \ltrpar\s1\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\loch\fs24\lang1033 +\par \pard\plain \ltrpar\s1\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\f5\fs16\lang1033\loch\f5\fs16\lang1033 {\rtlch \ltrch\loch\f5\fs16\lang1033\i0\b0 Ziel: Last Man Standing (Bleibe als Letzter am Leben und gewinne)} +\par \pard\plain \ltrpar\s1\rtlch\af11\afs24\lang1081\ltrch\dbch\af7\langfe1081\hich\fs24\lang1033\loch\fs24\lang1033 +\par } \ No newline at end of file diff --git a/planet/Arena.ocf/Overcast.ocs/DescUS.rtf b/planet/Arena.ocf/Overcast.ocs/DescUS.rtf new file mode 100644 index 000000000..dbe2de972 Binary files /dev/null and b/planet/Arena.ocf/Overcast.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Icon.png b/planet/Arena.ocf/Overcast.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Icon.png rename to planet/Arena.ocf/Overcast.ocs/Icon.png diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Map.bmp b/planet/Arena.ocf/Overcast.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Map.bmp rename to planet/Arena.ocf/Overcast.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scenario.txt b/planet/Arena.ocf/Overcast.ocs/Scenario.txt similarity index 96% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scenario.txt rename to planet/Arena.ocf/Overcast.ocs/Scenario.txt index 40438936f..ce718a25a 100644 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/Scenario.txt +++ b/planet/Arena.ocf/Overcast.ocs/Scenario.txt @@ -2,6 +2,7 @@ Title=Overcast Version=5,2,0,1 MinPlayer=2 +Difficulty=50 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Script.c b/planet/Arena.ocf/Overcast.ocs/Script.c similarity index 90% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Script.c rename to planet/Arena.ocf/Overcast.ocs/Script.c index b9598f09c..2468dcdfa 100644 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Script.c @@ -6,12 +6,14 @@ --*/ +static Overcast_air_particles; protected func Initialize() { // Goal. CreateObject(Goal_LastManStanding); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); //Enviroment. Cloud->Place(25); @@ -99,18 +101,25 @@ protected func Initialize() // Chests with weapons. var chest; chest = CreateObject(Chest, 764, 128, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); chest = CreateObject(Chest, 732, 336, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); chest = CreateObject(Chest, 116, 400, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); chest = CreateObject(Chest, 272, 152, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); chest = CreateObject(Chest, 424, 480, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); chest = CreateObject(Chest, 872, 520, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); chest = CreateObject(Chest, 72, 208, NO_OWNER); + chest->MakeInvincible(); AddEffect("FillChest", chest, 100, 72); // Some columns as decoration. @@ -132,7 +141,7 @@ protected func Initialize() grass->SetR(r[i]); } - // Blue chest with jar of winds. + // Blue chest with wind bag var chest_blue = CreateObject(Chest, 850, 648, NO_OWNER); chest_blue->SetClrModulation(RGB(100,180,255)); AddEffect("FillBlueChest", chest_blue, 100, 72); @@ -144,6 +153,13 @@ protected func Initialize() // Wind channel. AddEffect("WindChannel", nil, 100, 1); + + Overcast_air_particles = + { + Prototype = Particles_Air(), + Size = PV_KeyFrames(0, 0, 0, 100, PV_Random(5, 10), 1000, 0), + OnCollision = PC_Die() + }; return; } @@ -168,7 +184,7 @@ global func FxWindChannelTimer(object target, proplist effect) continue; obj->SetYDir(speed - 36, 100); } - CreateParticle("AirIntake", 464+Random(40), 344+Random(112), RandomX(-1,1), -30, 60+Random(10), RGB(100+Random(25),128+Random(20),255)); + CreateParticle("Air", 464+Random(40), 344+Random(112), RandomX(-1,1), -30, PV_Random(10, 40), Overcast_air_particles); // Divider with random wind. if (!Random(100)) @@ -196,11 +212,11 @@ global func FxWindChannelTimer(object target, proplist effect) } } if (effect.Divider == 1) - CreateParticle("AirIntake", 464+Random(40), 280+Random(10), RandomX(-1,1), -30, 60+Random(10), RGB(100+Random(25),128+Random(20),255)); + CreateParticle("Air", 464+Random(40), 280+Random(10), RandomX(-1,1), -30, PV_Random(10, 40), Overcast_air_particles); if (effect.Divider == 0) - CreateParticle("AirIntake", 464+Random(40), 280+Random(10), RandomX(-20,-10), -20, 60+Random(10), RGB(100+Random(25),128+Random(20),255)); + CreateParticle("Air", 464+Random(40), 280+Random(10), RandomX(-20,-10), -20, PV_Random(10, 40), Overcast_air_particles); if (effect.Divider == 2) - CreateParticle("AirIntake", 464+Random(40), 280+Random(10), RandomX(10,20), -20, 60+Random(10), RGB(100+Random(25),128+Random(20),255)); + CreateParticle("Air", 464+Random(40), 280+Random(10), RandomX(10,20), -20, PV_Random(10, 40), Overcast_air_particles); // Second shaft with upward wind. for (var obj in FindObjects(Find_InRect(464, 96, 40, 144))) @@ -227,7 +243,7 @@ global func FxWindChannelTimer(object target, proplist effect) continue; obj->SetYDir(speed - 36, 100); } - CreateParticle("AirIntake", 464+Random(40), 160+Random(96), RandomX(-1,1), -30, 60+Random(10), RGB(100+Random(25),128+Random(20),255)); + CreateParticle("Air", 464+Random(40), 160+Random(96), RandomX(-1,1), -30, PV_Random(10, 40), Overcast_air_particles); return 1; } @@ -259,7 +275,7 @@ global func FxFillBlueChestStart(object target, proplist effect, int temporary) { if (temporary) return 1; - target->CreateContents(JarOfWinds); + target->CreateContents(WindBag); var w_list = [Firestone, Boompack, Balloon, FireballScroll, WindScroll]; for (var i = 0; i < 4; i++) target->CreateContents(w_list[Random(GetLength(w_list))]); @@ -274,8 +290,8 @@ global func FxFillBlueChestTimer(object target, proplist effect) if (target->ContentsCount() < 6) target->CreateContents(w_list[Random(GetLength(w_list))]); - if (!FindObject(Find_ID(JarOfWinds))) - target->CreateContents(JarOfWinds); + if (!FindObject(Find_ID(WindBag))) + target->CreateContents(WindBag); return 1; } @@ -324,7 +340,7 @@ func OnClonkLeftRelaunch(object clonk) { var pos = GetRandomSpawn(); clonk->SetPosition(pos[0],pos[1]); - CastParticles("Magic",36,12,pos[0],pos[1],30,60,clonk->GetColor(),clonk->GetColor(),clonk); + CreateParticle("Air", pos[0],pos[1], PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 10), Overcast_air_particles, 25); return; } diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c similarity index 56% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c index d32de8b6f..9faea2d5f 100644 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c @@ -8,7 +8,7 @@ public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("Fireball", 0, 100, 1, 0, GetID(), pClonk->GetOwner(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); + AddEffect("Fireball", nil, 100, 1, nil, GetID(), pClonk->GetOwner(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); Sound("Fireball"); Sound("Fireball"); RemoveObject(); @@ -50,23 +50,16 @@ public func FxFireballTimer(pTarget, effect, iEffectTime) } else if(iEffectTime < 70) { - CreateParticle("FireballSmoke",x,y,Sin(Random(360),2),Cos(Random(360),2),RandomX(120,180),RGBa(100,100,100,70)); - CreateParticle("MagicSpark",x,y,Sin(Random(360),RandomX(5,13)),Cos(Random(360),RandomX(5,13)),RandomX(30,70),RGB(255,255,255)); - - //if(!Random(10)) if(Random(2))angle++; else angle--; angle+=Sin(iEffectTime*30,18); - x+=Sin(angle, 6); - y+=-Cos(angle, 6); - effect.x=x; - effect.y=y; - for(var i=0;i<6;++i) - { - var c=HSL(Random(50), 200+Random(25), Random(100)); - var rx=RandomX(-2, 2); - var ry=RandomX(-2, 2); - CreateParticle("MagicFire", x+rx, y+ry, Sin(angle+180,6)+ry, -Cos(angle+180,6)+rx, 80+Random(20), c); - CreateParticle("MagicFire", x+rx, y+ry, Sin(angle+180,6)+ry, -Cos(angle+180,6)+rx, 20+Random(10), RGB(255,255,0)); - } + var xspeed = Sin(angle, 6); + var yspeed = -Cos(angle, 6); + + CreateParticle("SmokeDirty", x, y, PV_Random(-2, 2), PV_Random(-2, 2), PV_Random(30, 60), Particles_SmokeTrail(), 1); + CreateParticle("FireDense", x, y, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 20), Particles_Fire(), 10); + CreateParticle("Fire", x, y, PV_Random(0, - 10 * xspeed), PV_Random(0, - 10 * yspeed), PV_Random(20, 90), Particles_Glimmer(), 10); + + effect.x += xspeed; + effect.y += yspeed; } return 1; diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/DefCore.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/DefCore.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Graphics.8.png b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Script.c b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Script.c similarity index 54% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Script.c rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Script.c index dd660fecf..b5a670c72 100644 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/Script.c @@ -11,9 +11,12 @@ public func ControlUse(object clonk, int x, int y) var pos = GetRandomSpawn(); x = pos[0]; y = pos[1]; - - DrawParticleLine("Magic",0,0,-GetX()+x,-GetY()+y,3,64,RGB(0,128,255),RGB(0,200,255),-1); - DrawParticleLine("MagicFire",0,0,-GetX()+x,-GetY()+y,4,64,RGB(0,255,128),RGB(0,255,20),-1); + DrawParticleLine("Flash", 0,0,-GetX()+x,-GetY()+y, 3, 0, 0, 8, {Prototype = Particles_Flash(), Size = 20, R = 50, G = 50, B = 255}); + + // Make sure the clonk loses the attach procedure. + var action = clonk->GetAction(); + if (action && clonk.ActMap[action].Procedure == DFA_ATTACH) + clonk->SetAction("Jump"); clonk->SetPosition(x, y); clonk->SetXDir(0); clonk->SetYDir(-5); diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/TeleportScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Script.c b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Script.c similarity index 72% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Script.c rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Script.c index 7b98e9916..b08fe4ef6 100644 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Script.c +++ b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Script.c @@ -8,7 +8,7 @@ public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("WindScrollStorm", 0, 100, 1, 0, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY(), pClonk->GetOwner()); + AddEffect("WindScrollStorm", nil, 100, 1, nil, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY(), pClonk->GetOwner()); RemoveObject(); return 1; } @@ -24,7 +24,11 @@ public func FxWindScrollStormStart(pTarget, effect, iTemp, angle, x, y, owner) effect.y=y-Cos(angle,43); effect.owner=owner; - + effect.particles = + { + Prototype = Particles_Air(), + Size = PV_Random(2, 5) + }; } public func FxWindScrollStormTimer(pTarget, effect, iEffectTime) @@ -36,19 +40,14 @@ public func FxWindScrollStormTimer(pTarget, effect, iEffectTime) if(iEffectTime<36) { - var r=Random(360); - var d=Random(40); - CreateParticle("AirIntake",Sin(r,d)+x,-Cos(r,d)+y,xdir/3,ydir/3 +2,64,RGB(Random(80),100+Random(50),255)); - return 1; + var r=Random(360); + var d=Random(40); + CreateParticle("Air", Sin(r,d)+x,-Cos(r,d)+y, xdir/3, ydir/3, PV_Random(10, 30), effect.particles, 1); + return 1; } else if(iEffectTime<180 ) { - for(var i=0; i<5; i++) - { - var r=Random(360); - var d=Random(40); - CreateParticle("AirIntake",Sin(r,d)+x,-Cos(r,d)+y,xdir/2,ydir/2 +2,64,RGB(Random(80),100+Random(50),255)); - } + CreateParticle("Air", PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), xdir/2, ydir/2, PV_Random(10, 30), effect.particles, 5); for(var obj in FindObjects(Find_Distance(40,x,y),Find_Not(Find_Category(C4D_Structure)))) { diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/System.ocg/ClearBricks.c b/planet/Arena.ocf/Overcast.ocs/System.ocg/ClearBricks.c similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/System.ocg/ClearBricks.c rename to planet/Arena.ocf/Overcast.ocs/System.ocg/ClearBricks.c diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/System.ocg/LimitUse.c b/planet/Arena.ocf/Overcast.ocs/System.ocg/LimitUse.c similarity index 98% rename from planet/BackToTheRocks.ocf/Overcast.ocs/System.ocg/LimitUse.c rename to planet/Arena.ocf/Overcast.ocs/System.ocg/LimitUse.c index d7f821df9..2977bed4e 100644 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/System.ocg/LimitUse.c +++ b/planet/Arena.ocf/Overcast.ocs/System.ocg/LimitUse.c @@ -1,6 +1,6 @@ // Limits the use of an object to a certain amount. -#appendto JarOfWinds +#appendto WindBag #appendto Club local use_count; diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Title.txt b/planet/Arena.ocf/Overcast.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Title.txt rename to planet/Arena.ocf/Overcast.ocs/Title.txt diff --git a/planet/Arena.ocf/RockBottom.ocs/DescDE.rtf b/planet/Arena.ocf/RockBottom.ocs/DescDE.rtf new file mode 100644 index 000000000..9eca82b88 --- /dev/null +++ b/planet/Arena.ocf/RockBottom.ocs/DescDE.rtf @@ -0,0 +1,29 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\froman\fprq0\fcharset128 Times New Roman;}{\f6\fnil\fprq2\fcharset128 Droid Sans;}{\f7\fnil\fprq2\fcharset128 Lohit Hindi;}{\f8\fnil\fprq0\fcharset128 Lohit Hindi;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\hich\af6\dbch\af7\afs28\loch\f4\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af8 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3500}}\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b\rtlch \ltrch\loch\fs20\loch\f5 +Im Brunnen} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +Unten im Brunnen beginnt ein Gefecht.} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +Ziel: Last Man Standing (Bleibe als Letzter am Leben und gewinne)} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +- Eine winzige Arena f\uc2 \u252\'c3\'bcr zwei bis vier Spieler.\uc1 } +\par } \ No newline at end of file diff --git a/planet/Arena.ocf/RockBottom.ocs/DescUS.rtf b/planet/Arena.ocf/RockBottom.ocs/DescUS.rtf new file mode 100644 index 000000000..fe120f816 Binary files /dev/null and b/planet/Arena.ocf/RockBottom.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/Icon.png b/planet/Arena.ocf/RockBottom.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/RockBottom.ocs/Icon.png rename to planet/Arena.ocf/RockBottom.ocs/Icon.png diff --git a/planet/Arena.ocf/RockBottom.ocs/Map.bmp b/planet/Arena.ocf/RockBottom.ocs/Map.bmp new file mode 100644 index 000000000..082b894fd Binary files /dev/null and b/planet/Arena.ocf/RockBottom.ocs/Map.bmp differ diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/Scenario.txt b/planet/Arena.ocf/RockBottom.ocs/Scenario.txt similarity index 95% rename from planet/BackToTheRocks.ocf/RockBottom.ocs/Scenario.txt rename to planet/Arena.ocf/RockBottom.ocs/Scenario.txt index 3ab7b05a6..b8190f4fc 100644 --- a/planet/BackToTheRocks.ocf/RockBottom.ocs/Scenario.txt +++ b/planet/Arena.ocf/RockBottom.ocs/Scenario.txt @@ -2,7 +2,7 @@ Title=Bottom Version=5,2,0,1 MinPlayer=2 -MaxPlayer=4 +Difficulty=20 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/Script.c b/planet/Arena.ocf/RockBottom.ocs/Script.c similarity index 55% rename from planet/BackToTheRocks.ocf/RockBottom.ocs/Script.c rename to planet/Arena.ocf/RockBottom.ocs/Script.c index b64823087..f1624e355 100644 --- a/planet/BackToTheRocks.ocf/RockBottom.ocs/Script.c +++ b/planet/Arena.ocf/RockBottom.ocs/Script.c @@ -11,24 +11,55 @@ protected func Initialize() // Goal. CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); // Chests with weapons. - CreateObject(Chest, 108, 248, NO_OWNER); - AddEffect("IntFillChests", nil, 100, 3 * 36, this); + CreateObject(Chest, 108, 248, NO_OWNER)->MakeInvincible(); + AddEffect("IntFillChests", nil, 100, 3 * 36); // Objects fade after 5 seconds. CreateObject(Rule_ObjectFade)->DoFadeTime(7 * 36); + + // Some decoration trunks ranks and a waterfall. + var trunk = CreateObject(Trunk, 76, 324); + trunk->SetR(60); trunk.Plane = 510; + trunk.MeshTransformation = [-731, 0, 682, 0, 0, 1000, 0, 0, -682, 0, -731, 0]; + trunk = CreateObject(Trunk, 123, 68); + trunk->SetR(115); trunk.Plane = 510; + trunk.MeshTransformation = [469, 0, 883, 0, 0, 1000, 0, 0, -883, 0, 469, 0]; + trunk = CreateObject(Trunk, 172, 134); + trunk->SetR(-110); trunk.Plane = 510; + trunk.MeshTransformation = [-545, 0, -839, 0, 0, 1000, 0, 0, 839, 0, -545, 0]; + + var waterfall; + waterfall = CreateWaterfall(130, 53, 2, "Water"); + waterfall->SetDirection(4, 0, 3, 6); + waterfall = CreateWaterfall(144, 50, 8, "Water"); + waterfall->SetDirection(6, 0, 5, 6); + CreateLiquidDrain(100, 315, 10); + CreateLiquidDrain(130, 315, 10); + CreateLiquidDrain(160, 315, 10); + + CreateObject(Fern, 48, 114); + CreateObject(Fern, 284, 128); + CreateObject(Lorry, 294, 128)->SetR(20); + CreateObject(Pickaxe, 260, 128)->SetR(-45); + CreateObject(Mushroom, 271, 136); + + CreateObject(Rank, 146, 302)->SetR(180); + CreateObject(Rank, 198, 190)->SetR(225); + CreateObject(Rank, 54, 66)->SetR(180); + CreateObject(Rank, 42, 232)->SetR(120); + CreateObject(Rank, 269, 230)->SetR(-120); + + for (var i = 0; i < 2 + Random(6); i++) + CreateObject(Rank, 114, 10 + Random(140))->SetR(RandomX(60, 120)); + for (var i = 0; i < 2 + Random(6); i++) + CreateObject(Rank, 190, 10 + Random(140))->SetR(-RandomX(60, 120)); - //Water needs to be OK - AddEffect("Refiller",0,100,6); return; } -global func FxRefillerTimer(object pTarget, effect, int timer) -{ - for(var i=0; i<10; i++) if(!GBackLiquid(100,315)) InsertMaterial(Material("Water"),135,385); -} - // Gamecall from LastManStanding goal, on respawning. protected func OnPlayerRelaunch(int plr) { diff --git a/planet/Arena.ocf/RockBottom.ocs/System.ocg/MultipleSelection.c b/planet/Arena.ocf/RockBottom.ocs/System.ocg/MultipleSelection.c new file mode 100644 index 000000000..37b679566 --- /dev/null +++ b/planet/Arena.ocf/RockBottom.ocs/System.ocg/MultipleSelection.c @@ -0,0 +1,21 @@ +#appendto RelaunchContainer + +private func OpenWeaponMenu(object clonk) +{ + if (!menu) + { + var weapons = WeaponList(); + if(weapons) + { + menu = clonk->CreateRingMenu(this, this); + for (var weapon in weapons) + { + if(weapon == Firestone) menu->AddItem(weapon,2); + else if(weapon == Dynamite) menu->AddItem(weapon,2); + else menu->AddItem(weapon, 1); + } + menu->Show(); + menu->SetUncloseable(); + } + } +} diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/Title.txt b/planet/Arena.ocf/RockBottom.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/RockBottom.ocs/Title.txt rename to planet/Arena.ocf/RockBottom.ocs/Title.txt diff --git a/planet/Arena.ocf/Ruins.ocs/DescDE.rtf b/planet/Arena.ocf/Ruins.ocs/DescDE.rtf new file mode 100644 index 000000000..e737a01da --- /dev/null +++ b/planet/Arena.ocf/Ruins.ocs/DescDE.rtf @@ -0,0 +1,25 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\froman\fprq0\fcharset128 Times New Roman;}{\f6\fnil\fprq2\fcharset128 Droid Sans;}{\f7\fnil\fprq2\fcharset128 Lohit Hindi;}{\f8\fnil\fprq0\fcharset128 Lohit Hindi;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\hich\af6\dbch\af7\afs28\loch\f4\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af8 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3500}}\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b\rtlch \ltrch\loch\fs20\lang1031\loch\f5 +Der Kessel} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch\lang1031 +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1031\loch\f5 +Im Kessel kann keiner entkommen. Nur der beste K\uc2 \u228\'c3\'a4mpfer wird aus seinen Tiefen wieder emporsteigen.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch\lang1031 +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\lang1031\loch\f5 +Ziel: Last Man Standing (Bleibe als Letzter am Leben und gewinne)} +\par } \ No newline at end of file diff --git a/planet/Arena.ocf/Ruins.ocs/DescUS.rtf b/planet/Arena.ocf/Ruins.ocs/DescUS.rtf new file mode 100644 index 000000000..def4f6a13 Binary files /dev/null and b/planet/Arena.ocf/Ruins.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/Map.bmp b/planet/Arena.ocf/Ruins.ocs/Map.bmp similarity index 74% rename from planet/BackToTheRocks.ocf/Ruins.ocs/Map.bmp rename to planet/Arena.ocf/Ruins.ocs/Map.bmp index 1b633ecc8..c9348ea13 100644 Binary files a/planet/BackToTheRocks.ocf/Ruins.ocs/Map.bmp and b/planet/Arena.ocf/Ruins.ocs/Map.bmp differ diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/Scenario.txt b/planet/Arena.ocf/Ruins.ocs/Scenario.txt similarity index 95% rename from planet/BackToTheRocks.ocf/Ruins.ocs/Scenario.txt rename to planet/Arena.ocf/Ruins.ocs/Scenario.txt index 351bbffdf..d687542e5 100644 --- a/planet/BackToTheRocks.ocf/Ruins.ocs/Scenario.txt +++ b/planet/Arena.ocf/Ruins.ocs/Scenario.txt @@ -2,7 +2,7 @@ Title=Ruins Version=5,2,0,1 MinPlayer=2 -MaxPlayer=6 +Difficulty=30 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/Script.c b/planet/Arena.ocf/Ruins.ocs/Script.c similarity index 88% rename from planet/BackToTheRocks.ocf/Ruins.ocs/Script.c rename to planet/Arena.ocf/Ruins.ocs/Script.c index 3bca91156..5dbdba075 100644 --- a/planet/BackToTheRocks.ocf/Ruins.ocs/Script.c +++ b/planet/Arena.ocf/Ruins.ocs/Script.c @@ -12,16 +12,17 @@ protected func Initialize() // Goal. CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); // Mood. SetSkyAdjust(RGBa(255, 255, 255, 127), RGB(255, 200, 150)); SetGamma(RGB(40, 35, 30), RGB(140, 135, 130), RGB(255, 250, 245)); // Chests with weapons. - CreateObject(Chest, 230, 224, NO_OWNER); - CreateObject(Chest, 500, 64, NO_OWNER); - CreateObject(Chest, 124, 128, NO_OWNER); - CreateObject(Chest, 340, 440, NO_OWNER); + CreateObject(Chest, 230, 224, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 500, 64, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 124, 128, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 340, 440, NO_OWNER)->MakeInvincible(); AddEffect("IntFillChests", nil, 100, 2 * 36); // Ropeladders to get to the upper part. @@ -45,7 +46,7 @@ protected func Initialize() edge->PermaEdge(); } - AddEffect("DryTime",0,100,2); + AddEffect("DryTime",nil,100,2); return; } @@ -72,7 +73,7 @@ global func FxRainTimer(object pTarget, effect, int timer) } if(timer>(RUINS_RAIN_PERIOD_TIME+Random(800))) { - AddEffect("DryTime",0,100,2); + AddEffect("DryTime",nil,100,2); return -1; } @@ -84,11 +85,11 @@ global func FxDryTimeTimer(object pTarget, effect, int timer) InsertMaterial(Material("Water"),Random(LandscapeWidth()-60)+30,1,Random(7)-3,100+Random(100)); return 1; } - for(var i=0; i<6+Random(4);i++) - ExtractLiquid(310+Random(50),430+Random(10)); + ExtractLiquidAmount(310+Random(50),430+Random(10),6+Random(4)); + if(!GBackLiquid(335,430)) { - AddEffect("Rain",0,100,2); + AddEffect("Rain",nil,100,2); return -1; } } diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/System.ocg/UnUseableRopeLadders.c b/planet/Arena.ocf/Ruins.ocs/System.ocg/UnUseableRopeLadders.c similarity index 100% rename from planet/BackToTheRocks.ocf/Ruins.ocs/System.ocg/UnUseableRopeLadders.c rename to planet/Arena.ocf/Ruins.ocs/System.ocg/UnUseableRopeLadders.c diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/Title.txt b/planet/Arena.ocf/Ruins.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Ruins.ocs/Title.txt rename to planet/Arena.ocf/Ruins.ocs/Title.txt diff --git a/planet/Arena.ocf/ScorchedGardens.ocs/DescDE.rtf b/planet/Arena.ocf/ScorchedGardens.ocs/DescDE.rtf new file mode 100644 index 000000000..19b004733 --- /dev/null +++ b/planet/Arena.ocf/ScorchedGardens.ocs/DescDE.rtf @@ -0,0 +1,29 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\froman\fprq0\fcharset128 Times New Roman;}{\f6\fnil\fprq2\fcharset128 Droid Sans;}{\f7\fnil\fprq2\fcharset128 Lohit Hindi;}{\f8\fnil\fprq0\fcharset128 Lohit Hindi;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\hich\af6\dbch\af7\afs28\loch\f4\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af8 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3500}}\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b\rtlch \ltrch\loch\fs20\loch\f5 +Versengte G\uc2 \u228\'c3\'a4rten\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +Einst ein wahres Paradies, sind die Versengten G\uc2 \u228\'c3\'a4rten nun nichts weiter als eine raue Gegend, in der nur noch feuerfestes Gew\u228\'c3\'a4chs gedeiht. Neben der Bedrohung durch deine Feinde machen dir auch noch die Lava und pl\u246\'c3\'b6tzlich auftauchende Meteoriten das Leben Schwer.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +Ziel: Melee} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +- Benutze den Telehandschuh um Meteoriten auf deine Feinde zu schleudern.} +\par } \ No newline at end of file diff --git a/planet/Arena.ocf/ScorchedGardens.ocs/DescUS.rtf b/planet/Arena.ocf/ScorchedGardens.ocs/DescUS.rtf new file mode 100644 index 000000000..cb3039eef Binary files /dev/null and b/planet/Arena.ocf/ScorchedGardens.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/DefCore.txt b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/DefCore.txt similarity index 87% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/DefCore.txt rename to planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/DefCore.txt index fa9497e71..016dda1b7 100644 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/DefCore.txt +++ b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/DefCore.txt @@ -9,6 +9,5 @@ Vertices=1 VertexY=1 Mass=1 Rotate=1 -Placement=0 StretchGrowth=1 Oversize=1 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics.10.png b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics.10.png similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics.10.png rename to planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics.10.png diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics1.10.png b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics1.10.png similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics1.10.png rename to planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Graphics1.10.png diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Script.c b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Script.c similarity index 79% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Script.c rename to planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Script.c index c7928c8b7..516e4475a 100644 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Script.c +++ b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Script.c @@ -20,7 +20,14 @@ protected func Damage() private func Destroy() { - CastParticles("Grass", 10, 35, 0, 0, 30, 50, RGB(255,255,255), RGB(255,255,255)); + var particles = + { + Prototype = Particles_Straw(), + R = 200, + G = 50, + B = 50 + }; + CreateParticle("Grass", 0, 0, PV_Random(-20, 20), PV_Random(-20, 10), PV_Random(30, 100), particles, 30); RemoveObject(); } diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Title.png b/planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Title.png similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Title.png rename to planet/Arena.ocf/ScorchedGardens.ocs/Grass.ocd/Title.png diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Icon.png b/planet/Arena.ocf/ScorchedGardens.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Icon.png rename to planet/Arena.ocf/ScorchedGardens.ocs/Icon.png diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Map.bmp b/planet/Arena.ocf/ScorchedGardens.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Map.bmp rename to planet/Arena.ocf/ScorchedGardens.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Scenario.txt b/planet/Arena.ocf/ScorchedGardens.ocs/Scenario.txt similarity index 89% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Scenario.txt rename to planet/Arena.ocf/ScorchedGardens.ocs/Scenario.txt index 4010c83ed..ac3e11c17 100644 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Scenario.txt +++ b/planet/Arena.ocf/ScorchedGardens.ocs/Scenario.txt @@ -1,7 +1,8 @@ [Head] -Title=Overcast +Title=ScorchedGardens Version=5,2,0,1 MinPlayer=2 +Difficulty=40 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Script.c b/planet/Arena.ocf/ScorchedGardens.ocs/Script.c similarity index 60% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Script.c rename to planet/Arena.ocf/ScorchedGardens.ocs/Script.c index 9c1d4a0d1..300d43b84 100644 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Script.c +++ b/planet/Arena.ocf/ScorchedGardens.ocs/Script.c @@ -14,6 +14,7 @@ protected func Initialize() // Goal. CreateObject(Goal_DeathMatch, 0, 0, NO_OWNER); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); //Enviroment. CreateObject(Rule_ObjectFade)->DoFadeTime(10 * 36); @@ -21,65 +22,29 @@ protected func Initialize() CreateObject(Column,160,304)->SetClrModulation(RGB(255,100,80)); CreateObject(Column,448,272)->SetClrModulation(RGB(255,100,80)); - AddEffect("RandomMeteor", nil, 100, 36-Min(GetPlayerCount()*3,20), this); - AddEffect("RemoveCorpses", nil, 100, 1, this); + AddEffect("RandomMeteor", nil, 100, 36-Min(GetPlayerCount()*3,20)); + AddEffect("DangerousLava", nil, 100, 1); // Smooth brick edges. PlaceEdges(); PlaceGras(); return; } -global func FxRemoveCorpsesTimer() +global func FxDangerousLavaTimer() { //uber effect abuse - for(var dead in FindObjects(Find_ID(Clonk),Find_Not(Find_OCF(OCF_Alive)))) - { - CastParticles("MagicFire",100,50,dead->GetX(),dead->GetY(),50+Random(30)); - CastParticles("MagicFire",50,30,dead->GetX(),dead->GetY(),70+Random(60)); - dead->RemoveObject(); - } for(var burning in FindObjects(Find_ID(Clonk),Find_OCF(OCF_OnFire))) { burning->DoEnergy(-3); //lava hurts a lot } } + global func FxRandomMeteorTimer() { if(!Random(10)) return ; - - var flint = CreateObject(Firestone,50+Random(LandscapeWidth()-100),-10); - flint->SetYDir(25+Random(6)); - flint->SetXDir(RandomX(-20,20)); - flint->SetMass(0); - AddEffect("Meteorsparkle",flint,100,1,nil,nil,true); -} - -public func FxMeteorSparkleStart(obj, effect, iTemp, natural) -{ - if(iTemp) return; - effect.n=natural; -} - -global func FxMeteorsparkleTimer(obj, effect, time) -{ - - var x=obj->GetX(), y=obj->GetY(); - CreateParticle("FireballSmoke",x,y,Sin(Random(360),2),Cos(Random(360),2),RandomX(120,180),RGBa(100,100,100,70)); - for(var i=0; i<6; i++) CreateParticle("MagicFire",x,y,Sin(Random(360),RandomX(5,6)),Cos(Random(360),RandomX(5,6)),RandomX(50,90),HSL(Random(50), 200+Random(25), Random(100))); - CreateParticle("MagicSpark",x,y,Sin(Random(360),RandomX(15,33)),Cos(Random(360),RandomX(15,33)),RandomX(30,70),RGB(255,255,255)); - if(obj->Contained()) obj->Hit(); - if(Abs(obj->GetXDir())<3 && Abs(obj->GetYDir())<3) effect.count++; - else effect.count=0; - if(effect.count>10) obj->Hit(); -} -global func FxMeteorsparkleStop (obj, effect, reason, iTemp) -{ - if(iTemp) return; - for(var i=0; i<30; i++) CreateParticle("MagicSpark",obj->GetX(),obj->GetY(),Sin(Random(360),RandomX(15,33)),Cos(Random(360),RandomX(15,33)),RandomX(30,70),RGB(255,255,255)); - - return ; + LaunchMeteor(50+Random(LandscapeWidth()-100),-10, 40 + Random(40), RandomX(-20,20), 0); } private func PlaceEdges() @@ -133,7 +98,7 @@ protected func OnPlayerRelaunch(int plr) func OnClonkLeftRelaunch(object clonk) { - CastParticles("Magic",36,12,clonk->GetX(),clonk->GetY(),30,60,clonk->GetColor(),clonk->GetColor(),clonk); + clonk->CreateParticle("Fire", 0, 0, PV_Random(-20, 20), PV_Random(-40, 5), PV_Random(20, 90), Particles_Glimmer(), 30); clonk->SetYDir(-5); return; } @@ -141,4 +106,3 @@ func OnClonkLeftRelaunch(object clonk) func WinKillCount() { return 5; } -func RelaunchWeaponList() { return []; } diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/System.ocg/Clonk.c b/planet/Arena.ocf/ScorchedGardens.ocs/System.ocg/Clonk.c similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/System.ocg/Clonk.c rename to planet/Arena.ocf/ScorchedGardens.ocs/System.ocg/Clonk.c diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Title.txt b/planet/Arena.ocf/ScorchedGardens.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Title.txt rename to planet/Arena.ocf/ScorchedGardens.ocs/Title.txt diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/DescDE.rtf b/planet/Arena.ocf/ThunderousSkies.ocs/DescDE.rtf new file mode 100644 index 000000000..54aad2d48 --- /dev/null +++ b/planet/Arena.ocf/ThunderousSkies.ocs/DescDE.rtf @@ -0,0 +1,32 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\froman\fprq0\fcharset128 Times New Roman;}{\f6\fnil\fprq2\fcharset128 Droid Sans;}{\f7\fnil\fprq2\fcharset128 Lohit Hindi;}{\f8\fnil\fprq0\fcharset128 Lohit Hindi;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\hich\af6\dbch\af7\afs28\loch\f4\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af8 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3500}}\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b\rtlch \ltrch\loch\fs20\loch\f5 +Donnernde Himmel} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\loch\f5 +Erlange die Herrschaft \uc2 \u252\'c3\'bcber diese Himmelsinsel, die hoch oben in den Wolken schwebt.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\b0\rtlch \ltrch\loch\fs16\loch\f5 +Ziel: King of the Hill }{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +(nur der K\uc2 \u246\'c3\'b6nig bekommt Punkte f\u252\'c3\'bcr Kills oder andere Spieler f\u252\'c3\'bcr einen K\u246\'c3\'b6nigsmord)\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\rtlch \ltrch\loch +} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +- Erlange die Herrschaft \uc2 \u252\'c3\'bcber die Insel, indem zu 5 Punkte erreichst.\uc1 } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033\nowidctlpar{\b0\rtlch \ltrch\loch\fs16\lang1031\loch\f5 +- Als K\uc2 \u246\'c3\'b6nig wirst du um 30% des Schadens, den du verursachst, geheilt!\uc1 } +\par } \ No newline at end of file diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/DescUS.rtf b/planet/Arena.ocf/ThunderousSkies.ocs/DescUS.rtf new file mode 100644 index 000000000..b78a7c023 Binary files /dev/null and b/planet/Arena.ocf/ThunderousSkies.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Icon.png b/planet/Arena.ocf/ThunderousSkies.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Icon.png rename to planet/Arena.ocf/ThunderousSkies.ocs/Icon.png diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Map.bmp b/planet/Arena.ocf/ThunderousSkies.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Map.bmp rename to planet/Arena.ocf/ThunderousSkies.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scenario.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scenario.txt similarity index 96% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scenario.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scenario.txt index a78e686e5..229278309 100644 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scenario.txt +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Scenario.txt @@ -2,6 +2,7 @@ Title=Overcast Version=5,2,0,1 MinPlayer=2 +Difficulty=60 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c similarity index 78% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Script.c rename to planet/Arena.ocf/ThunderousSkies.ocs/Script.c index 2fcfca583..a07906ff6 100644 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Script.c @@ -6,6 +6,7 @@ --*/ +static ThunderousSkies_air_particles, ThunderousSkies_air_particles_red; protected func Initialize() { @@ -16,6 +17,7 @@ protected func Initialize() goal->SetPointLimit(5); AddEffect("BlessTheKing",goal,100,1,nil); CreateObject(Rule_KillLogs); + CreateObject(Rule_Gravestones); //Enviroment. //SetSkyAdjust(RGBa(250,250,255,128),RGB(200,200,220)); @@ -28,16 +30,16 @@ protected func Initialize() CreateObject(Column,810,179); // Chests with weapons. - CreateObject(Chest, 175, 200, NO_OWNER); - CreateObject(Chest, 800, 150, NO_OWNER); - CreateObject(Chest, 430, 240, NO_OWNER); - CreateObject(Chest, 610, 340, NO_OWNER); - CreateObject(Chest, 355, 390, NO_OWNER); + CreateObject(Chest, 175, 200, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 800, 150, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 430, 240, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 610, 340, NO_OWNER)->MakeInvincible(); + CreateObject(Chest, 355, 390, NO_OWNER)->MakeInvincible(); - AddEffect("IntFillChests", nil, 100, 2 * 36, this); + AddEffect("IntFillChests", nil, 100, 2 * 36, nil); // Smooth brick edges. - AddEffect("ChanneledWind", nil, 100, 1, this); - AddEffect("Balloons", nil, 100, 100, this); + AddEffect("ChanneledWind", nil, 100, 1, nil); + AddEffect("Balloons", nil, 100, 100, nil); // Moving bricks. var brick; @@ -49,6 +51,24 @@ protected func Initialize() CreateObject(BrickEdge, 380, 416)->PermaEdge(); PlaceGras(); + + ThunderousSkies_air_particles = + { + Prototype = Particles_Air(), + Size = PV_KeyFrames(0, 0, 0, 100, PV_Random(2, 5), 1000, 0), + Stretch = PV_Speed(2000, 0), + OnCollision = PC_Stop(), + ForceY = -20, + Attach = ATTACH_Back | ATTACH_MoveRelative + }; + + ThunderousSkies_air_particles_red = + { + Prototype = ThunderousSkies_air_particles, + R = 255, + G = PV_KeyFrames(0, 0, 255, 250, 255, 500, 0), + B = PV_KeyFrames(0, 0, 255, 250, 255, 500, 0) + }; return; } global func FxLifestealDamage(object target, effect, int damage, int cause, int from) @@ -81,40 +101,18 @@ global func FxLifedrainTimer(object target, effect, int timer) } global func FxBlessTheKingTimer(object target, effect, int timer) { - - //evil effect abuse :O - for(var dead in FindObjects(Find_ID(Clonk),Find_Not(Find_OCF(OCF_Alive)))) - { - CastParticles("Air",50,50,dead->GetX(),dead->GetY(),50+Random(30)); - for(var i=0; i<200; i++) - { - var r=Random(360); - CreateParticle("AirIntake",dead->GetX()+Sin(r,6-Random(5)),dead->GetY()-Cos(r,6-Random(5)),RandomX(-2,2),-(i/3),20+Random(20),dead->GetPlayerColor()); - } - dead->RemoveObject(); - } - if(!FindObject(Find_ID(KingOfTheHill_Location))) return 1; if(FindObject(Find_ID(KingOfTheHill_Location))->GetKing() == nil) return 1; var king=FindObject(Find_ID(KingOfTheHill_Location))->GetKing(); - - for(var i=0; i<5; i++) + var particles = ThunderousSkies_air_particles; + var duration = 10; + if (GetEffect("Lifedrain", king)) { - var r=Random(360); - var clr=RGBa(30,100-Random(50),255-Random(160),230+Random(20)); - var str=0; - var lifedrain = GetEffect("Lifedrain",king); - if(lifedrain) - { - clr=RGBa(BoundBy(-lifedrain.drain,30,225)+Random(20),160-(BoundBy(-lifedrain.drain/2,10,100))-Random(50),230-BoundBy(-lifedrain.drain,30,225)+Random(20), 230+Random(20)); - var str=Random(BoundBy(-lifedrain.drain/10,2,6)); - } - CreateParticle("AirIntake",king->GetX()+Sin(r,6-Random(5)),king->GetY()-Cos(r,6-Random(5)),Sin(r + 90,8+Random(4)+str),-Cos(r +90,8+Random(4)+str),20+Random(30) +str*str,clr); - CreateParticle("AirIntake",king->GetX()+Sin(r + 180,6-Random(5)),king->GetY()-Cos(r+180,6-Random(5)),Sin(r + 90,8+Random(4)+str),-Cos(r +90,8+Random(4)+str),20+Random(30)+str*str,clr); - + particles = ThunderousSkies_air_particles_red; + duration *= 2; } - CreateParticle("AirIntake",king->GetX()+Sin(r + 180,6-Random(5)),king->GetY()-Cos(r+180,6-Random(5)),0,-25,20+Random(20),king->GetPlayerColor()); + king->CreateParticle("Air", 0, 8, PV_Random(-10, 10),PV_Random(0, 10), PV_Random(duration, 2 * duration), particles, 4); return 1; } @@ -130,9 +128,8 @@ global func FxChanneledWindTimer() obj->SetYDir(Max(obj->GetYDir()-5,-50)); obj->SetXDir(obj->GetXDir()+RandomX(-1,1)); } - - CreateParticle("AirIntake",230+Random(40),398,RandomX(-1,1),-30,60+Random(10),RGB(100+Random(25),128+Random(20),255)); - CreateParticle("AirIntake",700+Random(60),348,RandomX(-1,1),-30,60+Random(10),RGB(100+Random(25),128+Random(20),255)); + CreateParticle("Air", 230+Random(40),398,RandomX(-1,1),-30, PV_Random(10, 30), ThunderousSkies_air_particles); + CreateParticle("Air", 700+Random(60),348,RandomX(-1,1),-30, PV_Random(10, 30), ThunderousSkies_air_particles); } global func FxBalloonsTimer() @@ -162,7 +159,7 @@ global func FxBalloonsTimer() var balloon = CreateObject(TargetBalloon, x, y-30, NO_OWNER); balloon->SetProperty("load",target); target->SetAction("Attach", balloon); - CreateParticle("Flash", x, y - 50, 0, 0, 500, RGB(255, 255, 255)); + CreateParticle("Flash", x, y, 0, 0, 8, Particles_Flash()); AddEffect("HorizontalMoving", balloon, 1, 1, balloon); balloon->SetXDir(((Random(2)*2)-1) * (Random(4)+3)); } @@ -204,7 +201,7 @@ private func MakeTarget(int x, int y) var balloon = CreateObject(TargetBalloon, x, y-30, NO_OWNER); balloon->SetProperty("load",target); target->SetAction("Attach", balloon); - CreateParticle("Flash", x, y - 50, 0, 0, 500, RGB(255, 255, 255)); + CreateParticle("Flash", x, y, 0, 0, 8, Particles_Flash()); } diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Fireball.ogg diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c similarity index 61% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c index a4c904395..3786a9f73 100644 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/Script.c @@ -8,7 +8,7 @@ public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("Fireball", 0, 100, 1, 0, GetID(), pClonk->GetOwner(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); + AddEffect("Fireball", nil, 100, 1, nil, GetID(), pClonk->GetOwner(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY()); Sound("Fireball"); Sound("Fireball"); RemoveObject(); @@ -60,23 +60,16 @@ public func FxFireballTimer(pTarget, effect, iEffectTime) } else if(iEffectTime < 70) { - CreateParticle("FireballSmoke",x,y,Sin(Random(360),2),Cos(Random(360),2),RandomX(120,180),RGBa(100,100,100,70)); - CreateParticle("MagicSpark",x,y,Sin(Random(360),RandomX(5,13)),Cos(Random(360),RandomX(5,13)),RandomX(30,70),RGB(255,255,255)); - - //if(!Random(10)) if(Random(2))angle++; else angle--; angle+=Sin(iEffectTime*30,18); - x+=Sin(angle, 6); - y+=-Cos(angle, 6); - effect.x=x; - effect.y=y; - for(var i=0;i<6;++i) - { - var c=HSL(Random(50), 200+Random(25), Random(100)); - var rx=RandomX(-2, 2); - var ry=RandomX(-2, 2); - CreateParticle("MagicFire", x+rx, y+ry, Sin(angle+180,6)+ry, -Cos(angle+180,6)+rx, 80+Random(20), c); - CreateParticle("MagicFire", x+rx, y+ry, Sin(angle+180,6)+ry, -Cos(angle+180,6)+rx, 20+Random(10), RGB(255,255,0)); - } + var xspeed = Sin(angle, 6); + var yspeed = -Cos(angle, 6); + + CreateParticle("SmokeDirty", x, y, PV_Random(-2, 2), PV_Random(-2, 2), PV_Random(30, 60), Particles_SmokeTrail(), 1); + CreateParticle("FireDense", x, y, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(5, 20), Particles_Fire(), 10); + CreateParticle("Fire", x, y, PV_Random(0, - 10 * xspeed), PV_Random(0, - 10 * yspeed), PV_Random(20, 90), Particles_Glimmer(), 10); + + effect.x += xspeed; + effect.y += yspeed; } return 1; diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/FireballScroll.ocd/authors.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/DefCore.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/DefCore.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Graphics.8.png b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Graphics.png b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Graphics.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Graphics.png rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Graphics.png diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Particle.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Particle.txt new file mode 100644 index 000000000..86a56d26a --- /dev/null +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=LightningStrike +Face=0,0,16,2000,-8,0 diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Script.c new file mode 100644 index 000000000..6d01fd4bb --- /dev/null +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Script.c @@ -0,0 +1,116 @@ +/*-- + Scroll: Thunder + Author: Mimmo + + Call down a devastating storm down from above. +--*/ + + +public func ControlUse(object pClonk) +{ + Sound("Blast3"); + Exit(0,-GetY()); + AddEffect("ThunderStrike",nil,100,1,nil,this->GetID(),pClonk->GetOwner(),this->GetX()-5); + RemoveObject(); + return 1; +} +global func FxThunderStrikeStart(pTarget, effect, iTemp, owner, x) +{ + if(iTemp) return; + effect.owner=owner; + effect.x=x; + + effect.particles_air = + { + Prototype = Particles_Air(), + Size = PV_Random(1, 5) + }; +} +global func FxThunderStrikeTimer(pTarget, effect, iEffectTime) +{ + var move = effect.x; + + if(iEffectTime>36) + { + var particles_lightning = + { + Size = 4000, + BlitMode = GFX_BLIT_Additive, + Alpha = PV_Linear(255, 0) + }; + var owner = effect.owner; + var x=0; + var wdt = 18; + var y = []; + var targets=[]; + for(var i = (x-wdt); i < (wdt*2); i++ ) + { + + while(!GBackSolid(i+move,y[i+wdt]) && y[i+wdt] < LandscapeHeight()) + y[i+wdt]++; + + } + + for(var i = (x-wdt); i < (wdt*2); i++ ) + { + var particles = Particles_ElectroSpark1(); + if (Random(2)) + particles = Particles_ElectroSpark2(); + if(!(i%5)) + for(var k=0; kGetID() == TargetBalloon) + { + var arw=CreateObject(Arrow,0,0,owner); + t->OnProjectileHit(arw); + arw->RemoveObject(); + } + else + { + if(t->GetOwner() != owner) + { + t->DoEnergy(-15,0,0,owner); + t->Fling(BoundBy((t->GetX()-(move))/4,-3,3),-6); + } + } + } + return -1; + } + else if(iEffectTime<4) + { + if(iEffectTime%3) + { + for (var y = 0; !GBackSolid(x+move+5,y) && y < LandscapeHeight(); y += Random(4) + 3) + { + var add=Random((iEffectTime*5))*((Random(2)*2) -1); + CreateParticle("Air", x+move+5+add, y, PV_Random(-2, 2), PV_Random(-10, -5), PV_Random(5, 20), effect.particles_air); + } + } + } +} + + + + +local Name = "$Name$"; +local Description = "$Description$"; +local Collectible = 1; diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Graphics.8.png diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Script.c similarity index 72% rename from planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Script.c rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Script.c index 7b98e9916..b08fe4ef6 100644 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/Scrolls.ocd/WindScroll.ocd/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/Script.c @@ -8,7 +8,7 @@ public func ControlUse(object pClonk, int ix, int iy) { - AddEffect("WindScrollStorm", 0, 100, 1, 0, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY(), pClonk->GetOwner()); + AddEffect("WindScrollStorm", nil, 100, 1, nil, GetID(), Angle(0,0,ix,iy),pClonk->GetX(), pClonk->GetY(), pClonk->GetOwner()); RemoveObject(); return 1; } @@ -24,7 +24,11 @@ public func FxWindScrollStormStart(pTarget, effect, iTemp, angle, x, y, owner) effect.y=y-Cos(angle,43); effect.owner=owner; - + effect.particles = + { + Prototype = Particles_Air(), + Size = PV_Random(2, 5) + }; } public func FxWindScrollStormTimer(pTarget, effect, iEffectTime) @@ -36,19 +40,14 @@ public func FxWindScrollStormTimer(pTarget, effect, iEffectTime) if(iEffectTime<36) { - var r=Random(360); - var d=Random(40); - CreateParticle("AirIntake",Sin(r,d)+x,-Cos(r,d)+y,xdir/3,ydir/3 +2,64,RGB(Random(80),100+Random(50),255)); - return 1; + var r=Random(360); + var d=Random(40); + CreateParticle("Air", Sin(r,d)+x,-Cos(r,d)+y, xdir/3, ydir/3, PV_Random(10, 30), effect.particles, 1); + return 1; } else if(iEffectTime<180 ) { - for(var i=0; i<5; i++) - { - var r=Random(360); - var d=Random(40); - CreateParticle("AirIntake",Sin(r,d)+x,-Cos(r,d)+y,xdir/2,ydir/2 +2,64,RGB(Random(80),100+Random(50),255)); - } + CreateParticle("Air", PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), xdir/2, ydir/2, PV_Random(10, 30), effect.particles, 5); for(var obj in FindObjects(Find_Distance(40,x,y),Find_Not(Find_Category(C4D_Structure)))) { diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Scrolls.ocd/WindScroll.ocd/StringTblUS.txt diff --git a/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FastDynamite.c b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FastDynamite.c new file mode 100644 index 000000000..ca4fd5648 --- /dev/null +++ b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FastDynamite.c @@ -0,0 +1,15 @@ +/* Everyone wins! */ + +#appendto Dynamite + +local fast; + +func Initialize() +{ + fast=0; + _inherited(); +} + +func MakeFast(int f) { fast=f; } + +func FuseTime() { return 140 - fast; } diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FlyingArrowpack.c b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FlyingArrowpack.c similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FlyingArrowpack.c rename to planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FlyingArrowpack.c diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FlyingBoompack.c b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FlyingBoompack.c similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FlyingBoompack.c rename to planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FlyingBoompack.c diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FlyingDynamite.c b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FlyingDynamite.c similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FlyingDynamite.c rename to planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/FlyingDynamite.c diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/Lifesteal.c b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/Lifesteal.c similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/Lifesteal.c rename to planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/Lifesteal.c diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/NoRegeneration.c b/planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/NoRegeneration.c similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/NoRegeneration.c rename to planet/Arena.ocf/ThunderousSkies.ocs/System.ocg/NoRegeneration.c diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/DefCore.txt b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/DefCore.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.2.png b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.2.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.2.png rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.2.png diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.mesh b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.mesh similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.mesh rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Graphics.mesh diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Scene.material b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Scene.material rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Scene.material diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Script.c b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Script.c similarity index 91% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Script.c rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Script.c index 9591f666e..6d6572e36 100644 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Script.c +++ b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Script.c @@ -3,10 +3,6 @@ local ysin; local load; -func Definition(def) { - SetProperty("Name", "$Name$", def); -} - protected func Initialize() { ysin = 0; @@ -39,7 +35,7 @@ public func IsProjectileTarget(target,shooter) public func OnProjectileHit(object projectile) { - CastParticles("Air",20,5,0,-10,170,190,RGB(255,255,255),RGB(255,255,255)); + CreateParticle("Air", 0, -10, PV_Random(-30, 30), PV_Random(-30,30), PV_Random(30, 120), Particles_Air(), 10); if(load) load->~Fall(projectile->GetController()); RemoveObject(); } @@ -61,6 +57,7 @@ func FxFlyOffTimer(target, effect, time) } func Definition(def) { + SetProperty("Name", "$Name$", def); SetProperty("ActMap", { Float = { diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblDE.txt b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblDE.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblUS.txt b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblUS.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Target_Balloon.skeleton b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Target_Balloon.skeleton similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Target_Balloon.skeleton rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/Target_Balloon.skeleton diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/target_balloon.png b/planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/target_balloon.png similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/target_balloon.png rename to planet/Arena.ocf/ThunderousSkies.ocs/TargetBalloon.ocd/target_balloon.png diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Title.txt b/planet/Arena.ocf/ThunderousSkies.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Title.txt rename to planet/Arena.ocf/ThunderousSkies.ocs/Title.txt diff --git a/planet/Arena.ocf/Title.png b/planet/Arena.ocf/Title.png new file mode 100644 index 000000000..b0249c01b Binary files /dev/null and b/planet/Arena.ocf/Title.png differ diff --git a/planet/Arena.ocf/Title.txt b/planet/Arena.ocf/Title.txt new file mode 100644 index 000000000..f60ed1542 --- /dev/null +++ b/planet/Arena.ocf/Title.txt @@ -0,0 +1,2 @@ +DE:Arena +US:Arena diff --git a/planet/Arena.ocf/Title1.png b/planet/Arena.ocf/Title1.png new file mode 100644 index 000000000..10ad95622 Binary files /dev/null and b/planet/Arena.ocf/Title1.png differ diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Boomattack.skeleton.xml b/planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Boomattack.skeleton.xml similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Boomattack.skeleton.xml rename to planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Boomattack.skeleton.xml diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/DefCore.txt b/planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/DefCore.txt rename to planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Graphics.mesh.xml b/planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Graphics.mesh.xml similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Graphics.mesh.xml rename to planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Graphics.mesh.xml diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Scene.material b/planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Scene.material rename to planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Scene.material diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Script.c b/planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Script.c similarity index 82% rename from planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Script.c rename to planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Script.c index dc7db31c6..90b1f8d45 100644 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/BigBoomattack.ocd/Script.c +++ b/planet/Arena.ocf/Windmill.ocs/BigBoomattack.ocd/Script.c @@ -24,8 +24,15 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime) if(fuel<=0) { DoFireworks(); + return; } - + + if(GetAction() != "Fly") + { + SetAction("Fly"); + SetComDir(COMD_None); + } + var ignition = iEffectTime % 15; if(!ignition) @@ -35,23 +42,13 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime) } - if(!Random(iEffectTime % 15)) - { - var sizemod = ignition*ignition/5; - - var x = -Sin(GetR(),70); - var y = +Cos(GetR(),70); - - CreateParticle("ExploSmoke",x,y,RandomX(-1,1),RandomX(-1,1),RandomX(250,600),RGBa(130,130,130,100)); - CreateParticle("Thrust",x,y,GetXDir()/2,GetYDir()/2,RandomX(160,240)+sizemod,RGBa(255,200,200,200)); - } - - if(GetAction() != "Fly") - { - SetAction("Fly"); - SetComDir(COMD_None); - } - + var x = -Sin(GetR(), 80); + var y = +Cos(GetR(), 80); + + var xdir = GetXDir() / 2; + var ydir = GetYDir() / 2; + CreateParticle("FireDense", x, y, PV_Random(xdir - 20, xdir + 20), PV_Random(ydir - 20, ydir + 20), PV_Random(16 * 6, 38 * 6), {Prototype = Particles_Thrust(), Size = PV_Random(40, 60)}, 5); + fuel--; } diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Boomattack.skeleton.xml b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Boomattack.skeleton.xml similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Boomattack.skeleton.xml rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Boomattack.skeleton.xml diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/DefCore.txt b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/DefCore.txt rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Graphics.mesh.xml b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Graphics.mesh.xml similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Graphics.mesh.xml rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Graphics.mesh.xml diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Scene.material b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Scene.material rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Scene.material diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Script.c b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Script.c similarity index 83% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Script.c rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Script.c index db73c5b6f..02f24f57c 100644 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/Script.c +++ b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/Script.c @@ -19,6 +19,7 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime) if(fuel<=0) { DoFireworks(); + return; } var ignition = iEffectTime % 10; @@ -31,24 +32,20 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime) SetR(angle); } - - if(!Random(iEffectTime % 5)) - { - var sizemod = ignition*ignition/3; - - var x = -Sin(GetR(),22); - var y = +Cos(GetR(),22); - - CreateParticle("ExploSmoke",x,y,RandomX(-1,1),RandomX(-1,2),RandomX(120,280),RGBa(130,130,130,75)); - CreateParticle("Thrust",x,y,GetXDir()/2,GetYDir()/2,RandomX(80,120)+sizemod,RGBa(255,200,200,160)); - } - if(GetAction() != "Fly") { SetAction("Fly"); SetComDir(COMD_None); } - + + var x = -Sin(GetR(), 15); + var y = +Cos(GetR(), 15); + + var xdir = GetXDir() / 2; + var ydir = GetYDir() / 2; + CreateParticle("FireDense", x, y, PV_Random(xdir - 4, xdir + 4), PV_Random(ydir - 4, ydir + 4), PV_Random(16, 38), Particles_Thrust(), 5); + + fuel--; } @@ -63,9 +60,9 @@ public func IsProjectileTarget(target,shooter) public func OnProjectileHit(object shot) { - DoFireworks(); var gol = FindObject(Find_ID(Goal_SaveTheWindmills)); if(gol) gol->IncShotScore(shot->GetController()); + DoFireworks(); return 1; } @@ -96,7 +93,7 @@ func Launch(int angle) SetComDir(COMD_None); Exit(); - AddEffect("Flight",this,150,1,this,this); + AddEffect("Flight",this,150,1,this); //AddEffect("HitCheck", this, 1,1, nil,nil, 0, 0); SetR(angle); diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/StringTblDE.txt b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/StringTblDE.txt rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/StringTblUS.txt b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/StringTblUS.txt rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/boomattack.png b/planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/boomattack.png similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Boomattack.ocd/boomattack.png rename to planet/Arena.ocf/Windmill.ocs/Boomattack.ocd/boomattack.png diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/DescDE.rtf b/planet/Arena.ocf/Windmill.ocs/DescDE.rtf similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/DescDE.rtf rename to planet/Arena.ocf/Windmill.ocs/DescDE.rtf diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/DescUS.rtf b/planet/Arena.ocf/Windmill.ocs/DescUS.rtf similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/DescUS.rtf rename to planet/Arena.ocf/Windmill.ocs/DescUS.rtf diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Map.bmp b/planet/Arena.ocf/Windmill.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Map.bmp rename to planet/Arena.ocf/Windmill.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/DefCore.txt b/planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/DefCore.txt rename to planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/Graphics.png b/planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/Graphics.png similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/Graphics.png rename to planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/Graphics.png diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/Script.c b/planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/Script.c similarity index 75% rename from planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/Script.c rename to planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/Script.c index 8c70c287b..1ff03c0bf 100644 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/Script.c +++ b/planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/Script.c @@ -10,9 +10,11 @@ func Initialize() score = []; boss = false; wave = 1; - // Set scoreboard caption. - SetScoreboardData(SBRD_Caption, SBRD_Caption, "$ScoreCaption$", SBRD_Caption); - SetScoreboardData(SBRD_Caption, SBRD_Rockets, "{{Goal_SaveTheWindmills}}", SBRD_Caption); + // init scoreboard + Scoreboard->Init( + [{key = "windmills", title = Goal_SaveTheWindmills, sorted = true, desc = true, default = 0, priority = 80}] + ); + Scoreboard->SetTitle("$ScoreCaption$"); // Remove settlement eval data. HideSettlementScoreInEvaluation(true); inherited(...); @@ -48,8 +50,7 @@ public func IncShotScore(int plr) score[plrid]++; if (plr != NO_OWNER) { - SetScoreboardData(plrid, SBRD_Rockets, Format("%d", score[plrid]), score[plrid]); - SortScoreboard(SBRD_Rockets, true); + Scoreboard->SetPlayerData(plr, "windmills", score[plrid]); } NotifyHUD(); } @@ -80,9 +81,8 @@ protected func InitializePlayer(int plr) { var plrid = GetPlayerID(plr); score[plrid] = 0; - // Create scoreboard player entry for this player. - SetScoreboardData(plrid, SBRD_Caption, GetTaggedPlayerName(plr), SBRD_Caption); - SetScoreboardData(plrid, SBRD_Rockets, Format("%d", score[plrid]), score[plrid]); + // Create scoreboard player entry for this player + Scoreboard->NewPlayerEntry(plr); return _inherited(plr, ...); } diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblDE.txt b/planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblDE.txt rename to planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblUS.txt b/planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblUS.txt rename to planet/Arena.ocf/Windmill.ocs/SaveTheWindmills.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Scenario.txt b/planet/Arena.ocf/Windmill.ocs/Scenario.txt similarity index 95% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Scenario.txt rename to planet/Arena.ocf/Windmill.ocs/Scenario.txt index d94962888..cb886358b 100644 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/Scenario.txt +++ b/planet/Arena.ocf/Windmill.ocs/Scenario.txt @@ -2,7 +2,7 @@ Icon=39 Title=Windmill Version=5,2,0,1 -MaxPlayer=8 +Difficulty=10 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Script.c b/planet/Arena.ocf/Windmill.ocs/Script.c similarity index 98% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Script.c rename to planet/Arena.ocf/Windmill.ocs/Script.c index 904c7d4ad..d91274954 100644 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/Script.c +++ b/planet/Arena.ocf/Windmill.ocs/Script.c @@ -27,7 +27,7 @@ func Initialize() CreateObject(Goal_SaveTheWindmills,10,10); PlaceGrass(100, 800, 1400); SetSkyParallax(0,25,25,0,0,0,50); - AddEffect("BoomAttack", 0, 100, 35); + AddEffect("BoomAttack", nil, 100, 35); Sound("WindLoop",true,40,nil,+1); } @@ -90,6 +90,7 @@ global func CreateAttackWave(int angle, int rockets, int anglespread) gui_arrow->SetObjectBlitMode(GFX_BLIT_Mod2); } gui_arrow->SetR(angle); + gui_arrow.Plane = 500; } } diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Sky.jpg b/planet/Arena.ocf/Windmill.ocs/Sky.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Sky.jpg rename to planet/Arena.ocf/Windmill.ocs/Sky.jpg diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/StringTblDE.txt b/planet/Arena.ocf/Windmill.ocs/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/StringTblDE.txt rename to planet/Arena.ocf/Windmill.ocs/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/StringTblUS.txt b/planet/Arena.ocf/Windmill.ocs/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/StringTblUS.txt rename to planet/Arena.ocf/Windmill.ocs/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/System.ocg/CheatArrow.c b/planet/Arena.ocf/Windmill.ocs/System.ocg/CheatArrow.c similarity index 86% rename from planet/BackToTheRocks.ocf/Windmill.ocs/System.ocg/CheatArrow.c rename to planet/Arena.ocf/Windmill.ocs/System.ocg/CheatArrow.c index 2dd50d60a..3beee803c 100644 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/System.ocg/CheatArrow.c +++ b/planet/Arena.ocf/Windmill.ocs/System.ocg/CheatArrow.c @@ -4,7 +4,7 @@ public func SetStackCount(int amount) { count = MaxStackCount(); - Update(); + UpdateStackDisplay(); } public func Hit() @@ -17,7 +17,7 @@ public func HitObject(object obj) { if(obj->GetOCF() & OCF_CrewMember) return; inherited(obj,...); - RemoveObject(); + if (this) RemoveObject(); } func UpdatePicture() diff --git a/planet/Arena.ocf/Windmill.ocs/System.ocg/SensitiveWindGenerator.c b/planet/Arena.ocf/Windmill.ocs/System.ocg/SensitiveWindGenerator.c new file mode 100644 index 000000000..bf0ac03f2 --- /dev/null +++ b/planet/Arena.ocf/Windmill.ocs/System.ocg/SensitiveWindGenerator.c @@ -0,0 +1,9 @@ +#appendto WindGenerator + +func Damage() +{ + Explode(30); +} + +// No lightbulbs +func MakePowerProducer(power) { return false; } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/Title.txt b/planet/Arena.ocf/Windmill.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/Title.txt rename to planet/Arena.ocf/Windmill.ocs/Title.txt diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/authors.txt b/planet/Arena.ocf/Windmill.ocs/authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Windmill.ocs/authors.txt rename to planet/Arena.ocf/Windmill.ocs/authors.txt diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/Boomrace.ocs/DescUS.rtf deleted file mode 100644 index 1365ce7c2..000000000 Binary files a/planet/BackToTheRocks.ocf/Boomrace.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/System.ocg/Clonk.c b/planet/BackToTheRocks.ocf/Boomrace.ocs/System.ocg/Clonk.c deleted file mode 100644 index d1c750a9e..000000000 --- a/planet/BackToTheRocks.ocf/Boomrace.ocs/System.ocg/Clonk.c +++ /dev/null @@ -1,15 +0,0 @@ -// The clonk can only hold one item and only collect boompacks. - -#appendto Clonk - -protected func RejectCollect(id objid, object obj) -{ - if (objid != Boompack) - return true; - return _inherited(objid, obj); -} - -public func MaxContentsCount() -{ - return 2; -} diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/Boomshire.ocs/DescDE.rtf deleted file mode 100644 index ba7def853..000000000 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/DescDE.rtf +++ /dev/null @@ -1,22 +0,0 @@ -{\rtf1\ansi\deff0\adeflang1025 -{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq2\fcharset0 Calibri;}{\f4\froman\fprq2\fcharset0 Times New Roman;}{\f5\fnil\fprq2\fcharset0 MS Mincho;}{\f6\fnil\fprq2\fcharset0 Tahoma;}{\f7\fnil\fprq0\fcharset0 Tahoma;}} -{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} -{\stylesheet{\s1\sa200\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af3\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\snext1 Normal;} -{\s2\sb240\sa120\keepn\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af6\afs28\lang1025\ltrch\dbch\af5\langfe1031\hich\f2\fs28\lang1031\loch\f2\fs28\lang1031\sbasedon1\snext3 Heading;} -{\s3\sa120\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af3\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\sbasedon1\snext3 Body Text;} -{\s4\sa120\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af7\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\sbasedon3\snext4 List;} -{\s5\sb120\sa120\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af7\afs24\lang1025\ai\ltrch\dbch\langfe1031\hich\f3\fs24\lang1031\i\loch\f3\fs24\lang1031\i\sbasedon1\snext5 caption;} -{\s6\sa200\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af7\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\sbasedon1\snext6 Index;} -{\*\cs8\cf0\rtlch\af0\afs24\lang1031\ltrch\dbch\af0\langfe1031\hich\f0\fs24\lang1031\loch\f0\fs24\lang1031 Default Paragraph Font;} -} -{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern6800}}\deftab720 -{\*\pgdsctbl -{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1417\margrsxn1417\margtsxn1417\margbsxn1134\pgdscnxt0 Standard;}} -{\*\pgdscno0}\paperh15840\paperw12240\margl1417\margr1417\margt1417\margb1134\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1417\margrsxn1417\margtsxn1417\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc -\pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs20\lang1025\ab\ltrch\dbch\langfe1031\hich\fs20\lang1031\b\loch\fs20\lang1031\b {\rtlch \ltrch\loch\f0\fs20\lang1031\i0\b Boomshire} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs18\lang1025\ltrch\dbch\langfe1031\hich\fs18\lang1031\loch\fs18\lang1031 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs22\lang1025\ltrch\dbch\langfe1031\hich\fs22\lang1031\loch\fs22\lang1031{\rtlch \ltrch\loch\f0\fs22\lang1031\i0\b0\rtlch\ltrch\dbch\hich\fs16\loch\fs16 Dieses Rennen f\'fcr zwei Spieler erfordert anders als in normalen Rennen die Zusammenarbeit der Spieler, denn hier kann keine Aufgabe allein gel\'f6st werden.} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs16\lang1025\ltrch\dbch\langfe1031\hich\fs16\lang1031\loch\fs16\lang1031 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs16\lang1025\ltrch\dbch\langfe1031\hich\fs16\lang1031\loch\fs16\lang1031 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs22\lang1025\ltrch\dbch\langfe1031\hich\fs22\lang1031\loch\fs22\lang1031{\rtlch \ltrch\loch\f0\fs22\lang1031\i0\b0\rtlch\ltrch\dbch\hich\fs16\loch\fs16 Achtung: Es werden genau zwei Spieler ben\'f6tigt!} -\par } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/Boomshire.ocs/DescUS.rtf deleted file mode 100644 index 3a7c7413e..000000000 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/DescUS.rtf +++ /dev/null @@ -1,23 +0,0 @@ -{\rtf1\ansi\deff0\adeflang1025 -{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq2\fcharset0 Calibri;}{\f4\froman\fprq2\fcharset0 Times New Roman;}{\f5\fnil\fprq2\fcharset0 MS Mincho;}{\f6\fnil\fprq2\fcharset0 Tahoma;}{\f7\fnil\fprq0\fcharset0 Tahoma;}} -{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} -{\stylesheet{\s1\sa200\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af3\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\snext1 Normal;} -{\s2\sb240\sa120\keepn\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af6\afs28\lang1025\ltrch\dbch\af5\langfe1031\hich\f2\fs28\lang1031\loch\f2\fs28\lang1031\sbasedon1\snext3 Heading;} -{\s3\sa120\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af3\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\sbasedon1\snext3 Body Text;} -{\s4\sa120\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af7\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\sbasedon3\snext4 List;} -{\s5\sb120\sa120\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af7\afs24\lang1025\ai\ltrch\dbch\langfe1031\hich\f3\fs24\lang1031\i\loch\f3\fs24\lang1031\i\sbasedon1\snext5 caption;} -{\s6\sa200\cf0\sl276\slmult1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af7\afs22\lang1025\ltrch\dbch\langfe1031\hich\f3\fs22\lang1031\loch\f3\fs22\lang1031\sbasedon1\snext6 Index;} -{\*\cs8\cf0\rtlch\af0\afs24\lang1031\ltrch\dbch\af0\langfe1031\hich\f0\fs24\lang1031\loch\f0\fs24\lang1031 Default Paragraph Font;} -} -{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern6800}}\deftab720 -{\*\pgdsctbl -{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1417\margrsxn1417\margtsxn1417\margbsxn1134\pgdscnxt0 Standard;}} -{\*\pgdscno0}\paperh15840\paperw12240\margl1417\margr1417\margt1417\margb1134\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1417\margrsxn1417\margtsxn1417\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc -\pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs20\lang1025\ab\ltrch\dbch\langfe1031\hich\fs20\lang1033\b\loch\fs20\lang1033\b {\rtlch \ltrch\loch\f0\fs20\lang1033\i0\b Boomshire} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs18\lang1025\ltrch\dbch\langfe1031\hich\fs18\lang1033\loch\fs18\lang1033 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs16\lang1025\ltrch\dbch\langfe1031\hich\fs16\lang1033\loch\fs16\lang1033 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs22\lang1025\ltrch\dbch\langfe1031\hich\fs22\lang1033\loch\fs22\lang1033{\rtlch \ltrch\loch\f0\fs22\lang1033\i0\b0\rtlch\ltrch\dbch\hich\fs16\loch\fs16 This cooperative race for two players is different from other races, because the players need to work together in order to win the race. None of the tasks can be solved alone.} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs16\lang1025\ltrch\dbch\langfe1031\hich\fs16\lang1033\loch\fs16\lang1033 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs16\lang1025\ltrch\dbch\langfe1031\hich\fs16\lang1033\loch\fs16\lang1033 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ql\rtlch\afs22\lang1025\ltrch\dbch\langfe1031\hich\fs22\lang1033\loch\fs22\lang1033{\rtlch \ltrch\loch\f0\fs22\lang1033\i0\b0\rtlch\ltrch\dbch\hich\fs16\loch\fs16 Warning: Needs exactly two players!} -\par } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Straw.ocd/Particle.txt b/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Straw.ocd/Particle.txt deleted file mode 100644 index be68d326a..000000000 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Straw.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Straw -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=50 -AlphaFade=0 -RByV=1 -Attach=1 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/BristleRidge.ocs/DescUS.rtf deleted file mode 100644 index 7a9240932..000000000 Binary files a/planet/BackToTheRocks.ocf/BristleRidge.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/Cavern.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/Cavern.ocs/DescUS.rtf deleted file mode 100644 index 983cdd948..000000000 Binary files a/planet/BackToTheRocks.ocf/Cavern.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/DescDE.rtf b/planet/BackToTheRocks.ocf/DescDE.rtf deleted file mode 100644 index b4a8ae3b0..000000000 Binary files a/planet/BackToTheRocks.ocf/DescDE.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/DescUS.rtf b/planet/BackToTheRocks.ocf/DescUS.rtf deleted file mode 100644 index 795134c45..000000000 Binary files a/planet/BackToTheRocks.ocf/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/FrozenFortress.ocs/DescUS.rtf deleted file mode 100644 index 2d8fe9ead..000000000 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/DescUS.rtf +++ /dev/null @@ -1,25 +0,0 @@ -{\rtf1\ansi\deff0\adeflang1025 -{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Times New Roman;}{\f4\fnil\fprq2\fcharset0 MS Mincho;}{\f5\fnil\fprq0\fcharset0 Tahoma;}} -{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} -{\stylesheet{\s1\rtlch\afs24\lang255\ltrch\dbch\langfe255\hich\fs24\lang4105\loch\fs24\lang4105\snext1 Normal;} -{\s2\sb240\sa120\keepn\rtlch\af2\afs28\lang255\ltrch\dbch\af4\langfe255\hich\f2\fs28\lang4105\loch\f2\fs28\lang4105\sbasedon1\snext3 Heading;} -{\s3\sa120\rtlch\afs24\lang255\ltrch\dbch\langfe255\hich\fs24\lang4105\loch\fs24\lang4105\sbasedon1\snext3 Body Text;} -{\s4\sa120\rtlch\afs24\lang255\ltrch\dbch\langfe255\hich\fs24\lang4105\loch\fs24\lang4105\sbasedon3\snext4 List;} -{\s5\sb120\sa120\rtlch\af5\afs24\lang255\ai\ltrch\dbch\langfe255\hich\fs24\lang4105\i\loch\fs24\lang4105\i\sbasedon1\snext5 caption;} -{\s6\rtlch\afs24\lang255\ltrch\dbch\langfe255\hich\fs24\lang4105\loch\fs24\lang4105\sbasedon1\snext6 Index;} -{\s7\sb120\sa120\rtlch\afs24\lang255\ai\ltrch\dbch\langfe255\hich\fs24\lang4105\i\loch\fs24\lang4105\i\sbasedon1\snext7 caption;} -} -{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern6800}}\deftab720 -{\*\pgdsctbl -{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} -{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc -\pard\plain \ltrpar\s1\ql\rtlch\afs20\lang255\ab\ltrch\dbch\langfe255\hich\fs20\lang4105\b\loch\fs20\lang4105\b {\rtlch \ltrch\loch\f0\fs20\lang4105\i0\b Frozen Fortress} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 Two rivaling fortresses are fighting in these unfavourable surroundings.} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 - Steal your enemy's flag and bring it to your base!} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 - Three useful spells which are bound to scrolls can help you.} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 - The chests are restocked often with weapons and other useful stuff.} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 - The geyser in the middle of the map erupts almost once a minute.} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 - Because it's so cold here, you can't dig ice, but you can still blast it.} -\par \pard\plain \ltrpar\s1\ql\rtlch\afs16\lang255\ltrch\dbch\langfe255\hich\fs16\lang4105\loch\fs16\lang4105 {\rtlch \ltrch\loch\f0\fs16\lang4105\i0\b0 - The gates open automatically when a friendly Clonk comes within range.} -\par } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/StringTblDE.txt b/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/StringTblDE.txt deleted file mode 100644 index 5c8663f48..000000000 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/StringTblDE.txt +++ /dev/null @@ -1,9 +0,0 @@ -Name=Flagge - -MsgBeamFlag=Teleportiere die Flagge in deine Basis. -MsgGrabFlag=Schnapp dir die Flagge und bring sie in deine Basis. - -MsgFlagStolen=%s hat die Flagge von %s geklaut. -MsgFlagBeamed=%s hat die Flagge in ihre Basis zurueckgebeamt. -MsgFlagCaptured=%s hat erfolgreich die Flagge geklaut, und damit fuer sein Team einen Punkt gemacht. -MsgFlagRestored=Die Flagge von %s wurde zurueckgesetzt. diff --git a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/StringTblUS.txt b/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/StringTblUS.txt deleted file mode 100644 index 6d78cc999..000000000 --- a/planet/BackToTheRocks.ocf/FrozenFortress.ocs/Flag.ocd/StringTblUS.txt +++ /dev/null @@ -1,9 +0,0 @@ -Name=Flag - -MsgBeamFlag=Beam the flag to your base. -MsgGrabFlag=Grab the flag and carry it to your base. - -MsgFlagStolen=%s stole the flag of %s. -MsgFlagBeamed=%s beamed the flag to their base. -MsgFlagCaptured=%s successfully captured a flag, and scored a point. -MsgFlagRestored=The flag of %s got restored. \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/Hideout.ocs/DescDE.rtf deleted file mode 100644 index 8a67108c4..000000000 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/DescDE.rtf +++ /dev/null @@ -1,176 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} -{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;} -{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} -{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f410\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f417\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid3944165\rsid4480968\rsid8603462\rsid12124512\rsid13005169}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0 -\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator MimmoO}{\creatim\yr2010\mo12\dy3\hr18\min34}{\revtim\yr2010\mo12\dy7\hr22\min24}{\version6}{\edmins0}{\nofpages1}{\nofwords87}{\nofchars553}{\nofcharsws639}{\vern32859}} -{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale160\rsidroot12124512 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid12124512 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\insrsid3944165 \hich\af0\dbch\af31505\loch\f0 Versteck}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 -\f0\fs20\insrsid12124512\charrsid12124512 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 -\par \hich\af0\dbch\af31505\loch\f0 \hich\f0 Besch\'fc\loch\f0 tze dein Versteck und versuche, di}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512 \hich\af0\dbch\af31505\loch\f0 e Flagge des Gegners zu erobern}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\insrsid12124512\charrsid12124512 \hich\af0\dbch\af31505\loch\f0 . Schnapp}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512 \hich\af0\dbch\af31505\loch\f0 '}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 -\hich\af0\dbch\af31505\loch\f0 \hich\f0 die die Flagge und bring sie in deine Basis, w\'e4\hich\af0\dbch\af31505\loch\f0 hrend sich deine Flagge in deiner Basis befindet, um zu punkten.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid8603462 -\hich\af0\dbch\af31505\loch\f0 -\par -\par \hich\af0\dbch\af31505\loch\f0 Einige Tipps:}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid8603462 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 \hich\af0\dbch\af31505\loch\f0 \hich\f0 - Toren k\'f6\loch\f0 \hich\f0 nnen zerst\'f6\loch\f0 rt werden. Die Tore in der Basis }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\insrsid12124512 \hich\af0\dbch\af31505\loch\f0 werden}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 \hich\af0\dbch\af31505\loch\f0 automatisch gesteuert. -\par \hich\af0\dbch\af31505\loch\f0 - Truhen in der Basis beinhalten grundlegen}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid13005169 \hich\af0\dbch\af31505\loch\f0 d}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 -\hich\af0\dbch\af31505\loch\f0 e Waffen. -\par \hich\af0\dbch\af31505\loch\f0 \hich\f0 - Truhen au\'df\loch\f0 erhalb der Basis beinhalt\hich\af0\dbch\af31505\loch\f0 en weitere Waffen. -\par \hich\af0\dbch\af31505\loch\f0 - Die mittlere Truhe beinhaltet viele Kristalle und besondere }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512 \hich\af0\dbch\af31505\loch\f0 \hich\f0 Gegenst\'e4\loch\f0 nde.}{\rtlch\fcs1 \af0\afs16 -\ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 -\par \hich\af0\dbch\af31505\loch\f0 - Wirf Kristalle}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid4480968 \hich\af0\dbch\af31505\loch\f0 !}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512\charrsid12124512 \hich\af0\dbch\af31505\loch\f0 }{ -\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid4480968 \hich\af0\dbch\af31505\loch\f0 Sie aktivieren sich beim Aufprall.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12124512 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid4480968 \hich\af0\dbch\af31505\loch\f0 \hich\f0 - Get\'f6\loch\f0 tete Gegner hi\hich\af0\dbch\af31505\loch\f0 nt\hich\af0\dbch\af31505\loch\f0 -erlassen einen Heilkristall. Dieser heilt den Clonk bei benutzung langsam.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid4480968\charrsid12124512 -\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12124512 {\rtlch\fcs1 \af31507\afs16 \ltrch\fcs0 \insrsid3944165\charrsid12124512 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000308e -01195596cb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/Hideout.ocs/DescUS.rtf deleted file mode 100644 index 5acc40f83..000000000 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/DescUS.rtf +++ /dev/null @@ -1,170 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid353196\rsid4794103\rsid5510515\rsid9379569\rsid11019026}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0 -\mnaryLim1}{\info{\operator MimmoO}{\creatim\yr2010\mo12\dy3\hr18\min20}{\revtim\yr2010\mo12\dy7\hr22\min25}{\version5}{\edmins0}{\nofpages1}{\nofwords71}{\nofchars450}{\nofcharsws520}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/ -word/2003/wordml}}\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale160\rsidroot9379569 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\lang1033\langfe1031\langnp1033\insrsid11019026\charrsid5510515 \hich\af0\dbch\af31505\loch\f0 Hideout}{ -\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\lang1033\langfe1031\langnp1033\insrsid11019026\charrsid5510515 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid11019026\charrsid5510515 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid11019026\charrsid9379569 \hich\af0\dbch\af31505\loch\f0 -Protect your hideout from the opposing team and try to capture the enemy flag. Steal and bring the enemy flag into your hideout once to }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid4794103 -\hich\af0\dbch\af31505\loch\f0 score}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid11019026\charrsid9379569 \hich\af0\dbch\af31505\loch\f0 . }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\lang1033\langfe1031\langnp1033\insrsid353196 -\par -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid11019026\charrsid9379569 \hich\af0\dbch\af31505\loch\f0 Some hints: -\par \hich\af0\dbch\af31505\loch\f0 - The gates can be destructed and are auto controlled for the hideout. -\par \hich\af0\dbch\af31505\loch\f0 - Chests inside the hideout contain basic weapons. -\par \hich\af0\dbch\af31505\loch\f0 - Chests outside the hideout contain more advanced weapons.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid11019026 -\par \hich\af0\dbch\af31505\loch\f0 - The central chest contains only gems and special stuff. -\par \hich\af0\dbch\af31505\loch\f0 - Throw \hich\af0\dbch\af31505\loch\f0 gems}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid5510515 \hich\af0\dbch\af31505\loch\f0 ! They activate on impact.}{\rtlch\fcs1 \af0\afs16 -\ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid11019026 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid5510515 \hich\af0\dbch\af31505\loch\f0 - Killed enemies leave a Heal Gem behind. Use it to slowly heal your clonk.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\lang1033\langfe1031\langnp1033\insrsid5510515\charrsid9379569 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000d042 -e2385596cb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/StringTblDE.txt b/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/StringTblDE.txt deleted file mode 100644 index 5c8663f48..000000000 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/StringTblDE.txt +++ /dev/null @@ -1,9 +0,0 @@ -Name=Flagge - -MsgBeamFlag=Teleportiere die Flagge in deine Basis. -MsgGrabFlag=Schnapp dir die Flagge und bring sie in deine Basis. - -MsgFlagStolen=%s hat die Flagge von %s geklaut. -MsgFlagBeamed=%s hat die Flagge in ihre Basis zurueckgebeamt. -MsgFlagCaptured=%s hat erfolgreich die Flagge geklaut, und damit fuer sein Team einen Punkt gemacht. -MsgFlagRestored=Die Flagge von %s wurde zurueckgesetzt. diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/StringTblUS.txt b/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/StringTblUS.txt deleted file mode 100644 index 6d78cc999..000000000 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/Flag.ocd/StringTblUS.txt +++ /dev/null @@ -1,9 +0,0 @@ -Name=Flag - -MsgBeamFlag=Beam the flag to your base. -MsgGrabFlag=Grab the flag and carry it to your base. - -MsgFlagStolen=%s stole the flag of %s. -MsgFlagBeamed=%s beamed the flag to their base. -MsgFlagCaptured=%s successfully captured a flag, and scored a point. -MsgFlagRestored=The flag of %s got restored. \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Script.c b/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Script.c deleted file mode 100644 index 06b628565..000000000 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/LifeGem.ocd/Script.c +++ /dev/null @@ -1,55 +0,0 @@ -/*--- Life Gem ---*/ - -local Collectible = 1; -local Name = "$Name$"; -local Description = "$Description$"; - -// does not fade out. Who wants to leave it lying around anyway! -func HasNoFadeOut(){return true;} - -func Initialize() -{ - AddEffect("Sparkle", this, 10, 2, this); - return 1; -} - -func FxSparkleTimer(target, effect, effect_time) -{ - if(this()->Contained()) return; - CreateParticle("MagicRing", 0, 0, 0, 0, Cos(effect_time*10, 100), RGBa(255,20,20,100), this, false); - return true; -} - -public func ControlUse(object clonk, int ix, int iy) -{ - // applies the healing effect even when the Clonk is at full HP - // does this because you can block one source of damage - AddEffect("GemHealing", clonk, 10, 4, nil, this->GetID()); - clonk->Sound("Breathing", false, 50, nil); - this->RemoveObject(); - return true; -} - -func FxGemHealingTimer(target, effect, effect_time) -{ - if(target->GetEnergy() >= target->GetMaxEnergy()) - { - if(effect_time < 36) return 0; - return -1; - } - target->DoEnergy(500, true); - var xoff=RandomX(-5,5); - for(var fac=-1; fac <= 1;fac+=2)CreateParticle("Magic", AbsX(target->GetX()) + fac * xoff, AbsY(target->GetY()) + RandomX(-8,8), 0, -2, 40, RGB(255,200,200), target, Random(2)); - if(!Random(10)) effect.switcher=!effect.switcher; - if(effect.switcher) - CreateParticle("MagicSpark", AbsX(target->GetX()) + RandomX(-3,3), AbsY(target->GetY()) + RandomX(-0,8), 0, -2, 30, RGBa(255,55,55, 50), target, Random(2)); -} - -func FxGemHealingDamage(target, effect, damage, cause) -{ - if(damage >= 0) return damage; - RemoveEffect(nil, target, effect); - - // can actually block one source of damage - use wisely - return 0; -} diff --git a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Script.c b/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Script.c deleted file mode 100644 index ddce144cc..000000000 --- a/planet/BackToTheRocks.ocf/Hideout.ocs/ShieldGem.ocd/SolidCrystal.ocd/Script.c +++ /dev/null @@ -1,16 +0,0 @@ -/*-- CrystalShield --*/ - - -protected func Initialize() -{ - AddEffect("Selfdestruction",this,100,4+Random(2),this,this->GetID()); - return; -} - -func FxSelfdestructionTimer(object target, effect, int timer) -{ - CreateParticle("Magic",RandomX(-4,4),RandomX(-4,4),0,0,12+Random(10),target->GetClrModulation()); - if(timer>175) target->RemoveObject(); - return 1; -} - diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/MeleeMountain.ocs/DescDE.rtf deleted file mode 100644 index 653a296ae..000000000 Binary files a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/MeleeMountain.ocs/DescUS.rtf deleted file mode 100644 index 02a7bbbc8..000000000 Binary files a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Map.bmp b/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Map.bmp deleted file mode 100644 index 6284358d2..000000000 Binary files a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Map.bmp and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Mountains2.jpg b/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Mountains2.jpg deleted file mode 100644 index c44c001b1..000000000 Binary files a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Mountains2.jpg and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Script.c b/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Script.c deleted file mode 100644 index b6db81fa0..000000000 --- a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Script.c +++ /dev/null @@ -1,60 +0,0 @@ -/*-- Mountain Melee --*/ - -protected func Initialize() -{ - CreateObject(Goal_LastManStanding, 0, 0, NO_OWNER); - SetSkyAdjust(RGB(230, 210, 150), RGB(150, 100, 0)); - //Environment - PlaceGrass(80); - // Chests. - CreateObject(Chest, 600, 495, NO_OWNER); - CreateObject(Chest, 1169, 454, NO_OWNER); - CreateObject(Chest, 1123, 124, NO_OWNER); - CreateObject(Chest, 180, 404, NO_OWNER); - CreateObject(Chest, 261, 163, NO_OWNER); - CreateObject(Rule_ObjectFade)->DoFadeTime(5 * 36); - CreateObject(Rule_KillLogs); - AddEffect("IntFillChests", nil, 100, 70, this); - return; -} - -// Gamecall from lastmanstanding rule, on respawning. -protected func OnPlayerRelaunch(int plr) -{ - var clonk = GetCrew(plr); - var relaunch = CreateObject(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner()); - relaunch->StartRelaunch(clonk); - return; -} - -// Refill chests. -global func FxIntFillChestsTimer() -{ - var chest = FindObjects(Find_ID(Chest), Sort_Random())[0]; - var w_list = [Shovel,Bow,Musket,Club,Javelin,Boompack,Loam,Firestone,JarOfWinds,GrappleBow]; - - if (chest->ContentsCount() < 5) - chest->CreateChestContents(w_list[Random(GetLength(w_list))]); -} - -global func CreateChestContents(id obj_id) -{ - if (!this) - return; - var obj = CreateObject(obj_id); - if (obj_id == Bow) - obj->CreateContents(Arrow); - if (obj_id == Musket) - obj->CreateContents(LeadShot); - obj->Enter(this); - return; -} - -// GameCall from lastmanstanding -func OnClonkLeftRelaunch(object clonk) -{ - clonk->SetPosition(RandomX(30, LandscapeWidth() - 30), -20); -} - -func KillsToRelaunch() { return 0; } -func RelaunchWeaponList(){ return [Boompack, JarOfWinds, GrappleBow, Shovel]; } diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Title.txt b/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Title.txt deleted file mode 100644 index 28eff0303..000000000 --- a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Bergkampf -US:Mountain Melee \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/DescDE.rtf deleted file mode 100644 index ab81f27bb..000000000 Binary files a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/DescUS.rtf deleted file mode 100644 index b6fab7c43..000000000 Binary files a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/MagicFire.ocd/Graphics.png b/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/MagicFire.ocd/Graphics.png deleted file mode 100644 index 1aace6bb8..000000000 Binary files a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/MagicFire.ocd/Graphics.png and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/MagicFire.ocd/Particle.txt b/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/MagicFire.ocd/Particle.txt deleted file mode 100644 index 03e6a3db5..000000000 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/MagicFire.ocd/Particle.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Particle] -Name=MagicFire2 -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,128,128,-64,-64 -Delay=0 -Repeats=1 -GravityAcc=-4 -VertexCount=1 -VertexY=64 -AlphaFade=3 -Additive=1 -RByV=0 -Attach=0 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Sword.c b/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Sword.c deleted file mode 100644 index 6fb04b08c..000000000 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/King_Sword.c +++ /dev/null @@ -1,105 +0,0 @@ -#appendto Sword - -local king_size; - -public func MakeKingSize() { king_size = true; SetMeshMaterial("KingSword2",0); } -public func MakeNormalSize() { king_size = false; SetMeshMaterial("Sword2",0); } -public func Departure() { MakeNormalSize(); } - - -func CheckStrike(iTime) -{ - - - //if(iTime < 20) return; - var offset_x=7; - var offset_y=0; - if(Contained()->GetDir() == DIR_Left) offset_x*=-1; - - if(!(Contained()->GetContact(-1) & CNAT_Bottom)) - offset_y=10; - - var width=10; - var height=20; - var angle=0; - - var doBash=Abs(Contained()->GetXDir()) > 5 || Abs(Contained()->GetYDir()) > 5; - if(!doBash) doBash=Contained()->GetContact(-1) & CNAT_Bottom; - - if(doBash) - { - if(Contained()->GetDir() == DIR_Left) - angle=-(Max(5, Abs(Contained()->GetXDir()))); - else angle=(Max(5, Abs(Contained()->GetXDir()))); - } - - for(var obj in FindObjects(Find_AtRect(offset_x - width/2, offset_y - height/2, width, height), - Find_NoContainer(), - Find_Exclude(Contained()), - Find_Layer(GetObjectLayer()))) - { - if (obj->~IsProjectileTarget(this, Contained()) || obj->GetOCF() & OCF_Alive) - { - var effect_name=Format("HasBeenHitBySwordEffect%d", magic_number); - var sword_name=Format("HasBeenHitBySword%d", this->ObjectNumber()); - var first=true; - // don't hit objects twice - if(!GetEffect(effect_name, obj)) - { - AddEffect(effect_name, obj, 1, 60 /* arbitrary */, 0, 0); - - if(GetEffect(sword_name, obj)) - { - //Log("successive hit"); - first=false; - } - else - { - //Log("first hit overall"); - AddEffect(sword_name, obj, 1, 40, 0, 0); - } - - if(!king_size) - { - // Reduce damage by shield - var shield=ApplyShieldFactor(Contained(), obj, 0); // damage out of scope? - if(shield == 100) - continue; - } - // fixed damage (10) - var damage=((100-shield)*10*1000 / 100); - if(king_size) damage+=3000+Random(3000); - ProjectileHit(obj, damage, ProjectileHit_no_query_catch_blow_callback | ProjectileHit_exact_damage | ProjectileHit_no_on_projectile_hit_callback, FX_Call_EngGetPunched); - - // object has not been deleted? - if(obj) - { - if(offset_y) - ApplyWeaponBash(obj, 100, 0); - else - if(!first) - ApplyWeaponBash(obj, damage/50, Angle(0, 0, angle, -10)); - else - if(!offset_y) - DoWeaponSlow(obj, 300); - - // Particle effect - var x=-1; - var p="Slice2"; - if(Contained()->GetDir() == DIR_Right) - { - x=1; - p="Slice1"; - } - CreateParticle(p, AbsX(obj->GetX())+RandomX(-1,1), AbsY(obj->GetY())+RandomX(-1,1), 0, 0, 100, RGB(255,255,255), obj); - } - - // sound and done. We can only hit one target - Sound(Format("WeaponHit%d.ogg", 1+Random(3)), false); - break; - } - } - } - -} - diff --git a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/MultipleSelection.c b/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/MultipleSelection.c deleted file mode 100644 index 03d79eb5f..000000000 --- a/planet/BackToTheRocks.ocf/MoltenMonarch.ocs/System.ocg/MultipleSelection.c +++ /dev/null @@ -1,42 +0,0 @@ -/* larger dynamite explosion */ - -#appendto RelaunchContainer - -private func OpenWeaponMenu(object clonk) -{ - if (!menu) - { - var weapons = WeaponList(); - if(weapons) - { - menu = clonk->CreateRingMenu(Clonk, this); - for (var weapon in weapons) - { - if(weapon == Firestone) menu->AddItem(weapon,2); - else if(weapon == Dynamite) menu->AddItem(weapon,2); - else menu->AddItem(weapon); - } - menu->Show(); - } - } -} - - -public func Selected(object menu, object selector, bool alt) -{ - if (!selector) - return false; - - for (var i = 0; i < selector->GetAmount(); i++) - { - var newobj = CreateObject(selector->GetSymbol()); - if (newobj->GetID() == Bow) - newobj->CreateContents(Arrow); - if (newobj->GetID() == Musket) - newobj->CreateContents(LeadShot); - Contents()->Collect(newobj); - } - menu->Show(); - RelaunchClonk(); - return true; -} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/Overcast.ocs/DescDE.rtf deleted file mode 100644 index 3c61ca66b..000000000 --- a/planet/BackToTheRocks.ocf/Overcast.ocs/DescDE.rtf +++ /dev/null @@ -1,162 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid2063973\rsid9125203}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator MimmoO} -{\creatim\yr2010\mo10\dy17\hr22\min53}{\revtim\yr2010\mo10\dy18\hr17\min17}{\version3}{\edmins0}{\nofpages1}{\nofwords58}{\nofchars369}{\nofcharsws426}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale150\rsidroot9125203 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\insrsid2063973 \hich\af0\dbch\af31505\loch\f0 Bedeckt}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 -\f0\fs20\insrsid9125203 -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid9125203 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid2063973 \hich\af0\dbch\af31505\loch\f0 Hoch oben in den Wolken befinden sich - entgegen jeder \hich\af0\dbch\af31505\loch\f0 Vernunft\hich\af0\dbch\af31505\loch\f0 - - schwebende Gesteinsbrocken. Mutige Forscher machten sich auf, um die dortige Gegend zu erkunden, und trafen dort auf an Schriftrollen gebundene Zauber. Getrieben von der Gier nach diesen Schriftrollen beginnt ein Kampf, bei -\hich\af0\dbch\af31505\loch\f0 dem auch selbige zu Einsatz kommen.\hich\af0\dbch\af31505\loch\f0 \hich\f0 Schau blo\'df\loch\f0 nicht runter! -\par -\par \hich\af0\dbch\af31505\loch\f0 \hich\f0 Ein Melee in luftigen H\'f6\loch\f0 hen. Wer als letzter noch lebt, gewinnt. -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid9125203 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000000ee -248ed76ecb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Overcast.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/Overcast.ocs/DescUS.rtf deleted file mode 100644 index 0cfae75a1..000000000 Binary files a/planet/BackToTheRocks.ocf/Overcast.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/RockBottom.ocs/DescDE.rtf deleted file mode 100644 index 97fafd606..000000000 --- a/planet/BackToTheRocks.ocf/RockBottom.ocs/DescDE.rtf +++ /dev/null @@ -1,159 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid2782181\rsid3020466\rsid8216789\rsid8880064}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info -{\operator MimmoO}{\creatim\yr2010\mo10\dy9\hr17\min50}{\revtim\yr2010\mo10\dy9\hr22\min3}{\version5}{\edmins0}{\nofpages1}{\nofwords13}{\nofchars83}{\nofcharsws95}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale150\rsidroot3020466 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\insrsid8216789 \hich\af0\dbch\af31505\loch\f0 Im Brunnen}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 -\f0\fs20\insrsid3020466 -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid3020466 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid3020466 \hich\af0\dbch\af31505\loch\f0 Unten im Brunnen beginnt ein Gefecht. Eine }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid2782181 \hich\af0\dbch\af31505\loch\f0 winzige}{\rtlch\fcs1 -\af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid3020466 \hich\af0\dbch\af31505\loch\f0 \hich\f0 Arena f\'fc\loch\f0 r zwei bis }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid8880064 \hich\af0\dbch\af31505\loch\f0 vier}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\insrsid3020466 \hich\af0\dbch\af31505\loch\f0 Spieler.}{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid3020466 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000d05b -b506ed67cb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/RockBottom.ocs/DescUS.rtf deleted file mode 100644 index 872308b2c..000000000 --- a/planet/BackToTheRocks.ocf/RockBottom.ocs/DescUS.rtf +++ /dev/null @@ -1,160 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid467672\rsid6753429\rsid11423277\rsid12786061}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1} -{\info{\operator MimmoO}{\creatim\yr2010\mo10\dy9\hr17\min52}{\revtim\yr2010\mo10\dy9\hr22\min3}{\version5}{\edmins0}{\nofpages1}{\nofwords12}{\nofchars78}{\nofcharsws89}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/word -ml}}\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale150\rsidroot6753429 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\lang1033\langfe1031\langnp1033\insrsid467672 \hich\af0\dbch\af31505\loch\f0 Rock Bottom}{\rtlch\fcs1 -\af0\afs20 \ltrch\fcs0 \f0\fs20\lang1033\langfe1031\langnp1033\insrsid6753429\charrsid6753429 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid6753429\charrsid6753429 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid6753429 \hich\af0\dbch\af31505\loch\f0 Down in the fountain, a battle begins. A }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\lang1033\langfe1031\langnp1033\insrsid11423277 \hich\af0\dbch\af31505\loch\f0 tiny}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid6753429 \hich\af0\dbch\af31505\loch\f0 arena for two to }{\rtlch\fcs1 -\af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid12786061 \hich\af0\dbch\af31505\loch\f0 four}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid6753429 \hich\af0\dbch\af31505\loch\f0 players.}{ -\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid6753429\charrsid6753429 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000080e9 -8601ed67cb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/Map.bmp b/planet/BackToTheRocks.ocf/RockBottom.ocs/Map.bmp deleted file mode 100644 index eae09132a..000000000 Binary files a/planet/BackToTheRocks.ocf/RockBottom.ocs/Map.bmp and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/RockBottom.ocs/System.ocg/MultipleSelection.c b/planet/BackToTheRocks.ocf/RockBottom.ocs/System.ocg/MultipleSelection.c deleted file mode 100644 index 03d79eb5f..000000000 --- a/planet/BackToTheRocks.ocf/RockBottom.ocs/System.ocg/MultipleSelection.c +++ /dev/null @@ -1,42 +0,0 @@ -/* larger dynamite explosion */ - -#appendto RelaunchContainer - -private func OpenWeaponMenu(object clonk) -{ - if (!menu) - { - var weapons = WeaponList(); - if(weapons) - { - menu = clonk->CreateRingMenu(Clonk, this); - for (var weapon in weapons) - { - if(weapon == Firestone) menu->AddItem(weapon,2); - else if(weapon == Dynamite) menu->AddItem(weapon,2); - else menu->AddItem(weapon); - } - menu->Show(); - } - } -} - - -public func Selected(object menu, object selector, bool alt) -{ - if (!selector) - return false; - - for (var i = 0; i < selector->GetAmount(); i++) - { - var newobj = CreateObject(selector->GetSymbol()); - if (newobj->GetID() == Bow) - newobj->CreateContents(Arrow); - if (newobj->GetID() == Musket) - newobj->CreateContents(LeadShot); - Contents()->Collect(newobj); - } - menu->Show(); - RelaunchClonk(); - return true; -} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/Ruins.ocs/DescDE.rtf deleted file mode 100644 index e1f61183b..000000000 Binary files a/planet/BackToTheRocks.ocf/Ruins.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/Ruins.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/Ruins.ocs/DescUS.rtf deleted file mode 100644 index d88aecf6b..000000000 Binary files a/planet/BackToTheRocks.ocf/Ruins.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/DescDE.rtf deleted file mode 100644 index b3f2150df..000000000 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/DescDE.rtf +++ /dev/null @@ -1,163 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid2063973\rsid4814691\rsid9125203\rsid12532703\rsid16718851}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0 -\mnaryLim1}{\info{\operator MimmoO}{\creatim\yr2010\mo10\dy17\hr22\min53}{\revtim\yr2011\mo2\dy11\hr18\min10}{\version6}{\edmins0}{\nofpages1}{\nofwords54}{\nofchars307}{\nofcharsws360}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office -/word/2003/wordml}}\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale150\rsidroot9125203 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\insrsid4814691 \hich\af0\dbch\af31505\loch\f0 Versengt\hich\af0\dbch\af31505\loch\f0 \hich\f0 e G\'e4\loch\f0 -rten}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\insrsid9125203 -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid9125203 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid4814691 \hich\af0\dbch\af31505\loch\f0 \hich\f0 Einst ein wahres Paradies, sind die Versengten G\'e4\loch\f0 \hich\f0 rten nun nichts weiter als eine raue Gegend, in der nur noch feuerfestes Gew\'e4 -\loch\f0 \hich\f0 chs gedeiht. Neben der Bedrohung durch deine Feinde machen dir auch noch die Lava und pl\'f6\loch\f0 tzlich auftauchende Meteoriten da\hich\af0\dbch\af31505\loch\f0 s Leben Schwer.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\insrsid2063973 -\par -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid4814691 \hich\af0\dbch\af31505\loch\f0 Eine\hich\af0\dbch\af31505\loch\f0 feurige Last-Man-Standing Runde. Bleib als Letzer am Leben und gewinne!}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\insrsid2063973 -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid9125203 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000060b0 -df910ecacb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/DescUS.rtf deleted file mode 100644 index 0d5b94b9e..000000000 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/DescUS.rtf +++ /dev/null @@ -1,162 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid9926211\rsid14300856}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator MimmoO} -{\creatim\yr2010\mo12\dy16\hr15\min54}{\revtim\yr2011\mo2\dy11\hr17\min54}{\version3}{\edmins0}{\nofpages1}{\nofwords45}{\nofchars285}{\nofcharsws329}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale160\rsidroot14300856 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\lang1033\langfe1031\langnp1033\insrsid9926211 \hich\af0\dbch\af31505\loch\f0 S\hich\af0\dbch\af31505\loch\f0 -corched Gardens}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\lang1033\langfe1031\langnp1033\insrsid14300856\charrsid14300856 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid9926211 \hich\af0\dbch\af31505\loch\f0 -Once a beautiful place, the Scorched Gardens are now nothing more than a deserted place, where only fire-proof plants can grow. In addition to the threat posed b\hich\af0\dbch\af31505\loch\f0 y your enemies, lava pools and randomly -\hich\af0\dbch\af31505\loch\f0 occurring\hich\af0\dbch\af31505\loch\f0 meteorites \hich\af0\dbch\af31505\loch\f0 only wait to kill you.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 -\par -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid9926211 \hich\af0\dbch\af31505\loch\f0 A fiery Last-Man-Standing round. Survive as the last one and win.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000e063 -a95a0ccacb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Grass.ocd/Graphics.png b/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Grass.ocd/Graphics.png deleted file mode 100644 index 175f7dd06..000000000 Binary files a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Grass.ocd/Graphics.png and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Grass.ocd/Particle.txt b/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Grass.ocd/Particle.txt deleted file mode 100644 index 2e89adf9d..000000000 --- a/planet/BackToTheRocks.ocf/ScorchedGardens.ocs/Grass.ocd/Grass.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Grass -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=20 -AlphaFade=0 -RByV=3 -Attach=0 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/ShiverPeak.ocs/DescDE.rtf deleted file mode 100644 index 20a0dbc67..000000000 --- a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/DescDE.rtf +++ /dev/null @@ -1,19 +0,0 @@ -{\rtf1\ansi\deff0\adeflang1025 -{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Times New Roman;}{\f4\fmodern\fprq1\fcharset0 Courier New;}{\f5\fnil\fprq2\fcharset0 MS Mincho;}{\f6\fnil\fprq2\fcharset0 Tahoma;}{\f7\fnil\fprq0\fcharset0 Tahoma;}} -{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} -{\stylesheet{\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\snext1 Normal;} -{\s2\sb240\sa120\keepn\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs28\lang255\ltrch\dbch\af5\langfe255\hich\f2\fs28\lang4105\loch\f2\fs28\lang4105\sbasedon1\snext3 Heading;} -{\s3\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\sbasedon1\snext3 Body Text;} -{\s4\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af7\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\sbasedon3\snext4 List;} -{\s5\sb120\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af7\afs24\lang255\ai\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\i\loch\f0\fs24\lang4105\i\sbasedon1\snext5 caption;} -{\s6\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af7\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\sbasedon1\snext6 Index;} -} -{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern6800}}\deftab720 -{\*\pgdsctbl -{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} -{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc -\pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs20\lang255\ab\ltrch\dbch\af0\langfe255\hich\f0\fs20\lang1031\b\loch\f0\fs20\lang1031\b {\rtlch \ltrch\loch\f0\fs20\lang1031\i0\b Schauderberg} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs24\lang255\ab\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang1031\b\loch\f0\fs24\lang1031\b -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sa283\rtlch\af0\afs16\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs16\lang1033\loch\f0\fs16\lang1033{\rtlch \ltrch\loch\f0\fs16\lang1033\i0\b0{\ltrch\hich\lang1031\loch\lang1031 {\*\bkmkstart DDE_LINK}F\'fchre deine Mannschaft an die Spitze des sagenumwobenen Schauderberg!}}{\rtlch \ltrch\loch\f0\fs16\lang1033\i0\b0 {\*\bkmkend DDE_LINK} Als ein Luftschiff gegen die Bergspitze flog, verlor es eine Ladung Schie\'dfpulver und Dynamit, deshalb wirst du wahrscheinlich gen\'fcgend Sprengstoff \'fcber den Berg verstreut finden.} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs16\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs16\lang1031\loch\f0\fs16\lang1031 {\rtlch \ltrch\loch\f0\fs16\lang1031\i0\b0 Ein Wettrennen auf die Spitze des Berges, geeignet f\'fcr jede Anzahl von Spielern.} -\par } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/ShiverPeak.ocs/DescUS.rtf deleted file mode 100644 index 10fbc8ac5..000000000 --- a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/DescUS.rtf +++ /dev/null @@ -1,20 +0,0 @@ -{\rtf1\ansi\deff0\adeflang1025 -{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Times New Roman;}{\f4\fnil\fprq2\fcharset0 MS Mincho;}{\f5\fnil\fprq2\fcharset0 Tahoma;}{\f6\fnil\fprq0\fcharset0 Tahoma;}} -{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} -{\stylesheet{\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\snext1 Normal;} -{\s2\sb240\sa120\keepn\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af5\afs28\lang255\ltrch\dbch\af4\langfe255\hich\f2\fs28\lang4105\loch\f2\fs28\lang4105\sbasedon1\snext3 Heading;} -{\s3\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\sbasedon1\snext3 Body Text;} -{\s4\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\sbasedon3\snext4 List;} -{\s5\sb120\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs24\lang255\ai\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\i\loch\f0\fs24\lang4105\i\sbasedon1\snext5 caption;} -{\s6\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs24\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs24\lang4105\loch\f0\fs24\lang4105\sbasedon1\snext6 Index;} -} -{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern6800}}\deftab720 -{\*\pgdsctbl -{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} -{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc -\pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs20\lang255\ab\ltrch\dbch\af0\langfe255\hich\f0\fs20\lang1031\b\loch\f0\fs20\lang1031\b {\rtlch \ltrch\loch\f0\fs20\lang1031\i0\b Shiver Peak} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs16\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs16\lang1031\loch\f0\fs16\lang1031 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs16\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs16\lang1031\loch\f0\fs16\lang1031 {\rtlch \ltrch\loch\f0\fs16\lang1031\i0\b0 Lead your expedition to the top of the fabled Shiver Peak! A shipment of gunpowder and dynamite was lost when a blimp crashed into the tall peak, so you'll likely find ample explosives scattered about the mountain.} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs16\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs16\lang1031\loch\f0\fs16\lang1031 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af0\afs16\lang255\ltrch\dbch\af0\langfe255\hich\f0\fs16\lang1031\loch\f0\fs16\lang1031 {\rtlch \ltrch\loch\f0\fs16\lang1031\i0\b0 A cooperative parkour to reach the top of the mountain, suitable for any number of players.} -\par } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/DescDE.rtf b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/DescDE.rtf deleted file mode 100644 index f2fbfdd83..000000000 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/DescDE.rtf +++ /dev/null @@ -1,165 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid2063973\rsid9125203\rsid12532703\rsid16718851}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1} -{\info{\operator MimmoO}{\creatim\yr2010\mo10\dy17\hr22\min53}{\revtim\yr2010\mo12\dy16\hr15\min57}{\version5}{\edmins0}{\nofpages1}{\nofwords56}{\nofchars360}{\nofcharsws415}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003 -/wordml}}\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale150\rsidroot9125203 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\insrsid12532703 \hich\af0\dbch\af31505\loch\f0 Donnernde Himmel}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 -\f0\fs20\insrsid9125203 -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid9125203 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid16718851 \hich\af0\dbch\af31505\loch\f0 Erlange die Herrschaf}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12532703 \hich\af0\dbch\af31505\loch\f0 \hich\f0 t \'fc\loch\f0 -ber diese Himmelsinsel, die h\hich\af0\dbch\af31505\loch\f0 o\hich\af0\dbch\af31505\loch\f0 ch oben in den Wolken \hich\af0\dbch\af31505\loch\f0 schwebt. Zahlreiche Waffen, Zauber und Umgebungsobjekte helfen dir, deine \hich\af0\dbch\af31505\loch\f0 G -\hich\af0\dbch\af31505\loch\f0 egner zu vernichten.\hich\af0\dbch\af31505\loch\f0 \hich\f0 T\'f6\loch\f0 \hich\f0 te Gegner als K\'f6\loch\f0 \hich\f0 nig oder t\'f6\loch\f0 \hich\f0 te den aktuellen K\'f6\loch\f0 \hich\f0 nig, um zu punkten. Als K\'f6 -\loch\f0 nig wirst du um 30% des Schadens, den du verursachst, geheilt!}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid2063973 -\par -\par \hich\af0\dbch\af31505\loch\f0 Ein}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid12532703 \hich\af0\dbch\af31505\loch\f0 e}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\insrsid2063973 \hich\af0\dbch\af31505\loch\f0 }{\rtlch\fcs1 \af0\afs16 -\ltrch\fcs0 \f0\fs16\insrsid12532703 \hich\af0\dbch\af31505\loch\f0 King-of-the-Hill-Runde\hich\af0\dbch\af31505\loch\f0 \hich\f0 in luftigen H\'f6\loch\f0 hen. Wer zuerst 10 Punkte erreicht, gewinnt.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\insrsid2063973 -\par }{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\insrsid9125203 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000070bd -e07d319dcb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/DescUS.rtf b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/DescUS.rtf deleted file mode 100644 index 72c0bee0b..000000000 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/DescUS.rtf +++ /dev/null @@ -1,163 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} -{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} -{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid14300856}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator MimmoO} -{\creatim\yr2010\mo12\dy16\hr15\min54}{\revtim\yr2010\mo12\dy16\hr15\min59}{\version2}{\edmins0}{\nofpages1}{\nofwords70}{\nofchars321}{\nofcharsws390}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale160\rsidroot14300856 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\lang1033\langfe1031\langnp1033\insrsid14300856\charrsid14300856 \hich\af0\dbch\af31505\loch\f0 -Thunderous Skies}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\lang1033\langfe1031\langnp1033\insrsid14300856\charrsid14300856 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 -\par }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 \hich\af0\dbch\af31505\loch\f0 Claim the rule over this sky island, which floats up high in the sky. Numerous weapons, spells and enviro -\hich\af0\dbch\af31505\loch\f0 n\hich\af0\dbch\af31505\loch\f0 ment objects\hich\af0\dbch\af31505\loch\f0 will help you to fight your enemies. Kill and enemy as the king, or kill the current king to score a point. You get healed by 30% of th -\hich\af0\dbch\af31505\loch\f0 e damage you do, while you are the king.}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 -\par -\par \hich\af0\dbch\af31505\loch\f0 A }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 \hich\af0\dbch\af31505\loch\f0 King-of-the-Hill-round}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 -\f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 \hich\af0\dbch\af31505\loch\f0 in great heights. Who }{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 \hich\af0\dbch\af31505\loch\f0 -scores 10 points first}{\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1033\langfe1031\langnp1033\insrsid14300856 \hich\af0\dbch\af31505\loch\f0 , wins. -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000f047 -a7ca319dcb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningSpark.ocd/Graphics.png b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningSpark.ocd/Graphics.png deleted file mode 100644 index 9032951cd..000000000 Binary files a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningSpark.ocd/Graphics.png and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningSpark.ocd/Particle.txt b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningSpark.ocd/Particle.txt deleted file mode 100644 index 8e01852d0..000000000 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningSpark.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=LightningSpark -MaxCount=1000 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=50 -VertexCount=1 -VertexY=50 -AlphaFade=12 -Additive=1 -RByV=1 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Particle.txt b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Particle.txt deleted file mode 100644 index ad8fedded..000000000 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/LightningStrike.ocd/Particle.txt +++ /dev/null @@ -1,14 +0,0 @@ -[Particle] -Name=LightningStrike -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Bounce -DrawFn=Std -Face=0,0,16,2000,-8,0 -Delay=0 -Repeats=0 -GravityAcc=0 -AlphaFade=20 -Additive=1 -Attach=1 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Script.c b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Script.c deleted file mode 100644 index 9919397a3..000000000 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/Scrolls.ocd/ThunderScroll.ocd/Script.c +++ /dev/null @@ -1,103 +0,0 @@ -/*-- - Scroll: Thunder - Author: Mimmo - - Call down a devastating storm down from above. ---*/ - - -public func ControlUse(object pClonk) -{ - Sound("Blast3"); - Exit(0,-GetY()); - AddEffect("ThunderStrike",0,100,1,0,this->GetID(),pClonk->GetOwner(),this->GetX()-5); - RemoveObject(); - return 1; -} -global func FxThunderStrikeStart(pTarget, effect, iTemp, owner, x) -{ - if(iTemp) return; - effect.owner=owner; - effect.x=x; -} -global func FxThunderStrikeTimer(pTarget, effect, iEffectTime) -{ - var move = effect.x; - - if(iEffectTime>36) - { - - var owner = effect.owner; - var x=0; - var wdt = 18; - var y = []; - var targets=[]; - for(var i = (x-wdt); i < (wdt*2); i++ ) - { - - while(!GBackSolid(i+move,y[i+wdt]) && y[i+wdt] < LandscapeHeight()) - y[i+wdt]++; - - } - - for(var i = (x-wdt); i < (wdt*2); i++ ) - { - if(!(i%5)) - for(var k=0; kGetID() == TargetBalloon) - { - var arw=CreateObject(Arrow,0,0,owner); - t->OnProjectileHit(arw); - arw->RemoveObject(); - } - else - { - if(t->GetOwner() != owner) - { - t->DoEnergy(-15,0,0,owner); - t->Fling(BoundBy((t->GetX()-(move))/4,-3,3),-6); - } - } - } - return -1; - } - else if(iEffectTime<4) - { - if(iEffectTime%3) - { - - while(!GBackSolid(x+move+5,y) && y < LandscapeHeight()) - { - var add=Random((iEffectTime*5))*((Random(2)*2) -1); - CreateParticle("Air",x+move+5+add,y,0,RandomX(-2,1),10+(iEffectTime*5),RGB(255-Random(50),255-Random(30),255-Random(5))); - y+=Random(4)+3; - } - } - } -} - - - - -local Name = "$Name$"; -local Description = "$Description$"; -local Collectible = 1; diff --git a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FastDynamite.c b/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FastDynamite.c deleted file mode 100644 index 4c64cfeba..000000000 --- a/planet/BackToTheRocks.ocf/ThunderousSkies.ocs/System.ocg/FastDynamite.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Everyone wins! */ - -#appendto Dynamite - -local fast; - -func Initialize() -{ - fast=0; - _inherited(); -} - -func MakeFast(int f) { fast=f; } - -private func Fusing() -{ - var sin=Sin(180-GetR(),5); - var cos=Cos(180-GetR(),5); - - if(Contained()!=nil) - { - //If the dynamite is held, sparks come from clonk's center. - sin=0; - cos=0; - } - - // Effekt - if(GetActTime() < (120-fast)) - CastParticles("Spark",1,20,sin,cos,15,25,RGB(255,200,0),RGB(255,255,150)); - // Explosion - else if(GetActTime() > (140-fast)) - DoExplode(); -} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Title.png b/planet/BackToTheRocks.ocf/Title.png deleted file mode 100644 index 442e0c454..000000000 Binary files a/planet/BackToTheRocks.ocf/Title.png and /dev/null differ diff --git a/planet/BackToTheRocks.ocf/Title.txt b/planet/BackToTheRocks.ocf/Title.txt deleted file mode 100644 index 7ae27c2f2..000000000 --- a/planet/BackToTheRocks.ocf/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Back to the Rocks -US:Back to the Rocks diff --git a/planet/BackToTheRocks.ocf/Windmill.ocs/System.ocg/SensitiveWindGenerator.c b/planet/BackToTheRocks.ocf/Windmill.ocs/System.ocg/SensitiveWindGenerator.c deleted file mode 100644 index 3ee2f5834..000000000 --- a/planet/BackToTheRocks.ocf/Windmill.ocs/System.ocg/SensitiveWindGenerator.c +++ /dev/null @@ -1,6 +0,0 @@ -#appendto WindGenerator - -func Damage() -{ - Explode(30); -} \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/DescDE.rtf b/planet/BeyondTheRocks.ocf/Crash.ocs/DescDE.rtf deleted file mode 100644 index f9bf86bbc..000000000 Binary files a/planet/BeyondTheRocks.ocf/Crash.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/DescUS.rtf b/planet/BeyondTheRocks.ocf/Crash.ocs/DescUS.rtf deleted file mode 100644 index 9f8a4db2e..000000000 --- a/planet/BeyondTheRocks.ocf/Crash.ocs/DescUS.rtf +++ /dev/null @@ -1,21 +0,0 @@ -{\rtf1\ansi\deff1\adeflang1025 -{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\fswiss\fprq0\fcharset0 Arial;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset0 Mangal;}} -{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} -{\stylesheet{\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\loch\f1\fs24\lang1043\snext1 Normal;} -{\s2\sb240\sa120\keepn\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af5\afs28\lang1043\ltrch\dbch\af4\langfe1043\hich\f2\fs28\lang1043\loch\f2\fs28\lang1043\sbasedon1\snext3 Heading;} -{\s3\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\loch\f1\fs24\lang1043\sbasedon1\snext3 Body Text;} -{\s4\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs24\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\loch\f1\fs24\lang1043\sbasedon3\snext4 List;} -{\s5\sb120\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs24\lang1043\ai\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\i\loch\f1\fs24\lang1043\i\sbasedon1\snext5 caption;} -{\s6\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af6\afs24\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\loch\f1\fs24\lang1043\sbasedon1\snext6 Index;} -} -{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern3300}}\deftab720 -{\*\pgdsctbl -{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} -{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc -\pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1043\ab\ltrch\dbch\af1\langfe1043\hich\f1\fs20\lang1033\b\loch\f1\fs20\lang1033\b {\rtlch \ltrch\loch\f1\fs20\lang1033\i0\b Crash landing} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1043\ab\ltrch\dbch\af1\langfe1043\hich\f1\fs20\lang1033\b\loch\f1\fs20\lang1033\b -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs20\lang1043\loch\f1\fs20\lang1043 {\rtlch \ltrch\loch\f1\fs20\lang1043\i0\b0 Moments ago, you were merrily sitting in your airplane on your way to the Clonkibean Sea. But then, sudden turbulences caused by a volcano below catch your plane and you tumble towards the ground...} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\loch\f1\fs24\lang1043 -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs24\lang1043\loch\f1\fs24\lang1043 {\rtlch \ltrch\loch\f1\fs20\lang1043\i0\b0 Recover the plane to continue your voyage to a well-deserved vacation!} -\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1043\ltrch\dbch\af1\langfe1043\hich\f1\fs20\lang1033\loch\f1\fs20\lang1033 -\par } \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Game.txt b/planet/BeyondTheRocks.ocf/Crash.ocs/Game.txt deleted file mode 100644 index eba679b50..000000000 --- a/planet/BeyondTheRocks.ocf/Crash.ocs/Game.txt +++ /dev/null @@ -1,3635 +0,0 @@ -[Object] -id=Grass -Properties=5141;false;"Prototype"=DGrass -Timer=2 -Category=4097 -Plane=-500 -Size=148000 -Mass=1 -X=F35782656 -Y=F35323904 -Width=17 -Height=10 -Offset=-8,-4 -Vertices=1 -VertexY=1 -Picture=0,0,0,0 -OCF=12845761 -Graphics=Grass::1 - -[Object] -id=Grass -Properties=5143;false;"Prototype"=DGrass -Timer=29 -Category=4097 -Plane=-500 -Size=109000 -Mass=1 -X=F34996224 -Y=F35258368 -Width=13 -Height=7 -Offset=-6,-3 -Vertices=1 -VertexY=1 -Picture=0,0,0,0 -OCF=12845761 - -[Object] -id=Grass -Properties=5144;false;"Prototype"=DGrass -Timer=28 -Category=4097 -Plane=-500 -Size=112000 -Mass=1 -X=F85590016 -Y=F46268416 -Width=13 -Height=7 -Offset=-6,-3 -Vertices=1 -VertexY=1 -Picture=0,0,0,0 -OCF=12845761 - -[Object] -id=Rule_TeamAccount -Properties=2;false;"Prototype"=DRule_TeamAccount -Timer=33 -Category=65 -Plane=100 -Size=100000 -Mass=1 -X=F3276800 -Y=F3276800 -Picture=0,0,0,0 -OCF=12845121 - -[Object] -id=Tree_Coniferous -Properties=3;false;"MeshTransformation"=E1,"Prototype"=DTree_Coniferous,"Action"=n -Timer=163 -Category=1 -Plane=100 -Size=95500 -Mass=143 -Damage=12 -X=F25034752 -Y=F54132736 -Width=57 -Height=105 -Offset=-28,-52 -Vertices=9 -VertexY=42,28,19,9,0,-9,-19,-28,-42 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845697 -Component=Wood=3 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=13;false;"MeshTransformation"=E2,"Prototype"=DTree_Coniferous -Timer=164 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F13893632 -Y=F54198272 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Library_Power -Properties=23;false;"neutral"=b1,"Prototype"=DLibrary_Power,"power_links"=E3,"sleeping_links"=E4,"power_balance"=i200 -Timer=14 -Category=1 -Plane=100 -Size=100000 -Mass=1 -Width=1 -Height=1 -Offset=-1,-1 -Picture=0,0,0,0 -OCF=12845121 - -[Object] -id=Tree_Coniferous -Properties=87;false;"MeshTransformation"=E5,"Prototype"=DTree_Coniferous -Timer=165 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F13697024 -Y=F53936128 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=90;false;"MeshTransformation"=E6,"Prototype"=DTree_Coniferous -Timer=165 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F13107200 -Y=F54067200 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=99;false;"MeshTransformation"=E7,"Prototype"=DTree_Coniferous -Timer=164 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F16646144 -Y=F54001664 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=106;false;"MeshTransformation"=E8,"Prototype"=DTree_Coniferous -Timer=166 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F24182784 -Y=F54132736 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=113;false;"MeshTransformation"=E9,"Prototype"=DTree_Coniferous -Timer=167 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F20381696 -Y=F53936128 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=130;false;"MeshTransformation"=E10,"Prototype"=DTree_Coniferous -Timer=166 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F917504 -Y=F53936128 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=153;false;"MeshTransformation"=E11,"Prototype"=DTree_Coniferous -Timer=167 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F17891328 -Y=F54132736 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=164;false;"MeshTransformation"=E12,"Prototype"=DTree_Coniferous -Timer=168 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F28180480 -Y=F32440320 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=167;false;"MeshTransformation"=E13,"Prototype"=DTree_Coniferous -Timer=167 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F33030144 -Y=F32309248 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=170;false;"MeshTransformation"=E14,"Prototype"=DTree_Coniferous -Timer=168 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F21626880 -Y=F33030144 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5015;false;"MeshTransformation"=E15,"Prototype"=DTree_Coniferous -Timer=214 -Category=1 -Plane=100 -Size=100500 -Mass=150 -X=F87556096 -Y=F20774912 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5018;false;"MeshTransformation"=E16,"Prototype"=DTree_Coniferous -Timer=174 -Category=1 -Plane=100 -Size=100500 -Mass=150 -X=F88735744 -Y=F20316160 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5021;false;"MeshTransformation"=E17,"Prototype"=DTree_Coniferous -Timer=46 -Category=1 -Plane=100 -Size=100500 -Mass=150 -X=F93978624 -Y=F16318464 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5024;false;"MeshTransformation"=E18,"Prototype"=DTree_Coniferous -Timer=236 -Category=1 -Plane=100 -Size=100500 -Mass=150 -X=F85262336 -Y=F22085632 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Fern -Properties=5033;false;"MeshTransformation"=E19,"Prototype"=DFern -Timer=290 -Category=1 -Plane=100 -Size=100100 -Mass=1 -X=F87228416 -Y=F45875200 -Width=28 -Height=10 -Offset=-14,-5 -Vertices=2 -VertexY=0,3 -VertexCNAT=16,8 -Picture=0,0,0,0 -OCF=12845249 - - [Mesh] - Valid=true - -[Object] -id=Fern -Properties=5036;false;"MeshTransformation"=E20,"Prototype"=DFern -Timer=80 -Category=1 -Plane=100 -Size=100100 -Mass=1 -X=F96206848 -Y=F43515904 -Width=28 -Height=10 -Offset=-14,-5 -Vertices=2 -VertexY=0,3 -VertexCNAT=16,8 -Picture=0,0,0,0 -OCF=14942401 - - [Mesh] - Valid=true - -[Object] -id=Fern -Properties=5039;false;"MeshTransformation"=E21,"Prototype"=DFern -Timer=320 -Category=1 -Plane=100 -Size=100100 -Mass=1 -X=F103743488 -Y=F45416448 -Width=28 -Height=10 -Offset=-14,-5 -Vertices=2 -VertexY=0,3 -VertexCNAT=16,8 -Picture=0,0,0,0 -OCF=12845249 - - [Mesh] - Valid=true - -[Object] -id=Lichen -Properties=5044;false;"grow_stage"=i3,"Action"=E22,"Prototype"=DLichen -Timer=192 -Category=1 -Plane=100 -Size=100000 -Mass=10 -X=F90243072 -Y=F44892160 -Width=25 -Height=25 -Offset=-12,-12 -Vertices=2 -VertexY=7,12 -VertexCNAT=16,8 -VertexFriction=50,100 -Picture=0,0,0,0 -OCF=12845121 -ActionTime=9292 -Phase=3 -PhaseDelay=1792 -Component=Moss=4 - -[Object] -id=Lichen -Properties=5048;false;"grow_stage"=i3,"Action"=E22,"Prototype"=DLichen -Timer=62 -Category=1 -Plane=100 -Size=100000 -Mass=10 -X=F99221504 -Y=F44892160 -Width=25 -Height=25 -Offset=-12,-12 -Vertices=2 -VertexY=7,12 -VertexCNAT=16,8 -VertexFriction=50,100 -Picture=0,0,0,0 -OCF=12845121 -ActionTime=9162 -Phase=3 -PhaseDelay=1662 -Component=Moss=4 - -[Object] -id=Rank -Properties=5050;false;"MeshTransformation"=E23,"Prototype"=DRank -Timer=12 -Category=1 -Plane=100 -Rotation=28 -Size=100000 -Mass=1 -X=F88604672 -Y=F28508160 -R=F1835008 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexX=0,-1 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Rank -Properties=5051;false;"MeshTransformation"=E24,"Prototype"=DRank -Timer=20 -Category=1 -Plane=100 -Rotation=6 -Size=100000 -Mass=1 -X=F93585408 -Y=F29032448 -R=F393216 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Rank -Properties=5054;false;"MeshTransformation"=E25,"Prototype"=DRank -Timer=2 -Category=1 -Plane=100 -Rotation=332 -Size=100000 -Mass=1 -X=F93782016 -Y=F29818880 -R=F21757952 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexX=0,1 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Rank -Properties=5055;false;"MeshTransformation"=E26,"Prototype"=DRank -Timer=12 -Category=1 -Plane=100 -Rotation=4 -Size=100000 -Mass=1 -X=F36175872 -Y=F38404096 -R=F262144 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Rank -Properties=5056;false;"MeshTransformation"=E27,"Prototype"=DRank -Timer=21 -Category=1 -Plane=100 -Rotation=343 -Size=100000 -Mass=1 -X=F34996224 -Y=F39190528 -R=F22478848 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexX=0,1 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Rank -Properties=5059;false;"MeshTransformation"=E28,"Prototype"=DRank -Timer=9 -Category=1 -Plane=100 -Rotation=23 -Size=100000 -Mass=1 -X=F21102592 -Y=F40108032 -R=F1507328 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexX=0,-1 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Rank -Properties=5060;false;"MeshTransformation"=E29,"Prototype"=DRank -Timer=29 -Category=1 -Plane=100 -Rotation=8 -Size=100000 -Mass=1 -X=F26476544 -Y=F49741824 -R=F524288 -Width=32 -Height=32 -Offset=-16,-16 -Vertices=2 -VertexY=0,3 -VertexCNAT=3,4 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5061;false;"MeshTransformation"=E30,"Prototype"=DTree_Coniferous -Timer=165 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F23330816 -Y=F35782656 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=2360001 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Trunk -Properties=5064;false;"MeshTransformation"=E31,"Prototype"=DTrunk -Timer=4 -Category=1 -Plane=100 -Size=100000 -Mass=40 -X=F94830592 -Y=F42729472 -Width=20 -Height=60 -Offset=-10,-30 -Vertices=2 -VertexY=-25,25 -VertexCNAT=4,8 -Picture=0,0,0,0 -OCF=12845761 - - [Mesh] - Valid=true - -[Object] -id=SproutBerryBush -Properties=5065;false;"grown_sprouts_count"=i3,"Prototype"=DSproutBerryBush,"last_checked_y"=i1,"sprout_count"=i3,"sprout_evolve_counter"=i0,"max_sprouts"=i2,"saved_water"=i85 -Timer=32 -Category=1 -Plane=100 -Size=100000 -Mass=10 -X=F84148224 -Y=F47579136 -Width=16 -Height=16 -Offset=-8,-8 -Vertices=2 -VertexY=0,8 -VertexCNAT=0,8 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=12845121 -Effects=(1,7752,10386,5065,SproutBerryBush,5067;false;"Name"=s"DontFlower") - -[Object] -id=Tree_Coniferous -Properties=5086;false;"MeshTransformation"=E32,"Prototype"=DTree_Coniferous -Timer=165 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F21823488 -Y=F54001664 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5093;false;"MeshTransformation"=E33,"Prototype"=DTree_Coniferous -Timer=47 -Category=1 -Plane=100 -Size=100003 -Mass=150 -X=F84803584 -Y=F22151168 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 - - [Mesh] - Valid=true - -[Object] -id=SproutBerryBush -Properties=5096;false;"grown_sprouts_count"=i3,"Prototype"=DSproutBerryBush,"last_checked_y"=i2,"sprout_count"=i3,"sprout_evolve_counter"=i0,"max_sprouts"=i2,"saved_water"=i75 -Timer=8 -Category=1 -Plane=100 -Size=100000 -Mass=10 -X=F36765696 -Y=F55836672 -Width=16 -Height=16 -Offset=-8,-8 -Vertices=2 -VertexY=0,8 -VertexCNAT=0,8 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=12845121 -Effects=(1,7208,10106,5096,SproutBerryBush,5098;false;"Name"=s"DontFlower") - -[Object] -id=Wheat -Properties=5119;false;"Prototype"=DWheat,"stalks"=E34 -Timer=232 -Category=1 -Plane=100 -Size=100300 -Mass=6 -X=F60227584 -Y=F35520512 -Width=12 -Height=20 -Offset=-6,-10 -Vertices=2 -VertexY=8,10 -VertexCNAT=16,8 -VertexFriction=10,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Seeds=2 -Effects=(3,6882,350,5119,Wheat,5123;false;"Name"=s"WindCheck","speed"=i0) - -[Object] -id=Wheat -Properties=5124;false;"Prototype"=DWheat,"stalks"=E35 -Timer=166 -Category=1 -Plane=100 -Size=100300 -Mass=6 -X=F84934656 -Y=F39518208 -Width=12 -Height=20 -Offset=-6,-10 -Vertices=2 -VertexY=8,10 -VertexCNAT=16,8 -VertexFriction=10,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Seeds=2 -Effects=(3,6816,350,5124,Wheat,5128;false;"Name"=s"WindCheck","speed"=i0) - -[Object] -id=WheatStalk -Properties=5129;false;"ActMap"=E36,"Prototype"=DWheatStalk -Timer=12 -Category=1 -Plane=100 -Size=100000 -Mass=2 -X=F88604672 -Y=F58523648 -Width=8 -Height=20 -Offset=-4,-10 -Vertices=2 -VertexY=0,10 -VertexCNAT=16,8 -VertexFriction=10,100 -Picture=0,0,0,0 -OCF=12845121 - -[Object] -id=Tree_Coniferous -Properties=5160;false;"Prototype"=DTree_Coniferous -Timer=167 -Category=1 -Plane=100 -Size=47003 -Mass=70 -X=F12713984 -Y=F55836672 -Width=28 -Height=51 -Offset=-14,-25 -Vertices=9 -VertexY=21,14,9,4,0,-4,-9,-14,-21 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845697 -Component=Wood=1 -Effects=(1,3317,35,0,None,5161;false;"growth"=i5,"Name"=s"IntGrowth") - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5176;false;"Prototype"=DTree_Coniferous -Timer=167 -Category=1 -Plane=100 -Size=17003 -Mass=25 -X=F13434880 -Y=F57016320 -Width=10 -Height=18 -Offset=-5,-9 -Vertices=9 -VertexY=7,5,3,1,0,-1,-3,-5,-7 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845697 -Component=Wood=0 -Effects=(1,1217,35,0,None,5177;false;"growth"=i5,"Name"=s"IntGrowth") - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=5182;false;"Prototype"=DTree_Coniferous -Timer=237 -Category=1 -Plane=100 -Size=8003 -Mass=12 -X=F86638592 -Y=F24313856 -Width=4 -Height=8 -Offset=-2,-4 -Vertices=9 -VertexY=3,2,1,0,0,0,-1,-2,-3 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=2359937 -Component=Wood=0 -Effects=(1,587,35,0,None,5183;false;"growth"=i5,"Name"=s"IntGrowth") - - [Mesh] - Valid=true - -[Object] -id=Chest -Properties=17;false;"chestanim"=i0,"MeshTransformation"=E37,"Prototype"=DChest -Category=2 -Plane=200 -Size=100000 -Mass=26 -X=F17301504 -Y=F83584607 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=5204;5205;5206;5207;5208;5209;5210;5211 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,36) - -[Object] -id=WoodenCabin -Properties=21;false;"Action"=n,"Prototype"=DWoodenCabin -Timer=11 -Category=2 -Plane=200 -Size=100000 -Mass=4005 -X=F4063232 -Y=F55862886 -Width=94 -Height=40 -Offset=-47,-20 -Vertices=8 -VertexX=-26,26,-22,23,-38,-38,43,40 -VertexY=-7,-6,19,19,4,19,-4,19 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=29625921 -Component=Wood=5;Rock=4 -Contents=678;343;374 - - [Mesh] - Valid=true - -[Object] -id=Windmill -Properties=22;false;"MeshTransformation"=E38,"Prototype"=DWindmill,"wind_anim"=i0,"queue"=E39,"last_wind"=i200 -Timer=14 -Category=2 -Plane=200 -Size=100000 -Mass=2500 -X=F9935258 -Y=F54099914 -Width=50 -Height=96 -Offset=-25,-48 -Vertices=5 -VertexX=0,25,15,-15,-25 -VertexY=-47,-20,47,47,-20 -VertexFriction=50,50,100,100,50 -Picture=0,0,0,0 -OCF=12862529 -Component=Rock=6;Wood=2 -Effects=(100,75124,5,22,Windmill,26;false;"Name"=s"ProcessQueue") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=5 - Number=0 - Type=Leaf - Animation=Spin - Position=linear(F469376,F519897,F0,90,Loop,36) - -[Object] -id=Idol -Properties=32;false;"Prototype"=DIdol -Timer=12 -Category=2 -Plane=200 -Size=100000 -Mass=200 -X=F6815744 -Y=F56125029 -Width=15 -Height=30 -Offset=-7,-15 -Vertices=4 -VertexX=-7,-7,7,7 -VertexY=-10,15,-10,15 -VertexFriction=50,100,50,100 -Picture=0,0,0,0 -OCF=12845637 -Component=GoldBar=3 - - [Mesh] - Valid=true - -[Object] -id=Lorry -Properties=62;false;"iTremble"=i100,"MeshTransformation"=E40,"Prototype"=DLorry,"drive_anim"=i0,"tremble_anim"=n,"iRotWheels"=i1400 -Category=4 -Plane=300 -Rotation=-14 -Size=100000 -Mass=85 -X=F4988600 -Y=F84571569 -R=F-917504 -Width=30 -Height=30 -Offset=-15,-15 -Vertices=4 -VertexX=-9,5,-6,8 -VertexY=-4,-8,9,5 -VertexCNAT=5,6,9,10 -VertexFriction=80,80,10,10 -AttachX=86 -AttachY=1295 -AttachVtx=3 -Picture=0,0,0,0 -OCF=29639237 -Component=Metal=2;Wood=1 -Contents=287 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=5 - Number=0 - Type=Leaf - Animation=Drive - Position=const(F65536) - -[Object] -id=Catapult -Properties=78;false;"aim_anim"=i0,"Action"=n,"Prototype"=DCatapult,"dir"=i1,"olddir"=i1,"turn_anim"=i1 -Timer=33 -Category=4 -Plane=300 -Size=80000 -Mass=100 -X=F29183184 -Y=F34896453 -Width=34 -Height=24 -Offset=-17,-12 -Vertices=4 -VertexX=-16,15,-16,15 -VertexY=-9,-9,10,10 -VertexCNAT=5,6,9,10 -VertexFriction=80,80,10,10 -AttachX=429 -AttachY=543 -AttachVtx=2 -Picture=0,0,0,0 -OCF=29622277 -Component=Metal=0;Wood=4 -ColorMod=4285032552 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=ArmPosition - Position=const(F0) - - [AnimationNode] - Slot=5 - Number=1 - Type=Leaf - Animation=TurnRight - Position=const(F115343) - -[Object] -id=SproutBerryBush_Sprout -Properties=5068;false;"attached_flower"=i-1,"MeshTransformation"=E41,"Prototype"=DSproutBerryBush_Sprout,"grow_anim"=s"Grow2","Action"=E42,"leaves"=E43,"attached_berry"=i-1 -Timer=17 -Category=4 -Plane=300 -Rotation=353 -Size=100000 -Mass=50 -X=F84148224 -Y=F47579136 -R=F23134208 -Width=70 -Height=70 -Offset=-35,-35 -Vertices=1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=12845761 -ActionTime=7752 -ActionTarget1=5065 -Component=Wood=1 -Effects=(1,7750,37,5068,SproutBerryBush_Sprout,5083;false;"Name"=s"LifeTimer") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Grow2 - Position=linear(F20971,F0,F20971,10,Hold,36) - - [Attached] - Number=1 - ParentBone=1 - ChildBone=0 - AttachTransformation=(F126418,F0,F15532,F0,F0,F127336,F0,F0,F-15532,F0,F126418,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - - [Attached] - Number=2 - ParentBone=8 - ChildBone=0 - AttachTransformation=(F50528,F0,F-113508,F0,F0,F124190,F0,F0,F113508,F0,F50528,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - -[Object] -id=SproutBerryBush_Sprout -Properties=5073;false;"attached_flower"=i-1,"MeshTransformation"=E44,"Prototype"=DSproutBerryBush_Sprout,"grow_anim"=s"Grow2","Action"=E42,"leaves"=E45,"attached_berry"=i-1 -Timer=17 -Category=4 -Plane=300 -Rotation=349 -Size=100000 -Mass=50 -X=F84148224 -Y=F47579136 -R=F22872064 -Width=70 -Height=70 -Offset=-35,-35 -Vertices=1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=12845761 -ActionTime=7752 -ActionTarget1=5065 -Component=Wood=1 -Effects=(1,7750,37,5073,SproutBerryBush_Sprout,5084;false;"Name"=s"LifeTimer") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Grow2 - Position=linear(F20971,F0,F20971,10,Hold,36) - - [Attached] - Number=1 - ParentBone=1 - ChildBone=0 - AttachTransformation=(F-16515,F0,F-117899,F0,F0,F119144,F0,F0,F117899,F0,F-16515,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - - [Attached] - Number=2 - ParentBone=8 - ChildBone=0 - AttachTransformation=(F-115212,F0,F-39714,F0,F0,F121831,F0,F0,F39714,F0,F-115212,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - -[Object] -id=SproutBerryBush_Sprout -Properties=5078;false;"attached_flower"=i-1,"MeshTransformation"=E46,"Prototype"=DSproutBerryBush_Sprout,"grow_anim"=s"Grow1","Action"=E42,"leaves"=E47,"attached_berry"=i-1 -Timer=17 -Category=4 -Plane=300 -Rotation=9 -Size=100000 -Mass=50 -X=F84148224 -Y=F47579136 -R=F589824 -Width=70 -Height=70 -Offset=-35,-35 -Vertices=1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=12845761 -ActionTime=7752 -ActionTarget1=5065 -Component=Wood=1 -Effects=(1,7750,38,5078,SproutBerryBush_Sprout,5085;false;"Name"=s"LifeTimer") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Grow1 - Position=linear(F20971,F0,F20971,10,Hold,36) - - [Attached] - Number=1 - ParentBone=1 - ChildBone=0 - AttachTransformation=(F95617,F0,F66977,F0,F0,F116785,F0,F0,F-66977,F0,F95617,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - - [Attached] - Number=2 - ParentBone=8 - ChildBone=0 - AttachTransformation=(F98041,F0,F66060,F0,F0,F118292,F0,F0,F-66060,F0,F98041,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - -[Object] -id=SproutBerryBush_Sprout -Properties=5099;false;"attached_flower"=i-1,"MeshTransformation"=E48,"Prototype"=DSproutBerryBush_Sprout,"grow_anim"=s"Grow2","Action"=E42,"leaves"=E49,"attached_berry"=i-1 -Timer=33 -Category=4 -Plane=300 -Rotation=18 -Size=100000 -Mass=50 -X=F36765696 -Y=F55836672 -R=F1179648 -Width=70 -Height=70 -Offset=-35,-35 -Vertices=1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=12845761 -ActionTime=7208 -ActionTarget1=5096 -Component=Wood=1 -Effects=(1,7206,30,5099,SproutBerryBush_Sprout,5114;false;"Name"=s"LifeTimer") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Grow2 - Position=linear(F20971,F0,F20971,10,Hold,36) - - [Attached] - Number=1 - ParentBone=1 - ChildBone=0 - AttachTransformation=(F119734,F0,F50790,F0,F0,F130023,F0,F0,F-50790,F0,F119734,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - - [Attached] - Number=2 - ParentBone=8 - ChildBone=0 - AttachTransformation=(F-102891,F0,F-59441,F0,F0,F118882,F0,F0,F59441,F0,F-102891,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - -[Object] -id=SproutBerryBush_Sprout -Properties=5104;false;"attached_flower"=i-1,"MeshTransformation"=E50,"Prototype"=DSproutBerryBush_Sprout,"grow_anim"=s"Grow1","Action"=E42,"leaves"=E51,"attached_berry"=i-1 -Timer=33 -Category=4 -Plane=300 -Rotation=14 -Size=100000 -Mass=50 -X=F36765696 -Y=F55836672 -R=F917504 -Width=70 -Height=70 -Offset=-35,-35 -Vertices=1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=12845761 -ActionTime=7208 -ActionTarget1=5096 -Component=Wood=1 -Effects=(1,7206,36,5104,SproutBerryBush_Sprout,5115;false;"Name"=s"LifeTimer") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Grow1 - Position=linear(F20971,F0,F20971,10,Hold,36) - - [Attached] - Number=1 - ParentBone=1 - ChildBone=0 - AttachTransformation=(F102498,F0,F64028,F0,F0,F120913,F0,F0,F-64028,F0,F102498,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - - [Attached] - Number=2 - ParentBone=8 - ChildBone=0 - AttachTransformation=(F63635,F0,F-97976,F0,F0,F116785,F0,F0,F97976,F0,F63635,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - -[Object] -id=SproutBerryBush_Sprout -Properties=5109;false;"attached_flower"=i-1,"MeshTransformation"=E52,"Prototype"=DSproutBerryBush_Sprout,"grow_anim"=s"Grow1","Action"=E42,"leaves"=E53,"attached_berry"=i-1 -Timer=33 -Category=4 -Plane=300 -Rotation=343 -Size=100000 -Mass=50 -X=F36765696 -Y=F55836672 -R=F22478848 -Width=70 -Height=70 -Offset=-35,-35 -Vertices=1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=12845761 -ActionTime=7208 -ActionTarget1=5096 -Component=Wood=1 -Effects=(1,7206,31,5109,SproutBerryBush_Sprout,5116;false;"Name"=s"LifeTimer") - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Grow1 - Position=linear(F20971,F0,F20971,10,Hold,36) - - [Attached] - Number=1 - ParentBone=1 - ChildBone=0 - AttachTransformation=(F115933,F0,F-14221,F0,F0,F116785,F0,F0,F14221,F0,F115933,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - - [Attached] - Number=2 - ParentBone=8 - ChildBone=0 - AttachTransformation=(F93519,F0,F-78512,F0,F0,F122159,F0,F0,F78512,F0,F93519,F0) - ChildMesh=SproutBerryBush_Leaf:: - - [ChildInstance] - Valid=true - -[Object] -id=FloatingMessage -Properties=5212;false;"alpha"=i231,"Action"=E54,"Prototype"=DFloatingMessage,"g"=i255,"b"=i0,"r"=i0,"msg"=s"+200{{Library_PowerConsumer}}" -Timer=15 -Category=4 -Plane=300 -Size=100000 -Mass=1 -X=F9961472 -Y=F52822016 -YDir=F-65536 -Width=8 -Height=8 -Offset=-4,-4 -Picture=0,0,0,0 -Mobile=true -OCF=12845121 -ComDir=-1 -ActionTime=15 -Effects=(1,15,4,5212,FloatingMessage,5213;false;"Name"=s"FadeOut","step"=i8) - -[Object] -id=Crate -Properties=7;false;"MeshTransformation"=E55,"Prototype"=DCrate,"crateanim"=i0 -Timer=30 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F10387492 -Y=F85093501 -Width=12 -Height=12 -Offset=-6,-6 -Vertices=4 -VertexX=-4,-4,5,5 -VertexY=-2,5,-2,5 -VertexCNAT=5,9,6,10 -VertexFriction=25,25,25,25 -Picture=0,0,0,0 -OCF=12845125 -Component=Wood=3 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,36) - -[Object] -id=Crate -Properties=8;false;"MeshTransformation"=E56,"Prototype"=DCrate,"crateanim"=i0 -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F8903065 -Y=F85091907 -Width=12 -Height=12 -Offset=-6,-6 -Vertices=4 -VertexX=-4,-4,5,5 -VertexY=-2,5,-2,5 -VertexCNAT=5,9,6,10 -VertexFriction=25,25,25,25 -Picture=0,0,0,0 -OCF=12845125 -Component=Wood=3 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,36) - -[Object] -id=Bread -Properties=9;false;"Prototype"=DBread -Timer=11 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F11206656 -Y=F85354048 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=12845129 -Component=Flour=1 - -[Object] -id=Bread -Properties=5204;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5205;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5206;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5207;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5208;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5209;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5210;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Bread -Properties=5211;false;"Prototype"=DBread -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F17301504 -Y=F83584607 -Width=8 -Height=4 -Offset=-4,-2 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,1,1 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=73 -Contained=17 -Component=Flour=1 - -[Object] -id=Nugget -Properties=10;false;"Prototype"=DNugget -Timer=27 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F2621440 -Y=F79324774 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=11;false;"Prototype"=DNugget -Timer=20 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F1179648 -Y=F79717990 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::1 - -[Object] -id=Nugget -Properties=12;false;"Prototype"=DNugget -Timer=27 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F3211264 -Y=F83060326 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=5158;false;"Prototype"=DNugget -Timer=2 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F28770304 -Y=F82536038 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::3 - -[Object] -id=Nugget -Properties=5159;false;"Prototype"=DNugget -Timer=31 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F31784960 -Y=F75654758 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::1 - -[Object] -id=Nugget -Properties=5173;false;"Prototype"=DNugget -Timer=4 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F103546880 -Y=F74671718 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::3 - -[Object] -id=Nugget -Properties=5181;false;"Prototype"=DNugget -Timer=13 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F96337920 -Y=F70805094 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 - -[Object] -id=Nugget -Properties=5198;false;"Prototype"=DNugget -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F2162688 -Y=F85943910 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=5199;false;"Prototype"=DNugget -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F8781824 -Y=F88303206 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=5200;false;"Prototype"=DNugget -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F16580608 -Y=F86337126 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=5201;false;"Prototype"=DNugget -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F24182784 -Y=F84108902 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::1 - -[Object] -id=Nugget -Properties=5202;false;"Prototype"=DNugget -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F24444928 -Y=F81487462 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Nugget=1 -Graphics=Nugget::2 - -[Object] -id=Metal -Properties=16;false;"Prototype"=DMetal -Timer=30 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F8126464 -Y=F85288537 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=12845641 -Component=Ore=1 - -[Object] -id=Coal -Properties=249;false;"Prototype"=DCoal -Timer=24 -Category=16 -Plane=500 -Size=100000 -Mass=9 -X=F14286848 -Y=F66217574 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75 -Picture=0,0,0,0 -OCF=2360009 -Component=Wood=2 -Graphics=Coal::2 - -[Object] -id=Coal -Properties=268;false;"Prototype"=DCoal -Timer=18 -Category=16 -Plane=500 -Size=100000 -Mass=9 -X=F6160384 -Y=F68576870 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75 -Picture=0,0,0,0 -OCF=2360009 -Component=Wood=2 -Graphics=Coal::1 - -[Object] -id=Coal -Properties=272;false;"Prototype"=DCoal -Timer=7 -Category=16 -Plane=500 -Size=100000 -Mass=9 -X=F6422528 -Y=F66217574 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75 -Picture=0,0,0,0 -OCF=2360009 -Component=Wood=2 - -[Object] -id=Rock -Properties=250;false;"Prototype"=DRock -Timer=27 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F18284544 -Y=F63268454 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 - -[Object] -id=Rock -Properties=5137;false;"Prototype"=DRock -Timer=8 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F30736384 -Y=F79586918 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::1 - -[Object] -id=Rock -Properties=5139;false;"Prototype"=DRock -Timer=34 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F14745600 -Y=F87516774 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::3 - -[Object] -id=Rock -Properties=5142;false;"Prototype"=DRock -Timer=3 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F4521984 -Y=F73754214 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::2 - -[Object] -id=Rock -Properties=5151;false;"Prototype"=DRock -Timer=12 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F2949120 -Y=F59991654 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::8 - -[Object] -id=Rock -Properties=5152;false;"Prototype"=DRock -Timer=25 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F35848192 -Y=F66545254 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::7 - -[Object] -id=Rock -Properties=5163;false;"Prototype"=DRock -Timer=25 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F73203712 -Y=F77227622 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::2 - -[Object] -id=Rock -Properties=5164;false;"Prototype"=DRock -Timer=9 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F77070336 -Y=F85747302 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::3 - -[Object] -id=Rock -Properties=5167;false;"Prototype"=DRock -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F92667904 -Y=F70477414 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::4 - -[Object] -id=Rock -Properties=5172;false;"Prototype"=DRock -Timer=23 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F97320960 -Y=F58549861 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Rock=1 -Graphics=Rock::7 - -[Object] -id=Loam -Properties=251;false;"Prototype"=DLoam -Timer=17 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F33882112 -Y=F62416483 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::3 - -[Object] -id=Loam -Properties=5184;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F26411008 -Y=F66479718 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::3 - -[Object] -id=Loam -Properties=5185;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F22216704 -Y=F82339430 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=5186;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F11665408 -Y=F86271590 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=5187;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F47644672 -Y=F83781222 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=5188;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F57933824 -Y=F87647846 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=5189;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F78315520 -Y=F85485158 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 - -[Object] -id=Loam -Properties=5190;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F102760448 -Y=F72967782 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=5191;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F102563840 -Y=F57960038 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=5192;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F89128960 -Y=F51668582 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=5193;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F99549184 -Y=F47736422 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=5194;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F88342528 -Y=F47539814 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=5195;false;"Prototype"=DLoam -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F90374144 -Y=F23357030 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Wood -Properties=275;false;"Prototype"=DWood -Timer=6 -Category=16 -Plane=500 -Rotation=35 -Size=100000 -Mass=6 -X=F33947648 -Y=F70674029 -R=F2293760 -Width=22 -Height=22 -Offset=-11,-11 -Vertices=3 -VertexX=4,-5 -VertexY=1,-1 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=12845769 -Component=Wood=1 - -[Object] -id=Wood -Properties=323;false;"Prototype"=DWood -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F85327872 -Y=F59234106 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -InLiquid=true -OCF=13894345 -Component=Wood=1 - -[Object] -id=Wood -Properties=324;false;"Action"=n,"Prototype"=DWood -Timer=11 -Category=16 -Plane=500 -Size=98000 -Mass=5 -Damage=12 -X=F92405760 -Y=F62615766 -Width=11 -Height=11 -Offset=-6,-5 -Vertices=3 -VertexX=3,-4 -VertexY=0,1 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -InLiquid=true -OCF=1311369 -Component=Wood=0 -ColorMod=4281344032 - -[Object] -id=Ore -Properties=280;false;"Prototype"=DOre -Timer=3 -Category=16 -Plane=500 -Size=100000 -Mass=9 -X=F17629184 -Y=F72443494 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=60,60,60 -Picture=0,0,0,0 -OCF=2359881 -Graphics=Ore::3 - -[Object] -id=Firestone -Properties=285;false;"Prototype"=DFirestone -Timer=34 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F3211264 -Y=F86271590 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=286;false;"Prototype"=DFirestone -Timer=19 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F2359296 -Y=F84043366 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=287;false;"Prototype"=DFirestone -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F4988600 -Y=F84571569 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=8388681 -Contained=62 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=288;false;"Prototype"=DFirestone -Timer=2 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29622272 -Y=F60319334 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=289;false;"Prototype"=DFirestone -Timer=16 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F3276800 -Y=F62219878 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=290;false;"Prototype"=DFirestone -Timer=22 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F24510464 -Y=F58615398 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=291;false;"Prototype"=DFirestone -Timer=22 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F19726336 -Y=F60778086 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=292;false;"Prototype"=DFirestone -Timer=12 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F2490368 -Y=F70280806 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=293;false;"Prototype"=DFirestone -Timer=12 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F14155776 -Y=F71132774 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=294;false;"Prototype"=DFirestone -Timer=12 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F32899072 -Y=F64579174 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=295;false;"Prototype"=DFirestone -Timer=12 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F15007744 -Y=F60647014 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=296;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F27066368 -Y=F74278502 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=297;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F49610752 -Y=F80832102 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=298;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F24510464 -Y=F84960870 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=299;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F22609920 -Y=F70346342 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=300;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F38404096 -Y=F81946214 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=301;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10092544 -Y=F88499814 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=302;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F24969216 -Y=F70739558 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=303;false;"Prototype"=DFirestone -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F46792704 -Y=F82142822 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=316;false;"Prototype"=DFirestone -Timer=26 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F83034112 -Y=F62678630 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=317;false;"Prototype"=DFirestone -Timer=33 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F88211456 -Y=F53765734 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=320;false;"Prototype"=DFirestone -Timer=12 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F91291648 -Y=F60057190 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=321;false;"Prototype"=DFirestone -Timer=25 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F95944704 -Y=F47212134 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=322;false;"Prototype"=DFirestone -Timer=6 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F85721088 -Y=F76572262 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=5196;false;"Prototype"=DFirestone -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F5242880 -Y=F72246886 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=5197;false;"Prototype"=DFirestone -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F23003136 -Y=F80635494 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=5203;false;"Prototype"=DFirestone -Timer=1 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F7340032 -Y=F73950822 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Moss -Properties=327;false;"graphic"=i2,"Prototype"=DMoss,"lastpos"=E57,"wetness"=i0 -Timer=5 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F88932352 -Y=F45442661 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75,75 -Picture=0,0,0,0 -OCF=12845769 -Component=Moss=1 -Graphics=Moss::2Dry -Effects=(100,20620,36,327,Moss,328;false;"Name"=s"MossMoisture") - -[Object] -id=Moss -Properties=329;false;"graphic"=i2,"Prototype"=DMoss,"lastpos"=E58,"wetness"=i30 -Timer=18 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F83150521 -Y=F59242390 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75,75 -Picture=0,0,0,0 -InLiquid=true -OCF=13894345 -Component=Moss=1 -Graphics=Moss::2 -Effects=(100,20458,36,329,Moss,330;false;"Name"=s"MossMoisture") - -[Object] -id=Moss -Properties=333;false;"graphic"=i0,"Prototype"=DMoss,"lastpos"=E59,"wetness"=i0 -Timer=33 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F22020096 -Y=F36005472 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75,75 -Picture=0,0,0,0 -OCF=12845769 -Component=Moss=1 -Graphics=Moss::Dry -Effects=(100,20228,36,333,Moss,334;false;"Name"=s"MossMoisture") - -[Object] -id=Moss -Properties=335;false;"graphic"=i1,"Prototype"=DMoss,"lastpos"=E60,"wetness"=i0 -Timer=11 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F33284099 -Y=F35553275 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75,75 -Picture=0,0,0,0 -OCF=12845769 -Component=Moss=1 -Graphics=Moss::1Dry -Effects=(100,20066,36,335,Moss,336;false;"Name"=s"MossMoisture") - -[Object] -id=Moss -Properties=339;false;"graphic"=i1,"Prototype"=DMoss,"lastpos"=E61,"wetness"=i0 -Timer=6 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F36765696 -Y=F55993958 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=75,75,75 -Picture=0,0,0,0 -OCF=12845769 -Component=Moss=1 -Graphics=Moss::1Dry -Effects=(100,19956,36,339,Moss,340;false;"Name"=s"MossMoisture") - -[Object] -id=Seeds -Properties=343;false;"Prototype"=DSeeds -Timer=15 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F4063232 -Y=F55862886 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=8388681 -Contained=21 -Component=Rock=1 - -[Object] -id=Seeds -Properties=374;false;"Prototype"=DSeeds -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=2 -X=F4063232 -Y=F55862886 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=8388681 -Contained=21 -Component=Rock=1 - -[Object] -id=Sproutberry -Properties=678;false;"Prototype"=DSproutberry -Timer=32 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F4063232 -Y=F55862886 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,3,-3 -VertexY=0,3,3 -VertexFriction=50,100,100 -Picture=0,0,0,0 -OCF=8388681 -Contained=21 - - [Mesh] - Valid=true - -[Object] -id=Seaweed -Properties=5134;false;"Action"=E62,"Prototype"=DSeaweed -Timer=6 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F88014867 -Y=F64513577 -YDir=F52428 -Width=6 -Height=16 -Offset=-3,-8 -Vertices=2 -VertexY=-7,7 -VertexCNAT=4,3 -VertexFriction=10,100 -Picture=0,0,0,0 -InLiquid=true -OCF=1310785 -ActionTime=6026 -Phase=49 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=0 - Number=0 - Type=Leaf - Animation=Sway - Position=action(F64225,5134) - -[Object] -id=Seaweed -Properties=5138;false;"Action"=E62,"Prototype"=DSeaweed -Timer=25 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F93716480 -Y=F59860582 -YDir=F65535 -Width=6 -Height=16 -Offset=-3,-8 -Vertices=2 -VertexY=-7,7 -VertexCNAT=4,3 -VertexFriction=10,100 -Picture=0,0,0,0 -InLiquid=true -OCF=1310785 -ActionTime=5752 -Phase=68 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=0 - Number=0 - Type=Leaf - Animation=Sway - Position=action(F89128,5138) - -[Object] -id=Seaweed -Properties=5140;false;"Action"=E63,"Prototype"=DSeaweed -Timer=13 -Category=16 -Plane=500 -Size=100000 -Mass=1 -X=F99876864 -Y=F59663974 -YDir=F65535 -Width=6 -Height=16 -Offset=-3,-8 -Vertices=2 -VertexY=-7,7 -VertexCNAT=4,3 -VertexFriction=10,100 -Picture=0,0,0,0 -InLiquid=true -OCF=1310785 -ActionTime=16 -Phase=8 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=0 - Number=0 - Type=Leaf - Animation=Sway - Position=action(F10485,5140) - -[Script] -StaticVariables=6;CON_VC_Players=n,g_player_cursor_pos=n,Clonk_IdleActions=n,LibraryFlag_flag_list=n,Library_Power_power_compounds=E64,g_is_initialized=n -Scenario=false;"Prototype"=t -Values=a(12;i-87,i0,i-996,i0,i0,i1000,i0,i0,i996,i0,i-87,i0),a(12;i-643,i0,i-766,i0,i0,i1000,i0,i0,i766,i0,i-643,i0),a(2;E65),a(0;),a(12;i500,i0,i-866,i0,i0,i1000,i0,i0,i866,i0,i500,i0),a(12;i156,i0,i988,i0,i0,i1000,i0,i0,i-988,i0,i156,i0),a(12;i-809,i0,i-588,i0,i0,i1000,i0,i0,i588,i0,i-809,i0),a(12;i191,i0,i982,i0,i0,i1000,i0,i0,i-982,i0,i191,i0),a(12;i656,i0,i-755,i0,i0,i1000,i0,i0,i755,i0,i656,i0),a(12;i970,i0,i242,i0,i0,i1000,i0,i0,i-242,i0,i970,i0),a(12;i469,i0,i883,i0,i0,i1000,i0,i0,i-883,i0,i469,i0),a(12;i-375,i0,i-927,i0,i0,i1000,i0,i0,i927,i0,i-375,i0),a(12;i848,i0,i530,i0,i0,i1000,i0,i0,i-530,i0,i848,i0),a(12;i829,i0,i-559,i0,i0,i1000,i0,i0,i559,i0,i829,i0),a(12;i-999,i0,i35,i0,i0,i1000,i0,i0,i-35,i0,i-999,i0),a(12;i-191,i0,i-982,i0,i0,i1000,i0,i0,i982,i0,i-191,i0),a(12;i995,i0,i105,i0,i0,i1000,i0,i0,i-105,i0,i995,i0),a(12;i731,i0,i682,i0,i0,i1000,i0,i0,i-682,i0,i731,i0),a(12;i-883,i0,i469,i0,i0,i1000,i0,i0,i-469,i0,i-883,i0),a(12;i934,i0,i358,i0,i0,i1000,i0,i0,i-358,i0,i934,i0),a(12;i848,i0,i530,i0,i0,i1000,i0,i0,i-530,i0,i848,i0),p(true;"Wdt"=i25,"Name"=s"Grow","Y"=i0,"X"=i0,"Length"=i4,"NextAction"=s"Grown","Prototype"=E66,"Procedure"=n,"Hgt"=i25,"PhaseCall"=s"Grow","Delay"=i2500),a(12;i17,i0,i-1000,i0,i0,i1000,i0,i0,i1000,i0,i17,i0),a(12;i326,i0,i946,i0,i0,i1000,i0,i0,i-946,i0,i326,i0),a(12;i-358,i0,i-934,i0,i0,i1000,i0,i0,i934,i0,i-358,i0),a(12;i-788,i0,i-616,i0,i0,i1000,i0,i0,i616,i0,i-788,i0),a(12;i809,i0,i588,i0,i0,i1000,i0,i0,i-588,i0,i809,i0),a(12;i809,i0,i-588,i0,i0,i1000,i0,i0,i588,i0,i809,i0),a(12;i848,i0,i-530,i0,i0,i1000,i0,i0,i530,i0,i848,i0),a(12;i191,i0,i982,i0,i0,i1000,i0,i0,i-982,i0,i191,i0),a(12;i-574,i0,i-819,i0,i0,i1000,i0,i0,i819,i0,i-574,i0),a(12;i993,i0,i122,i0,i0,i1000,i0,i0,i-122,i0,i993,i0),a(12;i-17,i0,i1000,i0,i0,i1000,i0,i0,i-1000,i0,i-17,i0),a(0;),a(0;),p(false;"Prototype"=E67),a(12;i669,i0,i743,i0,i0,i1000,i0,i0,i-743,i0,i669,i0),a(12;i866,i0,i-500,i0,i0,i1000,i0,i0,i500,i0,i866,i0),a(0;),a(12;i974,i0,i225,i0,i0,i1000,i0,i0,i-225,i0,i974,i0),a(12;i-876,i0,i-1798,i0,i0,i2000,i0,i0,i1798,i0,i-876,i0),p(true;"Length"=i1,"Name"=s"Attach","Prototype"=E66,"Procedure"=s"ATTACH","Directions"=i1,"FacetBase"=i1,"Delay"=i0),a(3;n,i1,i2),a(12;i-1732,i0,i-1000,i0,i0,i2000,i0,i0,i1000,i0,i-1732,i0),a(3;n,i1,i2),a(12;i1732,i0,i1000,i0,i0,i2000,i0,i0,i-1000,i0,i1732,i0),a(3;n,i1,i2),a(12;i-1842,i0,i-782,i0,i0,i2000,i0,i0,i782,i0,i-1842,i0),a(3;n,i1,i2),a(12;i1510,i0,i1312,i0,i0,i2000,i0,i0,i-1312,i0,i1510,i0),a(3;n,i1,i2),a(12;i1118,i0,i-1658,i0,i0,i2000,i0,i0,i1658,i0,i1118,i0),a(3;n,i1,i2),p(true;"Length"=i1,"Name"=s"Float","Prototype"=E68,"Procedure"=s"FLOAT","FacetBase"=i1,"Delay"=i0),a(12;i174,i0,i985,i0,i0,i1000,i0,i0,i-985,i0,i174,i0),a(12;i839,i0,i545,i0,i0,i1000,i0,i0,i-545,i0,i839,i0),a(2;i1357,i692),a(2;i1287,i899),a(2;i336,i542),a(2;i508,i542),a(2;i561,i854),p(false;"Wdt"=i8,"Name"=s"Sway","Animation"=s"Sway","Y"=i0,"Directions"=i2,"X"=i0,"Length"=i78,"NextAction"=s"Sway","Prototype"=E66,"Hgt"=i8,"Procedure"=n,"PhaseCall"=s"Check","Delay"=i2),p(false;"Wdt"=i8,"PhaseCall"=s"Check","Animation"=s"Sway","Delay"=i2,"Directions"=i2,"Name"=s"Sway","Length"=i78,"NextAction"=s"Sway","Prototype"=E68,"Hgt"=i8,"Procedure"=n,"Y"=i0,"X"=i0),a(1;O23),p(false;"amount"=i200,"obj"=O22),p(true;"Length"=i1,"Directions"=i1,"Procedure"=n,"Step"=i1),p(true;"Swing"=E69,"Swing2"=E70),p(true;"Length"=i1,"Directions"=i1,"Procedure"=n,"Step"=i1),p(true;"Wdt"=i8,"Name"=s"Swing","X"=i0,"Directions"=i2,"FlipDir"=i1,"Length"=i90,"NextAction"=s"Swing2","Prototype"=E66,"Procedure"=n,"Hgt"=i20,"Y"=i0,"Delay"=i1),p(true;"Wdt"=i8,"Name"=s"Swing","Reverse"=i1,"X"=i0,"Directions"=i2,"FlipDir"=i1,"Length"=i90,"NextAction"=s"Swing","Prototype"=E66,"Procedure"=n,"Hgt"=i20,"Y"=i0,"Delay"=i1), diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Map.bmp b/planet/BeyondTheRocks.ocf/Crash.ocs/Map.bmp deleted file mode 100644 index 7db9c5a5b..000000000 Binary files a/planet/BeyondTheRocks.ocf/Crash.ocs/Map.bmp and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Scenario.txt b/planet/BeyondTheRocks.ocf/Crash.ocs/Scenario.txt deleted file mode 100644 index fa6873b8d..000000000 --- a/planet/BeyondTheRocks.ocf/Crash.ocs/Scenario.txt +++ /dev/null @@ -1,42 +0,0 @@ -[Head] -Icon=37 -Title=Crash -Version=5,2,90,20 -Difficulty=10 -MaxPlayer=3 -NoInitialize=true - -[Game] -Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1 - -[Player1] -Wealth=0 -Crew=Clonk=1 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1; - -[Player2] -Wealth=0 -Crew=Clonk=1 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1; - -[Player3] -Wealth=0 -Crew=Clonk=1 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1; - -[Player4] -Wealth=0 -Crew=Clonk=1 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1; - -[Landscape] -Sky=Clouds2 -MapWidth=200,0,64,10000 -MapHeight=175,0,40,10000 -NewStyleLandscape=2 -NoScan=1 - -[Weather] -Climate=0,10,0,100 -YearSpeed=0,0,0,100 -Wind=0,100,-100,100 diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/PumpNoLava.c b/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/PumpNoLava.c deleted file mode 100644 index 7bd01ba78..000000000 --- a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/PumpNoLava.c +++ /dev/null @@ -1,9 +0,0 @@ -#appendto Pump - -// Pump can only pump water - -func Initialize() -{ - SetPumpableMaterials("Water"); - return _inherited(...); -} \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/StringTblUS.txt b/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/StringTblUS.txt deleted file mode 100644 index f2dc06972..000000000 --- a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/StringTblUS.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Intro -MsgIntro1=Wow, quite turbulent here... -MsgIntro2=Have a look at that lava lake! -MsgIntro3=Come on old girl, hang in there... -MsgIntro4=Uh oh... -MsgIntro5=Quick! The ejection seat! - -# NPC Pilot -NamePilot=Pilot -MsgCrashedPlane=So, have you found the plane yet? -AnsCrashedPlane=No, we're still searching. - -# NPC Merchant -MsgSellPlans=I have some interesting knowledge about constructions, which I can share with you for 150 clunkers. -AnsNoMoney=Then I have to mine for gold, I'll be back later. -AnsBuyPlans=That's a good deal, here you have the clunkers. -MsgGivePlans=Thanks, here are your plans for {{Pump}}, {{Pipe}}, {{Catapult}} and {{Cannon}}. But be careful with the pump; it's made of wood and cannot be used to pump lava! -MsgLeaveVillage=Please leave this quiet village. diff --git a/planet/BeyondTheRocks.ocf/DescDE.rtf b/planet/BeyondTheRocks.ocf/DescDE.rtf deleted file mode 100644 index dfe6e2d2a..000000000 Binary files a/planet/BeyondTheRocks.ocf/DescDE.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/DescUS.rtf b/planet/BeyondTheRocks.ocf/DescUS.rtf deleted file mode 100644 index 7c3ff9a7f..000000000 Binary files a/planet/BeyondTheRocks.ocf/DescUS.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/GoldRush.ocs/DescDE.rtf b/planet/BeyondTheRocks.ocf/GoldRush.ocs/DescDE.rtf deleted file mode 100644 index 63b0981d5..000000000 Binary files a/planet/BeyondTheRocks.ocf/GoldRush.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/GoldRush.ocs/DescUS.rtf b/planet/BeyondTheRocks.ocf/GoldRush.ocs/DescUS.rtf deleted file mode 100644 index 3982725de..000000000 Binary files a/planet/BeyondTheRocks.ocf/GoldRush.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Landscape.txt b/planet/BeyondTheRocks.ocf/GoldRush.ocs/Landscape.txt deleted file mode 100644 index e31f0fe01..000000000 --- a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Landscape.txt +++ /dev/null @@ -1,115 +0,0 @@ -/*-- - Goldmine - Author: Maikel - - A landscape with some smooth hills and some gold underneath the surface. ---*/ - -// Fills an overlay with random specks. -overlay RandomMat { - mask=1; invert=1; grp=1; - loosebounds=1; - // Combine multiple algortihms. - overlay { - algo=rndchecker; a=10; - zoomX=10; zoomY=-10; - turbulence=100; lambda=3; - mask=1; loosebounds=1; - } | overlay { - algo=bozo; a=8; - zoomX=10; zoomY=-10; - turbulence=1000; lambda=3; - mask=1; loosebounds=1; - } | overlay { - algo=bozo; a=8; - zoomX=-10; zoomY=10; - turbulence=1000; lambda=3; - mask=1; loosebounds=1; - }; -}; - -// Fills an overlay with some random spots. -overlay RandomSpots { - mask=1; invert=1; grp=1; - overlay { - algo=bozo; a=10; - zoomX=10; zoomY=-10; - turbulence=1000; lambda=3; - mask=1; loosebounds=1; - } & overlay { - algo=bozo; a=10; - zoomX=-10; zoomY=10; - turbulence=1000; lambda=3; - mask=1; loosebounds=1; - }; -}; - -map Goldmine { - // Use the sine algorithm for some small hills. - overlay { - mat=Earth; tex=earth; - algo=sin; - zoomX=40; zoomY=-100; - ox=20; oy=40; - turbulence=10; lambda=0; - // Different types of earth, some tunnel and materials. - RandomMat & overlay { - mat=Tunnel; tex=tunnel; - overlay { - algo=border; a=1; b=1; - mat=Earth; tex=Earth; - }; - }; - RandomMat & overlay { mat=Earth; tex=earth_rough; }; - RandomMat & overlay { mat=Earth; tex=earth_dry; }; - RandomSpots & overlay { mat=Earth; tex=earth_topsoil; }; - RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; - RandomSpots & overlay { mat=Coal; tex=coal; }; - RandomSpots & overlay { mat=Sulphur; tex=sulphur; }; - RandomSpots & overlay { mat=Ore; tex=Ore; }; - // Make layers with different types of materials. - // Upper layer with sulphur and coal. - overlay { - x=0; y=58; wdt=100; hgt=12; - turbulence=10; lambda=3; - loosebounds=1; mask=1; - RandomMat & overlay { mat=Earth; tex=earth_topsoil; }; - RandomMat & overlay { mat=Coal; tex=coal; }; - RandomMat & overlay { mat=Sulphur; tex=sulphur; }; - }; - // Middle layer with rock and ore. - overlay { - x=0; y=72; wdt=100; hgt=12; - turbulence=10; lambda=3; - loosebounds=1; mask=1; - RandomMat & overlay { mat=Earth; tex=earth_midsoil; }; - RandomMat & overlay { mat=Rock; tex=rock; }; - RandomMat & overlay { mat=Ore; tex=ore; }; - RandomSpots & overlay { mat=Rock; tex=rock_cracked; }; - RandomSpots & overlay { mat=Rock; tex=rock_cracked; }; - RandomSpots & overlay { mat=Rock; tex=rock_cracked; }; - RandomSpots & overlay { mat=Rock; tex=rock_cracked; }; - }; - // Bottom layer with gold. - overlay { - x=0; y=86; wdt=100; hgt=12; - turbulence=10; lambda=3; - loosebounds=1; mask=1; - RandomSpots & overlay { mat=Gold; tex=gold; }; - RandomSpots & overlay { mat=Gold; tex=gold; }; - RandomSpots & overlay { mat=Gold; tex=gold; }; - RandomSpots & overlay { mat=Gold; tex=gold; }; - RandomSpots & overlay { mat=Gold; tex=gold; }; - RandomMat & overlay { mat=Gold; tex=gold; }; - RandomMat & overlay { mat=Gold; tex=gold; }; - }; - // Border of earth and sand. - overlay { - algo=border; a=3; b=3; - mat=Sand; tex=sand_rough; - RandomMat & overlay { mat=Earth; tex=earth_rough; }; - RandomMat & overlay { mat=Earth; tex=earth_dry; }; - RandomMat & overlay { mat=Earth; tex=earth; }; - }; - }; -}; diff --git a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Scenario.txt b/planet/BeyondTheRocks.ocf/GoldRush.ocs/Scenario.txt deleted file mode 100644 index c56b1d917..000000000 --- a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Scenario.txt +++ /dev/null @@ -1,49 +0,0 @@ -[Head] -Icon=15 -Title=Goldmine -Version=5,0,0,0 -MaxPlayer=3 -Difficulty=10 - -[Definitions] -Definition1=Objects.ocd - -[Game] -Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1; - -[Player1] -Wealth=10 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Player2] -Wealth=10 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Player3] -Wealth=10 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Player4] -Wealth=10 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Landscape] -InEarth=Rock=1;Firestone=3;Loam=2 -InEarthLevel=40 -Sky=Clouds2 -MapWidth=100 -MapHeight=75 - -[Weather] -Climate=0 -YearSpeed=0 -Wind=0,100,-100,100 - diff --git a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Script.c b/planet/BeyondTheRocks.ocf/GoldRush.ocs/Script.c deleted file mode 100644 index 02512c8db..000000000 --- a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Script.c +++ /dev/null @@ -1,67 +0,0 @@ -/** - Goldmine - A simple landscape with some gold, the goal is to mine all gold. - - @authors Maikel -*/ - - -protected func Initialize() -{ - // Goal: Resource extraction, set to gold mining. - var goal = CreateObject(Goal_Wealth); - goal->SetWealthGoal(400); - - // Place some trees. - for (var i = 0; i < 16 + Random(4); i++) - PlaceVegetation(Tree_Coniferous, 0, LandscapeHeight() / 3, LandscapeWidth(), LandscapeHeight(), 1000 * (61 + Random(40))); - - // place some sprout berries - var bush = PlaceVegetation(SproutBerryBush, 0, LandscapeHeight() / 3, LandscapeWidth(), LandscapeHeight(), 100000); - if(bush) - for (var i = 0; i < 2; i++) - PlaceVegetation(SproutBerryBush, bush->GetX() - 200, bush->GetY() - 200, 400, 400, 100000); - PlaceGrass(100); - - // Set time of day to evening and create some clouds and celestials. - Cloud->Place(10); - Cloud->SetPrecipitation("Water", 15); - CreateObject(Environment_Celestial); - var time = CreateObject(Environment_Time); - time->SetTime(600); - time->SetCycleSpeed(12); - return; -} - -private func FindHeight(int x) -{ - var y = 0; - while (!GBackSemiSolid(x, y) && y < LandscapeHeight()) - y += 10; - return y; -} - -protected func InitializePlayer(int plr) -{ - // Increase wealth goal per player. - var goal = FindObject(Find_ID(Goal_Wealth)); - if (goal) - goal->SetWealthGoal(300 + 100 * Min(GetPlayerCount(), 3)); - - // Move clonks to location and give them a shovel. - var index = 0, crew; - while (crew = GetCrew(plr, index)) - { - var x = 275 + Random(50); - crew->SetPosition(x , FindHeight(x) - 20); - crew->CreateContents(Shovel); - // First clonk can construct, others can mine. - if (index == 0) - crew->CreateContents(Hammer); - else - crew->CreateContents(Axe); - index++; - } - return; -} - diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/DescDE.rtf b/planet/BeyondTheRocks.ocf/IronPeak.ocs/DescDE.rtf deleted file mode 100644 index e5bb052b1..000000000 Binary files a/planet/BeyondTheRocks.ocf/IronPeak.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/DescUS.rtf b/planet/BeyondTheRocks.ocf/IronPeak.ocs/DescUS.rtf deleted file mode 100644 index 498935189..000000000 Binary files a/planet/BeyondTheRocks.ocf/IronPeak.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Landscape.txt b/planet/BeyondTheRocks.ocf/IronPeak.ocs/Landscape.txt deleted file mode 100644 index 55f028397..000000000 --- a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Landscape.txt +++ /dev/null @@ -1,90 +0,0 @@ -/*-- - Iron Peak - Author: Maikel - - A mountain peak filled with iron ore and coal, the crust consists - of granite, rock, ice and some entrances. ---*/ - -// Fills an overlay randomly with the specified material. -overlay RandomMat { - mask=1; invert=1; grp=1; - // Combine multiple algortihms to obtain more regularity than just rndchecker. - overlay { - algo=rndchecker; a=18; - zoomX=-25; zoomY=-25; - turbulence=100; lambda=3; - mask=1; - } | overlay { - algo=bozo; a=25; - zoomX=10; zoomY=-10; - turbulence=1000; lambda=3; - mask=1; - } | overlay { - algo=bozo; a=25; - zoomX=-10; zoomY=10; - turbulence=1000; lambda=3; - mask=1; - }; -}; - -// Fills the mountain with materials. -overlay MountainMaterials { - // Earth as background material. - mat=Earth; tex=earth; - RandomMat & overlay { mat=Earth; tex=earth_dry; }; - RandomMat & overlay { mat=Earth; tex=earth_rough; }; - // Combine random mat with all materials needed. - RandomMat & overlay { mat=Granite; tex=granite; }; - RandomMat & overlay { mat=Rock; tex=rock_cracked; }; - RandomMat & overlay { mat=Snow; tex=snow1; }; - RandomMat & overlay { mat=Ice; tex=ice3; }; - RandomMat & overlay { mat=Rock; tex=rock; }; - RandomMat & overlay { mat=Tunnel; tex=tunnel; }; - RandomMat & overlay { mat=Ore; tex=ore; }; - RandomMat & overlay { mat=Sulphur; tex=sulphur; }; - RandomMat & overlay { mat=Coal; tex=coal; }; - // A little more diagonal tunnels. - overlay { - algo=lines; a=3; b=20; - rotate=45; - turbulence=100; - mat=Tunnel; tex=tunnel; - }; - overlay { - algo=lines; a=3; b=20; - rotate=-45; - turbulence=100; - mat=Tunnel; tex=tunnel; - }; -}; - -// Fills the mountain crust with rocks and some earth and ice. -overlay CrustMaterials { - mat=Rock; tex=rock; - // Combine random mat with crust materials. - RandomMat & overlay { mat=Earth; tex=earth_dry; }; - RandomMat & overlay { mat=Ice; tex=ice3; }; - RandomMat & overlay { mat=Tunnel; tex=tunnel; }; - RandomMat & overlay { mat=Granite; tex=granite; }; - RandomMat & overlay { mat=Rock; tex=rock_cracked; }; -}; - -map IronPeak { - overlay { - // A simple mountain peak with the polygon algorithm. - algo=poly; - point { x=0%; y=140%; }; - point { x=45%; y=12%; }; - point { x=55%; y=12%; }; - point { x=100%; y=140%; }; - turbulence=100; lambda=1; - // Fill the mountain with materials. - MountainMaterials; - overlay { - // Create a crust mainly with rocks and some entrance points. - algo=border; a=5; b=5; - CrustMaterials; - }; - }; -}; diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Scenario.txt b/planet/BeyondTheRocks.ocf/IronPeak.ocs/Scenario.txt deleted file mode 100644 index d6d07275e..000000000 --- a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Scenario.txt +++ /dev/null @@ -1,51 +0,0 @@ -[Head] -Icon=1 -Title=IronPeak -Version=5,0,0,0 -MaxPlayer=6 -Difficulty=20 - -[Definitions] -Definition1=Objects.ocd - -[Game] -Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1; - -[Player1] -Wealth=40 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Player2] -Wealth=40 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Player3] -Wealth=40 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Player4] -Wealth=40 -Crew=Clonk=2 -Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1; -HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; - -[Landscape] -InEarth=Rock=1;Firestone=3;Loam=2 -InEarthLevel=30,0,0,100 -Sky=Clouds2 -MapWidth=150 -MapHeight=150 -BottomOpen=1 - -[Weather] -Climate=100 -YearSpeed=0 -Wind=1,100,-100,100 -Rain=40 - diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Game.txt b/planet/BeyondTheRocks.ocf/Skylands.ocs/Game.txt deleted file mode 100644 index 7202c104a..000000000 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Game.txt +++ /dev/null @@ -1,3396 +0,0 @@ -[Object] -id=Rule_EnergyNeed -Properties=7;false;"Prototype"=DRule_EnergyNeed -Timer=34 -Category=65 -Plane=100 -Size=100000 -Mass=1 -X=F3276800 -Y=F3276800 -Picture=0,0,0,0 -OCF=12845121 - -[Object] -id=Rule_TeamAccount -Properties=8;false;"Prototype"=DRule_TeamAccount -Timer=34 -Category=65 -Plane=100 -Size=100000 -Mass=1 -X=F3276800 -Y=F3276800 -Picture=0,0,0,0 -OCF=12845121 - -[Object] -id=Rule_BuyAtFlagpole -Properties=9;false;"Prototype"=DRule_BuyAtFlagpole -Timer=34 -Category=65 -Plane=100 -Size=100000 -Mass=1 -X=F3276800 -Y=F3276800 -Picture=0,0,0,0 -OCF=12845121 - -[Object] -id=Tree_Coniferous -Properties=494;false;"MeshTransformation"=E1,"Prototype"=DTree_Coniferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=150 -X=F63730910 -Y=F58074672 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,495;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_Coniferous -Properties=497;false;"MeshTransformation"=E2,"Prototype"=DTree_Coniferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=150 -X=F50724864 -Y=F59375616 -Width=60 -Height=110 -Offset=-30,-55 -Vertices=9 -VertexY=45,30,20,10,0,-10,-20,-30,-45 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,498;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=500;false;"MeshTransformation"=E3,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F3014302 -Y=F27490082 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,501;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=503;false;"MeshTransformation"=E4,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F13823085 -Y=F25365690 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,504;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=506;false;"MeshTransformation"=E5,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F27656192 -Y=F56688640 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,507;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=509;false;"MeshTransformation"=E6,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F24161246 -Y=F58994972 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,510;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=512;false;"MeshTransformation"=E7,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F4767142 -Y=F47344816 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,513;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=515;false;"MeshTransformation"=E8,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F63832064 -Y=F19988480 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,516;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=518;false;"MeshTransformation"=E9,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F69337088 -Y=F19529728 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,519;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=521;false;"MeshTransformation"=E10,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F36066684 -Y=F5595937 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,522;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=524;false;"MeshTransformation"=E11,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F41418752 -Y=F6946816 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,525;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Tree_SmallConiferous -Properties=527;false;"MeshTransformation"=E12,"Prototype"=DTree_SmallConiferous -Timer=29 -Category=1 -Plane=100 -Size=100000 -Mass=80 -X=F8456239 -Y=F25339618 -Width=30 -Height=55 -Offset=-15,-27 -Vertices=9 -VertexY=22,15,10,5,0,-5,-10,-15,-22 -VertexCNAT=8,16,16,16,16,16,16,16,4 -VertexFriction=50,50,25,25,25,25,50,50,50 -Picture=0,0,0,0 -OCF=12845761 -Component=Wood=4 -Effects=(1,29,35,0,None,528;false;"Name"=s"IntGrowth","growth"=i5) - - [Mesh] - Valid=true - -[Object] -id=Chest -Properties=10;false;"MeshTransformation"=E13,"Prototype"=DChest,"chestanim"=i0 -Timer=34 -Category=2 -Plane=200 -Size=100000 -Mass=108 -X=F10763853 -Y=F58486923 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=477;476;475;448;417;416;387;386;385 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=11;false;"MeshTransformation"=E14,"Prototype"=DChest,"chestanim"=i0 -Timer=15 -Category=2 -Plane=200 -Size=100000 -Mass=168 -X=F29867678 -Y=F44325928 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=472;470;468;464;463;462;461;451;450;446;444;415;411;407;403 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=12;false;"MeshTransformation"=E15,"Prototype"=DChest,"chestanim"=i0 -Timer=18 -Category=2 -Plane=200 -Size=100000 -Mass=110 -X=F40062051 -Y=F67920539 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=478;449;420;419;418;381;380;379 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=13;false;"MeshTransformation"=E16,"Prototype"=DChest,"chestanim"=i0 -Timer=1 -Category=2 -Plane=200 -Size=100000 -Mass=212 -X=F41663666 -Y=F33321789 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=471;469;467;460;459;458;457;456;445;443;430;429;428;427;426;425;424;414;410;406;402;384 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=14;false;"MeshTransformation"=E17,"Prototype"=DChest,"chestanim"=i0 -Timer=3 -Category=2 -Plane=200 -Size=100000 -Mass=120 -X=F63101160 -Y=F34893943 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=442;441;440;439;437;435;413;409;405;401;383 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=15;false;"MeshTransformation"=E18,"Prototype"=DChest,"chestanim"=i0 -Timer=7 -Category=2 -Plane=200 -Size=100000 -Mass=116 -X=F16900256 -Y=F8086944 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=474;473;455;454;453;452;423;422;421;378 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=16;false;"MeshTransformation"=E19,"Prototype"=DChest,"chestanim"=i0 -Timer=33 -Category=2 -Plane=200 -Size=100000 -Mass=154 -X=F63070078 -Y=F9203753 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=433;432;431;399;398;397;396;395;394;393;392;391;390;389;388 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Chest -Properties=17;false;"MeshTransformation"=E20,"Prototype"=DChest,"chestanim"=i0 -Timer=2 -Category=2 -Plane=200 -Size=100000 -Mass=116 -X=F59550692 -Y=F45904737 -Width=20 -Height=24 -Offset=-10,-12 -Vertices=4 -VertexX=-8,-8,8,8 -VertexY=-2,11,-2,11 -VertexCNAT=5,9,6,10 -VertexFriction=50,50,100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Wood=3 -Contents=466;465;447;438;436;434;412;408;404;400;382 -ColorMod=3506438143 - - [Mesh] - Valid=true - - [AnimationNode] - Slot=1 - Number=0 - Type=Leaf - Animation=Open - Position=linear(F65,F0,F65,20,Hold,29) - -[Object] -id=Plane_Construction -Properties=377;false;"next_part"=DPlane_Skids,"Prototype"=DPlane_Construction,"progress"=n -Timer=9 -Category=2 -Plane=200 -Size=100000 -Mass=4000 -X=F17857108 -Y=F26312342 -Width=60 -Height=29 -Offset=-30,-14 -Vertices=2 -VertexX=-18,18 -VertexY=14,14 -VertexFriction=100,100 -Picture=0,0,0,0 -OCF=12845121 -Component=Plane_Propeller=1;Plane_Chassis=1;Plane_Skids=1;Plane_Engine=1;Plane_Wings=1 -Graphics=Plane_Construction::Site - -[Object] -id=Plane_Wings -Properties=18;false;"Prototype"=DPlane_Wings -Timer=26 -Category=4 -Plane=300 -Rotation=117 -Size=100000 -Mass=50 -X=F39350436 -Y=F7759462 -R=F7667712 -Width=38 -Height=38 -Offset=-19,-19 -Vertices=4 -VertexX=16,-12,12,-16 -VertexY=4,-11,11,-4 -VertexFriction=60,60,60,60 -Picture=0,0,0,0 -OCF=12845633 -Component=Wood=2;Metal=1 - -[Object] -id=Plane_Skids -Properties=19;false;"Prototype"=DPlane_Skids -Timer=17 -Category=4 -Plane=300 -Rotation=13 -Size=100000 -Mass=20 -X=F29949952 -Y=F58163199 -R=F851968 -Width=42 -Height=42 -Offset=-21,-21 -Vertices=5 -VertexX=-18,-11,8,17,-1 -VertexY=-1,-6,-1,7,3 -VertexFriction=30,60,60,30,30 -Picture=0,0,0,0 -OCF=12845633 -Component=Metal=2 - -[Object] -id=Plane_Chassis -Properties=20;false;"Prototype"=DPlane_Chassis -Timer=33 -Category=4 -Plane=300 -Rotation=-18 -Size=100000 -Mass=100 -X=F59506688 -Y=F62914560 -R=F-1179648 -Width=68 -Height=68 -Offset=-34,-34 -Vertices=6 -VertexX=-22,-26,2,-2,23,24 -VertexY=14,1,7,-7,-16,-7 -VertexFriction=30,60,30,60,60,30 -Picture=0,0,0,0 -InLiquid=true -OCF=13894209 -Component=Wood=3;Metal=2 - -[Object] -id=Plane_Propeller -Properties=372;false;"Prototype"=DPlane_Propeller -Timer=15 -Category=16 -Plane=500 -Rotation=20 -Size=100000 -Mass=20 -X=F67567616 -Y=F21587558 -R=F1310720 -Width=18 -Height=18 -Offset=-9,-9 -Vertices=3 -VertexX=-4,4,1 -VertexY=-1,-3,5 -VertexFriction=60,60,60 -Picture=0,0,0,0 -OCF=12845641 -Component=Wood=1;Metal=1 - -[Object] -id=GoldBar -Properties=378;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F16900256 -Y=F8086944 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Nugget=3 - -[Object] -id=GoldBar -Properties=379;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F40062051 -Y=F67920539 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Nugget=3 - -[Object] -id=GoldBar -Properties=380;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F40062051 -Y=F67920539 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Nugget=3 - -[Object] -id=GoldBar -Properties=381;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F40062051 -Y=F67920539 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Nugget=3 - -[Object] -id=GoldBar -Properties=382;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F59550692 -Y=F45904737 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Nugget=3 - -[Object] -id=GoldBar -Properties=383;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F63101160 -Y=F34893943 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Nugget=3 - -[Object] -id=GoldBar -Properties=384;false;"Prototype"=DGoldBar -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=16 -X=F41663666 -Y=F33321789 -Width=10 -Height=4 -Offset=-5,-2 -Vertices=3 -VertexX=-4,4 -VertexY=0,0,-1 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Nugget=3 - -[Object] -id=Nugget -Properties=385;false;"Prototype"=DNugget -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=10 -Component=Nugget=1 - -[Object] -id=Nugget -Properties=386;false;"Prototype"=DNugget -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=10 -Component=Nugget=1 -Graphics=Nugget::1 - -[Object] -id=Nugget -Properties=387;false;"Prototype"=DNugget -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=10 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=388;false;"Prototype"=DNugget -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Nugget -Properties=389;false;"Prototype"=DNugget -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Nugget=1 - -[Object] -id=Nugget -Properties=390;false;"Prototype"=DNugget -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Nugget=1 -Graphics=Nugget::4 - -[Object] -id=Loam -Properties=391;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=392;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 - -[Object] -id=Loam -Properties=393;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=394;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::3 - -[Object] -id=Loam -Properties=395;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=396;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::3 - -[Object] -id=Loam -Properties=397;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 - -[Object] -id=Loam -Properties=398;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=399;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63070078 -Y=F9203753 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=16 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=400;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59550692 -Y=F45904737 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Earth=2 - -[Object] -id=Loam -Properties=401;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63101160 -Y=F34893943 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Earth=2 - -[Object] -id=Loam -Properties=402;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=403;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Earth=2 - -[Object] -id=Loam -Properties=404;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59550692 -Y=F45904737 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Earth=2 - -[Object] -id=Loam -Properties=405;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63101160 -Y=F34893943 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Earth=2 - -[Object] -id=Loam -Properties=406;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Earth=2 - -[Object] -id=Loam -Properties=407;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=408;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59550692 -Y=F45904737 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Earth=2 -Graphics=Loam::3 - -[Object] -id=Loam -Properties=409;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63101160 -Y=F34893943 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Earth=2 - -[Object] -id=Loam -Properties=410;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=411;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Earth=2 - -[Object] -id=Loam -Properties=412;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59550692 -Y=F45904737 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=413;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F63101160 -Y=F34893943 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=414;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=415;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=416;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=10 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=417;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=10 -Component=Earth=2 - -[Object] -id=Loam -Properties=418;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F40062051 -Y=F67920539 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=419;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F40062051 -Y=F67920539 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=420;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F40062051 -Y=F67920539 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=421;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=422;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Earth=2 - -[Object] -id=Loam -Properties=423;false;"Prototype"=DLoam -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=489;false;"Prototype"=DLoam -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F7655487 -Y=F49958942 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=490;false;"Prototype"=DLoam -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F12004031 -Y=F31283182 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=491;false;"Prototype"=DLoam -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F2673246 -Y=F31685061 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::4 - -[Object] -id=Loam -Properties=492;false;"Prototype"=DLoam -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10324071 -Y=F28143392 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::2 - -[Object] -id=Loam -Properties=493;false;"Prototype"=DLoam -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F36178430 -Y=F12087050 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 - -[Object] -id=Loam -Properties=530;false;"Prototype"=DLoam -Timer=29 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F65235676 -Y=F22695850 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Loam -Properties=531;false;"Prototype"=DLoam -Timer=29 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F68962148 -Y=F23941221 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexY=3,-3 -VertexFriction=40,40 -Picture=0,0,0,0 -OCF=2359881 -Component=Earth=2 -Graphics=Loam::1 - -[Object] -id=Wood -Properties=424;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=425;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=426;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=427;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=428;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=429;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=430;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F41663666 -Y=F33321789 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=13 -Component=Wood=1 - -[Object] -id=Wood -Properties=431;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F63070078 -Y=F9203753 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=16 -Component=Wood=1 - -[Object] -id=Wood -Properties=432;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F63070078 -Y=F9203753 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=16 -Component=Wood=1 - -[Object] -id=Wood -Properties=433;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F63070078 -Y=F9203753 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=16 -Component=Wood=1 - -[Object] -id=Wood -Properties=434;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F59550692 -Y=F45904737 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=17 -Component=Wood=1 - -[Object] -id=Wood -Properties=435;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F63101160 -Y=F34893943 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=14 -Component=Wood=1 - -[Object] -id=Wood -Properties=436;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F59550692 -Y=F45904737 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=17 -Component=Wood=1 - -[Object] -id=Wood -Properties=437;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F63101160 -Y=F34893943 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=14 -Component=Wood=1 - -[Object] -id=Wood -Properties=438;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F59550692 -Y=F45904737 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=17 -Component=Wood=1 - -[Object] -id=Wood -Properties=439;false;"Prototype"=DWood -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=6 -X=F63101160 -Y=F34893943 -Width=12 -Height=12 -Offset=-7,-6 -Vertices=3 -VertexX=4,-5 -VertexY=-1,2 -VertexCNAT=1,2 -VertexFriction=50,50 -Picture=0,0,0,0 -OCF=713 -Contained=14 -Component=Wood=1 - -[Object] -id=Metal -Properties=440;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F63101160 -Y=F34893943 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Ore=1 - -[Object] -id=Metal -Properties=441;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F63101160 -Y=F34893943 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Ore=1 - -[Object] -id=Metal -Properties=442;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F63101160 -Y=F34893943 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=14 -Component=Ore=1 - -[Object] -id=Metal -Properties=443;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F41663666 -Y=F33321789 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Ore=1 - -[Object] -id=Metal -Properties=444;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F29867678 -Y=F44325928 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Ore=1 - -[Object] -id=Metal -Properties=445;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F41663666 -Y=F33321789 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Ore=1 - -[Object] -id=Metal -Properties=446;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F29867678 -Y=F44325928 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Ore=1 - -[Object] -id=Metal -Properties=447;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F59550692 -Y=F45904737 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Ore=1 - -[Object] -id=Metal -Properties=448;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F10763853 -Y=F58486923 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=10 -Component=Ore=1 - -[Object] -id=Metal -Properties=449;false;"Prototype"=DMetal -Timer=21 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F40062051 -Y=F67920539 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=12 -Component=Ore=1 - -[Object] -id=Metal -Properties=450;false;"Prototype"=DMetal -Timer=18 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F29867678 -Y=F44325928 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Ore=1 - -[Object] -id=Metal -Properties=451;false;"Prototype"=DMetal -Timer=18 -Category=16 -Plane=500 -Size=100000 -Mass=12 -X=F29867678 -Y=F44325928 -Width=12 -Height=4 -Offset=-6,-2 -Vertices=3 -VertexX=-5,5 -VertexCNAT=1,2,16 -VertexFriction=30,30,30 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Ore=1 - -[Object] -id=Rock -Properties=452;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Rock=1 -Graphics=Rock::6 - -[Object] -id=Rock -Properties=453;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Rock=1 -Graphics=Rock::5 - -[Object] -id=Rock -Properties=454;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Rock=1 -Graphics=Rock::8 - -[Object] -id=Rock -Properties=455;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=15 -Component=Rock=1 -Graphics=Rock::5 - -[Object] -id=Rock -Properties=456;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Rock=1 -Graphics=Rock::3 - -[Object] -id=Rock -Properties=457;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Rock=1 -Graphics=Rock::3 - -[Object] -id=Rock -Properties=458;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Rock=1 -Graphics=Rock::3 - -[Object] -id=Rock -Properties=459;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Rock=1 -Graphics=Rock::2 - -[Object] -id=Rock -Properties=460;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=13 -Component=Rock=1 -Graphics=Rock::1 - -[Object] -id=Rock -Properties=461;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Rock=1 -Graphics=Rock::2 - -[Object] -id=Rock -Properties=462;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Rock=1 -Graphics=Rock::9 - -[Object] -id=Rock -Properties=463;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Rock=1 -Graphics=Rock::2 - -[Object] -id=Rock -Properties=464;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=11 -Component=Rock=1 -Graphics=Rock::4 - -[Object] -id=Rock -Properties=465;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59550692 -Y=F45904737 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Rock=1 - -[Object] -id=Rock -Properties=466;false;"Prototype"=DRock -Timer=14 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59550692 -Y=F45904737 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=3 -VertexX=0,2,-2 -VertexY=1,-1,-1 -VertexFriction=40,40,40 -Picture=0,0,0,0 -OCF=585 -Contained=17 -Component=Rock=1 -Graphics=Rock::6 - -[Object] -id=Firestone -Properties=467;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=13 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=468;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=11 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=469;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=13 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=470;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=11 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=471;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F41663666 -Y=F33321789 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=13 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=472;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F29867678 -Y=F44325928 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=11 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=473;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=15 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=474;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F16900256 -Y=F8086944 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=15 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=475;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=10 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=476;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=10 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=477;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10763853 -Y=F58486923 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=10 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=478;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F40062051 -Y=F67920539 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=73 -Contained=12 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=479;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F10695055 -Y=F31810336 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=480;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F9388759 -Y=F29055264 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=481;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F2446485 -Y=F30570204 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=482;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F11679958 -Y=F28931595 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=483;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F37100825 -Y=F15229658 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=484;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F35341016 -Y=F11498878 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=485;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F6652431 -Y=F49768179 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 - -[Object] -id=Firestone -Properties=486;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F27913213 -Y=F59990726 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=487;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F31413280 -Y=F61037037 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=488;false;"Prototype"=DFirestone -Timer=10 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F55597458 -Y=F65502734 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::1 - -[Object] -id=Firestone -Properties=532;false;"Prototype"=DFirestone -Timer=29 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F59486896 -Y=F66279198 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Object] -id=Firestone -Properties=533;false;"Prototype"=DFirestone -Timer=29 -Category=16 -Plane=500 -Size=100000 -Mass=10 -X=F69667908 -Y=F23162447 -Width=8 -Height=8 -Offset=-4,-4 -Vertices=2 -VertexX=-3,3 -VertexY=1,-1 -VertexFriction=20 -Picture=0,0,0,0 -OCF=2359369 -Component=Sulphur=1 -Graphics=Firestone::2 - -[Script] -Scenario=false;"Prototype"=t -Values=a(12;i-829,i0,i-559,i0,i0,i1000,i0,i0,i559,i0,i-829,i0),a(12;i883,i0,i469,i0,i0,i1000,i0,i0,i-469,i0,i883,i0),a(12;i-449,i0,i219,i0,i0,i500,i0,i0,i-219,i0,i-449,i0),a(12;i-457,i0,i203,i0,i0,i500,i0,i0,i-203,i0,i-457,i0),a(12;i-328,i0,i377,i0,i0,i500,i0,i0,i-377,i0,i-328,i0),a(12;i-424,i0,i-265,i0,i0,i500,i0,i0,i265,i0,i-424,i0),a(12;i445,i0,i227,i0,i0,i500,i0,i0,i-227,i0,i445,i0),a(12;i129,i0,i483,i0,i0,i500,i0,i0,i-483,i0,i129,i0),a(12;i334,i0,i371,i0,i0,i500,i0,i0,i-371,i0,i334,i0),a(12;i487,i0,i112,i0,i0,i500,i0,i0,i-112,i0,i487,i0),a(12;i-404,i0,i294,i0,i0,i500,i0,i0,i-294,i0,i-404,i0),a(12;i-104,i0,i489,i0,i0,i500,i0,i0,i-489,i0,i-104,i0),a(12;i719,i0,i695,i0,i0,i1000,i0,i0,i-695,i0,i719,i0),a(12;i914,i0,i407,i0,i0,i1000,i0,i0,i-407,i0,i914,i0),a(12;i588,i0,i809,i0,i0,i1000,i0,i0,i-809,i0,i588,i0),a(12;i454,i0,i891,i0,i0,i1000,i0,i0,i-891,i0,i454,i0),a(12;i719,i0,i695,i0,i0,i1000,i0,i0,i-695,i0,i719,i0),a(12;i309,i0,i951,i0,i0,i1000,i0,i0,i-951,i0,i309,i0),a(12;i799,i0,i602,i0,i0,i1000,i0,i0,i-602,i0,i799,i0),a(12;i695,i0,i719,i0,i0,i1000,i0,i0,i-719,i0,i695,i0), diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/DefCore.txt b/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/DefCore.txt deleted file mode 100644 index 50fc22064..000000000 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/DefCore.txt +++ /dev/null @@ -1,15 +0,0 @@ -[DefCore] -id=LiftTower_Hook -Version=5,2,0,1 -Category=C4D_Object -Timer=2 -TimerCall=Rotation -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 \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Scenario.txt b/planet/BeyondTheRocks.ocf/Skylands.ocs/Scenario.txt deleted file mode 100644 index 4bc1b0509..000000000 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Scenario.txt +++ /dev/null @@ -1,51 +0,0 @@ -[Head] -Icon=25 -Title=Skylands -Version=5,2,90,20 -Difficulty=20 -MaxPlayer=30 -NoInitialize=true - -[Game] -Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1;Rule_BuyAtFlagpole=1 -ValueOverloads=Nugget=10;GoldBar=50; - -[Player1] -Wealth=50,0,0,250 -Crew=Clonk=2 -Knowledge=Plane_Engine=1;Foundry=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;LiftTower=1;Pump=1 -HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 -HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 - -[Player2] -Wealth=50,0,0,250 -Crew=Clonk=2 -Knowledge=Plane_Engine=1;Foundry=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;LiftTower=1;Pump=1 -HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 -HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 - -[Player3] -Wealth=50,0,0,250 -Crew=Clonk=2 -Knowledge=Plane_Engine=1;Foundry=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;LiftTower=1;Pump=1 -HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 -HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 - -[Player4] -Wealth=50,0,0,250 -Crew=Clonk=2 -Knowledge=Plane_Engine=1;Foundry=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;LiftTower=1;Pump=1 -HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 -HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5 - -[Landscape] -Sky=Clouds2 -BottomOpen=true -MapWidth=100,0,64,10000 -MapHeight=200,0,40,10000 -NewStyleLandscape=2 - -[Weather] -Climate=0,10,0,100 -YearSpeed=0,0,0,100 -Wind=0,100,-100,100 diff --git a/planet/BeyondTheRocks.ocf/Title.png b/planet/BeyondTheRocks.ocf/Title.png deleted file mode 100644 index 2b905d6f6..000000000 Binary files a/planet/BeyondTheRocks.ocf/Title.png and /dev/null differ diff --git a/planet/BeyondTheRocks.ocf/Title.txt b/planet/BeyondTheRocks.ocf/Title.txt deleted file mode 100644 index a41e2d0ea..000000000 --- a/planet/BeyondTheRocks.ocf/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Beyond the Rocks -US:Beyond the Rocks diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/DefCore.txt b/planet/Experimental.ocd/FireGlobe.ocd/DefCore.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/DefCore.txt rename to planet/Experimental.ocd/FireGlobe.ocd/DefCore.txt diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Graphics.6.png b/planet/Experimental.ocd/FireGlobe.ocd/Graphics.6.png similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Graphics.6.png rename to planet/Experimental.ocd/FireGlobe.ocd/Graphics.6.png diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Path.ocd/DefCore.txt b/planet/Experimental.ocd/FireGlobe.ocd/Path.ocd/DefCore.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Path.ocd/DefCore.txt rename to planet/Experimental.ocd/FireGlobe.ocd/Path.ocd/DefCore.txt diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Path.ocd/Graphics.png b/planet/Experimental.ocd/FireGlobe.ocd/Path.ocd/Graphics.png similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Path.ocd/Graphics.png rename to planet/Experimental.ocd/FireGlobe.ocd/Path.ocd/Graphics.png diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Path.ocd/Script.c b/planet/Experimental.ocd/FireGlobe.ocd/Path.ocd/Script.c similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Path.ocd/Script.c rename to planet/Experimental.ocd/FireGlobe.ocd/Path.ocd/Script.c diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Script.c b/planet/Experimental.ocd/FireGlobe.ocd/Script.c similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/Script.c rename to planet/Experimental.ocd/FireGlobe.ocd/Script.c diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/StringTblDE.txt b/planet/Experimental.ocd/FireGlobe.ocd/StringTblDE.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/StringTblDE.txt rename to planet/Experimental.ocd/FireGlobe.ocd/StringTblDE.txt diff --git a/planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/StringTblUS.txt b/planet/Experimental.ocd/FireGlobe.ocd/StringTblUS.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/FireGlobe.ocd/StringTblUS.txt rename to planet/Experimental.ocd/FireGlobe.ocd/StringTblUS.txt diff --git a/planet/Experimental.ocd/Hatch.ocd/DefCore.txt b/planet/Experimental.ocd/Hatch.ocd/DefCore.txt new file mode 100644 index 000000000..97011e93e --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/DefCore.txt @@ -0,0 +1,17 @@ +[DefCore] +id=Hatch +Version=5,2,0,1 +Category=C4D_Structure +Width=26 +Height=26 +Offset=-13,-13 +Vertices=5 +VertexX=0,-12,12,-10,10 +VertexY=0,0,0,6,6 +VertexFriction=100,100,100,100,100 +VertexCNAT=64,1,2,1,2 +SolidMask=0,0,20,20,0,0 +Components=Wood=4; +Construction=1 +Value=8 +Mass=10 diff --git a/planet/Experimental.ocd/Hatch.ocd/Graphics.png b/planet/Experimental.ocd/Hatch.ocd/Graphics.png new file mode 100644 index 000000000..cf3abf95b Binary files /dev/null and b/planet/Experimental.ocd/Hatch.ocd/Graphics.png differ diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/DefCore.txt b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/DefCore.txt new file mode 100644 index 000000000..65996287e --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Hatch_Graphic +Version=5,2,0,1 +Width=26 +Height=26 +Offset=-13,-13 +Category=C4D_Structure \ No newline at end of file diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Graphics.mesh b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Graphics.mesh new file mode 100644 index 000000000..8c418bf9f Binary files /dev/null and b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Graphics.mesh differ diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.png b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.png new file mode 100644 index 000000000..0c397c5a7 Binary files /dev/null and b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.png differ diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.skeleton b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.skeleton new file mode 100644 index 000000000..6978a1f6b Binary files /dev/null and b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch.skeleton differ diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch2.png b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch2.png new file mode 100644 index 000000000..0f32f4653 Binary files /dev/null and b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Hatch2.png differ diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Scene.material b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Scene.material new file mode 100644 index 000000000..ce9ebea1f --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Scene.material @@ -0,0 +1,40 @@ +material Hatch2 +{ + receive_shadows on + technique + { + pass + { + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 1.000000 1.000000 1.000000 1.000000 + specular 0.500000 0.500000 0.500000 1.000000 12.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + texture_unit + { + texture Hatch2.png + tex_address_mode wrap + filtering trilinear + } + } + } +} +material Hatch +{ + receive_shadows on + technique + { + pass + { + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 1.000000 1.000000 1.000000 1.000000 + specular 0.500000 0.500000 0.500000 1.000000 12.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + texture_unit + { + texture Hatch.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Script.c b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Script.c new file mode 100644 index 000000000..c434ee600 --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/Hatch3DGraphic.ocd/Script.c @@ -0,0 +1,45 @@ +//Hatch Graphic + +local hatch_anim; +local parent; + +protected func Initialize() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Translate(0,-10000), Trans_Rotate(-10,0,1,0), Trans_Rotate(-8,1,0,0))); +} + +public func SetHatchParent(object hatch) +{ + parent = hatch; +} + +func Anim(string anim_name) +{ + var animstart = 0; + if(hatch_anim) + { + if(GetAnimationPosition(hatch_anim) != GetAnimationLength(anim_name)) + { + animstart = GetAnimationLength(anim_name) - GetAnimationPosition(hatch_anim); + } + } + + StopAnimation(hatch_anim); + hatch_anim = PlayAnimation(anim_name, 5, Anim_Linear(animstart, 0, GetAnimationLength(anim_name), 14, ANIM_Hold), Anim_Const(1000)); +} + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Directions = 1, + X = 0, + Y = 0, + Wdt = 26, + Hgt = 26, + NextAction = "Attach", + }, +}; + +local Plane = 100; \ No newline at end of file diff --git a/planet/Experimental.ocd/Hatch.ocd/Script.c b/planet/Experimental.ocd/Hatch.ocd/Script.c new file mode 100644 index 000000000..dbe29dcc5 --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/Script.c @@ -0,0 +1,58 @@ +/* + Hatch + Author: Ringwaul +*/ + +local graphic; + +protected func Initialize() +{ + SetAction("Hatch"); + graphic = CreateObject(Hatch_Graphic); + graphic->SetAction("Attach", this); + graphic->SetHatchParent(this); + return 1; +} + +func ControlUp(object clonk) +{ + if(GetPhase() != 0) + { + graphic->Anim("Close"); + SetPhase(0); + SetSolidMask(0,0,26,26,0,0); + } +} + +func ControlDown(object clonk) +{ + if(GetPhase() != 1) + { + graphic->Anim("Open"); + SetPhase(1); + SetSolidMask(26,0,26,26,0,0); + } +} + +protected func Definition(def) +{ + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,-3000,-5000), Trans_Rotate(-30,1,0,0), Trans_Rotate(30,0,1,0), Trans_Translate(1000,1,0)),def); +} + +local Name = "$Name$"; +local Touchable = 2; +local ActMap = { + Hatch = { + Prototype = Action, + Name = "Hatch", + Procedure = DFA_NONE, + Directions = 1, + FlipDir = 0, + Length = 2, + Delay = 0, + X = 0, + Y = 0, + Wdt = 1, + Hgt = 1, +}, +}; \ No newline at end of file diff --git a/planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt b/planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt new file mode 100644 index 000000000..bf0599ad1 --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Hatch diff --git a/planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt b/planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt new file mode 100644 index 000000000..166659300 --- /dev/null +++ b/planet/Experimental.ocd/Hatch.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Hatch \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/Info.txt b/planet/Experimental.ocd/Info.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/Info.txt rename to planet/Experimental.ocd/Info.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/DefCore.txt b/planet/Experimental.ocd/LiftTower.ocd/DefCore.txt similarity index 80% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/DefCore.txt rename to planet/Experimental.ocd/LiftTower.ocd/DefCore.txt index b06e783ff..f12e4713c 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/DefCore.txt +++ b/planet/Experimental.ocd/LiftTower.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=LiftTower Version=5,2,0,1 Category=C4D_Structure -Timer=5 -TimerCall=SpinWheel Width=23 Height=68 Offset=-11,-10 @@ -15,6 +13,5 @@ Value=200 Mass=4500 Components=Metal=2;Wood=4; Exclusive=1 -BlastIncinerate=100 Construction=1 ContainBlast=1 \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Graphics.mesh b/planet/Experimental.ocd/LiftTower.ocd/Graphics.mesh similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Graphics.mesh rename to planet/Experimental.ocd/LiftTower.ocd/Graphics.mesh diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/DefCore.txt b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/DefCore.txt similarity index 82% rename from planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/DefCore.txt rename to planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/DefCore.txt index 50fc22064..5fec776b8 100644 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/DefCore.txt +++ b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=LiftTower_Hook Version=5,2,0,1 Category=C4D_Object -Timer=2 -TimerCall=Rotation Width=8 Height=8 Offset=-4,-4 diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/Graphics.8.png b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/Graphics.8.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/Graphics.8.png rename to planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/Graphics.8.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png rename to planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/Script.c b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/Script.c similarity index 93% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/Script.c rename to planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/Script.c index 9b007b829..34e6b5dd0 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/Script.c +++ b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/Script.c @@ -7,7 +7,7 @@ local tower, rope; 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"))); + 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]); @@ -108,6 +108,11 @@ func Construction(object constructor) tower = constructor; } +func Initialize() +{ + AddTimer("Rotation", 2); +} + func SetRope(bool no_connect) { rope = CreateObject(LiftTower_Rope,0,0,NO_OWNER); diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/StringTblDE.txt b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/StringTblDE.txt rename to planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/StringTblUS.txt b/planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Hook.ocd/StringTblUS.txt rename to planet/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/LiftTower.skeleton b/planet/Experimental.ocd/LiftTower.ocd/LiftTower.skeleton similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/LiftTower.skeleton rename to planet/Experimental.ocd/LiftTower.ocd/LiftTower.skeleton diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/DefCore.txt b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/DefCore.txt rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/Graphics.10.png b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/Graphics.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/Graphics.10.png rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/Graphics.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/Script.c b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/Script.c similarity index 96% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/Script.c rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/Script.c index 28edbe802..94399f9fa 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/Script.c +++ b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/Script.c @@ -10,6 +10,7 @@ #include Library_Rope static const Weight = 1; +static const Library_Rope_MAXLENGTH = 1000; // Call this to break the rope. public func BreakRope(bool silent) @@ -43,10 +44,11 @@ private func CreateSegment(int index, object previous) /*-- Rope connecting --*/ // Connects two objects to the rope, but the length will vary on their positions. -public func Connect(object obj1, object obj2) +public func Connect(object obj1, object obj2, int max_length) { StartRopeConnect(obj1, obj2); - SetMaxLength(200); + if (!max_length) max_length = Library_Rope_MAXLENGTH; + SetMaxLength(max_length); SetFixed(true, false); SetAction("Hide"); diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/StringTblDE.txt b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/StringTblDE.txt rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/StringTblUS.txt b/planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Rope.ocd/StringTblUS.txt rename to planet/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Scene.material b/planet/Experimental.ocd/LiftTower.ocd/Scene.material similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Scene.material rename to planet/Experimental.ocd/LiftTower.ocd/Scene.material diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Script.c b/planet/Experimental.ocd/LiftTower.ocd/Script.c similarity index 91% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Script.c rename to planet/Experimental.ocd/LiftTower.ocd/Script.c index 0107c55db..f871a6896 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/Script.c +++ b/planet/Experimental.ocd/LiftTower.ocd/Script.c @@ -20,6 +20,7 @@ protected func Initialize() hook_pos = CreateArray(); anim_no = PlayAnimation("Turn", 10, Anim_Const(0), Anim_Const(1000)); stopped = true; + AddEffect("SpinWheel", this, 0, 5); } /* Rope */ @@ -52,20 +53,17 @@ func Interact(object clonk) { if (!hook) OnRopeBreak(); - if (clonk->GetAction() == "Walk") + if (hook->Contained() == this) { - if (hook->Contained() == this) - { - if (clonk->Collect(hook,true)) - hook->SetRope(); - } - else - { - clonk->ObjectCommand("Grab", this); - } - return true; + if (clonk->Collect(hook,nil,nil,true)) + hook->SetRope(); } - return false; + else + { + clonk->ObjectCommand("Grab", this); + } + + return true; } func SetRope(object rope_to_set) @@ -116,7 +114,7 @@ private func FxDrawInStop(object target, effect, int temp) /* Animation */ -protected func SpinWheel() +protected func FxSpinWheelTimer() { if (!hook) return StopWheel(); if (hook->Contained() == this) return StopWheel(); @@ -168,4 +166,5 @@ func Definition(def) { local Name = "$Name$"; local Description = "$Description$"; -local Touchable = 1; \ No newline at end of file +local Touchable = 2; +local BlastIncinerate = 100; \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/StringTblDE.txt b/planet/Experimental.ocd/LiftTower.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/StringTblDE.txt rename to planet/Experimental.ocd/LiftTower.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/StringTblUS.txt b/planet/Experimental.ocd/LiftTower.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/LiftTower.ocd/StringTblUS.txt rename to planet/Experimental.ocd/LiftTower.ocd/StringTblUS.txt diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/DefCore.txt b/planet/Experimental.ocd/Moss.ocd/DefCore.txt similarity index 86% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/DefCore.txt rename to planet/Experimental.ocd/Moss.ocd/DefCore.txt index 5c819a78a..034b5007f 100644 --- a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/DefCore.txt +++ b/planet/Experimental.ocd/Moss.ocd/DefCore.txt @@ -14,8 +14,6 @@ Value=5 Mass=5 Components=Wood=2; Rotate=1 -ContactIncinerate=1 -BlastIncinerate=1 Rotate=1 Float=1 Collectible=1 diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics.8.png b/planet/Experimental.ocd/Moss.ocd/Graphics.8.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics.8.png rename to planet/Experimental.ocd/Moss.ocd/Graphics.8.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics1.8.png b/planet/Experimental.ocd/Moss.ocd/Graphics1.8.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics1.8.png rename to planet/Experimental.ocd/Moss.ocd/Graphics1.8.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics1Dry.8.png b/planet/Experimental.ocd/Moss.ocd/Graphics1Dry.8.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics1Dry.8.png rename to planet/Experimental.ocd/Moss.ocd/Graphics1Dry.8.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics2.8.png b/planet/Experimental.ocd/Moss.ocd/Graphics2.8.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics2.8.png rename to planet/Experimental.ocd/Moss.ocd/Graphics2.8.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics2Dry.8.png b/planet/Experimental.ocd/Moss.ocd/Graphics2Dry.8.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Graphics2Dry.8.png rename to planet/Experimental.ocd/Moss.ocd/Graphics2Dry.8.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/GraphicsDry.8.png b/planet/Experimental.ocd/Moss.ocd/GraphicsDry.8.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/GraphicsDry.8.png rename to planet/Experimental.ocd/Moss.ocd/GraphicsDry.8.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/DefCore.txt b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/DefCore.txt similarity index 84% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/DefCore.txt rename to planet/Experimental.ocd/Moss.ocd/Lichen.ocd/DefCore.txt index 4fd38582f..16a8cd50e 100644 --- a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/DefCore.txt +++ b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/DefCore.txt @@ -5,6 +5,3 @@ Category=C4D_StaticBack | C4D_Object Width=20 Height=20 Offset=-10,-10 -BlastIncinerate=1 - - diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Graphics.4.png b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Graphics.4.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Graphics.4.png rename to planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Graphics.4.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Graphics1.4.png b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Graphics1.4.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Graphics1.4.png rename to planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Graphics1.4.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Graphics2.4.png b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Graphics2.4.png similarity index 100% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Graphics2.4.png rename to planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Graphics2.4.png diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Script.c b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Script.c similarity index 83% rename from planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Script.c rename to planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Script.c index fbe8394a3..00ca58276 100644 --- a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Script.c +++ b/planet/Experimental.ocd/Moss.ocd/Lichen.ocd/Script.c @@ -37,7 +37,7 @@ public func Incineration() return; } -public func Damage(int change, int byplayer) +public func Damage() { if (GetDamage() > (size/4)) Destroy(); } @@ -45,12 +45,18 @@ public func Damage(int change, int byplayer) private func Destroy() { if(Random(maxsize+35)AddReservation(object_id, amount); - car->AddDelivery(container, object_id, amount); + car->AddDelivery(container, nil, object_id, amount); return true; } diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblDE.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblDE.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblDE.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblDE.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblUS.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblUS.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblUS.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/StringTblUS.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/DefCore.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/DefCore.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/DefCore.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/DefCore.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Graphics.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Graphics.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Graphics.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Graphics.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsArrange.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsArrange.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsArrange.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsArrange.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine0.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine0.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine0.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine0.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine1.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine1.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine1.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine1.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine2.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine2.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine2.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine2.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine3.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine3.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine3.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine3.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine4.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine4.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine4.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine4.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine5.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine5.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine5.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine5.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine6.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine6.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine6.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine6.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine7.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine7.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine7.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/GraphicsLine7.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Script.c similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Script.c rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/Script.c diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblDE.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblDE.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblDE.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblDE.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblUS.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblUS.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblUS.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableLine.ocd/StringTblUS.txt diff --git a/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/DefCore.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/DefCore.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/CableReel.ocd/DefCore.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/DefCore.txt diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Graphics.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Graphics.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/Graphics.png diff --git a/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/Script.c similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/CableReel.ocd/Script.c rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/Script.c diff --git a/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/StringTblDE.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/StringTblDE.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/CableReel.ocd/StringTblDE.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/StringTblDE.txt diff --git a/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/StringTblUS.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/StringTblUS.txt similarity index 100% rename from planet/Tests.ocf/Experimental.ocd/CableReel.ocd/StringTblUS.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/CableReel.ocd/StringTblUS.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/DefCore.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/DefCore.txt similarity index 93% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/DefCore.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/DefCore.txt index 1d232bdb0..9671d1fb9 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/DefCore.txt +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/DefCore.txt @@ -14,6 +14,5 @@ Mass=5 #Components=Metal=1 Picture=0,0,160,160 Exclusive=1 -BlastIncinerate=50 Construction=1 Collection=-10,-10,20,20 diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Graphics.8.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Graphics.8.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Graphics.8.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Graphics.8.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c similarity index 93% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c index aa2e22e35..a65a738af 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c @@ -11,7 +11,7 @@ local rotation = 0; protected func Initialize() { SetAction("Wait"); - SetGraphics(0, GetID(), 1, GFXOV_MODE_Base); + SetGraphics(nil, GetID(), 1, GFXOV_MODE_Base); return _inherited(...); } @@ -75,4 +75,5 @@ local ActMap = { }, }; -local Name = "$Name$"; \ No newline at end of file +local Name = "$Name$"; +local BlastIncinerate = 50; \ No newline at end of file diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblDE.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblDE.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblDE.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblDE.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblUS.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblUS.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblUS.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/StringTblUS.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt similarity index 88% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt index 1956ec2f9..a01c3a0fb 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt @@ -18,6 +18,4 @@ Collection=-12,-8,24,10 GrabPutGet=C4D_GrabGet|C4D_GrabPut Rotate=30 UprightAttach=0 -TimerCall=TurnWheels -Timer=1 BorderBound=1 \ No newline at end of file diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Graphics.mesh b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Graphics.mesh similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Graphics.mesh rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Graphics.mesh diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Script.c similarity index 96% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Script.c rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Script.c index 0b2d3b54a..106918af5 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Script.c +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Script.c @@ -24,6 +24,7 @@ protected func Initialize() tremble_anim = PlayAnimation("Tremble", 5, Anim_Const(0), Anim_Const(500)); iRotWheels = 0; + AddTimer("TurnWheels", 1); iTremble = 0; iMovementSpeed = 2; return _inherited(...); @@ -57,7 +58,7 @@ private func MaxContentsCount() protected func RejectCollect(id object_id, object obj) { - if (ContentsCount() < MaxContentsCount()) + if (ContentsCount() < this->MaxContentsCount()) { Sound("Clonk"); return false; diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblDE.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblDE.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblDE.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblDE.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblUS.txt b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblUS.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblUS.txt rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/lorry.png b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.png similarity index 100% rename from planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/lorry.png rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.png diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.skeleton b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.skeleton similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.skeleton rename to planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.skeleton diff --git a/planet/Tests.ocf/CableLorrys.ocs/Map.bmp b/planet/Experimental.ocf/CableLorrys.ocs/Map.bmp similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/Map.bmp rename to planet/Experimental.ocf/CableLorrys.ocs/Map.bmp diff --git a/planet/Tests.ocf/CableLorrys.ocs/Scenario.txt b/planet/Experimental.ocf/CableLorrys.ocs/Scenario.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/Scenario.txt rename to planet/Experimental.ocf/CableLorrys.ocs/Scenario.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/Script.c similarity index 96% rename from planet/Tests.ocf/CableLorrys.ocs/Script.c rename to planet/Experimental.ocf/CableLorrys.ocs/Script.c index d861cd994..fc420f223 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/Script.c +++ b/planet/Experimental.ocf/CableLorrys.ocs/Script.c @@ -16,13 +16,13 @@ protected func Initialize() var c3 = CreateObject(CableCrossing, 585, 415); var c4 = CreateObject(CableCrossing, 555, 385); var cabin = CreateObject(WoodenCabin, 490, 390); - CreateObject(LiftTower, 935, 360); +// CreateObject(LiftTower, 935, 360); - CreateObject(CableLine)->SetConnectedObjects(workshop, c1); +// CreateObject(CableLine)->SetConnectedObjects(workshop, c1); CreateObject(CableLine)->SetConnectedObjects(c1, c2); CreateObject(CableLine)->SetConnectedObjects(c2, c3); CreateObject(CableLine)->SetConnectedObjects(c3, c4); - CreateObject(CableLine)->SetConnectedObjects(c4, cabin); +// CreateObject(CableLine)->SetConnectedObjects(c4, cabin); CreateObject(Lorry, 835, 360); @@ -100,7 +100,7 @@ protected func Initialize() CreateObject(CableLine)->SetConnectedObjects(cross_ore3, cross_ore4); CreateObject(CableLine)->SetConnectedObjects(cross_ore4, cross_ore5); - // A departure into the sulphur mine. + // A departure into the firestone mine. var cross_sulph1 = CreateObject(CableCrossing, 290, 670); var cross_sulph2 = CreateObject(CableCrossing, 250, 700); CreateObject(CableLine)->SetConnectedObjects(cross_ore3, cross_sulph1); @@ -113,7 +113,7 @@ protected func Initialize() // Some resources are already available in the mines. cross_ore5->CreateContents(Ore, 10); cross_coal1->CreateContents(Coal, 10); - cross_sulph2->CreateContents(Sulphur, 10);*/ + cross_sulph2->CreateContents(Firestone, 10);*/ /* DrawMaterialQuad("Earth-earth", 235, 250, 265, 250, 265, 255, 235, 255); DrawMaterialQuad("Earth-earth", 185, 250, 215, 250, 215, 255, 185, 255); diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Teams.txt b/planet/Experimental.ocf/CableLorrys.ocs/Teams.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Teams.txt rename to planet/Experimental.ocf/CableLorrys.ocs/Teams.txt diff --git a/planet/Tests.ocf/CableLorrys.ocs/Title.txt b/planet/Experimental.ocf/CableLorrys.ocs/Title.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/Title.txt rename to planet/Experimental.ocf/CableLorrys.ocs/Title.txt diff --git a/planet/Experimental.ocf/DescDE.rtf b/planet/Experimental.ocf/DescDE.rtf new file mode 100644 index 000000000..1b86d7e6d Binary files /dev/null and b/planet/Experimental.ocf/DescDE.rtf differ diff --git a/planet/Experimental.ocf/DescUS.rtf b/planet/Experimental.ocf/DescUS.rtf new file mode 100644 index 000000000..002bc6227 --- /dev/null +++ b/planet/Experimental.ocf/DescUS.rtf @@ -0,0 +1,22 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset1 Times New Roman;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Mangal;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af5\dbch\af6\afs28\loch\f2\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af7 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af7\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af7 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 +Experimental} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{{\*\bkmkstart __DdeLink__2_537781242}\b0\kerning1\rtlch \ltrch\loch\fs16\lang1043\loch\f4 +This scenario folder contains }{\b0\kerning1\rtlch \ltrch\loch\fs16\lang1043\loch\f4{\*\bkmkend __DdeLink__2_537781242} +experimental scenarios and scenarios for testing purposes. Feel free to play them and post any feedback in our forums.} +\par } \ No newline at end of file diff --git a/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/DefCore.txt b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/DefCore.txt new file mode 100644 index 000000000..b03da3fab --- /dev/null +++ b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/DefCore.txt @@ -0,0 +1,13 @@ +[DefCore] +id=OCTier +Version=5,3,0,0 +Category=C4D_Living +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexX=-12,12 +VertexY=12,12 +VertexFriction=100,100 +VertexCNAT=8,8 +CrewMember=1 diff --git a/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/Graphics.mesh b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/Graphics.mesh new file mode 100644 index 000000000..1cb78b7a4 Binary files /dev/null and b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/Graphics.mesh differ diff --git a/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/OCTIER.skeleton b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/OCTIER.skeleton new file mode 100644 index 000000000..e1771d2b1 Binary files /dev/null and b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/OCTIER.skeleton differ diff --git a/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/Script.c b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/Script.c new file mode 100644 index 000000000..6db095b1d --- /dev/null +++ b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/Script.c @@ -0,0 +1,77 @@ +/* OCTier */ + +func Initialize() +{ + SetObjDrawTransform(5000,0,0,0,5000); // scale separately by DrawTransform, because scaling in mesh transform screws up Z clipping + SetAction("Walk"); + //SetDir(Random(2)); +} + +func StartWalk() +{ + if(!GetEffect("IntWalk", this)) + AddEffect("IntWalk", this, 1, 1, this); +} + +func StopWalk() +{ + if(GetAction() != "Walk") RemoveEffect("IntWalk", this); +} + +func Footstep() +{ + if (GetMaterialVal("DigFree", "Material", GetMaterial(0,10)) == 0) + Sound("StepHard?"); + else + { + var dir = Sign(GetXDir()); + var clr = GetAverageTextureColor(GetTexture(0,10)); + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + }; + CreateParticle("Dust", PV_Random(dir * -5, dir * -3), 8, PV_Random(dir * 2, dir * 1), PV_Random(-2, -3), PV_Random(36, 2 * 36), particles, 5); + Sound("StepSoft?"); + } +} + +func TestAnimation(anim) // run dig poke walk +{ + if (this.test_anim) StopAnimation(this.test_anim); + this.test_anim = PlayAnimation(anim, 1, Anim_Linear(0, 0, GetAnimationLength(anim), 40, ANIM_Loop), Anim_Const(1000)); + Message("@%s", anim); + return true; +} + + + + +local ActMap = { +Walk = { + Prototype = Action, + Name = "Walk", + Procedure = DFA_WALK, + Accel = 16, + Decel = 22, + Speed = 200, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + X = 0, + Y = 0, + Wdt = 8, + Hgt = 20, + StartCall = "StartWalk", + AbortCall = "StopWalk", +// InLiquidAction = "Swim", +}, +}; + +func Definition(def) { + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(90,0,1,0), Trans_Translate(0,-2500)), def); + +} diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Scene.material b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/textur.material similarity index 69% rename from planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Scene.material rename to planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/textur.material index 88e523648..13c419bbb 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Scene.material +++ b/planet/Experimental.ocf/OCTier.ocs/OCTier.ocd/textur.material @@ -1,4 +1,4 @@ -material KingOfTheHill_Star +material textur { receive_shadows on technique @@ -7,7 +7,7 @@ material KingOfTheHill_Star { ambient 0.500000 0.500000 0.500000 1.000000 diffuse 0.800000 0.800000 0.800000 1.000000 - specular 0.500000 0.500000 0.500000 1.000000 12.500000 + specular 0.000000 0.000000 0.000000 1.000000 0.250000 emissive 0.000000 0.000000 0.000000 1.000000 } } diff --git a/planet/Experimental.ocf/OCTier.ocs/Scenario.txt b/planet/Experimental.ocf/OCTier.ocs/Scenario.txt new file mode 100644 index 000000000..e3ebaefca --- /dev/null +++ b/planet/Experimental.ocf/OCTier.ocs/Scenario.txt @@ -0,0 +1,6 @@ +[Head] +Icon=26 +Title=pluto's OC Tier! + +[Definitions] +LocalOnly=1 diff --git a/planet/Experimental.ocf/OCTier.ocs/Script.c b/planet/Experimental.ocf/OCTier.ocs/Script.c new file mode 100644 index 000000000..c591b967b --- /dev/null +++ b/planet/Experimental.ocf/OCTier.ocs/Script.c @@ -0,0 +1,13 @@ +func Initialize() +{ + CreateObject(OCTier, 48, 100, -1)->TestAnimation("Run"); + CreateObject(OCTier, 88, 100, -1)->TestAnimation("Dig"); + CreateObject(OCTier, 128, 100, -1)->TestAnimation("Poke"); + CreateObject(OCTier, 168, 100, -1)->TestAnimation("Walk"); +} + +func InitializePlayer(plr) +{ +var oct = CreateObject(OCTier, 48, 52, -1); +oct->MakeCrewMember(plr); +} diff --git a/planet/Tests.ocf/Lines.ocs/Map.bmp b/planet/Experimental.ocf/Playground.ocs/Map.bmp similarity index 100% rename from planet/Tests.ocf/Lines.ocs/Map.bmp rename to planet/Experimental.ocf/Playground.ocs/Map.bmp diff --git a/planet/Tests.ocf/Lines.ocs/Scenario.txt b/planet/Experimental.ocf/Playground.ocs/Scenario.txt similarity index 98% rename from planet/Tests.ocf/Lines.ocs/Scenario.txt rename to planet/Experimental.ocf/Playground.ocs/Scenario.txt index 724b97a3c..be5d504b6 100644 --- a/planet/Tests.ocf/Lines.ocs/Scenario.txt +++ b/planet/Experimental.ocf/Playground.ocs/Scenario.txt @@ -34,7 +34,7 @@ VegetationLevel=100,0,0,100 InEarth=Rock=1;Gold=1;Fireglobe=1;Loam=1 InEarthLevel=65,0,0,100 Sky=Clouds2 -BottomOpen=1 +BottomOpen=0 MapWidth=500,0,64,10000 MapHeight=100,0,40,10000 MapZoom=10 diff --git a/planet/Tests.ocf/Lines.ocs/Script.c b/planet/Experimental.ocf/Playground.ocs/Script.c similarity index 96% rename from planet/Tests.ocf/Lines.ocs/Script.c rename to planet/Experimental.ocf/Playground.ocs/Script.c index 86b74b197..0fadae0ac 100644 --- a/planet/Tests.ocf/Lines.ocs/Script.c +++ b/planet/Experimental.ocf/Playground.ocs/Script.c @@ -132,8 +132,7 @@ func InitializePlayer(int iPlr, int iX, int iY, object pBase, int iTeam) { var clonk = CreateObject(Clonk, 0, 0, iPlr); clonk->MakeCrewMember(iPlr); - clonk->SetGraphics(nil, Skin_Steampunk); - SetCursor(iPlr,clonk); + SetCursor(iPlr,clonk); JoinPlayer(iPlr); return; } @@ -142,12 +141,8 @@ func InitializePlayer(int iPlr, int iX, int iY, object pBase, int iTeam) { var clonk = GetCrew(iPlr); clonk->DoEnergy(100000); -// clonk->SetPosition(502, 538); - // clonk->SetGraphics(nil, Skin_Steampunk); clonk->CreateContents(Musket); clonk->CreateContents(LeadShot); -// clonk->CreateContents(Javelin); -// clonk->CreateContents(DynamiteBox); clonk->CreateContents(GrappleBow); clonk->CreateContents(Bow); clonk->Collect(CreateObject(Arrow)); diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Teams.txt b/planet/Experimental.ocf/Playground.ocs/Teams.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Teams.txt rename to planet/Experimental.ocf/Playground.ocs/Teams.txt diff --git a/planet/Experimental.ocf/Playground.ocs/Title.txt b/planet/Experimental.ocf/Playground.ocs/Title.txt new file mode 100644 index 000000000..0d01cd033 --- /dev/null +++ b/planet/Experimental.ocf/Playground.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Playground +US:Playground \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Castle.psd b/planet/Experimental.ocf/Raiders.ocs/Castle.psd new file mode 100644 index 000000000..241dd5c27 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Castle.psd differ diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/DefCore.txt b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/DefCore.txt new file mode 100644 index 000000000..bb2a5fb50 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/DefCore.txt @@ -0,0 +1,11 @@ +[DefCore] +id=Raiders_CastleBack +Version=5,2,0,1 +Category=C4D_StaticBack +Width=264 +Height=171 +Offset=-132,-86 +Value=13 +Mass=5000 +Exclusive=1 +Construction=1 \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Graphics.mesh b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Graphics.mesh new file mode 100644 index 000000000..3a101a0c0 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Graphics.mesh differ diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Graphics.png2 b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Graphics.png2 new file mode 100644 index 000000000..b52188f80 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Graphics.png2 differ diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Scene.material b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Scene.material similarity index 55% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Scene.material rename to planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Scene.material index dbc6b617d..e1f391ed5 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/Scene.material +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Scene.material @@ -1,4 +1,4 @@ -material Lorry +material CastleBackground { receive_shadows on technique @@ -9,12 +9,14 @@ material Lorry diffuse 0.640000 0.640000 0.640000 1.000000 specular 0.500000 0.500000 0.500000 1.000000 12.500000 emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit - { - texture lorry.png - tex_address_mode wrap - filtering trilinear - } + + texture_unit + { + texture Wall.png + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } } } } diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Script.c b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Script.c new file mode 100644 index 000000000..6be5c73d4 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Script.c @@ -0,0 +1,15 @@ +/* Castle Background */ + +func Initialize() +{ + CreateObject(Raiders_FrontTower, -113, 85, NO_OWNER); + // First floor + CreateObject(Raiders_CastleFloor, -52, 51, NO_OWNER)->SetBreaky(1+Random(2)); + CreateObject(Raiders_CastleFloor, 35, 51, NO_OWNER)->SetBreaky(1+Random(2)); + // Second floor + CreateObject(Raiders_CastleFloor, 88, 11, NO_OWNER)->SetBreaky(1+Random(2)); + CreateObject(Raiders_CastleFloor, 1, 11, NO_OWNER)->SetBreaky(1+Random(2)); + // Third floor + CreateObject(Raiders_CastleFloor, -52, -29, NO_OWNER)->SetBreaky(3); + CreateObject(Raiders_CastleFloor, 35, -29, NO_OWNER)->SetBreaky(3); +} \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Wall.png b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Wall.png new file mode 100644 index 000000000..5f7f01476 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Background.ocd/Wall.png differ diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/DefCore.txt b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/DefCore.txt new file mode 100644 index 000000000..602294ec4 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=Raiders_CastleFloor +Version=5,2,0,1 +Category=C4D_StaticBack +Width=87 +Height=14 +Offset=-43,-7 +Value=7 +Mass=300 +Exclusive=1 +Construction=1 +SolidMask=0,14,87,6,0,0 \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/Graphics.png b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/Graphics.png new file mode 100644 index 000000000..3a3304aab Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/Graphics.png differ diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/Script.c b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/Script.c new file mode 100644 index 000000000..0a6ba55f6 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/Floor.ocd/Script.c @@ -0,0 +1,71 @@ +/* Castle Floor */ + +local breakiness; + +// Configure which parts of the floor can fall apart +// 1 = left, 2 = right, 3 = both +func SetBreaky(int level) +{ + breakiness = level; + SetAction("Be"); + AddTimer("CheckBurden", 4); +} + +private func CheckBurden() +{ + if (!breakiness) return RemoveTimer("CheckBurden"); + + if (breakiness >= 2) + if (FindObject(Find_InRect(10,-18, 18,10), Find_ID(Clonk))) + BreakRight(); + if (breakiness == 1 || breakiness == 3) + if (FindObject(Find_InRect(-28,-18, 18,10), Find_ID(Clonk))) + BreakLeft(); +} + +private func BreakRight() +{ + Sound("TreeCrack"); + CastObjects(Wood, 2, 15, 20, 1, 180, 90); + if (GetPhase() == 1) + { + SetPhase(3); + SetSolidMask(261,14,87,6,0,0); + } + else + { + SetPhase(2); + SetSolidMask(174,14,87,6,0,0); + } + breakiness -= 2; +} + +private func BreakLeft() +{ + Sound("TreeCrack"); + CastObjects(Wood, 2, 15, -20, 1, 180, 90); + if (GetPhase() == 2) + { + SetPhase(3); + SetSolidMask(261,14,87,6,0,0); + } + else + { + SetPhase(1); + SetSolidMask(87,14,87,6,0,0); + } + breakiness -= 1; +} + +local ActMap = { + Be = { + Prototype = Action, + Name = "Be", + X = 0, + Y = 0, + Wdt = 87, + Hgt = 14, + Length = 4, + Delay = 0, + }, +}; \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/DefCore.txt b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/DefCore.txt new file mode 100644 index 000000000..2fc8cc5cf --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=Raiders_FrontTower +Version=5,2,0,1 +Category=C4D_StaticBack +Width=38 +Height=166 +Offset=-19,-83 +Value=16 +Mass=1000 +Exclusive=1 +Construction=1 +SolidMask=38,0,38,166,0,0 \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/Graphics.png b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/Graphics.png new file mode 100644 index 000000000..9047dd77f Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/Graphics.png differ diff --git a/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/Script.c b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/Script.c new file mode 100644 index 000000000..fead859e7 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/CastleParts.ocd/FrontTower.ocd/Script.c @@ -0,0 +1,6 @@ +/* Castle front tower */ + +func Initialize() +{ + this.Plane = 550; +} \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/DefCore.txt b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/DefCore.txt new file mode 100644 index 000000000..4c96b42f0 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Skin_Ghost +Version=5,2,0,1 +Category=C4D_StaticBack \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/Graphics.mesh b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/Graphics.mesh new file mode 100644 index 000000000..c645bd9fe Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/Graphics.mesh differ diff --git a/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/Scene.material b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/Scene.material new file mode 100644 index 000000000..cab6b4e77 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/Scene.material @@ -0,0 +1,39 @@ +material clonkGhost +{ + receive_shadows on + technique + { + pass + { + ambient 0.500000 0.500000 0.500000 1.000000 + diffuse 0.810000 0.810000 0.810000 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 3.000000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit Overlay + { + texture clonkGhostOverlay.png + tex_address_mode wrap + filtering trilinear + colour_op_ex modulate src_texture src_player_colour + // take alpha from texture only, ignore player alpha + alpha_op_ex source1 src_texture src_player_colour + } + texture_unit Clonk + { + texture clonkGhost.png + tex_address_mode wrap + filtering trilinear + colour_op_ex blend_current_alpha src_current src_texture + // Don't blend alpha, to make sure we have full intensity at the base/overlay border region + alpha_op_ex add src_current src_texture + } + texture_unit Light + { + // apply lighting + colour_op_ex modulate src_current src_diffuse + alpha_op_ex modulate src_current src_diffuse + } + } + } +} \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhost.png b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhost.png new file mode 100644 index 000000000..f0eedc377 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhost.png differ diff --git a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemist.skeleton b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhost.skeleton similarity index 100% rename from planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemist.skeleton rename to planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhost.skeleton diff --git a/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhostOverlay.png b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhostOverlay.png new file mode 100644 index 000000000..cb35bf0e5 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Ghost.ocd/clonkGhostOverlay.png differ diff --git a/planet/Experimental.ocf/Raiders.ocs/Landscape.txt b/planet/Experimental.ocf/Raiders.ocs/Landscape.txt new file mode 100644 index 000000000..2be2617bd --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Landscape.txt @@ -0,0 +1,51 @@ +/*-- + Raiders + Author: Clonkonaut + + Perfectly shaped to fit the scenario. +--*/ + +map raiders { + + // Top surface + overlay earth_sin { mat=Earth; x=0; y=23; wdt=80; hgt=30; algo=sin; oy=23; ox=20; zoomX=60; zoomY=-20; turbulence=50; + } | + + // Underground with material + overlay earth { mat=Earth; x=0; y=38; wdt=100; hgt=70; + overlay dark_earth_spots { mat=Earth; tex=earth_topSoil; algo=bozo; turbulence=5000; loosebounds=1; a=-5; }; + overlay dark_earth { mat=Earth; tex=earth_topSoil; y=50; turbulence=2000; loosebounds=1; }; + overlay gold { mat=Gold; x=10; y=80; wdt=50; hgt=10; algo=rndchecker; zoomX=-40; zoomY=-40; turbulence=3000; loosebounds=1; }; + overlay ore { mat=Ore; x=65; y=60; wdt=35; hgt=30; algo=bozo; turbulence=3000; loosebounds=1; lambda=1; }; + overlay coal { mat=Coal; x=0; y=25; wdt=70; hgt=35; algo=rndchecker; turbulence=2000; loosebounds=1; zoomX=70; lambda=1; }; + overlay rock { mat=Rock; x=0; y=5; wdt=50; hgt=35; algo=bozo; turbulence=3000; loosebounds=1; zoomX=60; zoomY=60; }; + overlay rock2 { mat=Rock; x=50; y=5; wdt=50; hgt=35; algo=bozo; turbulence=100; loosebounds=1; zoomX=40; zoomY=40; }; + // Chasms reaching the surface + overlay chasms { mat=Tunnel; x=15; y=-25; wdt=61; hgt=35; algo=lines; a=7; b=20; turbulence=1000; loosebounds=1; }; + }; + + // Two caves in the ground, one with a granite border + overlay cave1 { mat=Tunnel; x=5; y=53; wdt=20; hgt=10; turbulence=10; loosebounds=1; }; + overlay cave2 { mat=Tunnel; x=65; y=66; wdt=20; hgt=15; turbulence=500; loosebounds=1; + overlay border { mat=Granite; algo=border; x=-50; y=-50; wdt=200; hgt=200; a=3; b=2; loosebounds=1; }; + }; + + // Underground lake + overlay u_lake { mat=Tunnel; x=15; y=75; wdt=25; hgt=15; turbulence=1000; loosebounds=1; + overlay water { mat=Water; x=-50; y=75; wdt=200; }; + }; + // Ensuring there is always a spot for moss near the lake + overlay tunnel { mat=Tunnel; x=10; y=75; wdt=10; hgt=5; turbulence=10; loosebounds=1; }; + + // The castle shall have a flat plateau + overlay castle_plateau { mat=Earth; x=74; y=27; wdt=26; hgt=12; + // An ancient elevator shaft + overlay shaft { mat=Tunnel; x=75; y=0; wdt=10; hgt=90; }; + }; + + // The crystal chamber + overlay chamber { mat=Tunnel; tex=brickback; x=90; y=85; wdt=8; hgt=8; + overlay wall { mat=Brick; algo=border; a=1; b=1; }; + }; + +}; \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Scenario.txt b/planet/Experimental.ocf/Raiders.ocs/Scenario.txt new file mode 100644 index 000000000..c0cc82b08 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Scenario.txt @@ -0,0 +1,44 @@ +[Head] +Icon=29 +Title=Raiders +Version=5,0,0,0 +MaxPlayer=4 +Difficulty=25 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1; + +[Player1] +Wealth=0 +Crew=Clonk=1 +Knowledge=Bread=1;CookedMushroom=1;Axe=1;Barrel=1;CableReel=1;Dynamite=1;DynamiteBox=1;Hammer=1;Pickaxe=1;Ropebridge=1;Ropeladder=1;Shovel=1;Bow=1;Arrow=1;Shield=1;Elevator=1;Flagpole=1;Foundry=1;Sawmill=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Windmill=1; + +[Player2] +Wealth=0 +Crew=Clonk=1 +Knowledge=Bread=1;CookedMushroom=1;Axe=1;Barrel=1;CableReel=1;Dynamite=1;DynamiteBox=1;Hammer=1;Pickaxe=1;Ropebridge=1;Ropeladder=1;Shovel=1;Bow=1;Arrow=1;Shield=1;Elevator=1;Flagpole=1;Foundry=1;Sawmill=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Windmill=1; + +[Player3] +Wealth=0 +Crew=Clonk=1 +Knowledge=Bread=1;CookedMushroom=1;Axe=1;Barrel=1;CableReel=1;Dynamite=1;DynamiteBox=1;Hammer=1;Pickaxe=1;Ropebridge=1;Ropeladder=1;Shovel=1;Bow=1;Arrow=1;Shield=1;Elevator=1;Flagpole=1;Foundry=1;Sawmill=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Windmill=1; + +[Player4] +Wealth=0 +Crew=Clonk=1 +Knowledge=Bread=1;CookedMushroom=1;Axe=1;Barrel=1;CableReel=1;Dynamite=1;DynamiteBox=1;Hammer=1;Pickaxe=1;Ropebridge=1;Ropeladder=1;Shovel=1;Bow=1;Arrow=1;Shield=1;Elevator=1;Flagpole=1;Foundry=1;Sawmill=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Windmill=1; + +[Landscape] +InEarth=Rock=1;Loam=2 +InEarthLevel=30,0,0,100 +Sky=Clouds2 +MapWidth=150 +MapHeight=120 + +[Weather] +Climate=0 +YearSpeed=0 +Wind=1,100,-100,100 \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Script.c b/planet/Experimental.ocf/Raiders.ocs/Script.c new file mode 100644 index 000000000..5d3a3677e --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Script.c @@ -0,0 +1,56 @@ +/** + Raiders of the Lost Castle + A settlement scenario in which the player exploits an old castle ruin and will finally face supernatural forces. + + @authors Clonkonaut +*/ + +static is_initialized; + +// Decoration and environmental objects, basic settings + +func Initialize() +{ + // Goal: Script goal. + var goal = CreateObject(Goal_Script); + goal.Description = "$GoalDesc1$"; + + // Vegetation + Tree_Coniferous->Place(20, Rectangle(106,121, 826,335), { keep_area = true }); + PlaceGrass(20, 0,106); + + // The castle + CreateObject(Raiders_CastleBack, 1068, 256, NO_OWNER); +} + +// Player related supplies and structures + +func DoInit(int plr) +{ + if (is_initialized) return; + + // Supplies + var crate = CreateObject(Crate, 30, FindHeight(30), plr); + crate->CreateContents(Shovel); + crate->CreateContents(Hammer); + crate->CreateContents(Axe); + crate = CreateObject(Crate, 45, FindHeight(30), plr); + crate->CreateContents(Bread, 3); + + // A flag + CreateConstruction(Flagpole, 70, FindHeight(70), plr, 100, true); + + is_initialized = true; +} + +// Player positioning + +protected func InitializePlayer(int plr) +{ + // Move crew to starting location + var crew = GetCrew(plr, 0); + var x = 80 + Random(10); + crew->SetPosition(x, FindHeight(x)-10); + + DoInit(plr); +} \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/StringTblDE.txt b/planet/Experimental.ocf/Raiders.ocs/StringTblDE.txt new file mode 100644 index 000000000..e791965fd --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/StringTblDE.txt @@ -0,0 +1 @@ +GoalDesc1=Erforsche die Burg um mehr über den Aufenthaltsort des Blutkristalls zu erfahren. \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Title.txt b/planet/Experimental.ocf/Raiders.ocs/Title.txt new file mode 100644 index 000000000..746d90304 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Jäger des verlorenen Schlosses +US:Raiders of the Lost Castle \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/DefCore.txt b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/DefCore.txt new file mode 100644 index 000000000..e05b4ac6e --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/DefCore.txt @@ -0,0 +1,16 @@ +[DefCore] +id=Pocketwatch +Version=5,2,0,1 +Category=C4D_Object +Width=6 +Height=6 +Offset=-3,-3 +Vertices=2 +VertexX=0,0 +VertexY=-2,2 +VertexFriction=25,25 +Timer=1 +TimerCall=WatchUpdate +Components=Metal=1; +Value=6 +Mass=3 diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Graphics.mesh b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Graphics.mesh new file mode 100644 index 000000000..a70096fc6 Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Graphics.mesh differ diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/PocketWatch.png b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/PocketWatch.png new file mode 100644 index 000000000..94a0e29cc Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/PocketWatch.png differ diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/PocketWatch.skeleton b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/PocketWatch.skeleton new file mode 100644 index 000000000..8d4e96dde Binary files /dev/null and b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/PocketWatch.skeleton differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Scene.material b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Scene.material similarity index 74% rename from planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Scene.material rename to planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Scene.material index 963e810ed..5e1eac537 100644 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Scene.material +++ b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Scene.material @@ -1,4 +1,4 @@ -material Boompack +material PocketWatch { receive_shadows on technique @@ -6,12 +6,12 @@ material Boompack pass { ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 0.640000 0.640000 0.640000 1.000000 + diffuse 1.000000 1.000000 1.000000 1.000000 specular 0.000000 0.000000 0.000000 1.000000 12.500000 emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture boompack.png + texture PocketWatch.png tex_address_mode wrap filtering trilinear } diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Script.c b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Script.c new file mode 100644 index 000000000..b893b36f0 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/Script.c @@ -0,0 +1,43 @@ +/* + Pocketwatch + Author: Ringwaul + + Tells Time +*/ + +local watch_anim; + +public func GetCarryMode(clonk) { return CARRY_HandBack; } +public func GetCarryTransform(clonk, sec, back) +{ + if(!sec) return Trans_Mul(Trans_Translate(2800,200,0), Trans_Rotate(90,0,0,1), Trans_Rotate(180,0,1,0)); + return Trans_Mul(Trans_Translate(2800,200,0), Trans_Rotate(90,0,0,1)); +} + + + +protected func Construction() +{ + watch_anim = PlayAnimation("time", 5, Anim_Const(1), Anim_Const(1000)); +} + +public func WatchUpdate() +{ + var time = FindObject(Find_ID(Environment_Time)); + + if(time) + { + var watch_time = ((13305 * (time->GetTime() * 2) / 1000) - 1); + if(watch_time > GetAnimationLength("time")) watch_time = (watch_time - GetAnimationLength("time")); + SetAnimationPosition(watch_anim, Anim_Const(watch_time)); + } + return 1; +} + +protected func Definition(def) +{ + SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(15,1,0,0), Trans_Rotate(5,0,1,0), Trans_Rotate(-5,0,0,1), Trans_Translate(500,-400,0), Trans_Scale(1350)),def); +} + +local Name = "$Name$"; +local Collectible = true; \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/StringTblDE.txt b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/StringTblDE.txt new file mode 100644 index 000000000..f25625121 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Taschenuhr \ No newline at end of file diff --git a/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/StringTblUS.txt b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/StringTblUS.txt new file mode 100644 index 000000000..f2ce237d1 --- /dev/null +++ b/planet/Experimental.ocf/Raiders.ocs/Watch.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Pocketwatch \ No newline at end of file diff --git a/planet/Experimental.ocf/Title.txt b/planet/Experimental.ocf/Title.txt new file mode 100644 index 000000000..ede08a24b --- /dev/null +++ b/planet/Experimental.ocf/Title.txt @@ -0,0 +1,2 @@ +DE:Experimentelles +US:Experimental diff --git a/planet/Graphics.ocg/ClonkSkins.png b/planet/Graphics.ocg/ClonkSkins.png index 7759a5d0e..f15cf78d4 100644 Binary files a/planet/Graphics.ocg/ClonkSkins.png and b/planet/Graphics.ocg/ClonkSkins.png differ diff --git a/planet/Graphics.ocg/Crew.png b/planet/Graphics.ocg/Crew.png index a5aa16f30..7481dbb18 100644 Binary files a/planet/Graphics.ocg/Crew.png and b/planet/Graphics.ocg/Crew.png differ diff --git a/planet/Graphics.ocg/Cursor.png b/planet/Graphics.ocg/Cursor.png index 22682d05e..75c979472 100644 Binary files a/planet/Graphics.ocg/Cursor.png and b/planet/Graphics.ocg/Cursor.png differ diff --git a/planet/Graphics.ocg/Flag.png b/planet/Graphics.ocg/Flag.png index 6a5853cc9..bfea8c2de 100644 Binary files a/planet/Graphics.ocg/Flag.png and b/planet/Graphics.ocg/Flag.png differ diff --git a/planet/Graphics.ocg/LandscapeShader.c b/planet/Graphics.ocg/LandscapeShader.c index 0281ef3e5..f98b0948e 100644 --- a/planet/Graphics.ocg/LandscapeShader.c +++ b/planet/Graphics.ocg/LandscapeShader.c @@ -10,12 +10,13 @@ uniform sampler3D materialTex; uniform vec2 resolution; // Texture map -#ifdef BROKEN_ARRAYS_WORKAROUND +#ifndef NO_BROKEN_ARRAYS_WORKAROUND uniform sampler1D matMapTex; #else uniform float matMap[256]; #endif uniform int materialDepth; +uniform vec2 materialSize; // Expected parameters for the scaler const vec2 scalerStepX = vec2(1.0 / 8.0, 0.0); @@ -35,7 +36,7 @@ int f2i(float x) { float queryMatMap(int pix) { -#ifdef BROKEN_ARRAYS_WORKAROUND +#ifndef NO_BROKEN_ARRAYS_WORKAROUND int idx = f2i(texture1D(matMapTex, float(pix) / 256.0 + 0.5 / 256.0).r); return float(idx) / 256.0 + 0.5 / float(materialDepth); #else @@ -98,10 +99,11 @@ void main() vec4 lopx = texture2D(landscapeTex[0], otherCoo); // Get material pixels + vec2 tcoo = gl_TexCoord[0].st * resolution / materialSize; float mi = queryMatMap(f2i(lpx.r)); - vec4 mpx = texture3D(materialTex, vec3(gl_TexCoord[0].st * resolution / vec2(512.0, 512.0) * vec2(4.0, 4.0), mi)); + vec4 mpx = texture3D(materialTex, vec3(tcoo, mi)); float omi = queryMatMap(f2i(lopx.r)); - vec4 ompx = texture3D(materialTex, vec3(gl_TexCoord[0].st * resolution / vec2(512.0, 512.0) * vec2(4.0, 4.0), omi)); + vec4 ompx = texture3D(materialTex, vec3(tcoo, omi)); // Brightness float ambientBright = 1.0, shadeBright = 0.8; diff --git a/planet/Graphics.ocg/Logo.png b/planet/Graphics.ocg/Logo.png index 7cce0caf2..9edc8d6c8 100644 Binary files a/planet/Graphics.ocg/Logo.png and b/planet/Graphics.ocg/Logo.png differ diff --git a/planet/Graphics.ocg/StartupAboutBG.png b/planet/Graphics.ocg/StartupAboutBG.png index cdb598850..08280d7e9 100644 Binary files a/planet/Graphics.ocg/StartupAboutBG.png and b/planet/Graphics.ocg/StartupAboutBG.png differ diff --git a/planet/Graphics.ocg/StartupLogo.png b/planet/Graphics.ocg/StartupLogo.png index 1b44e22f9..d3d0bc2b5 100644 Binary files a/planet/Graphics.ocg/StartupLogo.png and b/planet/Graphics.ocg/StartupLogo.png differ diff --git a/planet/Graphics.ocg/StartupNetworkBG.jpg b/planet/Graphics.ocg/StartupNetworkBG.jpg deleted file mode 100644 index 9b2fd7789..000000000 Binary files a/planet/Graphics.ocg/StartupNetworkBG.jpg and /dev/null differ diff --git a/planet/Graphics.ocg/StartupPlrPropBG.png b/planet/Graphics.ocg/StartupPlrPropBG.png index 7bd12172a..87597da3a 100644 Binary files a/planet/Graphics.ocg/StartupPlrPropBG.png and b/planet/Graphics.ocg/StartupPlrPropBG.png differ diff --git a/planet/Graphics.ocg/StartupPlrSelBG.jpg b/planet/Graphics.ocg/StartupPlrSelBG.jpg deleted file mode 100644 index 6d3f98a1c..000000000 Binary files a/planet/Graphics.ocg/StartupPlrSelBG.jpg and /dev/null differ diff --git a/planet/Graphics.ocg/StartupScenSelBG.jpg b/planet/Graphics.ocg/StartupScenSelBG.jpg deleted file mode 100644 index 4d2ac8cf7..000000000 Binary files a/planet/Graphics.ocg/StartupScenSelBG.jpg and /dev/null differ diff --git a/planet/Graphics.ocg/StartupScenSelIcons.png b/planet/Graphics.ocg/StartupScenSelIcons.png old mode 100644 new mode 100755 index e787414a0..a3a627081 Binary files a/planet/Graphics.ocg/StartupScenSelIcons.png and b/planet/Graphics.ocg/StartupScenSelIcons.png differ diff --git a/planet/Issues.ocf/Dummy.ocd/DefCore.txt b/planet/Issues.ocf/Dummy.ocd/DefCore.txt new file mode 100644 index 000000000..c6ed3e59c --- /dev/null +++ b/planet/Issues.ocf/Dummy.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Dummy +Version=5,3,0,0 +Category=C4D_StaticBack diff --git a/planet/Issues.ocf/Dummy.ocd/Graphics.png b/planet/Issues.ocf/Dummy.ocd/Graphics.png new file mode 100644 index 000000000..b15f128ed Binary files /dev/null and b/planet/Issues.ocf/Dummy.ocd/Graphics.png differ diff --git a/planet/Issues.ocf/Dummy.ocd/Script.c b/planet/Issues.ocf/Dummy.ocd/Script.c new file mode 100644 index 000000000..fb184eaee --- /dev/null +++ b/planet/Issues.ocf/Dummy.ocd/Script.c @@ -0,0 +1,9 @@ +/** + Dummy + + A dummy object which may serve for various purposes +*/ + + +local Name = "$Name$"; +local Visibility = VIS_None; diff --git a/planet/Issues.ocf/Dummy.ocd/StringTblDE.txt b/planet/Issues.ocf/Dummy.ocd/StringTblDE.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Issues.ocf/Dummy.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Issues.ocf/Dummy.ocd/StringTblUS.txt b/planet/Issues.ocf/Dummy.ocd/StringTblUS.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Issues.ocf/Dummy.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Issues.ocf/System.ocg/Testing.c b/planet/Issues.ocf/System.ocg/Testing.c new file mode 100644 index 000000000..48951ad28 --- /dev/null +++ b/planet/Issues.ocf/System.ocg/Testing.c @@ -0,0 +1,58 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2013 Nicolas Hake + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +static __test_last_result; + +global func TEST(section) +{ + if (!__test_last_result) + __test_last_result = { + section: nil, + ok: 0, + failed: 0 + }; + if (__test_last_result.section) + { + Log("** TEST: %s: [%d/%d ok]", __test_last_result.section, __test_last_result.ok, __test_last_result.ok + __test_last_result.failed); + } + __test_last_result.section = section; + __test_last_result.ok = __test_last_result.failed = 0; + if (section) + Log("** TEST: %s", section); +} + +global func END_TEST() +{ + TEST(nil); +} + +global func EXPECT_EQ(expected, actual, failure_msg) +{ + if (expected != actual) + { + ++__test_last_result.failed; + var readable_expected = Format("%v", expected); + var readable_actual = Format("%v", actual); + if (GetType(expected) == C4V_C4Object) + readable_expected = Format("%v /* %s */", expected, expected->GetName()); + if (GetType(actual) == C4V_C4Object) + readable_actual = Format("%v /* %s */", actual, actual->GetName()); + if (failure_msg) + Log("*** EXPECTATION %d FAILED: %s (%s != %s)", __test_last_result.failed + __test_last_result.ok, failure_msg, readable_expected, readable_actual); + else + Log("*** EXPECTATION %d FAILED: (%s != %s)", __test_last_result.failed + __test_last_result.ok, readable_expected, readable_actual); + } else { + ++__test_last_result.ok; + } +} \ No newline at end of file diff --git a/planet/Issues.ocf/Title.txt b/planet/Issues.ocf/Title.txt new file mode 100644 index 000000000..51a71fc90 --- /dev/null +++ b/planet/Issues.ocf/Title.txt @@ -0,0 +1 @@ +US:Test cases for reported bugs diff --git a/planet/Issues.ocf/issue973.ocs/Scenario.txt b/planet/Issues.ocf/issue973.ocs/Scenario.txt new file mode 100644 index 000000000..55cd39a0b --- /dev/null +++ b/planet/Issues.ocf/issue973.ocs/Scenario.txt @@ -0,0 +1,5 @@ +[Head] +Title=Test case for #973 + +[Definitions] +LocalOnly=1 diff --git a/planet/Issues.ocf/issue973.ocs/Script.c b/planet/Issues.ocf/issue973.ocs/Script.c new file mode 100644 index 000000000..1c4e848ec --- /dev/null +++ b/planet/Issues.ocf/issue973.ocs/Script.c @@ -0,0 +1,54 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2013 Nicolas Hake + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +/* Issue #973: {Find,Sort}_* with no origin should use the FindObject call's + * context object instead of 0,0 */ + +func Initialize() +{ + // Setup testing environment: one object for context, a second object at the context object, one object at 0,0 + var ctx = CreateObject(Dummy, 100, 100, NO_OWNER); + ctx->SetName("ctx"); + var at_origin = CreateObject(Dummy, 0, 0, NO_OWNER); + at_origin->SetName("at_origin"); + var at_object = CreateObject(Dummy, ctx->GetX(), ctx->GetY(), NO_OWNER); + at_object->SetName("at_object"); + + TEST("object context Find_Distance"); + EXPECT_EQ(at_object, ctx->FindObject(Find_Exclude(ctx), Find_Distance(1))); + + TEST("global context Find_Distance"); + EXPECT_EQ(at_origin, FindObject(Find_Exclude(ctx), Find_Distance(1, at_origin->GetX(), at_origin->GetY()))); + EXPECT_EQ(at_object, FindObject(Find_Exclude(ctx), Find_Distance(1, at_object->GetX(), at_object->GetY()))); + + TEST("object context Find_InRect"); + EXPECT_EQ(at_object, ctx->FindObject(Find_Exclude(ctx), Find_InRect(0, 0, 1, 1))); + EXPECT_EQ(at_origin, ctx->FindObject(Find_Exclude(ctx), Find_InRect(-ctx->GetX(), -ctx->GetY(), 1, 1))); + + TEST("global context Find_InRect"); + EXPECT_EQ(at_origin, FindObject(Find_Exclude(ctx), Find_InRect(at_origin->GetX(), at_origin->GetY(), 1, 1))); + EXPECT_EQ(at_object, FindObject(Find_Exclude(ctx), Find_InRect(at_object->GetX(), at_object->GetY(), 1, 1))); + + TEST("object context Sort_Distance"); + EXPECT_EQ(at_object, ctx->FindObject(Find_Exclude(ctx), Sort_Distance() )); + EXPECT_EQ(at_origin, ctx->FindObject(Find_Exclude(ctx), Sort_Reverse(Sort_Distance()))); + + TEST("global context Sort_Distance"); + EXPECT_EQ(at_object, FindObject(Find_Exclude(ctx), Sort_Distance(at_object->GetX(), at_object->GetY()) )); + EXPECT_EQ(at_origin, FindObject(Find_Exclude(ctx), Sort_Distance(at_origin->GetX(), at_origin->GetY()) )); + EXPECT_EQ(at_object, FindObject(Find_Exclude(ctx), Sort_Reverse(Sort_Distance(at_origin->GetX(), at_origin->GetY())))); + + END_TEST(); + GameOver(); +} diff --git a/planet/Issues.ocf/issue973.ocs/Title.txt b/planet/Issues.ocf/issue973.ocs/Title.txt new file mode 100644 index 000000000..da4f8f9e5 --- /dev/null +++ b/planet/Issues.ocf/issue973.ocs/Title.txt @@ -0,0 +1 @@ +US:#973: Find_Distance should respect FindObject context diff --git a/planet/Material.ocg/Ashes.ocm b/planet/Material.ocg/Ashes.ocm new file mode 100644 index 000000000..0954309c2 --- /dev/null +++ b/planet/Material.ocg/Ashes.ocm @@ -0,0 +1,16 @@ +[Material] +Name=Ashes +Shape=Smooth +Density=50 +Friction=80 +DigFree=1 +BlastFree=1 +Blast2PXSRatio=10 +MaxAirSpeed=25 +MaxSlide=1 +WindDrift=60 +Corrode=75 +Soil=1 +Placement=30 +TextureOverlay=ashes +Instable=1 diff --git a/planet/Material.ocg/Brick.ocm b/planet/Material.ocg/Brick.ocm index 51c048ce8..e94ad9ca3 100644 --- a/planet/Material.ocg/Brick.ocm +++ b/planet/Material.ocg/Brick.ocm @@ -1,7 +1,7 @@ [Material] Name=Brick Shape=Smoother -Density=50 +Density=90 Friction=15 Placement=80 TextureOverlay=brick1 diff --git a/planet/Material.ocg/BrickSoft.ocm b/planet/Material.ocg/BrickSoft.ocm index 8d6d9c755..2c7601641 100644 --- a/planet/Material.ocg/BrickSoft.ocm +++ b/planet/Material.ocg/BrickSoft.ocm @@ -1,7 +1,7 @@ [Material] Name=BrickSoft Shape=Smoother -Density=50 +Density=90 Friction=15 Placement=60 TextureOverlay=brick1 diff --git a/planet/Material.ocg/Coal.ocm b/planet/Material.ocg/Coal.ocm index ff9bebf20..4abc0a816 100644 --- a/planet/Material.ocg/Coal.ocm +++ b/planet/Material.ocg/Coal.ocm @@ -1,13 +1,13 @@ [Material] Name=Coal Shape=Rough -Density=50 +Density=60 Friction=75 DigFree=1 BlastFree=1 Blast2Object=Coal Dig2Object=Coal -Dig2ObjectRatio=200 +Dig2ObjectRatio=140 Blast2ObjectRatio=200 MaxAirSpeed=100 MaxSlide=1 diff --git a/planet/Material.ocg/Earth.ocm b/planet/Material.ocg/Earth.ocm index 9a3692f7a..04f7c4181 100644 --- a/planet/Material.ocg/Earth.ocm +++ b/planet/Material.ocg/Earth.ocm @@ -1,7 +1,7 @@ [Material] Name=Earth Shape=Smooth -Density=50 +Density=60 Friction=80 DigFree=1 BlastFree=1 diff --git a/planet/Material.ocg/Firestone.ocm b/planet/Material.ocg/Firestone.ocm new file mode 100644 index 000000000..f21652f16 --- /dev/null +++ b/planet/Material.ocg/Firestone.ocm @@ -0,0 +1,16 @@ +[Material] +Name=Firestone +Shape=Smooth +Density=60 +Friction=75 +BlastFree=1 +DigFree=1 +Dig2Object=Firestone +Dig2ObjectRatio=80 +Blast2Object=Firestone +Blast2ObjectRatio=80 +MaxAirSpeed=100 +MaxSlide=1 +Placement=40 +TextureOverlay=firestone +Inflammable=1 \ No newline at end of file diff --git a/planet/Material.ocg/Gold.ocm b/planet/Material.ocg/Gold.ocm index 9bc84df06..12809f2ce 100644 --- a/planet/Material.ocg/Gold.ocm +++ b/planet/Material.ocg/Gold.ocm @@ -1,7 +1,7 @@ [Material] Name=Gold Shape=Rough -Density=50 +Density=70 Friction=100 BlastFree=1 Blast2Object=Nugget diff --git a/planet/Material.ocg/Granite.ocm b/planet/Material.ocg/Granite.ocm index 8dd61e70e..a74cf93fe 100644 --- a/planet/Material.ocg/Granite.ocm +++ b/planet/Material.ocg/Granite.ocm @@ -1,7 +1,7 @@ [Material] Name=Granite Shape=Rough -Density=50 +Density=80 Friction=100 MaxAirSpeed=100 MaxSlide=250 diff --git a/planet/Material.ocg/Ice.ocm b/planet/Material.ocg/Ice.ocm index 7ad77b78a..80b60f2e5 100644 --- a/planet/Material.ocg/Ice.ocm +++ b/planet/Material.ocg/Ice.ocm @@ -1,7 +1,7 @@ [Material] Name=Ice Shape=TopFlat -Density=50 +Density=60 Friction=15 DigFree=1 BlastFree=1 diff --git a/planet/Material.ocg/ORE.ocm b/planet/Material.ocg/ORE.ocm index 06dbb0731..9fd8305f0 100644 --- a/planet/Material.ocg/ORE.ocm +++ b/planet/Material.ocg/ORE.ocm @@ -1,7 +1,7 @@ [Material] Name=Ore Shape=Rough -Density=50 +Density=70 Friction=100 BlastFree=1 Blast2Object=Ore diff --git a/planet/Material.ocg/Rock.ocm b/planet/Material.ocg/Rock.ocm index b909e8e98..59323970e 100644 --- a/planet/Material.ocg/Rock.ocm +++ b/planet/Material.ocg/Rock.ocm @@ -1,7 +1,7 @@ [Material] Name=Rock Shape=Rough -Density=50 +Density=70 Friction=100 BlastFree=1 Blast2Object=Rock diff --git a/planet/Material.ocg/Sand.ocm b/planet/Material.ocg/Sand.ocm index 9b958e03d..5113a273d 100644 --- a/planet/Material.ocg/Sand.ocm +++ b/planet/Material.ocg/Sand.ocm @@ -1,7 +1,7 @@ [Material] Name=Sand Shape=Smooth -Density=50 +Density=60 Friction=80 DigFree=1 BlastFree=1 diff --git a/planet/Material.ocg/Snow.ocm b/planet/Material.ocg/Snow.ocm index 033da8a5f..5a0b4d060 100644 --- a/planet/Material.ocg/Snow.ocm +++ b/planet/Material.ocg/Snow.ocm @@ -26,6 +26,6 @@ Dig2Object=Snow Dig2ObjectRatio=400 [Reaction] -Type=Convert +Type=Poof TargetSpec=Incindiary -ConvertMat=Water + diff --git a/planet/Material.ocg/Sulphur.ocm b/planet/Material.ocg/Sulphur.ocm deleted file mode 100644 index 98331e9ef..000000000 --- a/planet/Material.ocg/Sulphur.ocm +++ /dev/null @@ -1,16 +0,0 @@ -[Material] -Name=Sulphur -Shape=Rough -Density=50 -Friction=75 -DigFree=1 -BlastFree=1 -Dig2Object=Sulphur -Dig2ObjectRatio=200 -MaxAirSpeed=100 -MaxSlide=1 -Corrode=90 -Blast2Object=Sulphur -Blast2ObjectRatio=80 -Placement=40 -TextureOverlay=sulphur diff --git a/planet/Material.ocg/TEXMAP.TXT b/planet/Material.ocg/TEXMAP.TXT index fc9a1a94a..b24a6a0ef 100644 --- a/planet/Material.ocg/TEXMAP.TXT +++ b/planet/Material.ocg/TEXMAP.TXT @@ -1,69 +1,45 @@ # Static Map Material/Texture Table # Index +128 for underground materials + 10=Tunnel-tunnel -11=Tunnel-tunnel 12=Tunnel-brickback + 13=BrickSoft-brick1 + 19=DuroLava-lava_red 20=Water-water1-water2-water3-water1-water3-water2 -#21=Oil-Liquid 22=Acid-acid 23=Lava-lava_red -24=DuroLava-lava_red 25=Water-water -#26=Oil-Smooth -27=Acid-acid -28=Lava-lava_red + +28=Earth-earth 29=Earth-earth_dry 30=Earth-earth_rough 31=Earth-earth_topsoil 32=Earth-earth_midsoil -#33=Ashes-Smooth3 -#34=Ashes-Rough -#35=Ashes-Ridge +33=Ashes-ashes +35=SandDry-sand_rough 36=Ore-ore -37=Ore-ore -38=Ore-ore 40=Granite-granite -41=Granite-granite 42=Granite-rock 45=Gold-gold 50=Rock-rock 51=Rock-rock_cracked -52=Rock-rock -53=Sulphur-sulphur +53=Firestone-firestone 54=Coal-coal 55=Sand-sand_rough -#56=Sand-Smooth2 -#57=Sand-Smooth3 - - - -#59=FlyAshes-Smooth - -#60=Crystal-Flare -#61=Crystal-Structure -#62=Crystal-Structure2 +56=Sand-sand_smooth 65=Ice-ice2 -66=Ice-ice2 67=Ice-ice3 -68=Ice-ice3 70=Snow-snow1 -71=Snow-snow1 -72=Snow-snow1 + 73=Brick-brick1 - -#80=FlySand-Smooth2 -#81=FlySand-Smooth3 -#82=FlySand-Smooth - - diff --git a/planet/Material.ocg/Water.ocm b/planet/Material.ocg/Water.ocm index 79f4876bf..6bc3facde 100644 --- a/planet/Material.ocg/Water.ocm +++ b/planet/Material.ocg/Water.ocm @@ -12,3 +12,4 @@ TempConvStrength=3 BelowTempConvert=-10 BelowTempConvertTo=Ice Placement=10 +TextureOverlay=water \ No newline at end of file diff --git a/planet/Material.ocg/acid.jpg b/planet/Material.ocg/acid.jpg new file mode 100644 index 000000000..f00d3aa72 Binary files /dev/null and b/planet/Material.ocg/acid.jpg differ diff --git a/planet/Material.ocg/acid.png b/planet/Material.ocg/acid.png deleted file mode 100644 index 70408caad..000000000 Binary files a/planet/Material.ocg/acid.png and /dev/null differ diff --git a/planet/Material.ocg/ashes.jpg b/planet/Material.ocg/ashes.jpg new file mode 100644 index 000000000..a3913b3c2 Binary files /dev/null and b/planet/Material.ocg/ashes.jpg differ diff --git a/planet/Material.ocg/authors.txt b/planet/Material.ocg/authors.txt index d04dade87..584408e9f 100644 --- a/planet/Material.ocg/authors.txt +++ b/planet/Material.ocg/authors.txt @@ -5,10 +5,15 @@ Author Work(s) =============================================================================== Newton - coal, earth, earth_dry, gold, ice3, ore, - rock, rocked_cracked, sand_rough, sulphur, tunnel, water + rock, rocked_cracked, sand_rough, firestone, tunnel, water MimmoO - ice2, brick Nachtfalter - acid, lava_red Dustin Senos - earth_rough Andrew McConnochie - granite Ben Cloward - snow1 -Redwolf Design GmbH - snow, lava \ No newline at end of file +Redwolf Design GmbH - snow, lava +Pyrit - sand_smooth + +The following textures are licensed under the CC Attribution-Share Alike 3.0 Unported license (http://creativecommons.org/licenses/by-sa/3.0/) + +texturepalace.com - ashes (http://www.texturepalace.com/ash-wood-premium-and-free-stock-textures/) \ No newline at end of file diff --git a/planet/Material.ocg/firestone.jpg b/planet/Material.ocg/firestone.jpg new file mode 100644 index 000000000..06a8a56e0 Binary files /dev/null and b/planet/Material.ocg/firestone.jpg differ diff --git a/planet/Material.ocg/lava_red.jpg b/planet/Material.ocg/lava_red.jpg new file mode 100644 index 000000000..64fbb9b03 Binary files /dev/null and b/planet/Material.ocg/lava_red.jpg differ diff --git a/planet/Material.ocg/lava_red.png b/planet/Material.ocg/lava_red.png deleted file mode 100644 index 1376ae359..000000000 Binary files a/planet/Material.ocg/lava_red.png and /dev/null differ diff --git a/planet/Material.ocg/sand_smooth.jpg b/planet/Material.ocg/sand_smooth.jpg new file mode 100644 index 000000000..f3912992e Binary files /dev/null and b/planet/Material.ocg/sand_smooth.jpg differ diff --git a/planet/Material.ocg/sulphur.jpg b/planet/Material.ocg/sulphur.jpg deleted file mode 100644 index 4566c23d2..000000000 Binary files a/planet/Material.ocg/sulphur.jpg and /dev/null differ diff --git a/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/DefCore.txt b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/DefCore.txt new file mode 100644 index 000000000..98eaf5330 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_AcidDrilling +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/Graphics.png b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/Graphics.png new file mode 100644 index 000000000..4dd217a5a Binary files /dev/null and b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/Script.c b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/Script.c new file mode 100644 index 000000000..8a8facca0 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/Script.c @@ -0,0 +1,60 @@ +/*-- + Acid drilling + Author: Sven2 + + Player must fill a small basin with acid. +--*/ + + +#include Library_Goal + +local basin_x, basin_y; + +public func SetBasinPosition(int x, int y) +{ + SetPosition(0,0); + basin_x = x; basin_y = y; + return true; +} + + +/*-- Goal interface --*/ + +// The goal is fulfilled if a statue has been assigned and it's repaired. +public func IsFulfilled() +{ + return GetMaterial(basin_x, basin_y) == Material("Acid"); +} + +// Shows or hides a message window with information. +public func Activate(int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + var message; + if (IsFulfilled()) + { + message = "@$MsgGoalFulfilled$"; + } + else + { + message = "@$MsgGoalUnfulfilled$"; + } + CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + +//public func GetShortDescription(int plr) { return ""; } + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/StringTblDE.txt b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/StringTblDE.txt new file mode 100644 index 000000000..a3e33f758 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +Name=Säurebohrung + +#Goal window +MsgGoalFulfilled=Geschafft! Das Säurebecken ist gefüllt. +MsgGoalUnfulfilled=Fülle das Becken mit Säure! diff --git a/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/StringTblUS.txt b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/StringTblUS.txt new file mode 100644 index 000000000..3bb721b9e --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/AcidDrilling.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +Name=Acid drilling + +#Goal window +MsgGoalFulfilled=Done! The basin is filled with acid. +MsgGoalUnfulfilled=Fill the basin with acid! diff --git a/planet/Missions.ocf/AcidDrilling.ocs/DescDE.rtf b/planet/Missions.ocf/AcidDrilling.ocs/DescDE.rtf new file mode 100644 index 000000000..65ae22f2b Binary files /dev/null and b/planet/Missions.ocf/AcidDrilling.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/AcidDrilling.ocs/DescUS.rtf b/planet/Missions.ocf/AcidDrilling.ocs/DescUS.rtf new file mode 100644 index 000000000..25a4cbe6b Binary files /dev/null and b/planet/Missions.ocf/AcidDrilling.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/AcidDrilling.ocs/Map.bmp b/planet/Missions.ocf/AcidDrilling.ocs/Map.bmp new file mode 100644 index 000000000..7b883f290 Binary files /dev/null and b/planet/Missions.ocf/AcidDrilling.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/AcidDrilling.ocs/Objects.c b/planet/Missions.ocf/AcidDrilling.ocs/Objects.c new file mode 100644 index 000000000..9dd67d99c --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/Objects.c @@ -0,0 +1,274 @@ +/* Automatically created objects file */ + +func InitializeObjects() +{ + CreateObject(Tree_Coniferous, 1864, 236); + CreateObject(Tree_Coniferous, 1904, 268); + CreateObject(Tree_Coniferous, 1976, 260); + CreateObject(Tree_Coniferous, 1939, 267); + CreateObject(Tree_Coniferous, 2020, 244); + var Tree_Coniferous0021 = CreateObject(Tree_Coniferous, 1758, 149); + Tree_Coniferous0021->SetR(65); + Tree_Coniferous0021->SetPosition(1758, 130); + CreateObject(Tree_Coniferous, 1997, 255); + CreateObject(Tree_Coniferous, 1959, 271); + + CreateObject(Trunk, 1924, 272); + + CreateObject(Rule_TeamAccount, 50, 40); + + CreateObject(Rule_BuyAtFlagpole, 50, 40); + + CreateObject(Goal_AcidDrilling, 0, -10); + + CreateObject(Rule_BuyAtFlagpole, 50, 40); + + CreateObject(Goal_AcidDrilling, 0, -10); + + CreateObject(Rule_BuyAtFlagpole, 50, 40); + + CreateObject(Goal_AcidDrilling, 0, -10); + + var Chest0040 = CreateObject(Chest, 71, 222); + + var Catapult0041 = CreateObject(Catapult, 1063, 225); + Catapult0041->SetCon(64); + Catapult0041->SetRDir(-7); + Catapult0041->SetClrModulation(0xff808080); + + var Lorry0042 = CreateObject(Lorry, 1169, 666); + Lorry0042->SetR(-5); + Lorry0042->SetRDir(6); + Lorry0042->SetPosition(1169, 658); + + var Ore0044 = CreateObject(Ore, 1845, 299); + Ore0044->SetR(151); + Ore0044->SetPosition(1845, 297); + var Ore0045 = CreateObject(Ore, 1544, 206); + Ore0045->SetR(-129); + Ore0045->SetPosition(1544, 204); + var Ore0046 = CreateObject(Ore, 1568, 176); + Ore0046->SetR(-48); + Ore0046->SetPosition(1568, 175); + var Ore0047 = CreateObject(Ore, 1667, 231); + Ore0047->SetR(-166); + Ore0047->SetPosition(1667, 230); + var Ore0048 = CreateObject(Ore, 2197, 403); + Ore0048->SetR(145); + Ore0048->SetPosition(2197, 401); + var Ore0049 = CreateObject(Ore, 730, 345); + Ore0049->SetR(-99); + Ore0049->SetPosition(730, 343); + var Ore0050 = CreateObject(Ore, 1326, 174); + Ore0050->SetR(86); + Ore0050->SetPosition(1326, 172); + var Ore0051 = CreateObject(Ore, 1321, 211); + Ore0051->SetR(121); + Ore0051->SetPosition(1321, 209); + var Ore0052 = CreateObject(Ore, 810, 98); + Ore0052->SetR(-168); + Ore0052->SetPosition(810, 97); + var Ore0053 = CreateObject(Ore, 250, 166); + Ore0053->SetR(-171); + Ore0053->SetPosition(250, 165); + var Ore0054 = CreateObject(Ore, 271, 89); + Ore0054->SetR(122); + Ore0054->SetPosition(271, 87); + var Ore0055 = CreateObject(Ore, 539, 571); + Ore0055->SetR(109); + Ore0055->SetPosition(539, 569); + var Ore0056 = CreateObject(Ore, 392, 613); + Ore0056->SetR(-144); + Ore0056->SetPosition(392, 611); + var Ore0057 = CreateObject(Ore, 462, 523); + Ore0057->SetR(67); + Ore0057->SetPosition(462, 522); + + var Loam0058 = CreateObject(Loam, 1144, 170); + Loam0058->SetR(-122); + Loam0058->SetPosition(1144, 168); + var Loam0059 = CreateObject(Loam, 1553, 360); + Loam0059->SetR(-95); + Loam0059->SetPosition(1553, 360); + var Loam0060 = CreateObject(Loam, 1353, 334); + Loam0060->SetR(-84); + Loam0060->SetPosition(1353, 334); + var Loam0061 = CreateObject(Loam, 915, 517); + Loam0061->SetR(-154); + Loam0061->SetPosition(915, 514); + var Loam0062 = CreateObject(Loam, 867, 291); + Loam0062->SetR(-79); + Loam0062->SetPosition(867, 290); + var Loam0063 = CreateObject(Loam, 891, 138); + Loam0063->SetR(59); + Loam0063->SetPosition(891, 136); + var Loam0064 = CreateObject(Loam, 880, 107); + Loam0064->SetR(-169); + Loam0064->SetPosition(880, 104); + var Loam0065 = CreateObject(Loam, 636, 226); + Loam0065->SetR(13); + Loam0065->SetPosition(636, 223); + var Loam0066 = CreateObject(Loam, 555, 255); + Loam0066->SetR(-171); + Loam0066->SetPosition(555, 252); + var Loam0067 = CreateObject(Loam, 1880, 270); + Loam0067->SetR(48); + Loam0067->SetPosition(1880, 268); + var Loam0068 = CreateObject(Loam, 2029, 265); + Loam0068->SetR(-6); + Loam0068->SetPosition(2029, 262); + var Loam0069 = CreateObject(Loam, 1706, 160); + Loam0069->SetR(-108); + Loam0069->SetPosition(1706, 159); + var Loam0070 = CreateObject(Loam, 87, 262); + Loam0070->SetR(31); + Loam0070->SetPosition(87, 259); + var Loam0071 = CreateObject(Loam, 478, 305); + Loam0071->SetR(-173); + Loam0071->SetPosition(478, 302); + var Loam0072 = CreateObject(Loam, 613, 395); + Loam0072->SetR(114); + Loam0072->SetPosition(613, 394); + var Loam0073 = CreateObject(Loam, 736, 377); + Loam0073->SetR(142); + Loam0073->SetPosition(736, 375); + var Loam0074 = CreateObject(Loam, 675, 384); + Loam0074->SetR(125); + Loam0074->SetPosition(675, 382); + var Loam0075 = CreateObject(Loam, 1711, 520); + Loam0075->SetR(-52); + Loam0075->SetPosition(1711, 518); + var Loam0076 = CreateObject(Loam, 1671, 480); + Loam0076->SetR(131); + Loam0076->SetPosition(1671, 478); + var Loam0077 = CreateObject(Loam, 1987, 659); + Loam0077->SetR(137); + Loam0077->SetPosition(1987, 657); + var Loam0078 = CreateObject(Loam, 2243, 681); + Loam0078->SetR(103); + Loam0078->SetPosition(2243, 680); + var Loam0079 = CreateObject(Loam, 1535, 676); + Loam0079->SetR(-50); + Loam0079->SetPosition(1535, 674); + var Loam0080 = CreateObject(Loam, 2008, 456); + Loam0080->SetR(-152); + Loam0080->SetPosition(2008, 453); + var Loam0081 = CreateObject(Loam, 2030, 446); + Loam0081->SetR(-136); + Loam0081->SetPosition(2030, 444); + Lorry0042->CreateContents(Loam); + Lorry0042->CreateContents(Loam); + + var Nugget0084 = CreateObject(Nugget, 1421, 557); + Nugget0084->SetR(16); + Nugget0084->SetPosition(1421, 556); + var Nugget0085 = CreateObject(Nugget, 1391, 516); + Nugget0085->SetR(-23); + Nugget0085->SetPosition(1391, 515); + var Nugget0086 = CreateObject(Nugget, 1339, 563); + Nugget0086->SetR(-179); + Nugget0086->SetPosition(1339, 562); + var Nugget0087 = CreateObject(Nugget, 727, 566); + Nugget0087->SetR(-159); + Nugget0087->SetPosition(727, 564); + var Nugget0088 = CreateObject(Nugget, 111, 405); + Nugget0088->SetR(4); + Nugget0088->SetPosition(111, 404); + var Nugget0089 = CreateObject(Nugget, 70, 349); + Nugget0089->SetR(106); + Nugget0089->SetPosition(70, 347); + var Nugget0090 = CreateObject(Nugget, 72, 293); + Nugget0090->SetR(-117); + Nugget0090->SetPosition(72, 291); + + var Metal0091 = CreateObject(Metal, 1551, 254); + Metal0091->SetR(-35); + Metal0091->SetPosition(1551, 251); + var Metal0092 = CreateObject(Metal, 2172, 409); + Metal0092->SetR(70); + Metal0092->SetPosition(2172, 404); + var Metal0093 = CreateObject(Metal, 1827, 279); + Metal0093->SetR(-3); + Metal0093->SetPosition(1827, 279); + var Metal0094 = CreateObject(Metal, 175, 680); + Metal0094->SetR(148); + Metal0094->SetPosition(175, 677); + var Metal0095 = CreateObject(Metal, 205, 701); + Metal0095->SetR(-50); + Metal0095->SetPosition(205, 697); + var Metal0096 = CreateObject(Metal, 571, 583); + Metal0096->SetR(166); + Metal0096->SetPosition(571, 582); + Chest0040->CreateContents(Metal); + Chest0040->CreateContents(Metal); + Chest0040->CreateContents(Metal); + Chest0040->CreateContents(Metal); + + var Wood0101 = CreateObject(Wood, 79, 683); + Wood0101->SetR(44); + Wood0101->SetPosition(79, 680); + var Wood0102 = CreateObject(Wood, 148, 682); + Wood0102->SetR(-23); + Wood0102->SetPosition(148, 680); + var Wood0103 = CreateObject(Wood, 60, 683); + Wood0103->SetR(36); + Wood0103->SetPosition(60, 680); + var Wood0104 = CreateObject(Wood, 68, 682); + Wood0104->SetR(-37); + Wood0104->SetPosition(68, 680); + var Wood0105 = CreateObject(Wood, 2030, 690); + Wood0105->SetR(-84); + Wood0105->SetPosition(2030, 686); + var Wood0106 = CreateObject(Wood, 2035, 465); + Wood0106->SetR(95); + Wood0106->SetPosition(2035, 460); + var Wood0107 = CreateObject(Wood, 1734, 467); + Wood0107->SetR(-163); + Wood0107->SetPosition(1734, 466); + var Wood0108 = CreateObject(Wood, 1933, 436); + Wood0108->SetR(25); + Wood0108->SetPosition(1933, 434); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + Chest0040->CreateContents(Wood); + + Chest0040->CreateContents(GoldBar); + Chest0040->CreateContents(GoldBar); + Lorry0042->CreateContents(GoldBar); + + CreateObject(Mushroom, 1677, 232); + + Chest0040->CreateContents(WallKit); + Chest0040->CreateContents(WallKit); + Chest0040->CreateContents(WallKit); + + Lorry0042->CreateContents(Bread); + Lorry0042->CreateContents(Bread); + Lorry0042->CreateContents(Bread); + Lorry0042->CreateContents(Bread); + Lorry0042->CreateContents(Bread); + Chest0040->CreateContents(Bread); + Chest0040->CreateContents(Bread); + + CreateObject(Firestone, 2082, 328); + CreateObject(Firestone, 2171, 289); + CreateObject(Firestone, 1672, 119); + CreateObject(Firestone, 1856, 272); + CreateObject(Firestone, 1332, 220); + CreateObject(Firestone, 1264, 131); + CreateObject(Firestone, 1157, 366); + CreateObject(Firestone, 1134, 446); + CreateObject(Firestone, 597, 144); + CreateObject(Firestone, 833, 94); + CreateObject(Firestone, 451, 505); + CreateObject(Firestone, 557, 567); + CreateObject(Firestone, 153, 482); + CreateObject(Firestone, 251, 511); + CreateObject(Firestone, 263, 149); + return true; +} diff --git a/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/DefCore.txt b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/DefCore.txt new file mode 100644 index 000000000..ab20ce74d --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/DefCore.txt @@ -0,0 +1,17 @@ +[DefCore] +id=PowerCrystals +Version=5,2,0,1 +Category=C4D_Structure +Width=32 +Height=32 +Offset=-16,-16 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=100 +Value=50 +Mass=50 +Components=Metal=2 +Picture=0,0,32,32 +Exclusive=1 +Construction=1 diff --git a/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/Graphics.4.png b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/Graphics.4.png new file mode 100644 index 000000000..7cea16ef9 Binary files /dev/null and b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/Graphics.4.png differ diff --git a/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/Script.c b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/Script.c new file mode 100644 index 000000000..93b429fbb --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/Script.c @@ -0,0 +1,15 @@ +/*-- Power crystal --*/ + +#include Library_Flag + +protected func Initialize() +{ + SetCategory(C4D_StaticBack); + SetR(Random(360)); + SetObjectBlitMode(GFX_BLIT_Additive); + SetClrModulation(RGB(127+Random(3)*64,127+Random(3)*64,127+Random(3)*64)); + return _inherited(...); +} + +local Name = "$Name$"; +local Description = "$Description$"; diff --git a/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/StringTblDE.txt b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/StringTblDE.txt new file mode 100644 index 000000000..88352b636 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Energiekristall +Description=Markiert neutrales Gebiet, das nicht für Energietransfer genutzt werden kann. diff --git a/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/StringTblUS.txt b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/StringTblUS.txt new file mode 100644 index 000000000..a79cc5ba9 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/PowerCrystals.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Power crystal +Description=Marks a neutral area that cannot be used to transfer energy. diff --git a/planet/Missions.ocf/AcidDrilling.ocs/Scenario.txt b/planet/Missions.ocf/AcidDrilling.ocs/Scenario.txt new file mode 100644 index 000000000..1e91316c2 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/Scenario.txt @@ -0,0 +1,52 @@ +[Head] +Title=AcidDrilling +Icon=30 +Version=5,2,0,1 +Difficulty=100 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_AcidDrilling=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1;GrapleBow=1;InventorsLab=1;Lorry=1;RopeLadder=1 +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50 +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50 + +[Player2] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1;GrapleBow=1;InventorsLab=1;Lorry=1;RopeLadder=1 +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50 +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50 + +[Player3] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1;GrapleBow=1;InventorsLab=1;Lorry=1;RopeLadder=1 +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50 +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50 + +[Player4] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1;GrapleBow=1;InventorsLab=1;Lorry=1;RopeLadder=1 +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50 +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50 + +[Landscape] +Sky=Clouds1 +SkyScrollMode=1 +TopOpen=0 +BottomOpen=0 +MapWidth=300 +MapHeight=100 +MapZoom=8 + +[Weather] +Climate=00,0,0,00 +StartSeason=0,0,0,00 +YearSpeed=0,0,0,000 +Wind=100,0,100,100 + diff --git a/planet/Missions.ocf/AcidDrilling.ocs/Script.c b/planet/Missions.ocf/AcidDrilling.ocs/Script.c new file mode 100644 index 000000000..952285537 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/Script.c @@ -0,0 +1,83 @@ +/* Acid drilling */ + +static g_was_player_init, g_crystal_player; + +func Initialize() +{ + g_crystal_player = NO_OWNER; + // Goal + var goal = FindObject(Find_ID(Goal_AcidDrilling)); + if (!goal) goal = CreateObject(Goal_AcidDrilling); + goal->SetBasinPosition(2338, 250); + // Rules + if (!ObjectCount(Find_ID(Rule_TeamAccount))) CreateObject(Rule_TeamAccount); + if (!ObjectCount(Find_ID(Rule_BuyAtFlagpole))) CreateObject(Rule_BuyAtFlagpole); + return true; +} + +func InitializePlayer(int plr) +{ + var i; + // Script player owns power crystals + if (GetPlayerType(plr) == C4PT_Script) + { + g_crystal_player = plr; + for (i=0; iRemoveObject(); + InitPowerCrystals(plr); + return true; + } + if (g_crystal_player != NO_OWNER) SetHostility(g_crystal_player, plr, true, true, true); + // First player init base + if (!g_was_player_init) + { + CreateScriptPlayer("POMMES", 0, 0, CSPF_FixedAttributes | CSPF_NoEliminationCheck | CSPF_Invisible); + InitBase(plr); + g_was_player_init = true; + } + // Position and materials + var crew; + for (i=0; crew=GetCrew(plr,i); ++i) + { + crew->SetPosition(2100+Random(40), 233-10); + crew->CreateContents(Shovel); + } + return true; +} + +private func InitPowerCrystals(int owner) +{ + var positions = [[1013, 59], [1030, 320], [1050, 500], [1000, 660]]; + for (var pos in positions) CreateObject(PowerCrystals, pos[0], pos[1]+16, owner); + return true; +} + +private func InitBase(int owner) +{ + // Create standard base owned by player + var y=232; + var lorry = CreateObject(Lorry, 2040,y-2, owner); + if (lorry) + { + lorry->CreateContents(Loam, 6); + lorry->CreateContents(Wood, 15); + lorry->CreateContents(Metal, 4); + lorry->CreateContents(WallKit, 2); + lorry->CreateContents(Axe, 1); + lorry->CreateContents(Pickaxe, 1); + lorry->CreateContents(Hammer, 1); + lorry->CreateContents(Dynamite, 2); + lorry->CreateContents(Pipe, 2); + } + CreateObject(Pump, 2062,y, owner); + CreateObject(Flagpole, 2085,y, owner); + CreateObject(WindGenerator, 2110, y, owner); + CreateObject(ToolsWorkshop, 2150, y, owner); + CreateObject(WindGenerator, 2200, y, owner); + CreateObject(WoodenCabin, 2250, y, owner); + + CreateObject(Foundry, 1793, y, owner); + CreateObject(Flagpole, 1819, y, owner); + CreateObject(Sawmill, 1845, y, owner); + return true; +} diff --git a/planet/Missions.ocf/AcidDrilling.ocs/StringTblDE.txt b/planet/Missions.ocf/AcidDrilling.ocs/StringTblDE.txt new file mode 100644 index 000000000..3e87a1937 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/StringTblDE.txt @@ -0,0 +1,2 @@ +NamePlrTeam=Spieler +NameCrysTeam=Kristalle diff --git a/planet/Missions.ocf/AcidDrilling.ocs/StringTblUS.txt b/planet/Missions.ocf/AcidDrilling.ocs/StringTblUS.txt new file mode 100644 index 000000000..6ff190aee --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/StringTblUS.txt @@ -0,0 +1,2 @@ +NamePlrTeam=Players +NameCrysTeam=Crystals diff --git a/planet/Missions.ocf/AcidDrilling.ocs/System.ocg/PipeLine.c b/planet/Missions.ocf/AcidDrilling.ocs/System.ocg/PipeLine.c new file mode 100644 index 000000000..b715edea3 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/System.ocg/PipeLine.c @@ -0,0 +1,5 @@ +// Max distance for pipe line + +#appendto PipeLine + +local LineMaxDistance = 500; diff --git a/planet/Missions.ocf/AcidDrilling.ocs/Title.txt b/planet/Missions.ocf/AcidDrilling.ocs/Title.txt new file mode 100644 index 000000000..018d4e8a2 --- /dev/null +++ b/planet/Missions.ocf/AcidDrilling.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Säurebohrung +US:Acid drilling \ No newline at end of file diff --git a/planet/Missions.ocf/Crash.ocs/DescDE.rtf b/planet/Missions.ocf/Crash.ocs/DescDE.rtf new file mode 100644 index 000000000..42ec493d0 Binary files /dev/null and b/planet/Missions.ocf/Crash.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/Crash.ocs/DescUS.rtf b/planet/Missions.ocf/Crash.ocs/DescUS.rtf new file mode 100644 index 000000000..f24211dcc Binary files /dev/null and b/planet/Missions.ocf/Crash.ocs/DescUS.rtf differ diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/DefCore.txt b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/DefCore.txt rename to planet/Missions.ocf/Crash.ocs/Dialogue.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/Graphics.png b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Graphics.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/Graphics.png rename to planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Graphics.png diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/Portrait1.png b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Portrait1.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/Portrait1.png rename to planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Portrait1.png diff --git a/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Script.c b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Script.c new file mode 100644 index 000000000..c33da3ff9 --- /dev/null +++ b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/Script.c @@ -0,0 +1,220 @@ +/** + Dialogue + + Attach to a non player charachter to provide a message interface. +*/ + + +local dlg_target; +local dlg_name; +local dlg_info; +local dlg_progress; +local dlg_status; + +static const DLG_Status_Active = 0; +static const DLG_Status_Stop = 1; +static const DLG_Status_Remove = 2; + + +/*-- Dialogue creation --*/ + +// Sets a new dialogue for a npc. +global func SetDialogue(string name) +{ + if (!this) + return; + var dialogue = CreateObject(Dialogue); + dialogue->InitDialogue(name, this); + + dialogue->SetObjectLayer(nil); + + return dialogue; +} + +// Removes the existing dialogue of an object. +global func RemoveDialogue() +{ + if (!this) + return; + + var dialogue = FindObject(Find_ID(Dialogue), Find_ActionTarget(this)); + if (dialogue) + dialogue->RemoveObject(); + + return; +} + +/*-- Dialogue properties --*/ + +protected func Initialize() +{ + // Dialogue progress to one. + dlg_progress = 1; + + dlg_status = DLG_Status_Active; + + return; +} + +public func InitDialogue(string name, object target) +{ + dlg_target = target; + dlg_name = name; + + // Attach dialogue object to target. + SetAction("Dialogue", target); + + // Update dialogue to target. + UpdateDialogue(); + + return; +} + +private func UpdateDialogue() +{ + // Adapt size to target and its direction. + var wdt = dlg_target->GetID()->GetDefWidth(); + var hgt = dlg_target->GetID()->GetDefHeight(); + var dir = dlg_target->GetDir(); + SetShape(-wdt/2 + 2*(dir-1)*wdt, -hgt/2, 3*wdt, hgt); + // Transfer target name. + //SetName(Format("$MsgSpeak$", dlg_target->GetName())); + return; +} + +public func SetDialogueInfo() +{ + + + + return; +} + +public func SetDialogueProgress(int progress) +{ + dlg_progress = Max(1, progress); + return; +} + +public func SetDialogueStatus(int status) +{ + dlg_status = status; + return; +} + +/*-- Interaction --*/ + +// Players can talk to NPC via the interaction bar. +public func IsInteractable() { return true; } + +// Adapt appearance in the interaction bar. +public func GetInteractionMetaInfo(object clonk) +{ + if (InDialogue(clonk)) + return { Description = Format("$MsgSpeak$", dlg_target->GetName()) , IconName = nil, IconID = Clonk, Selected = true }; + + return { Description = Format("$MsgSpeak$", dlg_target->GetName()) , IconName = nil, IconID = Clonk, Selected = false }; +} + +// Called on player interaction. +public func Interact(object clonk) +{ + // Currently in a dialogue: abort that dialogue. + if (InDialogue(clonk)) + clonk->CloseMenu(); + + // No conversation context: abort. + if (!dlg_name) + return true; + + // Stop dialogue? + if (dlg_status == DLG_Status_Stop) + { + clonk->CloseMenu(); + dlg_status = DLG_Status_Active; + return true; + } + // Remove dialogue? + if (dlg_status == DLG_Status_Remove) + { + clonk->CloseMenu(); + RemoveObject(); + return true; + } + + // Start conversation context. + // Update dialogue progress first. + var progress = dlg_progress; + dlg_progress++; + // Then call relevant functions. + Call(Format("Dlg_%s_%d", dlg_name, progress), clonk); + + + + return true; +} + +private func InDialogue(object clonk) +{ + return clonk->GetMenu() == Dialogue; +} + +public func MessageBoxAll(string message, object talker) +{ + for(var i = 0; i < GetPlayerCount(); ++i) + MessageBox(message, GetCursor(GetPlayerByIndex(i)), talker); +} + +private func MessageBox(string message, object clonk, object talker) +{ + // Use current NPC as talker if unspecified. + if (!talker) + talker = dlg_target; + + // Use a menu for this dialogue. + clonk->CreateMenu(Dialogue, this, C4MN_Extra_None, nil, nil, C4MN_Style_Dialog, false, Dialogue); + + // Add NPC portrait. + //var portrait = Format("%i", talker->GetID()); //, Dialogue, talker->GetColor(), "1"); + clonk->AddMenuItem("", "MenuOk", Dialogue, nil, clonk, nil, C4MN_Add_ImgObject, talker); //TextSpec); + + // Add NPC message. + var msg = Format("%s: %s", talker->GetColor(), talker->GetName(), message); + clonk->AddMenuItem(msg, "", nil, nil, nil, nil, C4MN_Add_ForceNoDesc); + + // Add answers. + //for (var i = 0; i < GetLength(message.Answers); i++) + //{ + // var ans = message.Answers[i][0]; + // var call_back = message.Answers[i][1]; + // target->AddMenuItem(ans, call_back, nil, nil, target, nil, C4MN_Add_ForceNoDesc); + //} + + // Set menu decoration. + clonk->SetMenuDecoration(GUI_MenuDeco); + + // Set text progress to NPC name. + var name = dlg_target->GetName(); + var n_length; + while (GetChar(name, n_length)) + n_length++; + clonk->SetMenuTextProgress(n_length + 1); + + return; +} + +public func MenuOk(unused, object clonk) +{ + Interact(clonk); +} + +local ActMap = { + Dialogue = { + Prototype = Action, + Name = "Dialogue", + Procedure = DFA_ATTACH, + Delay = 0, + NextAction = "Dialogue", + } +}; +local Name = "$Name$"; diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/StringTblDE.txt b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/StringTblDE.txt rename to planet/Missions.ocf/Crash.ocs/Dialogue.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/StringTblUS.txt b/planet/Missions.ocf/Crash.ocs/Dialogue.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/StringTblUS.txt rename to planet/Missions.ocf/Crash.ocs/Dialogue.ocd/StringTblUS.txt diff --git a/planet/Missions.ocf/Crash.ocs/Map.bmp b/planet/Missions.ocf/Crash.ocs/Map.bmp new file mode 100644 index 000000000..7dd2b38a3 Binary files /dev/null and b/planet/Missions.ocf/Crash.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/Crash.ocs/Objects.c b/planet/Missions.ocf/Crash.ocs/Objects.c new file mode 100644 index 000000000..16c35261e --- /dev/null +++ b/planet/Missions.ocf/Crash.ocs/Objects.c @@ -0,0 +1,202 @@ +/* Automatically created objects file */ + +func InitializeObjects() +{ + CreateObject(Grass, 555, 551); + CreateObject(Grass, 533, 550); + CreateObject(Grass, 1306, 706); + + CreateObject(Tree_Coniferous, 380, 877); + CreateObject(Tree_Coniferous, 210, 875); + CreateObject(Tree_Coniferous, 207, 871); + CreateObject(Tree_Coniferous, 252, 872); + CreateObject(Tree_Coniferous, 367, 874); + CreateObject(Tree_Coniferous, 309, 871); + CreateObject(Tree_Coniferous, 179, 874); + CreateObject(Tree_Coniferous, 271, 874); + CreateObject(Tree_Coniferous, 423, 547); + CreateObject(Tree_Coniferous, 496, 556); + CreateObject(Tree_Coniferous, 322, 554); + CreateObject(Tree_Coniferous, 1339, 367); + CreateObject(Tree_Coniferous, 1357, 360); + CreateObject(Tree_Coniferous, 1393, 314); + CreateObject(Tree_Coniferous, 1304, 387); + + CreateObject(Fern, 1331, 702); + CreateObject(Fern, 1468, 663); + CreateObject(Fern, 1583, 696); + + var Lichen0076 = CreateObject(Lichen, 1377, 696); + Lichen0076->SetAction("Grow"); + Lichen0076->SetPhase(3); + var Lichen0079 = CreateObject(Lichen, 1514, 695); + Lichen0079->SetAction("Grow"); + Lichen0079->SetPhase(3); + + var Rank0082 = CreateObject(Rank, 1352, 438); + Rank0082->SetR(28); + Rank0082->SetPosition(1352, 435); + var Rank0083 = CreateObject(Rank, 1428, 446); + Rank0083->SetR(6); + Rank0083->SetPosition(1428, 443); + var Rank0084 = CreateObject(Rank, 1431, 458); + Rank0084->SetR(-28); + Rank0084->SetPosition(1431, 455); + var Rank0085 = CreateObject(Rank, 552, 589); + Rank0085->SetR(4); + Rank0085->SetPosition(552, 586); + var Rank0086 = CreateObject(Rank, 534, 601); + Rank0086->SetR(-17); + Rank0086->SetPosition(534, 598); + var Rank0087 = CreateObject(Rank, 322, 615); + Rank0087->SetR(23); + Rank0087->SetPosition(322, 612); + var Rank0088 = CreateObject(Rank, 404, 762); + Rank0088->SetR(8); + Rank0088->SetPosition(404, 759); + + CreateObject(Trunk, 1447, 682); + + CreateObject(SproutBerryBush, 1286, 734); + + CreateObject(Tree_Coniferous, 1297, 388); + + CreateObject(SproutBerryBush, 565, 861); + + CreateObject(Wheat, 919, 553); + CreateObject(Wheat, 1296, 614); + + var Tree_Coniferous0114 = CreateObject(Tree_Coniferous, 231, 878); + Tree_Coniferous0114->SetCon(47); + + var Chest0118 = CreateObject(Chest, 264, 1287); + + var WoodenCabin0119 = CreateObject(WoodenCabin, 62, 870); + + CreateObject(Idol, 102, 871); + + var Lorry0121 = CreateObject(Lorry, 76, 1299); + Lorry0121->SetR(-14); + Lorry0121->SetPosition(76, 1290); + + var Catapult0123 = CreateObject(Catapult, 445, 547); + Catapult0123->SetCon(80); + Catapult0123->SetRDir(1); + Catapult0123->SetClrModulation(0xff686868); + + CreateObject(Rock, 279, 965); + CreateObject(Rock, 469, 1214); + CreateObject(Rock, 225, 1335); + CreateObject(Rock, 69, 1125); + CreateObject(Rock, 45, 915); + CreateObject(Rock, 547, 1015); + CreateObject(Rock, 1117, 1178); + CreateObject(Rock, 1176, 1308); + CreateObject(Rock, 1414, 1075); + CreateObject(Rock, 1485, 893); + + CreateObject(Coal, 218, 1010); + CreateObject(Coal, 94, 1046); + CreateObject(Coal, 98, 1010); + + CreateObject(Ore, 269, 1105); + + CreateObject(Nugget, 40, 1210); + CreateObject(Nugget, 18, 1216); + CreateObject(Nugget, 49, 1267); + CreateObject(Nugget, 439, 1259); + CreateObject(Nugget, 485, 1154); + CreateObject(Nugget, 1580, 1139); + CreateObject(Nugget, 1470, 1080); + CreateObject(Nugget, 33, 1311); + CreateObject(Nugget, 134, 1347); + CreateObject(Nugget, 253, 1317); + CreateObject(Nugget, 369, 1283); + CreateObject(Nugget, 373, 1243); + + CreateObject(Metal, 124, 1302); + + CreateObject(Loam, 520, 950); + CreateObject(Loam, 403, 1010); + CreateObject(Loam, 339, 1252); + CreateObject(Loam, 178, 1312); + CreateObject(Loam, 727, 1274); + CreateObject(Loam, 884, 1333); + CreateObject(Loam, 1195, 1300); + CreateObject(Loam, 1568, 1109); + CreateObject(Loam, 1565, 880); + CreateObject(Loam, 1360, 784); + CreateObject(Loam, 1519, 724); + CreateObject(Loam, 1348, 721); + CreateObject(Loam, 1379, 352); + + var Wood0164 = CreateObject(Wood, 518, 1081); + Wood0164->SetR(35); + Wood0164->SetPosition(518, 1078); + CreateObject(Wood, 1302, 904); + var Wood0166 = CreateObject(Wood, 1335, 904); + Wood0166->SetClrModulation(0xff302020); + + CreateObject(Moss, 1357, 695); + CreateObject(Moss, 1269, 905); + CreateObject(Moss, 336, 558); + CreateObject(Moss, 479, 554); + CreateObject(Moss, 523, 847); + + CreateObject(Crate, 155, 1302); + CreateObject(Crate, 139, 1302); + + CreateObject(Bread, 171, 1301); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + Chest0118->CreateContents(Bread); + + WoodenCabin0119->CreateContents(Seeds); + WoodenCabin0119->CreateContents(Seeds); + + WoodenCabin0119->CreateContents(Sproutberry); + + var Seaweed0191 = CreateObject(Seaweed, 1343, 991); + Seaweed0191->SetYDir(14); + Seaweed0191->SetPhase(73); + var Seaweed0194 = CreateObject(Seaweed, 1430, 918); + Seaweed0194->SetYDir(14); + Seaweed0194->SetPhase(14); + var Seaweed0197 = CreateObject(Seaweed, 1527, 918); + Seaweed0197->SetYDir(14); + Seaweed0197->SetPhase(32); + + CreateObject(Firestone, 49, 1316); + CreateObject(Firestone, 36, 1282); + Lorry0121->CreateContents(Firestone); + CreateObject(Firestone, 452, 920); + CreateObject(Firestone, 50, 949); + CreateObject(Firestone, 374, 894); + CreateObject(Firestone, 301, 927); + CreateObject(Firestone, 38, 1072); + CreateObject(Firestone, 216, 1085); + CreateObject(Firestone, 502, 985); + CreateObject(Firestone, 229, 925); + CreateObject(Firestone, 413, 1133); + CreateObject(Firestone, 757, 1233); + CreateObject(Firestone, 374, 1296); + CreateObject(Firestone, 345, 1073); + CreateObject(Firestone, 586, 1250); + CreateObject(Firestone, 154, 1350); + CreateObject(Firestone, 381, 1079); + CreateObject(Firestone, 714, 1253); + CreateObject(Firestone, 1267, 956); + CreateObject(Firestone, 1346, 820); + CreateObject(Firestone, 1393, 916); + CreateObject(Firestone, 1464, 720); + CreateObject(Firestone, 1308, 1168); + CreateObject(Firestone, 80, 1102); + CreateObject(Firestone, 351, 1230); + CreateObject(Firestone, 112, 1128); + return true; +} diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/DefCore.txt b/planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/DefCore.txt rename to planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/Graphics.png b/planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/Graphics.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/Graphics.png rename to planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/Graphics.png diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/Script.c b/planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/Script.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/Script.c rename to planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/Script.c diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/StringTblDE.txt b/planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/StringTblDE.txt rename to planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/StringTblUS.txt b/planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/PlaneGoal.ocd/StringTblUS.txt rename to planet/Missions.ocf/Crash.ocs/PlaneGoal.ocd/StringTblUS.txt diff --git a/planet/Missions.ocf/Crash.ocs/Scenario.txt b/planet/Missions.ocf/Crash.ocs/Scenario.txt new file mode 100644 index 000000000..e4a994d14 --- /dev/null +++ b/planet/Missions.ocf/Crash.ocs/Scenario.txt @@ -0,0 +1,41 @@ +[Head] +Icon=37 +Title=Crash +Version=5,2,90,20 +Difficulty=30 +NoInitialize=true + +[Game] +Rules=Rule_TeamAccount=1 + +[Player1] +Wealth=0 +Crew=Clonk=1 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1; + +[Player2] +Wealth=0 +Crew=Clonk=1 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1; + +[Player3] +Wealth=0 +Crew=Clonk=1 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1; + +[Player4] +Wealth=0 +Crew=Clonk=1 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1; + +[Landscape] +Sky=Clouds2 +MapWidth=200,0,64,10000 +MapHeight=175,0,40,10000 +NewStyleLandscape=2 +NoScan=1 + +[Weather] +Climate=0,10,0,100 +YearSpeed=0,0,0,100 +Wind=0,100,-100,100 diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Script.c b/planet/Missions.ocf/Crash.ocs/Script.c similarity index 91% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Script.c rename to planet/Missions.ocf/Crash.ocs/Script.c index de3344a54..c7c7bf0eb 100644 --- a/planet/BeyondTheRocks.ocf/Crash.ocs/Script.c +++ b/planet/Missions.ocf/Crash.ocs/Script.c @@ -9,14 +9,16 @@ static g_is_initialized; func DoInit(int first_player) { + CreateObject(Windmill, 152, 825+48, 0); + // Set time of day to evening and create some clouds and celestials. Cloud->Place(20); CreateObject(Environment_Celestial); var time = CreateObject(Environment_Time); time->SetTime(600); - time->SetCycleSpeed(12); + time->SetCycleSpeed(20); // Waterfall - AddEffect("IntWaterfall", 0, 1, 1); + AddEffect("IntWaterfall", nil, 1, 1); // Windmill owner var windmill = FindObject(Find_ID(Windmill)); if (windmill) windmill->SetOwner(first_player); @@ -24,6 +26,9 @@ func DoInit(int first_player) // Goal CreateObject(Goal_Plane); + // Rules + CreateObject(Rule_TeamAccount, 50, 50); + // NPC: Merchant. var merchant = CreateObject(Clonk, 170, 870); merchant->MakeInvincible(); diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Sound.ocg/EngineDie.ogg b/planet/Missions.ocf/Crash.ocs/Sound.ocg/EngineDie.ogg similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Sound.ocg/EngineDie.ogg rename to planet/Missions.ocf/Crash.ocs/Sound.ocg/EngineDie.ogg diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Sound.ocg/authors.txt b/planet/Missions.ocf/Crash.ocs/Sound.ocg/authors.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Sound.ocg/authors.txt rename to planet/Missions.ocf/Crash.ocs/Sound.ocg/authors.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/StringTblDE.txt b/planet/Missions.ocf/Crash.ocs/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/StringTblDE.txt rename to planet/Missions.ocf/Crash.ocs/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/StringTblUS.txt b/planet/Missions.ocf/Crash.ocs/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/StringTblUS.txt rename to planet/Missions.ocf/Crash.ocs/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/Cannon.c b/planet/Missions.ocf/Crash.ocs/System.ocg/Cannon.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/Cannon.c rename to planet/Missions.ocf/Crash.ocs/System.ocg/Cannon.c diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/DlgMerchant.c b/planet/Missions.ocf/Crash.ocs/System.ocg/DlgMerchant.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/DlgMerchant.c rename to planet/Missions.ocf/Crash.ocs/System.ocg/DlgMerchant.c diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/DlgPilot.c b/planet/Missions.ocf/Crash.ocs/System.ocg/DlgPilot.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/DlgPilot.c rename to planet/Missions.ocf/Crash.ocs/System.ocg/DlgPilot.c diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/Intro.c b/planet/Missions.ocf/Crash.ocs/System.ocg/Intro.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/Intro.c rename to planet/Missions.ocf/Crash.ocs/System.ocg/Intro.c diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/StringTblDE.txt b/planet/Missions.ocf/Crash.ocs/System.ocg/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/System.ocg/StringTblDE.txt rename to planet/Missions.ocf/Crash.ocs/System.ocg/StringTblDE.txt diff --git a/planet/Missions.ocf/Crash.ocs/System.ocg/StringTblUS.txt b/planet/Missions.ocf/Crash.ocs/System.ocg/StringTblUS.txt new file mode 100644 index 000000000..1488c6f61 --- /dev/null +++ b/planet/Missions.ocf/Crash.ocs/System.ocg/StringTblUS.txt @@ -0,0 +1,18 @@ +# Intro +MsgIntro1=Wow, it's very turbulent here... +MsgIntro2=Have a look at that lava lake! +MsgIntro3=Come on old girl, hang in there... +MsgIntro4=Uh oh... +MsgIntro5=Quick! The ejecter seats! + +# NPC Pilot +NamePilot=Pilot +MsgCrashedPlane=So, have you found the plane yet? +AnsCrashedPlane=No, we're still searching. + +# NPC Merchant +MsgSellPlans=I know some interesting construction plans, which I can share with you for 150 clunkers. +AnsNoMoney=Then I'll have to mine for gold, I'll be back later. +AnsBuyPlans=That's a good deal, here you go. +MsgGivePlans=Thanks, here are the plans for {{Pump}}, {{Pipe}}, {{Catapult}} and {{Cannon}}. But be careful with the pump; it's made of wood and cannot be used to pump lava! +MsgLeaveVillage=Please leave this quiet village. diff --git a/planet/Tests.ocf/CableLorrys.ocs/Teams.txt b/planet/Missions.ocf/Crash.ocs/Teams.txt similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/Teams.txt rename to planet/Missions.ocf/Crash.ocs/Teams.txt diff --git a/planet/Missions.ocf/Crash.ocs/Title.jpg b/planet/Missions.ocf/Crash.ocs/Title.jpg new file mode 100644 index 000000000..73016cc83 Binary files /dev/null and b/planet/Missions.ocf/Crash.ocs/Title.jpg differ diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Title.txt b/planet/Missions.ocf/Crash.ocs/Title.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Title.txt rename to planet/Missions.ocf/Crash.ocs/Title.txt diff --git a/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/DefCore.txt new file mode 100644 index 000000000..de11737d6 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_Assassination +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/Graphics.png new file mode 100644 index 000000000..7b59810ce Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/Script.c new file mode 100644 index 000000000..0ed5192f2 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/Script.c @@ -0,0 +1,66 @@ +/*-- + Assassination goal + Author: Sven2 + + Target object must die. +--*/ + + +#include Library_Goal + +local victim, victim_name; + +protected func Initialize() +{ + return inherited(...); +} + +func SetVictim(object to_victim) +{ + victim = to_victim; + if (victim) victim_name = victim->GetName(); else victim_name = "???"; + SetName(Format("$Name2$", victim_name)); + return true; +} + +public func IsFulfilled() +{ + if (!victim) return true; // pushed out of landscape? + return !victim->GetAlive(); +} + +public func Activate(int byplr) +{ + if (IsFulfilled()) + ToggleGoalMessage(Format("$MsgGoalFulfilled$", victim_name), byplr); + else + ToggleGoalMessage(Format("$MsgGoalUnFulfilled$", victim_name), byplr); + return; +} + +// Shows or hides a message window with information. +private func ToggleGoalMessage(string msg, int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + CustomMessage(Format("@%s", msg), nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + + +public func GetShortDescription(int plr) +{ + return Name; +} + +/*-- Proplist --*/ +local Name = "$Name$"; diff --git a/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/StringTblDE.txt new file mode 100644 index 000000000..20899a2b0 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/StringTblDE.txt @@ -0,0 +1,4 @@ +Name=Toeten! +Name2=Toete %s! +MsgGoalFulfilled=%s ist tot. +MsgGoalUnFulfilled=Toete %s! diff --git a/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/StringTblUS.txt new file mode 100644 index 000000000..17cb4f066 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/AssassinationGoal.ocd/StringTblUS.txt @@ -0,0 +1,4 @@ +Name=Kill! +Name2=Kill %s! +MsgGoalFulfilled=%s is dead. +MsgGoalUnFulfilled=Kill %s! diff --git a/planet/Missions.ocf/DarkCastle.ocs/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/DescDE.rtf new file mode 100644 index 000000000..34992b11c Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/DescUS.rtf new file mode 100644 index 000000000..0e324747b Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/DescUS.rtf differ diff --git a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/DefCore.txt similarity index 65% rename from planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/DefCore.txt rename to planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/DefCore.txt index c55b5b00c..36af82e15 100644 --- a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/DefCore.txt +++ b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/DefCore.txt @@ -1,7 +1,10 @@ [DefCore] -id=ObjectRestorer +id=Dialogue Version=5,2,0,1 Category=C4D_StaticBack +Picture=0,0,64,64 Width=1 Height=1 -ClosedContainer=2 + + + diff --git a/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/Graphics.png new file mode 100644 index 000000000..e41ee72a1 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsAlchemist.png b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsAlchemist.png new file mode 100644 index 000000000..ffa622b33 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsAlchemist.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsFarmer.png b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsFarmer.png new file mode 100644 index 000000000..97179cf78 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsFarmer.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsFarmer2.png b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsFarmer2.png new file mode 100644 index 000000000..5eeee5286 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsFarmer2.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsSteampunk.png b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsSteampunk.png new file mode 100644 index 000000000..db1a2ab75 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/GraphicsSteampunk.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/Script.c new file mode 100644 index 000000000..78b05b725 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Dialogue.ocd/Script.c @@ -0,0 +1,42 @@ +/* Nachrichten fuers Intro */ + +func MessageBoxAll(string message, object talker, bool permanent) +{ + if (permanent) permanent = "@"; else permanent = ""; + message = Format("%s%s: %s", permanent, talker->GetColor(), talker->GetName(), message); + CustomMessage(message, nil, NO_OWNER, 150,150, nil, GUI_MenuDeco, GetPortraitDef(talker)); +} + +func GetPortraitDef(object talker) +{ + var portrait = talker.portrait; + // Default definition has Clonk portrait + // (Can't get default from skin, because there's no function GetSkin D:) + if (!portrait || portrait == "" || portrait == "Clonk") return Dialogue; + // Otherwise, bind portrait to an invisible object + // (note: invisible object is leaked. can't really know when the message will be gone.) + if (!talker.portrait_obj) + { + talker.portrait_obj = CreateObject(Dialogue); + talker.portrait_obj->SetAction("Attach", talker); + talker.portrait_obj->SetGraphics(portrait); + talker.portrait_obj.Visibility = VIS_None; + } + return talker.portrait_obj; +} + +func AttachTargetLost() { return RemoveObject(); } + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Attach", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Authors.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Authors.txt new file mode 100644 index 000000000..c6bb606f1 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Authors.txt @@ -0,0 +1 @@ +Decoration objects from EnvironmentPack by Dustin Ness (Dragonclonk) released under ISC. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/DefCore.txt new file mode 100644 index 000000000..7780b173d --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_Bag +Category=C4D_StaticBack +Width=10 +Height=10 +Offset=-5,-5 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Graphics.mesh new file mode 100644 index 000000000..32f2e6c35 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Scene.material new file mode 100644 index 000000000..156801a4e --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Scene.material @@ -0,0 +1,23 @@ +material EnvPack_Bag +{ + receive_shadows on + technique + { + pass + { + cull_hardware none + scene_blend alpha_blend + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture bag.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Script.c new file mode 100644 index 000000000..6db518707 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/Script.c @@ -0,0 +1,7 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() { +SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-180,180),0,10), Trans_Scale(RandomX(130,200)))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/bag.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/bag.png new file mode 100644 index 000000000..d29267722 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Bag.ocd/bag.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/DefCore.txt new file mode 100644 index 000000000..d726bc1b9 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_BridgeRustic_Back +Category=C4D_StaticBack +Width=46 +Height=18 +Offset=-23,-9 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Graphics.mesh new file mode 100644 index 000000000..5fd346c15 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Graphics.png new file mode 100644 index 000000000..2354f3791 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Scene.material new file mode 100644 index 000000000..d168f0989 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Scene.material @@ -0,0 +1,21 @@ +material EnvPack_BridgeRusticB +{ + receive_shadows on + technique + { + pass + { + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.300000 0.300000 0.300000 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture bridgerustic.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Script.c new file mode 100644 index 000000000..e462ae666 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/Script.c @@ -0,0 +1,22 @@ +protected func Initialize() +{ + //this.Plane = 400; +SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(15,0,10), Trans_Scale(200))); + //Trans_Translate(200,0,700), +} + +func SaveScenarioObject() { return false; } + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Directions = 1, + X = 0, + Y = 0, + Wdt = 64, + Hgt = 54, + NextAction = "Attach", + }, +}; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/bridgerustic.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/bridgerustic.png new file mode 100644 index 000000000..57c15ba66 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Back.ocd/bridgerustic.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DefCore.txt new file mode 100644 index 000000000..7f35049fb --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_BridgeRustic +Category=C4D_StaticBack +Width=46 +Height=18 +Offset=-23,-9 +SolidMask=0,0,46,18,0,0 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DescDE.rtf new file mode 100644 index 000000000..c5eb75494 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Rustikale Br\'fccke} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{{\*\bkmkstart __DdeLink__0_1927013023}\afs16\rtlch \ltrch\loch\fs16\lang1033{\*\bkmkend __DdeLink__0_1927013023} +Zwischen dir und dem Abgrund etwas Holz.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DescUS.rtf new file mode 100644 index 000000000..5ee97265f --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/DescUS.rtf @@ -0,0 +1,22 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Rustic Bridge} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{{\*\bkmkstart result_box}{\*\bkmkend result_box}\afs16\rtlch \ltrch\loch\fs16\lang9 +Between you and the abyss some wood.}{\afs16\rtlch \ltrch\loch\fs16\lang1033 + } +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/DefCore.txt new file mode 100644 index 000000000..1e0808cc4 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_BridgeRustic_Front +Category=C4D_StaticBack +Width=46 +Height=18 +Offset=-23,-9 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Graphics.mesh new file mode 100644 index 000000000..6aac743f6 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Graphics.png new file mode 100644 index 000000000..2354f3791 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Scene.material similarity index 57% rename from planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Scene.material rename to planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Scene.material index 6dde0a827..d1c25f6cf 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Scene.material +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Scene.material @@ -1,19 +1,18 @@ -material WindJar +material EnvPack_BridgeRustic { receive_shadows on technique { pass { - cull_hardware none - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 0.640000 0.640000 0.640000 1.000000 - specular 0.500000 0.500000 0.500000 1.000000 12.500000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 emissive 0.000000 0.000000 0.000000 1.000000 + texture_unit { - texture WindJar.png + texture bridgerustic.png tex_address_mode wrap filtering trilinear } diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Script.c new file mode 100644 index 000000000..20696b266 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/Script.c @@ -0,0 +1,22 @@ +protected func Initialize() +{ + this.Plane = 400; + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(15,0,10), Trans_Scale(200))); + +} + +func SaveScenarioObject() { return false; } + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Directions = 1, + X = 0, + Y = 0, + Wdt = 64, + Hgt = 54, + NextAction = "Attach", + }, +}; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/bridgerustic.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/bridgerustic.png new file mode 100644 index 000000000..57c15ba66 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Front.ocd/bridgerustic.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Graphics.png new file mode 100644 index 000000000..d07eccd10 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Script.c new file mode 100644 index 000000000..07676e846 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/BridgeRustic.ocd/Script.c @@ -0,0 +1,21 @@ +/** + @author Dustin Neß (dness.de) +*/ + +local graphicFront, graphicBack; + +protected func Construction() +{ + graphicBack = CreateObject(EnvPack_BridgeRustic_Back,-20,0,nil); + graphicBack->SetAction("Attach", this); + + + graphicFront = CreateObject(EnvPack_BridgeRustic_Front,0,0,nil); + graphicFront->SetAction("Attach", this); + + + + SetClrModulation(RGBa(0,0,0,0)); //Set SolidMask graphic invisible + + return true; +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DefCore.txt new file mode 100644 index 000000000..48b37a36c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_Candle +Category=C4D_StaticBack +Width=4 +Height=10 +Offset=-2,-5 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DescDE.rtf new file mode 100644 index 000000000..05a77a7b6 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Kerze} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Inbegriff von Romantik.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DescUS.rtf new file mode 100644 index 000000000..5859bf254 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Candle} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Pure atmosphere.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Graphics.mesh new file mode 100644 index 000000000..d4ef3bdfb Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Scene.material new file mode 100644 index 000000000..de13a22d8 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Scene.material @@ -0,0 +1,22 @@ +material EnvPack_Candle +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture candle.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Script.c new file mode 100644 index 000000000..3798f4826 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Script.c @@ -0,0 +1,76 @@ +/** + @author Dustin Neß (dness.de) +*/ + +local fShine = false; +local objShine; +local x = 0; +local y = 0; + +protected func Initialize() +{ + return SetAction("Shine"); +} + +protected func Construction() { + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-35,35),0,10), Trans_Scale(30))); + objShine = CreateObject(EnvPack_Candle_Shine, x, y + 10, -1); +} + +private func Shining() +{ + CreateParticle("Fire", 0, -5, 0, PV_Random(-1, 1), 20, Particles_Fire(), 2); + + //check if position changed + if (x != GetX() && y != GetY()) + { + x = GetX(); + y = GetY(); + objShine->SetObjectBlitMode(GFX_BLIT_Additive); + objShine->SetClrModulation(RGBa(255, 255, 255, 228)); + objShine->SetPosition(GetX(), GetY() - 5); + } + + if (!fShine) + fShine = true; +} + +//flickering +private func Noise() +{ + if (RandomX(5) <= 2) + { + objShine->SetClrModulation(RGBa(255, 255, 255, RandomX(190, 228))); + } +} + +public func SetOn(fOn) +{ + if (fOn) + { + if (!FindObject(Find_ID(objShine))) + objShine = CreateObject(EnvPack_Candle_Shine, 0, -5, -1); + SetAction("Shine"); + SetClrModulation(RGB(255, 255, 255)); + fShine = true; + } + else + { + objShine->RemoveObject(); + SetAction("Idle"); + SetClrModulation(RGB(155, 155, 155)); //Turn modell darker + fShine = false; + } + return true; +} + +local ActMap = { + Shine: { + Prototype: Action, + Name: "Shine", + StartCall: "Shining", + NextAction: "Shine", + EndCall: "Noise", + Delay: 5 + } +}; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Shine.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Shine.ocd/DefCore.txt new file mode 100644 index 000000000..76d9be834 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Shine.ocd/DefCore.txt @@ -0,0 +1,9 @@ +[DefCore] +id=EnvPack_Candle_Shine +Category=C4D_StaticBack +Width=20 +Height=20 +Offset=-10,-10 +BlitMode=1 +Oversize=1 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Shine.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Shine.ocd/Graphics.png new file mode 100644 index 000000000..c483bb22d Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/Shine.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/candle.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/candle.png new file mode 100644 index 000000000..dbfb7b5f6 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Candle.ocd/candle.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/DefCore.txt new file mode 100644 index 000000000..4b9137ea0 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_CandleSmall +Category=C4D_StaticBack +Width=4 +Height=4 +Offset=-2,-2 diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Graphics.mesh new file mode 100644 index 000000000..0a45b04db Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Scene.material new file mode 100644 index 000000000..40244f686 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Scene.material @@ -0,0 +1,22 @@ +material EnvPack_CandleSmall +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + ambient 2.500000 2.400000 2.700000 1.000000 + diffuse 2.000000 2.000000 1.000000 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 1.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture candlesmall.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Script.c new file mode 100644 index 000000000..04329739d --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Script.c @@ -0,0 +1,79 @@ +/** + @author Dustin Neß (dness.de) +*/ + +local fShine = false; +local objShine; +local x = 0; +local y = 0; + +protected func Initialize() +{ + return SetAction("Shine"); +} + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-35,35),0,10), Trans_Scale(60))); + objShine = CreateObject(EnvPack_CandleSmall_Shine, x, y + 10, -1); + objShine->SetCon(40); + objShine->SetClrModulation(RGBa(255,255,255,70)); +} + +private func Shining() +{ + + //check if position changed + if (x != GetX() && y != GetY()) + { + x = GetX(); + y = GetY(); + objShine->SetObjectBlitMode(GFX_BLIT_Additive); + //objShine->SetClrModulation(RGBa(255, 255, 255, 228)); + objShine->SetPosition(GetX(), GetY() + 1); + } + + if (!fShine) + fShine = true; +} + +//flickering +private func Noise() +{ + if (RandomX(5) <= 2) + { + //objShine->SetClrModulation(RGBa(255, 255, 255, RandomX(190, 228))); + objShine->SetClrModulation(RGBa(255,255,255,RandomX(60,70))); + } +} + +public func SetOn(fOn) +{ + if (fOn) + { + if (!FindObject(Find_ID(objShine))) + objShine = CreateObject(EnvPack_CandleSmall_Shine, 0, -5, -1); + SetAction("Shine"); + SetClrModulation(RGB(255, 255, 255)); + fShine = true; + } + else + { + objShine->RemoveObject(); + SetAction("Idle"); + SetClrModulation(RGB(155, 155, 155)); //Turn modell darker + fShine = false; + } + return true; +} + +local ActMap = { + Shine: { + Prototype: Action, + Name: "Shine", + StartCall: "Shining", + NextAction: "Shine", + EndCall: "Noise", + Delay: 5 + } +}; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Shine.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Shine.ocd/DefCore.txt new file mode 100644 index 000000000..d997f2935 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Shine.ocd/DefCore.txt @@ -0,0 +1,9 @@ +[DefCore] +id=EnvPack_CandleSmall_Shine +Category=C4D_StaticBack +Width=20 +Height=20 +Offset=-10,-10 +BlitMode=1 +Oversize=1 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Shine.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Shine.ocd/Graphics.png new file mode 100644 index 000000000..c483bb22d Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/Shine.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/candlesmall.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/candlesmall.png new file mode 100644 index 000000000..507f704d5 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/CandleSmall.ocd/candlesmall.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/DefCore.txt new file mode 100644 index 000000000..0b7719914 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_Crate +Category=C4D_StaticBack +Width=10 +Height=10 +Offset=-5,-5 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Graphics.mesh new file mode 100644 index 000000000..d5acc6ca2 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Scene.material new file mode 100644 index 000000000..adf0e049f --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Scene.material @@ -0,0 +1,22 @@ +material EnvPack_Crate +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 1.000000 1.000000 1.000000 1.000000 2.250000 + emissive 0.100000 0.100000 0.100000 1.000000 + + texture_unit + { + texture crate.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Script.c new file mode 100644 index 000000000..0d4e7f660 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/Script.c @@ -0,0 +1,9 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + //SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-180,180),RandomX(-10,10),10), Trans_Scale(RandomX(5,10)))); + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-180,180), 0, 1, 0), Trans_Scale(10))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/crate.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/crate.png new file mode 100644 index 000000000..eda98b3e9 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Crate.ocd/crate.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/DefCore.txt new file mode 100644 index 000000000..9bb9c6df6 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_FenceRustic +Category=C4D_StaticBack +Width=16 +Height=12 +Offset=-8,-6 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Graphics.mesh new file mode 100644 index 000000000..fb548fe14 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Scene.material new file mode 100644 index 000000000..2ff442ebb --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Scene.material @@ -0,0 +1,22 @@ +material EnvPack_FenceRustic +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture fencerustic.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Script.c new file mode 100644 index 000000000..8b3c16592 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/Script.c @@ -0,0 +1,8 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-35,35),0,10), Trans_Scale(60))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/fencerustic.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/fencerustic.png new file mode 100644 index 000000000..d210e4e8c Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/FenceRustic.ocd/fencerustic.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/DefCore.txt new file mode 100644 index 000000000..aa5d8bf64 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_Guidepost +Category=C4D_StaticBack +Width=10 +Height=36 +Offset=-5,-18 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Graphics.mesh new file mode 100644 index 000000000..9c132b725 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Scene.material new file mode 100644 index 000000000..6b58f9640 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Scene.material @@ -0,0 +1,22 @@ +material EnvPack_Guidepost +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture guidepost.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Script.c new file mode 100644 index 000000000..0f83d124f --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/Script.c @@ -0,0 +1,8 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-180,180),0,10), Trans_Scale(360))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/guidepost.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/guidepost.png new file mode 100644 index 000000000..b9ad4090a Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Guidepost.ocd/guidepost.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DefCore.txt new file mode 100644 index 000000000..dbb5dce05 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_Lantern +Category=C4D_StaticBack +Width=20 +Height=42 +Offset=-10,-21 diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescDE.rtf new file mode 100644 index 000000000..63ba12b21 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Laterne} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Beleuchtet f\'fcr gew\'f6hnlich den Weg.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescUS.rtf new file mode 100644 index 000000000..d4895f6d7 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Lantern} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Usually lit the way.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescUS.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescUS.txt new file mode 100644 index 000000000..68b193f86 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/DescUS.txt @@ -0,0 +1 @@ +Usually lit the way. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Graphics.mesh new file mode 100644 index 000000000..a7594a2a8 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Scene.material new file mode 100644 index 000000000..29997d2e0 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Scene.material @@ -0,0 +1,23 @@ +material EnvPack_Lantern +{ + receive_shadows on + technique + { + pass + { + cull_hardware none + scene_blend alpha_blend + ambient 0.700000 0.700000 0.500000 1.000000 + diffuse 0.920000 0.920000 0.900000 1.000000 + specular 0.600000 0.600000 0.600000 1.000000 6.250000 + emissive 0.300000 0.300000 0.000000 1.000000 + + texture_unit + { + texture lantern.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Script.c new file mode 100644 index 000000000..74a0db9f4 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Script.c @@ -0,0 +1,75 @@ +/** + @author Dustin Neß (dness.de) +*/ + +local fShine = false; +local objShine; +local x = 0; +local y = 0; + +protected func Initialize() +{ + return SetAction("Shine"); +} + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-30, 30), 11, 40), Trans_Scale(400))); + objShine = CreateObject(EnvPack_Lantern_Shine, x, y + 15, -1); +} + +private func Shining() +{ + //check if position changed + if (x != GetX() && y != GetY()) + { + x = GetX(); + y = GetY(); + objShine->SetObjectBlitMode(GFX_BLIT_Additive); + objShine->SetClrModulation(RGBa(255, 255, 255, 228)); + objShine->SetPosition(GetX(), GetY() - 15); + } + + if (!fShine) + fShine = true; +} + +//flickering +private func Noise() +{ + if (RandomX(5) <= 2) + { + objShine->SetClrModulation(RGBa(255, 255, 255, RandomX(190, 228))); + } +} + +public func SetOn(fOn) +{ + if (fOn) + { + if (!FindObject(Find_ID(objShine))) + objShine = CreateObject(EnvPack_Lantern_Shine, 0, 15, -1); + SetAction("Shine"); + SetClrModulation(RGB(255, 255, 255)); + fShine = true; + } + else + { + objShine->RemoveObject(); + SetAction("Idle"); + SetClrModulation(RGB(155, 155, 155)); //Turn modell darker + fShine = false; + } + return true; +} + +local ActMap = { + Shine: { + Prototype: Action, + Name: "Shine", + StartCall: "Shining", + NextAction: "Shine", + EndCall: "Noise", + Delay: 5 + } +}; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Shine.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Shine.ocd/DefCore.txt new file mode 100644 index 000000000..1292d0957 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Shine.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=EnvPack_Lantern_Shine +Category=C4D_StaticBack +Width=50 +Height=50 +Offset=-25,-25 diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Shine.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Shine.ocd/Graphics.png new file mode 100644 index 000000000..66ae19a95 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/Shine.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/lantern.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/lantern.png new file mode 100644 index 000000000..0d8af4a91 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Lantern.ocd/lantern.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/DefCore.txt new file mode 100644 index 000000000..c0ef74e59 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/DefCore.txt @@ -0,0 +1,17 @@ +[DefCore] +id=EnvPack_ManaAltar +Version=4,10,0,0 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=20 +Value=1 +Mass=10 +Components=EnvPack_ManaAltar=1 +Projectile=1 +Rotate=1 + diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/Graphics.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/Graphics.png rename to planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/Graphics.png diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/Script.c new file mode 100644 index 000000000..22d9c426b --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/Script.c @@ -0,0 +1,13 @@ +/** + ManaAltar + Beschreibung hier einfügen + + @author Dustin Neß (dness.de) +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +func Initialize() +{ +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/StringTblDE.txt new file mode 100644 index 000000000..6d3c254a8 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=ManaAltar +Description=Beschreibung hier einfügen \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/StringTblUS.txt new file mode 100644 index 000000000..6d3c254a8 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/ManaAltar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=ManaAltar +Description=Beschreibung hier einfügen \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DefCore.txt new file mode 100644 index 000000000..83bbc7461 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_Painting +Category=C4D_StaticBack +Width=16 +Height=14 +Offset=-8,-7 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DescDE.rtf new file mode 100644 index 000000000..a7514de57 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Gem\'e4lde} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +H\'e4ngt herum und erfreut die Gem\'fcter.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DescUS.rtf new file mode 100644 index 000000000..c4ffcb3c8 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Painting} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Just hanging around and pleased the minds.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Graphics.mesh new file mode 100644 index 000000000..d0e5d22cf Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Scene.material new file mode 100644 index 000000000..ef1fa5fee --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Scene.material @@ -0,0 +1,22 @@ +material EnvPack_Painting +{ + receive_shadows on + technique + { + pass + { + ambient 0.800000 0.500000 0.500000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit Painting + { + texture painting.png + tex_address_mode wrap + filtering trilinear + } + } + } +} + diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Script.c new file mode 100644 index 000000000..fd78b9ef2 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/Script.c @@ -0,0 +1,14 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(10,0,10), Trans_Scale(50))); + RandomPainting(3); +} + +//Change when changing textures is prossible soon(?) +public func RandomPainting(iMax) { + return Random(iMax); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/painting.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/painting.png new file mode 100644 index 000000000..f8a6869da Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Painting.ocd/painting.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DefCore.txt new file mode 100644 index 000000000..a209006f3 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_Rail +Category=C4D_StaticBack +Width=20 +Height=12 +Offset=-10,-6 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DescDE.rtf new file mode 100644 index 000000000..830cd9bfc --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Gel\'e4nder} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Das Gel\'e4nder ist an schwieriges Terrain und Felsen angebracht.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DescUS.rtf new file mode 100644 index 000000000..0979f85c3 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Rail} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +The railing is attached to difficult terrain or climbs.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Graphics.mesh new file mode 100644 index 000000000..24be1812e Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Graphics.mesh differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Scene.material similarity index 60% rename from planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Scene.material rename to planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Scene.material index 963e810ed..e044bf7d1 100644 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Scene.material +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Scene.material @@ -1,4 +1,4 @@ -material Boompack +material EnvPack_Rail { receive_shadows on technique @@ -6,12 +6,13 @@ material Boompack pass { ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 0.640000 0.640000 0.640000 1.000000 - specular 0.000000 0.000000 0.000000 1.000000 12.500000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 emissive 0.000000 0.000000 0.000000 1.000000 + texture_unit { - texture boompack.png + texture rail.png tex_address_mode wrap filtering trilinear } diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Script.c new file mode 100644 index 000000000..c4ab99ff2 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/Script.c @@ -0,0 +1,23 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + //random Side + if(Random(2)) + { + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(15,0,10), Trans_Scale(120))); + } else { + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(195,0,180), Trans_Scale(120))); + } +} + +//bring to front +public func SetToFront(bool fBool) { + if(fBool) { + return this.Plane = 510; + } else { + return this.Plane = 110; + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/rail.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/rail.png new file mode 100644 index 000000000..7c8f0f62d Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Rail.ocd/rail.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DefCore.txt new file mode 100644 index 000000000..0d6259d89 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_Scarecrow +Category=C4D_StaticBack +Width=10 +Height=18 +Offset=-5,-9 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DescDE.rtf new file mode 100644 index 000000000..db4b41ca9 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Vogelscheuche} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Sollte Federvieh vom Feld fernhalten, tut es aber meist doch nicht.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DescUS.rtf new file mode 100644 index 000000000..9568bf0f2 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f5\fnil\fprq2\fcharset0 Mangal;}{\f6\fnil\fprq0\fcharset128 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af5\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af3\langfe2052\dbch\af6\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af3\langfe2052\dbch\af6\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Scarecrow} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Should keep feather animal away from the field, but then it doesn't.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Graphics.mesh new file mode 100644 index 000000000..991f655f6 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Scene.material new file mode 100644 index 000000000..9a780083b --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Scene.material @@ -0,0 +1,23 @@ +material EnvPack_Scarecrow +{ + receive_shadows on + technique + { + pass + { + cull_hardware none + scene_blend alpha_blend + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 0.800000 0.799920 0.799920 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.250000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture scarecrow.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Script.c new file mode 100644 index 000000000..a5a22e0a4 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/Script.c @@ -0,0 +1,8 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-30,-80),1,10), Trans_Scale(90))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/bag.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/bag.png new file mode 100644 index 000000000..d29267722 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/bag.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/scarecrow.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/scarecrow.png new file mode 100644 index 000000000..8759525a1 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/Scarecrow.ocd/scarecrow.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DefCore.txt new file mode 100644 index 000000000..24faec744 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_TreeTrunks +Category=C4D_StaticBack +Width=24 +Height=10 +Offset=-10,-10 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DescDE.rtf new file mode 100644 index 000000000..089c21132 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Baumst\'e4mme} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Abgelagert und vergessen.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DescUS.rtf new file mode 100644 index 000000000..2a2fad44c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Tree Trunks} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Layed down and forgotten.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Graphics.mesh new file mode 100644 index 000000000..c91aa17ba Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Scene.material new file mode 100644 index 000000000..4a593c940 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Scene.material @@ -0,0 +1,21 @@ +material EnvPack_TreeTrunks +{ + receive_shadows on + technique + { + pass + { + ambient 0.000000 0.000000 0.000000 1.000000 + diffuse 0.640000 0.640000 0.640000 1.000000 + specular 1.300000 1.300000 0.300000 1.000000 12.500000 + emissive 0.300000 0.300000 0.300000 1.000000 + + texture_unit + { + texture treetrunks.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Script.c new file mode 100644 index 000000000..b5109280a --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Script.c @@ -0,0 +1,8 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-40,40),0,20), Trans_Scale(550))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Title.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Title.png new file mode 100644 index 000000000..f5db88652 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/Title.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/treetrunks.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/treetrunks.png new file mode 100644 index 000000000..a778c4d0a Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/TreeTrunks.ocd/treetrunks.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DefCore.txt new file mode 100644 index 000000000..ce7b5d039 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=EnvPack_WineBarrel +Category=C4D_StaticBack +Width=20 +Height=20 +Offset=-4,-4 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DescDE.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DescDE.rtf new file mode 100644 index 000000000..665463b66 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Weinfass} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +Dem Weintrinker ein Paradies.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DescUS.rtf b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DescUS.rtf new file mode 100644 index 000000000..70dc1baac --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset0 Mangal;}{\f5\fnil\fprq0\fcharset128 Mangal;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043 Standard;} +{\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\kerning1\hich\af4\langfe2052\dbch\af6\loch\f2\fs28\lang1031 Überschrift;} +{\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af3\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Textkörper;} +{\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Liste;} +{\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\kerning1\hich\af5\langfe2052\dbch\af3\ai\loch\f3\fs24\lang1031 Beschriftung;} +{\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af3\loch\f3\fs24\lang1031 Verzeichnis;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice.org}{\vern3400}}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720 + +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\b\afs20\ab\rtlch \ltrch\loch\fs20\lang1033 +Wine Barrel} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch +} +\par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\kerning1\hich\af3\langfe1043\dbch\af3\afs24\lang1081\loch\f3\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\lang1033 +The wine drinker's paradise.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Graphics.mesh b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Graphics.mesh new file mode 100644 index 000000000..581bdc49f Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Graphics.mesh differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Scene.material b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Scene.material new file mode 100644 index 000000000..fea9907c0 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Scene.material @@ -0,0 +1,23 @@ +material EnvPack_WineBarrel +{ + receive_shadows on + technique + { + pass + { + cull_hardware none + scene_blend alpha_blend + ambient 0.200000 0.200000 0.200000 1.000000 + diffuse 0.900000 0.900000 0.900000 1.000000 + specular 0.000000 0.000000 0.000000 1.000000 2.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + + texture_unit + { + texture winebarrel.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Script.c new file mode 100644 index 000000000..2131ff0b7 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/Script.c @@ -0,0 +1,8 @@ +/** + @author Dustin Neß (dness.de) +*/ + +protected func Construction() +{ + SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-50,50),0,10), Trans_Scale(500))); +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/winebarrel.png b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/winebarrel.png new file mode 100644 index 000000000..c3e687fcb Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/EnvironmentObjs.ocd/WineBarrel.ocd/winebarrel.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/DefCore.txt new file mode 100644 index 000000000..88460f2e6 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/DefCore.txt @@ -0,0 +1,13 @@ +[DefCore] +id=LargeCaveMushroomPoison +Version=5,2,0,1 +Category=C4D_Vehicle +Width=2 +Height=2 +Offset=0,-1 +Vertices=1 +VertexFriction=1 +Mass=1 +Oversize=1 +Float=1 +StretchGrowth=1 diff --git a/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/Graphics.8.png b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/Graphics.8.png new file mode 100644 index 000000000..f08feac5f Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/Graphics.8.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/PoisonLaunch.ogg b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/PoisonLaunch.ogg new file mode 100644 index 000000000..13e01ee06 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/PoisonLaunch.ogg differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/Script.c new file mode 100644 index 000000000..e62fbc057 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/Script.c @@ -0,0 +1,46 @@ +/*-- LargeCaveMushroomPoison --*/ + +func LaunchPoison(int x, int y, int vx, int vy, int owner) +{ + var poison = CreateObject(LargeCaveMushroomPoison, x,y, owner); + if (poison) poison->Launch(vx,vy); + return poison; +} + +func Launch(int vx, int vy) +{ + SetXDir(vx); SetYDir(vy); + SetRDir(Random(21)-10); + var fx = AddEffect("Move", this, 1, 2, this); + fx.lifetime = 100+Random(50); + return true; +} + +func ContactBottom() +{ + // bouncy bouncy! + SetXDir(Random(11)-5); + SetYDir(-5-Random(10)); + SetRDir(Random(21)-10); + return true; +} + +public func FxMoveTimer(object target, fx, int time) +{ + // lifetime + if (time > fx.lifetime || Stuck() || GBackLiquid()) { RemoveObject(); return FX_Execute_Kill; } + // Search victim to poison + var victim = FindObject(Find_AtRect(-5,-5,11,11), Find_OCF(OCF_Alive), Find_Layer(GetObjectLayer())); + if (victim) + { + var dx=victim->GetX()-GetX(), dy=victim->GetY()-GetY(); + var d=Max(Distance(dx,dy),1); + dx=dx*20/d; dy=dy*20/d; + SetXDir(dx); SetYDir(dy-5); + victim->DoEnergy(-1, false, FX_Call_EngCorrosion, GetOwner()); + } + // gfx effect + Smoke(Random(3)-1,-Random(3),5+Random(10),0xffa0ff80); +} + +local Plane = 550; diff --git a/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/StringTblDE.txt new file mode 100644 index 000000000..04b0d6062 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Gift \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/StringTblUS.txt new file mode 100644 index 000000000..1fc6bdcc7 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/LargeCaveMushroomPoison.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Poison diff --git a/planet/Missions.ocf/DarkCastle.ocs/Map.bmp b/planet/Missions.ocf/DarkCastle.ocs/Map.bmp new file mode 100644 index 000000000..ee5f06074 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/TEXMAP.TXT b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..0de8aca3c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,74 @@ +# Static Map Material/Texture Table +# Index +128 for underground materials +8=Tunnel-brickback3 +9=Tunnel-brickback2 +10=Tunnel-tunnel +11=Tunnel-tunnel +12=Tunnel-brickback +13=BrickSoft-brick1 +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +#21=Oil-Liquid +22=Acid-acid +23=Lava-lava_red +24=DuroLava-lava_red +25=Water-water +#26=Oil-Smooth +27=Acid-acid +28=Lava-lava_red +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes +#34=Ashes-Rough +#35=Ashes-Ridge + +36=Ore-ore +37=Ore-ore +38=Ore-ore + +40=Granite-granite +41=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked +52=Rock-rock + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth +#57=Sand-Smooth3 + + + +#59=FlyAshes-Smooth + +#60=Crystal-Flare +#61=Crystal-Structure +#62=Crystal-Structure2 + +65=Ice-ice2 +66=Ice-ice2 +67=Ice-ice3 +68=Ice-ice3 + +70=Snow-snow1 +71=Snow-snow1 +72=Snow-snow1 +73=Brick-brick1 +74=Brick-brick2 + +#80=FlySand-Smooth2 +#81=FlySand-Smooth3 +#82=FlySand-Smooth + + +OverloadMaterials +OverloadTextures diff --git a/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brick2.png b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brick2.png new file mode 100644 index 000000000..8ba865d91 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brick2.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback2.png b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback2.png new file mode 100644 index 000000000..9da9a48dd Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback2.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback2.psd b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback2.psd new file mode 100644 index 000000000..9d50fd54f Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback2.psd differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback3.png b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback3.png new file mode 100644 index 000000000..3f28fe724 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Material.ocg/brickback3.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Objects.c b/planet/Missions.ocf/DarkCastle.ocs/Objects.c new file mode 100644 index 000000000..1b78957d3 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Objects.c @@ -0,0 +1,668 @@ +/* Automatically created objects file */ + +func InitializeObjects() +{ + var Grass0001 = CreateObject(Grass, 396, 1149); + Grass0001->SetClrModulation(0xffa08060); + var Grass0002 = CreateObject(Grass, 232, 1181); + Grass0002->SetClrModulation(0xffa08060); + var Grass0003 = CreateObject(Grass, 228, 1180); + Grass0003->SetClrModulation(0xffa08060); + + var Tree_Coniferous_Burned0004 = CreateObject(Tree_Coniferous_Burned, 17, 1141); + Tree_Coniferous_Burned0004->SetR(10); + Tree_Coniferous_Burned0004->SetPosition(17, 1097); + var Tree_Coniferous_Burned0005 = CreateObject(Tree_Coniferous_Burned, 43, 1156); + Tree_Coniferous_Burned0005->SetCon(75); + Tree_Coniferous_Burned0005->SetR(100); + Tree_Coniferous_Burned0005->SetPosition(43, 1150); + + var Tree_Coniferous0006 = CreateObject(Tree_Coniferous, 415, 1161); + Tree_Coniferous0006->SetCon(75); + Tree_Coniferous0006->SetR(10); + Tree_Coniferous0006->SetClrModulation(0xffc08060); + Tree_Coniferous0006->SetPosition(415, 1129); + + var Rank0010 = CreateObject(Rank, 241, 1183); + Rank0010->SetR(17); + Rank0010->SetPosition(241, 1180); + + var Fern0011 = CreateObject(Fern, 312, 1432); + Fern0011->SetClrModulation(0xffa08060); + + var LargeCaveMushroom0015 = CreateObject(LargeCaveMushroom, 1355, 1451); + LargeCaveMushroom0015->SetClrModulation(0xffcddfdf); + var LargeCaveMushroom0019 = CreateObject(LargeCaveMushroom, 1308, 1409); + LargeCaveMushroom0019->SetR(180); + LargeCaveMushroom0019->SetClrModulation(0xffdae7dc); + LargeCaveMushroom0019->SetPosition(1308, 1384); + var LargeCaveMushroom0023 = CreateObject(LargeCaveMushroom, 1411, 1447); + LargeCaveMushroom0023->SetClrModulation(0xffe9d5dd); + var LargeCaveMushroom0027 = CreateObject(LargeCaveMushroom, 1420, 1397); + LargeCaveMushroom0027->SetR(160); + LargeCaveMushroom0027->SetClrModulation(0xffeaedfb); + LargeCaveMushroom0027->SetPosition(1420, 1374); + + var Rank0031 = CreateObject(Rank, 1430, 1423); + Rank0031->SetR(-25); + Rank0031->SetPosition(1430, 1420); + + var Lichen0032 = CreateObject(Lichen, 1387, 1439); + Lichen0032->SetAction("Grown"); + var Lichen0035 = CreateObject(Lichen, 1310, 1455); + Lichen0035->SetAction("Grown"); + var Lichen0038 = CreateObject(Lichen, 1466, 1415); + Lichen0038->SetAction("Grown"); + + var Trunk0041 = CreateObject(Trunk, 217, 1184); + Trunk0041->SetR(-10); + Trunk0041->SetPosition(217, 1159); + + var EnvPack_Bag0042 = CreateObject(EnvPack_Bag, 846, 885); + EnvPack_Bag0042->SetClrModulation(0xffa0a0a0); + CreateObject(EnvPack_Bag, 840, 888); + CreateObject(EnvPack_Bag, 844, 888); + + CreateObject(EnvPack_BridgeRustic, 1096, 673); + + CreateObject(EnvPack_Candle, 1054, 672); + + var EnvPack_Candle_Shine0049 = CreateObject(EnvPack_Candle_Shine, 1054, 672); + EnvPack_Candle_Shine0049->SetClrModulation(0xbfffffff); + EnvPack_Candle_Shine0049->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0050 = CreateObject(EnvPack_Candle_Shine, 1054, 672); + EnvPack_Candle_Shine0050->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0050->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0051 = CreateObject(EnvPack_Candle_Shine, 1054, 671); + EnvPack_Candle_Shine0051->SetClrModulation(0xc9ffffff); + EnvPack_Candle_Shine0051->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Candle, 1054, 575); + + var EnvPack_Candle_Shine0053 = CreateObject(EnvPack_Candle_Shine, 1054, 575); + EnvPack_Candle_Shine0053->SetClrModulation(0xd9ffffff); + EnvPack_Candle_Shine0053->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0054 = CreateObject(EnvPack_Candle_Shine, 1054, 575); + EnvPack_Candle_Shine0054->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0054->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0055 = CreateObject(EnvPack_Candle_Shine, 1054, 575); + EnvPack_Candle_Shine0055->SetClrModulation(0xd8ffffff); + EnvPack_Candle_Shine0055->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Candle, 1185, 616); + + var EnvPack_Candle_Shine0057 = CreateObject(EnvPack_Candle_Shine, 1185, 616); + EnvPack_Candle_Shine0057->SetClrModulation(0xc6ffffff); + EnvPack_Candle_Shine0057->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0058 = CreateObject(EnvPack_Candle_Shine, 1185, 616); + EnvPack_Candle_Shine0058->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0058->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0059 = CreateObject(EnvPack_Candle_Shine, 1185, 616); + EnvPack_Candle_Shine0059->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0059->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Candle, 1531, 448); + + var EnvPack_Candle_Shine0061 = CreateObject(EnvPack_Candle_Shine, 1531, 448); + EnvPack_Candle_Shine0061->SetClrModulation(0xd4ffffff); + EnvPack_Candle_Shine0061->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0062 = CreateObject(EnvPack_Candle_Shine, 1531, 448); + EnvPack_Candle_Shine0062->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0062->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0063 = CreateObject(EnvPack_Candle_Shine, 1531, 447); + EnvPack_Candle_Shine0063->SetClrModulation(0xddffffff); + EnvPack_Candle_Shine0063->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Candle, 1362, 432); + + var EnvPack_Candle_Shine0065 = CreateObject(EnvPack_Candle_Shine, 1362, 432); + EnvPack_Candle_Shine0065->SetClrModulation(0xc7ffffff); + EnvPack_Candle_Shine0065->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0066 = CreateObject(EnvPack_Candle_Shine, 1362, 432); + EnvPack_Candle_Shine0066->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0066->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0067 = CreateObject(EnvPack_Candle_Shine, 1361, 430); + EnvPack_Candle_Shine0067->SetClrModulation(0xcbffffff); + EnvPack_Candle_Shine0067->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_CandleSmall, 1556, 432); + + var EnvPack_CandleSmall_Shine0069 = CreateObject(EnvPack_CandleSmall_Shine, 1556, 423); + EnvPack_CandleSmall_Shine0069->SetCon(40); + EnvPack_CandleSmall_Shine0069->SetClrModulation(0x43ffffff); + EnvPack_CandleSmall_Shine0069->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_CandleSmall_Shine0070 = CreateObject(EnvPack_CandleSmall_Shine, 1556, 429); + EnvPack_CandleSmall_Shine0070->SetCon(40); + EnvPack_CandleSmall_Shine0070->SetClrModulation(0x46ffffff); + EnvPack_CandleSmall_Shine0070->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_CandleSmall_Shine0071 = CreateObject(EnvPack_CandleSmall_Shine, 1555, 432); + EnvPack_CandleSmall_Shine0071->SetCon(40); + EnvPack_CandleSmall_Shine0071->SetClrModulation(0x41ffffff); + EnvPack_CandleSmall_Shine0071->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Crate, 1017, 576); + + CreateObject(EnvPack_FenceRustic, 1111, 728); + CreateObject(EnvPack_FenceRustic, 1089, 735); + + CreateObject(EnvPack_Guidepost, 315, 1167); + + CreateObject(EnvPack_Lantern, 894, 488); + + var EnvPack_Lantern_Shine0077 = CreateObject(EnvPack_Lantern_Shine, 894, 477); + EnvPack_Lantern_Shine0077->SetClrModulation(0xd3ffffff); + EnvPack_Lantern_Shine0077->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Lantern_Shine0078 = CreateObject(EnvPack_Lantern_Shine, 894, 477); + EnvPack_Lantern_Shine0078->SetClrModulation(0xe4ffffff); + EnvPack_Lantern_Shine0078->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Lantern_Shine0079 = CreateObject(EnvPack_Lantern_Shine, 894, 477); + EnvPack_Lantern_Shine0079->SetClrModulation(0xc6ffffff); + EnvPack_Lantern_Shine0079->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Lantern, 1291, 472); + + var EnvPack_Lantern_Shine0081 = CreateObject(EnvPack_Lantern_Shine, 1291, 461); + EnvPack_Lantern_Shine0081->SetClrModulation(0xd5ffffff); + EnvPack_Lantern_Shine0081->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Lantern_Shine0082 = CreateObject(EnvPack_Lantern_Shine, 1291, 461); + EnvPack_Lantern_Shine0082->SetClrModulation(0xe4ffffff); + EnvPack_Lantern_Shine0082->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Lantern_Shine0083 = CreateObject(EnvPack_Lantern_Shine, 1291, 461); + EnvPack_Lantern_Shine0083->SetClrModulation(0xccffffff); + EnvPack_Lantern_Shine0083->SetObjectBlitMode(GFX_BLIT_Additive); + + CreateObject(EnvPack_Painting, 1235, 537); + + CreateObject(EnvPack_Rail, 1121, 672); + + CreateObject(EnvPack_Scarecrow, 204, 1185); + + CreateObject(EnvPack_TreeTrunks, 788, 888); + + CreateObject(EnvPack_WineBarrel, 1438, 552); + CreateObject(EnvPack_WineBarrel, 1455, 553); + + CreateObject(EnvPack_Candle, 1471, 552); + + var EnvPack_Candle_Shine0091 = CreateObject(EnvPack_Candle_Shine, 1471, 552); + EnvPack_Candle_Shine0091->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0091->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0092 = CreateObject(EnvPack_Candle_Shine, 1471, 552); + EnvPack_Candle_Shine0092->SetClrModulation(0xe4ffffff); + EnvPack_Candle_Shine0092->SetObjectBlitMode(GFX_BLIT_Additive); + var EnvPack_Candle_Shine0093 = CreateObject(EnvPack_Candle_Shine, 1472, 552); + EnvPack_Candle_Shine0093->SetClrModulation(0xddffffff); + EnvPack_Candle_Shine0093->SetObjectBlitMode(GFX_BLIT_Additive); + + var Ruin10094 = CreateObject(Ruin1, 97, 1179); + Ruin10094->SetR(16); + Ruin10094->SetPosition(97, 1150); + + CreateObject(Ruin2, 353, 1145); + + CreateObject(Ruin3, 267, 1180); + + CreateObject(Foundry, 238, 1287); + + var Chest0100 = CreateObject(Chest, 1473, 1414); + var Chest0101 = CreateObject(Chest, 1574, 583); + var Chest0102 = CreateObject(Chest, 823, 887); + var Chest0103 = CreateObject(Chest, 856, 887); + var Chest0104 = CreateObject(Chest, 1032, 575); + var Chest0105 = CreateObject(Chest, 136, 103); + + var StoneDoor0106 = CreateObject(StoneDoor, 940, 671); + StoneDoor0106->SetComDir(COMD_Down); + var StoneDoor0107 = CreateObject(StoneDoor, 1348, 527); + StoneDoor0107->SetComDir(COMD_Down); + var StoneDoor0108 = CreateObject(StoneDoor, 1347, 431); + StoneDoor0108->SetComDir(COMD_Down); + + var SpinWheel0109 = CreateObject(SpinWheel, 961, 672); + SpinWheel0109->SetStoneDoor(StoneDoor0106); + var SpinWheel0110 = CreateObject(SpinWheel, 1367, 527); + SpinWheel0110->SetStoneDoor(StoneDoor0107); + var SpinWheel0111 = CreateObject(SpinWheel, 1384, 471); + SpinWheel0111->SetStoneDoor(StoneDoor0108); + + CreateObject(Column, 1197, 551); + CreateObject(Column, 1218, 463); + + CreateObject(Idol, 1080, 575); + + var SteamEngine0115 = CreateObject(SteamEngine, 1529, 585); + SteamEngine0115->SetCategory(C4D_StaticBack); + + CreateObject(Elevator, 1366, 615); + var Elevator0180 = CreateObject(Elevator, 167, 1184); + Elevator0180->SetClrModulation(0xffa08060); + + CreateObject(Airship, 931, 495); + + var Catapult0202 = CreateObject(Catapult, 697, 887); + Catapult0202->SetRDir(2); + + var Lorry0203 = CreateObject(Lorry, 149, 1324); + Lorry0203->SetR(24); + Lorry0203->SetPosition(149, 1315); + var Lorry0205 = CreateObject(Lorry, 1428, 1253); + Lorry0205->SetR(-30); + Lorry0205->SetPosition(1428, 1243); + + CreateObject(Airship_Burnt, 38, 1152); + + var Cannon0208 = CreateObject(Cannon, 788, 679); + Cannon0208->SetR(30); + Cannon0208->SetPosition(788, 669); + CreateObject(Cannon, 1004, 471); + CreateObject(Cannon, 1336, 336); + + var Clonk0211 = CreateObject(Clonk, 673, 886); + Clonk0211->SetColor(0xff); + Clonk0211->SetName("Horst"); + S2AI->AddAI(Clonk0211); + S2AI->SetHome(Clonk0211, 670, 878, DIR_Left); + S2AI->SetGuardRange(Clonk0211, 400, 800, 500, 150); + S2AI->SetAllyAlertRange(Clonk0211, 60); + S2AI->SetEncounterCB(Clonk0211, "EncounterOutpost"); + var Clonk0219 = CreateObject(Clonk, 710, 887); + Clonk0219->SetColor(0xff); + Clonk0219->SetName("Hanniball"); + S2AI->AddAI(Clonk0219); + S2AI->SetHome(Clonk0219, 709, 877, DIR_Left); + S2AI->SetGuardRange(Clonk0219, 300, 700, 500, 250); + S2AI->SetAllyAlertRange(Clonk0219, 60); + var Clonk0226 = CreateObject(Clonk, 781, 671); + Clonk0226->SetDir(DIR_Right); + Clonk0226->SetColor(0xff); + Clonk0226->SetName("Twonky"); + S2AI->AddAI(Clonk0226); + S2AI->SetHome(Clonk0226, 781, 663, DIR_Right); + S2AI->SetGuardRange(Clonk0226, 481, 511, 600, 300); + var Clonk0234 = CreateObject(Clonk, 1010, 671); + Clonk0234->SetDir(DIR_Right); + Clonk0234->SetColor(0xff); + Clonk0234->SetName("Sven"); + S2AI->AddAI(Clonk0234); + S2AI->SetHome(Clonk0234, 1010, 663, DIR_Right); + S2AI->SetGuardRange(Clonk0234, 710, 511, 600, 300); + var Clonk0242 = CreateObject(Clonk, 985, 671); + Clonk0242->SetDir(DIR_Right); + Clonk0242->SetColor(0xff); + Clonk0242->SetName("Luki"); + S2AI->AddAI(Clonk0242); + S2AI->SetHome(Clonk0242, 985, 663, DIR_Right); + S2AI->SetGuardRange(Clonk0242, 685, 511, 600, 300); + var Clonk0250 = CreateObject(Clonk, 1373, 1246); + Clonk0250->SetColor(0xffff0000); + Clonk0250->SetName("Anna"); + S2AI->AddAI(Clonk0250); + S2AI->SetHome(Clonk0250, 1370, 1237, DIR_Left); + S2AI->SetGuardRange(Clonk0250, 1150, 1140, 320, 150); + S2AI->SetAllyAlertRange(Clonk0250, 170); + var Clonk0258 = CreateObject(Clonk, 1449, 1246); + Clonk0258->SetColor(0xffff0000); + Clonk0258->SetName("Cindy"); + S2AI->AddAI(Clonk0258); + S2AI->SetHome(Clonk0258, 1448, 1237, DIR_Left); + S2AI->SetGuardRange(Clonk0258, 1150, 1140, 320, 150); + S2AI->SetAllyAlertRange(Clonk0258, 170); + S2AI->SetEncounterCB(Clonk0258, "EncounterCave"); + var Clonk0266 = CreateObject(Clonk, 307, 1166); + Clonk0266->SetDir(DIR_Right); + Clonk0266->SetColor(0xff); + Clonk0266->SetClrModulation(0xffffa020); + Clonk0266->SetName("Farmer"); + var Clonk0273 = CreateObject(Clonk, 1197, 551); + Clonk0273->SetDir(DIR_Right); + Clonk0273->SetColor(0xff); + Clonk0273->SetName("Sabrina"); + S2AI->AddAI(Clonk0273); + S2AI->SetHome(Clonk0273, 1196, 542, DIR_Right); + S2AI->SetGuardRange(Clonk0273, 896, 392, 600, 300); + var Clonk0281 = CreateObject(Clonk, 1266, 550); + Clonk0281->SetColor(0xff); + Clonk0281->SetName("Laura"); + S2AI->AddAI(Clonk0281); + S2AI->SetGuardRange(Clonk0281, 966, 391, 600, 300); + var Clonk0289 = CreateObject(Clonk, 1287, 471); + Clonk0289->SetDir(DIR_Right); + Clonk0289->SetColor(0xff); + S2AI->AddAI(Clonk0289); + S2AI->SetHome(Clonk0289, 1287, 464, DIR_Right); + S2AI->SetGuardRange(Clonk0289, 987, 312, 600, 300); + var Clonk0297 = CreateObject(Clonk, 1092, 575); + Clonk0297->SetDir(DIR_Right); + Clonk0297->SetColor(0xff); + Clonk0297->SetName("Wolfgang"); + S2AI->AddAI(Clonk0297); + S2AI->SetHome(Clonk0297, 1092, 567, DIR_Right); + S2AI->SetGuardRange(Clonk0297, 792, 416, 600, 300); + var Clonk0305 = CreateObject(Clonk, 1569, 431); + Clonk0305->Kill(Clonk0305, true); + Clonk0305->SetCon(200); + Clonk0305->SetColor(0xff); + Clonk0305->SetClrModulation(0xffff8000); + Clonk0305->SetObjectBlitMode(GFX_BLIT_Additive); + Clonk0305->SetName("Horax"); + Clonk0305.MaxEnergy = 200000; + Clonk0305->DoEnergy(150); + S2AI->AddAI(Clonk0305); + S2AI->SetHome(Clonk0305, 1568, 413, DIR_Left); + S2AI->SetGuardRange(Clonk0305, 1268, 263, 600, 300); + S2AI->SetEncounterCB(Clonk0305, "EncounterKing"); + var Clonk0312 = CreateObject(Clonk, 1070, 575); + Clonk0312->SetColor(0xff); + Clonk0312->SetName("Hans"); + S2AI->AddAI(Clonk0312); + S2AI->SetHome(Clonk0312, 1069, 566, DIR_Left); + S2AI->SetGuardRange(Clonk0312, 769, 416, 600, 300); + var Clonk0320 = CreateObject(Clonk, 1019, 471); + Clonk0320->SetColor(0xff); + Clonk0320->SetName("Joki"); + S2AI->AddAI(Clonk0320); + S2AI->SetGuardRange(Clonk0320, 719, 312, 600, 300); + var Clonk0328 = CreateObject(Clonk, 285, 1182); + Clonk0328->Kill(Clonk0328, true); + Clonk0328->SetColor(0xffff0000); + var Clonk0334 = CreateObject(Clonk, 208, 1183); + Clonk0334->Kill(Clonk0334, true); + Clonk0334->SetDir(DIR_Right); + Clonk0334->SetColor(0xffff0000); + + CreateObject(Rock, 879, 1003); + CreateObject(Rock, 262, 1182); + CreateObject(Rock, 140, 1183); + CreateObject(Rock, 48, 1151); + CreateObject(Rock, 154, 1206); + CreateObject(Rock, 154, 1206); + CreateObject(Rock, 241, 1287); + CreateObject(Rock, 338, 1257); + CreateObject(Rock, 661, 1393); + CreateObject(Rock, 813, 887); + CreateObject(Rock, 893, 1291); + CreateObject(Rock, 1248, 1088); + CreateObject(Rock, 1334, 1012); + CreateObject(Rock, 1268, 933); + CreateObject(Rock, 1296, 795); + CreateObject(Rock, 1501, 933); + CreateObject(Rock, 1473, 676); + CreateObject(Rock, 1367, 655); + CreateObject(Rock, 1505, 1163); + CreateObject(Rock, 1482, 1050); + CreateObject(Rock, 1402, 1448); + CreateObject(Rock, 1025, 1393); + CreateObject(Rock, 742, 1522); + CreateObject(Rock, 712, 1351); + CreateObject(Rock, 1047, 1207); + Clonk0250->CreateContents(Rock); + Clonk0250->CreateContents(Rock); + Clonk0250->CreateContents(Rock); + + CreateObject(Coal, 59, 1346); + CreateObject(Coal, 156, 1370); + CreateObject(Coal, 243, 1555); + CreateObject(Coal, 61, 1495); + CreateObject(Coal, 140, 1380); + SteamEngine0115->CreateContents(Coal); + SteamEngine0115->CreateContents(Coal); + SteamEngine0115->CreateContents(Coal); + + CreateObject(Ore, 227, 1366); + CreateObject(Ore, 64, 1421); + CreateObject(Ore, 264, 1454); + CreateObject(Ore, 462, 1479); + CreateObject(Ore, 77, 1486); + CreateObject(Ore, 1481, 1449); + CreateObject(Ore, 1438, 1464); + CreateObject(Ore, 1566, 1562); + + CreateObject(Nugget, 1079, 1217); + CreateObject(Nugget, 1244, 1139); + CreateObject(Nugget, 1156, 1164); + CreateObject(Nugget, 1127, 1166); + + CreateObject(Wood, 19, 1135); + CreateObject(Wood, 749, 1056); + CreateObject(Wood, 168, 1512); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Lorry0203->CreateContents(Wood); + Chest0103->CreateContents(Wood); + Chest0103->CreateContents(Wood); + Chest0103->CreateContents(Wood); + Chest0103->CreateContents(Wood); + Chest0103->CreateContents(Wood); + CreateObject(Wood, 346, 1456); + CreateObject(Wood, 336, 1456); + Lorry0205->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Chest0100->CreateContents(Wood); + Lorry0205->CreateContents(Wood); + Lorry0205->CreateContents(Wood); + Lorry0205->CreateContents(Wood); + Lorry0205->CreateContents(Wood); + Chest0104->CreateContents(Wood); + Chest0104->CreateContents(Wood); + Chest0104->CreateContents(Wood); + Chest0104->CreateContents(Wood); + Chest0104->CreateContents(Wood); + CreateObject(Wood, 167, 1512); + CreateObject(Wood, 177, 1512); + CreateObject(Wood, 511, 1497); + + Lorry0203->CreateContents(Loam); + CreateObject(Loam, 199, 1287); + CreateObject(Loam, 283, 1431); + CreateObject(Loam, 372, 1391); + CreateObject(Loam, 415, 1431); + CreateObject(Loam, 484, 1487); + CreateObject(Loam, 511, 1502); + CreateObject(Loam, 37, 1274); + CreateObject(Loam, 200, 1583); + CreateObject(Loam, 356, 1559); + CreateObject(Loam, 314, 1231); + CreateObject(Loam, 921, 1287); + CreateObject(Loam, 1042, 1392); + CreateObject(Loam, 1180, 1578); + CreateObject(Loam, 1481, 1415); + CreateObject(Loam, 1527, 1406); + CreateObject(Loam, 958, 983); + CreateObject(Loam, 1267, 896); + CreateObject(Loam, 892, 828); + CreateObject(Loam, 1393, 644); + CreateObject(Loam, 1462, 1079); + CreateObject(Loam, 1501, 1415); + Chest0103->CreateContents(Loam); + Chest0103->CreateContents(Loam); + Chest0103->CreateContents(Loam); + Chest0105->CreateContents(Loam); + Chest0105->CreateContents(Loam); + Chest0105->CreateContents(Loam); + Chest0105->CreateContents(Loam); + Chest0105->CreateContents(Loam); + + var GoldBar0478 = CreateObject(GoldBar, 1293, 1236); + GoldBar0478->SetR(22); + GoldBar0478->SetPosition(1293, 1235); + Lorry0205->CreateContents(GoldBar); + Lorry0205->CreateContents(GoldBar); + + Clonk0211->CreateContents(Sword); + Clonk0258->CreateContents(Sword); + Clonk0234->CreateContents(Sword); + Clonk0242->CreateContents(Sword); + Clonk0312->CreateContents(Sword); + Clonk0289->CreateContents(Sword); + Clonk0305->CreateContents(Sword); + Clonk0219->CreateContents(Sword); + + var Arrow0489 = Clonk0211->CreateContents(Arrow); + Arrow0489->SetR(90); + var Arrow0490 = Clonk0211->CreateContents(Arrow); + Arrow0490->SetR(90); + var Arrow0491 = Chest0102->CreateContents(Arrow); + Arrow0491->SetR(90); + var Arrow0492 = Clonk0226->CreateContents(Arrow); + Arrow0492->SetR(90); + var Arrow0493 = Clonk0226->CreateContents(Arrow); + Arrow0493->SetR(90); + var Arrow0494 = Clonk0320->CreateContents(Arrow); + Arrow0494->SetR(90); + var Arrow0495 = Clonk0320->CreateContents(Arrow); + Arrow0495->SetR(90); + var Arrow0496 = Clonk0305->CreateContents(Arrow); + Arrow0496->SetR(90); + var Arrow0497 = Clonk0305->CreateContents(Arrow); + Arrow0497->SetR(90); + + Clonk0211->CreateContents(Bow); + Chest0102->CreateContents(Bow); + Clonk0226->CreateContents(Bow); + Clonk0320->CreateContents(Bow); + Clonk0305->CreateContents(Bow); + + var Boompack0503 = CreateObject(Boompack, 135, 1324); + Boompack0503->SetColor(0xff); + + Lorry0203->CreateContents(DynamiteBox); + Lorry0205->CreateContents(DynamiteBox); + Chest0100->CreateContents(DynamiteBox); + Chest0100->CreateContents(DynamiteBox); + Chest0105->CreateContents(DynamiteBox); + + CreateObject(Dynamite, 1334, 1224); + + Lorry0205->CreateContents(Pickaxe); + Clonk0250->CreateContents(Pickaxe); + Clonk0258->CreateContents(Pickaxe); + + Lorry0203->CreateContents(Shovel); + + var Barrel0514 = CreateObject(Barrel, 167, 1333); + Barrel0514->SetR(-13); + Barrel0514->SetPosition(167, 1327); + + var Seaweed0516 = CreateObject(Seaweed, 169, 1543); + Seaweed0516->SetPhase(49); + var Seaweed0519 = CreateObject(Seaweed, 815, 1342); + Seaweed0519->SetPhase(49); + var Seaweed0522 = CreateObject(Seaweed, 719, 1078); + Seaweed0522->SetPhase(68); + var Seaweed0525 = CreateObject(Seaweed, 772, 1087); + Seaweed0525->SetPhase(8); + var Seaweed0528 = CreateObject(Seaweed, 1258, 1279); + Seaweed0528->SetPhase(75); + var Seaweed0628 = CreateObject(Seaweed, 847, 1366); + Seaweed0628->SetCon(1); + + CreateObject(Mushroom, 126, 1320); + CreateObject(Mushroom, 212, 1287); + CreateObject(Mushroom, 367, 1392); + CreateObject(Mushroom, 268, 1431); + + Chest0101->CreateContents(Musket); + + Chest0101->CreateContents(LeadShot); + Chest0101->CreateContents(LeadShot); + Chest0101->CreateContents(LeadShot); + + Clonk0281->CreateContents(Javelin); + Clonk0273->CreateContents(Javelin); + Clonk0281->CreateContents(Javelin); + Clonk0273->CreateContents(Javelin); + Clonk0281->CreateContents(Javelin); + Clonk0273->CreateContents(Javelin); + + Clonk0312->CreateContents(Shield); + Clonk0289->CreateContents(Shield); + Clonk0305->CreateContents(Shield); + + Chest0104->CreateContents(Bread); + Chest0104->CreateContents(Bread); + Chest0104->CreateContents(Bread); + Chest0105->CreateContents(Bread); + Chest0105->CreateContents(Bread); + Chest0105->CreateContents(Bread); + + CreateObject(EnvPack_ManaAltar, 1052, 471); + + Catapult0202->CreateContents(Firestone); + Catapult0202->CreateContents(Firestone); + Catapult0202->CreateContents(Firestone); + Catapult0202->CreateContents(Firestone); + Catapult0202->CreateContents(Firestone); + CreateObject(Firestone, 38, 1190); + CreateObject(Firestone, 101, 1215); + CreateObject(Firestone, 369, 1282); + CreateObject(Firestone, 22, 1254); + CreateObject(Firestone, 376, 1217); + CreateObject(Firestone, 139, 1347); + CreateObject(Firestone, 280, 1464); + CreateObject(Firestone, 451, 1439); + CreateObject(Firestone, 678, 1365); + CreateObject(Firestone, 838, 1101); + CreateObject(Firestone, 880, 1090); + CreateObject(Firestone, 1022, 1226); + CreateObject(Firestone, 1338, 1262); + CreateObject(Firestone, 1144, 1408); + CreateObject(Firestone, 1051, 1366); + CreateObject(Firestone, 1328, 1487); + CreateObject(Firestone, 1467, 1461); + CreateObject(Firestone, 911, 981); + CreateObject(Firestone, 1118, 766); + CreateObject(Firestone, 948, 788); + CreateObject(Firestone, 781, 911); + CreateObject(Firestone, 1356, 806); + CreateObject(Firestone, 1287, 852); + Clonk0250->CreateContents(Firestone); + Clonk0250->CreateContents(Firestone); + Clonk0258->CreateContents(Firestone); + Chest0103->CreateContents(Firestone); + Chest0103->CreateContents(Firestone); + Chest0103->CreateContents(Firestone); + Clonk0297->CreateContents(Firestone); + Clonk0297->CreateContents(Firestone); + Clonk0297->CreateContents(Firestone); + Clonk0297->CreateContents(Firestone); + Chest0104->CreateContents(Firestone); + Chest0104->CreateContents(Firestone); + Chest0104->CreateContents(Firestone); + Clonk0305->CreateContents(Firestone); + Clonk0305->CreateContents(Firestone); + Clonk0305->CreateContents(Firestone); + + return true; +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/DefCore.txt new file mode 100644 index 000000000..b20f0c2da --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=Ruin1 +Version=5,2,0,1 +Category=C4D_Structure +Width=94 +Height=43 +Offset=-47,-23 +Vertices=7 +VertexX=-26,26,-22,23,-38,-38,40 +VertexY=-7,-6,19,19,4,19,19 +VertexFriction=50,50,100,100 +Value=20 +Mass=1000 +Components=Wood=5;Rock=4 +Rotate=1 diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/Graphics.3.png b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/Graphics.3.png new file mode 100644 index 000000000..172b5bdff Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/Graphics.3.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/Script.c new file mode 100644 index 000000000..5b1f4c508 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/Script.c @@ -0,0 +1,6 @@ +/*-- Ruin --*/ + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/StringTblDE.txt new file mode 100644 index 000000000..293fcaa2a --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ruine +Description=Relikt vergangener Siedlungen. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/StringTblUS.txt new file mode 100644 index 000000000..a402dc94c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin1.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Ruin +Description=Relic of past settlements. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/DefCore.txt new file mode 100644 index 000000000..c7ceb6bd5 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Ruin2 +Version=5,2,0,1 +Category=C4D_Structure +Width=80 +Height=96 +Offset=-40,-48 +Vertices=5 +VertexX=0,25,15,-15,-25 +VertexY=-10,-20,47,47,-20 +VertexFriction=50,50,100,100,50 +Value=5 +Mass=100 +Components=Rock=6;Wood=2; diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/Graphics.3.png b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/Graphics.3.png new file mode 100644 index 000000000..f77b8dfb8 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/Graphics.3.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/Script.c new file mode 100644 index 000000000..5b1f4c508 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/Script.c @@ -0,0 +1,6 @@ +/*-- Ruin --*/ + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/StringTblDE.txt new file mode 100644 index 000000000..293fcaa2a --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ruine +Description=Relikt vergangener Siedlungen. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/StringTblUS.txt new file mode 100644 index 000000000..a402dc94c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin2.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Ruin +Description=Relic of past settlements. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/DefCore.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/DefCore.txt new file mode 100644 index 000000000..b9bbbc898 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Ruin3 +Version=5,2,90,21 +Category=C4D_Structure +Width=50 +Height=52 +Offset=-25,-26 +Vertices=6 +VertexX=-1,10,20,-23,-23,0 +VertexY=-17,-25,-14,25,25,25 +VertexFriction=50,50,50,100,100,100 +Value=20 +Mass=500 +Components=Wood=3;Metal=3 diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/Graphics.3.png b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/Graphics.3.png new file mode 100644 index 000000000..932ae5825 Binary files /dev/null and b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/Graphics.3.png differ diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/Script.c new file mode 100644 index 000000000..5b1f4c508 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/Script.c @@ -0,0 +1,6 @@ +/*-- Ruin --*/ + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/StringTblDE.txt new file mode 100644 index 000000000..293fcaa2a --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ruine +Description=Relikt vergangener Siedlungen. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/StringTblUS.txt new file mode 100644 index 000000000..a402dc94c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Ruin3.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Ruin +Description=Relic of past settlements. \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt b/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt new file mode 100644 index 000000000..37d39f69a --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Scenario.txt @@ -0,0 +1,33 @@ +[Head] +Icon=36 +Title=DarkCastle +Version=5,3,90 +Difficulty=75 +NoInitialize=true + +[Game] +Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1; + +[Player1] +Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1; + +[Player2] +Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1; + +[Player3] +Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1; + +[Player4] +Knowledge=ToolsWorkshop=1;Foundry=1;Flagpole=1;Elevator=1;Armory=1;ChemicalLab=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1;Bucket=1;Sword=1;Metal=1;GoldBar=1;Balloon=1;Boompack=1;GrappleBow=1;JarOfWinds=1;Pipe=1;Pump=1;PowderKeg=1;Ropeladder=1;Bow=1;Arrow=1;Club=1;IronBomb=1;Javelin=1;Shield=1; + +[Landscape] +Sky=Clouds2 +MapWidth=200,0,64,10000 +MapHeight=200,0,40,10000 +NoScan=true +FlatChunkShapes=0 + +[Weather] +Climate=0,10,0,100 +YearSpeed=0,0,0,100 +Wind=0,100,-100,100 diff --git a/planet/Missions.ocf/DarkCastle.ocs/Script.c b/planet/Missions.ocf/DarkCastle.ocs/Script.c new file mode 100644 index 000000000..99b91d151 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Script.c @@ -0,0 +1,136 @@ +/** + Evil Castle + Desc + + @authors Sven2 +*/ + +static const S2DD_InitialRelaunchs = 0; + +static g_is_initialized; + +func DoInit(int first_player) +{ + // Goal + var goal = CreateObject(Goal_Assassination); + if (goal) goal->SetVictim(Object(3816)); + // Elevators + // Top + Object(332)->SetNoPowerNeed(true); + Object(331)->CreateShaft(470); + // Left + Object(420)->CreateShaft(100); + // Shrooms + Object(2318)->AddPoisonEffect(0,0); // floor left + Object(2369)->AddPoisonEffect(0,0); // ceiling left + Object(2375)->AddPoisonEffect(-20,0); // floor right + Object(2398)->AddPoisonEffect(10,-10); // ceiling right + // Message when first player enters shroom area + ScheduleCall(nil, Scenario.ShroomCaveCheck, 21, 0xffffff); + // Scorching village + Object(343)->AddScorch(-20,-10, -45, 50, 1500); + Object(344)->AddScorch(-15,42, 90, 50, 1200); + Object(346)->AddScorch(-12,18, 130, 80, 1300); + // Rules + CreateObject(Rule_TeamAccount); + CreateObject(Rule_NoPowerNeed); + // Horax + Object(3816).JumpSpeed = 200; + // Update AI stuff + var fx; + for (var enemy in FindObjects(Find_ID(Clonk), Find_Owner(NO_OWNER))) + if (fx = S2AI->GetAI(enemy)) + { + fx.weapon = fx.target = nil; + S2AI->BindInventory(enemy); + enemy->DoEnergy(10000); + enemy->AddEnergyBar(); + } + // Intro. Message 250 frames + regular message time + Dialogue->MessageBoxAll("$MsgIntro1$", Object(2648), true); + Schedule(nil, "Dialogue->MessageBoxAll(\"$MsgIntro1$\", Object(2648))", 250, 1); + return true; +} + +func InitializePlayer(int plr) +{ + // Players only + if (GetPlayerType(plr)!=C4PT_User) return; + // Scenario init + if (!g_is_initialized) g_is_initialized = DoInit(plr); + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,400,250,flag); + SetPlayerViewLock(plr, true); + // Initial join + JoinPlayer(plr); + return true; +} + +func RelaunchPlayer(int plr) +{ + var clonk = CreateObject(Clonk, 50, 1000, plr); + clonk->MakeCrewMember(plr); + SetCursor(plr, clonk); + JoinPlayer(plr); + return true; +} + +func JoinPlayer(int plr) +{ + // Place in village + var crew; + for(var index = 0; crew = GetCrew(plr, index); ++index) + { + var x = 35 + Random(10); + var y = 1140; + crew->SetPosition(x , y); + crew->SetDir(DIR_Right); + crew->DoEnergy(1000); + // First crew member gets shovel and hammer. Try to get those items from the corpse if they still exist + // so we don't end up with dozens of useless shovels + if (!index) + { + for (var equip_id in [Shovel, Hammer]) + { + var obj = FindObject(Find_ID(equip_id), Find_Owner(plr)); + if (obj) obj->Enter(crew); else crew->CreateContents(equip_id); + } + } + } + return true; +} + + +/* Enemy encounter messages */ + +func EncounterCave(object enemy, object player) +{ + Dialogue->MessageBoxAll("$MsgEncounterCave$", enemy); + return true; +} + +func EncounterOutpost(object enemy, object player) +{ + Dialogue->MessageBoxAll("$MsgEncounterOutpost$", enemy); + return true; +} + +func EncounterKing(object enemy, object player) +{ + if (!player) player = enemy; // Leads to a funny message, but better than a null pointer. + Dialogue->MessageBoxAll(Format("$MsgEncounterKing$", player->GetName()), enemy); + return true; +} + + +/* Mushroom cave encounter */ + +func ShroomCaveCheck() +{ + var intruder = FindObject(Find_InRect(1252,1342,320,138), Find_OCF(OCF_CrewMember)); + if (!intruder) return true; + Dialogue->MessageBoxAll("$MsgEncounterShrooms$", intruder); + ClearScheduleCall(nil, Scenario.ShroomCaveCheck); + return true; +} \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt b/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt new file mode 100644 index 000000000..9db70e28b --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/StringTblDE.txt @@ -0,0 +1,5 @@ +MsgIntro1=Hilfe! King Horax hat unser Dorf zerstoert und wir sind alle zu feige, ihn anzugreifen. Koennt Ihr ihm Einhalt gebieten? +MsgEncounterCave=Ein Eindringling klaut unser Gold! Schnappt ihn! +MsgEncounterOutpost=Halt, im Namen des Koenigs! +MsgEncounterKing=Ah, %s. Ich habe Euch bereits erwartet. +MsgEncounterShrooms=Was ist denn das fuer ein Gestank? Von diesen Pflanzen sollten wir uns besser fern halten... diff --git a/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt b/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt new file mode 100644 index 000000000..8118f3193 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/StringTblUS.txt @@ -0,0 +1,5 @@ +MsgIntro1=Help! Tyrant Horax has destroyed our village, drank all our beer and taken our women. We are too chicken to face him ourselves; can you please stop him? +MsgEncounterCave=An intruder tries to steal out gold. Catch him! +MsgEncounterOutpost=Stop, in the name of the king! +MsgEncounterKing=Ah, %s. I have been awaiting you. +MsgEncounterShrooms=What is this smell? We better stay away from those plants... \ No newline at end of file diff --git a/planet/Missions.ocf/DarkCastle.ocs/System.ocg/Scorches.c b/planet/Missions.ocf/DarkCastle.ocs/System.ocg/Scorches.c new file mode 100644 index 000000000..1ec448f9d --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/System.ocg/Scorches.c @@ -0,0 +1,24 @@ +global func AddScorch(int x, int y, int r, int strength, int duration) +{ + var scorch = CreateObject(Wood, x,y, NO_OWNER); + if (!scorch) return nil; + scorch->SetObjectLayer(scorch); + scorch->SetR(r); + scorch->SetClrModulation(0x80804000); + scorch->SetCategory(C4D_StaticBack); + scorch.Collectible = false; // SetObjectLayer is not enough... + scorch.Plane = this.Plane+1; + var fx = AddEffect("FireScorching", scorch, 1, 2, scorch); + fx.strength = strength; + fx.duration = duration; + return scorch; +} + +global func FxFireScorchingTimer(object target, proplist effect, int time) +{ + if (time >= effect.duration) { RemoveObject(); return FX_Execute_Kill; } + // particles + var wind = BoundBy(GetWind(), -5, 5); + CreateParticle("SmokeDirty", PV_Random(-5, 5), PV_Random(-5, 5), wind, -effect.strength/8, PV_Random(20, 40), Particles_SmokeTrail(), 2); + return FX_OK; +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/System.ocg/ShroomPoison.c b/planet/Missions.ocf/DarkCastle.ocs/System.ocg/ShroomPoison.c new file mode 100644 index 000000000..94766ce87 --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/System.ocg/ShroomPoison.c @@ -0,0 +1,106 @@ +/* Poison trigger on cave mushroom */ +// Adds a timer that checks for passing Clonks and sprays poison at them + +#appendto LargeCaveMushroom + +static const ShroomPoison_SprayOffY = -20, + ShroomPoison_SearchWdt = 30, + ShroomPoison_SearchHgt = 50, + ShroomPoison_SearchOffY = 8; + +func AddPoisonEffect(int off_x, int off_y) +{ + // off_x and off_y is the offset of the cap of the unrotated mushroom from its regular position at GetX()/GetY()-20 + // set this to match offset caused by animation + var fx = AddEffect("SearchPoisonTarget", this, 1, 12, this); + if (fx) + { + fx.off_x = off_x; + fx.off_y = off_y; + } + return fx; +} + +func FxSearchPoisonTargetTimer(object target, proplist fx) +{ + // Currently on cooldown? + if (fx.cooldown) if (--fx.cooldown) return FX_OK; + // Find target to spray poison at + var victim = FindObject(Find_AtRect(XY2TX(fx.off_x,fx.off_y+ShroomPoison_SearchOffY)-ShroomPoison_SearchWdt/2,XY2TY(fx.off_x,fx.off_y+ShroomPoison_SearchOffY)-ShroomPoison_SearchHgt/2,ShroomPoison_SearchWdt,ShroomPoison_SearchHgt), Find_OCF(OCF_Alive), Find_Layer(GetObjectLayer())); + if (!victim) return FX_OK; + // Target found. Spray! + var src_x = GetX()+XY2TX(fx.off_x,fx.off_y); + var src_y = GetY()+XY2TY(fx.off_x,fx.off_y+ShroomPoison_SprayOffY); + var tx=victim->GetX()-src_x, ty=victim->GetY()-src_y; + var d=Max(Distance(tx,ty),1); + var vx=tx*30/d, vy=ty*30/d-15; + for (var i=0; i<5; ++i) + LargeCaveMushroomPoison->LaunchPoison(src_x+Random(11)-5,src_y+Random(11)-5,vx+Random(11)-5,vy+Random(11)-5, GetOwner()); + Sound("PoisonLaunch"); + // Don't spray again for a few seconds + fx.cooldown=10; + return FX_OK; +} + +// apply rotation and scale to x/y coordinates +func XY2TX(int x, int y) { var r=GetR(); return (Cos(r,x)-Sin(r,y))*GetCon()/100; } +func XY2TY(int x, int y) { var r=GetR(); return (Sin(r,x)+Cos(r,y))*GetCon()/100; } + + +/* Debug display */ + +func DbgShowSprayRange(fx) +{ + if (fx.dbg_rect) DbgHideSprayRange(fx); + // Debug function to show search and spray range + var x1=ShroomPoison_SearchWdt/-2+XY2TX(fx.off_x,fx.off_y+ShroomPoison_SearchOffY)+GetX(), y1=ShroomPoison_SearchHgt/-2+XY2TY(fx.off_x,fx.off_y+ShroomPoison_SearchOffY)+GetY(); + var x2=x1+ShroomPoison_SearchWdt, y2=y1+ShroomPoison_SearchHgt; + fx.dbg_rect = DrawRect(x1,y1,x2,y2,0xff00ff00); + fx.dbg_pos = CreateObject(Rock); + if (fx.dbg_pos) + { + fx.dbg_pos->SetPosition(GetX()+XY2TX(fx.off_x,fx.off_y),GetY()+XY2TY(fx.off_x,fx.off_y+ShroomPoison_SprayOffY)); + fx.dbg_pos->SetCategory(1); + } + return true; +} + +func DrawRect(int x1,int y1,int x2,int y2,int clr) +{ + var r = {}; + r.t=DebugLine->Create(x1,y1,x2,y1,clr); + r.r=DebugLine->Create(x2,y1,x2,y2,clr); + r.b=DebugLine->Create(x2,y2,x1,y2,clr); + r.l=DebugLine->Create(x1,y2,x1,y1,clr); + return r; +} + +func ClearRect(r) +{ + if (r.t) r.t->RemoveObject(); + if (r.r) r.r->RemoveObject(); + if (r.b) r.b->RemoveObject(); + if (r.l) r.l->RemoveObject(); + return true; +} + +func DbgHideSprayRange(fx) +{ + if (fx.dbg_rect) { ClearRect(fx.dbg_rect); fx.dbg_rect = nil; } + if (fx.dbg_pos) { fx.dbg_pos->RemoveObject(); fx.dbg_pos = nil; } + return true; +} + +func EditCursorSelection() +{ + var fx = GetEffect("SearchPoisonTarget", this); + if (fx) DbgShowSprayRange(fx); + return _inherited(...); +} + +func EditCursorDeselection() +{ + var fx = GetEffect("SearchPoisonTarget", this); + if (fx) DbgHideSprayRange(fx); + return _inherited(...); +} diff --git a/planet/Missions.ocf/DarkCastle.ocs/Teams.txt b/planet/Missions.ocf/DarkCastle.ocs/Teams.txt new file mode 100644 index 000000000..e0f02c84a --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Teams.txt @@ -0,0 +1,4 @@ +[Teams] +Active=false +Custom=false +AutoGenerateTeams=true diff --git a/planet/Missions.ocf/DarkCastle.ocs/Title.txt b/planet/Missions.ocf/DarkCastle.ocs/Title.txt new file mode 100644 index 000000000..0b1468e7c --- /dev/null +++ b/planet/Missions.ocf/DarkCastle.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Finsterschloss +US:Dark castle \ No newline at end of file diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/DescDE.rtf b/planet/Missions.ocf/DeadlyGrotto.ocs/DescDE.rtf new file mode 100644 index 000000000..aba4fb32e Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/DescUS.rtf b/planet/Missions.ocf/DeadlyGrotto.ocs/DescUS.rtf new file mode 100644 index 000000000..b395c9873 Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/Icon.png b/planet/Missions.ocf/DeadlyGrotto.ocs/Icon.png new file mode 100644 index 000000000..25f97136f Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/Icon.png differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/Landscape.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/Landscape.txt new file mode 100644 index 000000000..a49f924fb --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/Landscape.txt @@ -0,0 +1,111 @@ +/* Deadly grotto - by Sven2 */ + +overlay VaryTex { turbulence=10; algo=rndchecker; zoomX=-100; zoomY=-100; }; +overlay GraniteBorders {turbulence=100; mat=Granite; loosebounds=1; VaryTex {mat=Rock; tex=rock_cracked; a=1;};}; +overlay AcidVein { turbulence=100; algo=rndchecker; zoomX=-100; zoomY=100; a=5; y=-100; hgt=300; loosebounds=1; mat=Acid; }; + +map AcidCave { + // Base background is earth + mat=Earth; tex=earth_rough; + VaryTex { mat=Earth; tex=earth_dry; }; + VaryTex { mat=Earth; tex=earth; }; + + // Resources + VaryTex { mat=Rock; y=50px; zoomX=30; a=3;}; + VaryTex { mat=Granite; y=80px; zoomX=30; a=5;}; + VaryTex { mat=Coal; a=7; wdt=140px; }; + VaryTex { mat=Ore; a=8; }; + VaryTex { mat=Firestone; a=8; y=50px; }; + VaryTex { mat=Gold; hgt=30px; a=10; }; + + // Top caves for mushrooms + overlay { wdt=90px; hgt=40px; mask=1; + overlay { algo=rndchecker; x=5px; hgt=40px; mat=Tunnel; a=3;zoomX=20;zoomY=-20; turbulence=100; loosebounds=1; }; + }; + + // Granite borders + GraniteBorders { y=-20px; hgt=24px; }; + GraniteBorders { x=296px; }; + GraniteBorders { y=96px; }; + GraniteBorders { x=-20px; wdt=24px; }; + + // Acid veins + AcidVein { x=100px; }; + AcidVein { x=100px; rotate=-15; }; + AcidVein { x=100px; rotate=15; }; + + // Veins interrupted by some rock + overlay { x=100px; turbulence=10; loosebounds=1; mask=1; algo=rndchecker; a=1; zoomX=10; + VaryTex { mat=Rock; tex=rock_cracked; zoomX=-100; }; + VaryTex { mat=Granite; zoomX=-100; }; + }; + + // End cave + overlay { algo=poly; mat=DuroLava; turbulence=10; + point { x=250px; y=70px; }; + point { x=260px; y=40px; }; + point { x=280px; y=35px; }; + point { x=295px; y=45px; }; + point { x=290px; y=55px; }; + point { x=295px; y=80px; }; + point { x=275px; y=90px; }; + point { x=265px; y=90px; }; + + GraniteBorders { algo=border; a=1; b=1; }; + GraniteBorders { algo=border; a=1; b=1; turbulence=0;}; + }; + // End cave head pos + overlay { algo=poly; mat=Tunnel; turbulence=10; + point { x=265px; y=70px; }; + point { x=270px; y=60px; }; + point { x=280px; y=60px; }; + point { x=285px; y=70px; }; + point { x=275px; y=80px; }; + + overlay { y=72px; mat=Water; }; + + GraniteBorders { algo=border; a=1; b=1; }; + GraniteBorders { algo=border; a=1; b=1; turbulence=0;}; + + overlay { x=274px; wdt=2px; y=69px; hgt=2px; mat=Tunnel; }; + }; + + // Starting cave + overlay { algo=poly; mat=Tunnel; turbulence=10; + point { x=-100px; y=70px; }; + point { x=0px; y=70px; }; + point { x=0px; y=70px; }; + point { x=18px; y=85px; }; + point { x=65px; y=85px; }; + point { x=70px; y=75px; }; + point { x=80px; y=70px; }; + point { x=90px; y=80px; }; + point { x=80px; y=195px; }; + point { x=-100px; y=195px; }; + + // ensure border on right side + overlay { algo=border; a=1; b=1; x=82px; mat=Rock; tex=rock_cracked; }; + + // sky back + VaryTex { a=2; wdt=80px; }; + // windmill positions + overlay { x=70px; wdt=15px; y=80px; turbulence=10; loosebounds=1;}; + + // water at entrance + overlay { y=95px; mat=Water; }; + + // starting platform + overlay { x=70px; wdt=15px; y=92px; hgt=1px; mat=Brick; }; + overlay { y=93px; mat=Granite; algo=poly; + point { x=80px; y=-20px; }; + point { x=70px; y=0px; }; + point { x=60px; y=10px; }; + point { x=95px; y=10px; }; + point { x=85px; y=0px; }; + }; + + // rock at entrance + VaryTex { y=93px; mat=Rock; VaryTex { mat=Granite; }; }; + }; + +}; diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/DefCore.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/DefCore.txt new file mode 100644 index 000000000..f10f1edf6 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/DefCore.txt @@ -0,0 +1,16 @@ +[DefCore] +id=MinersStatue +Version=5,2,0,1 +Category=C4D_Structure +Width=46 +Height=80 +Offset=-23,-40 +Vertices=2 +VertexX=-5,12 +VertexY=32,32 +VertexFriction=100,100 +Value=200 +Mass=300 +Components=Rock=10;Metal=5; +Rotate=0 + diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Graphics.10.png b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Graphics.10.png new file mode 100644 index 000000000..a2ad27c14 Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Graphics.10.png differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/GraphicsBroken.10.png b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/GraphicsBroken.10.png new file mode 100644 index 000000000..563d7ab4c Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/GraphicsBroken.10.png differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/DefCore.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/DefCore.txt new file mode 100644 index 000000000..1ebfe895a --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=MinersStatue_Head +Version=5,2,0,1 +Category=C4D_Vehicle +Width=17 +Height=21 +Offset=-8,-10 +Vertices=7 +VertexX=-6,-4,0,6,8,2,-2 +VertexY=0,-7,-8,-8,0,8,6 +VertexFriction=50,50,50,50,50,50,50 +Value=50 +Mass=150 +Components=Rock=3;Metal=1; +Rotate=1 diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/Graphics.10.png b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/Graphics.10.png new file mode 100644 index 000000000..90defb8ee Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/Graphics.10.png differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/Script.c b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/Script.c new file mode 100644 index 000000000..3244ed833 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/Script.c @@ -0,0 +1,22 @@ +/*-- + Miner's statue part: Head + Author: Sven2 + + Missing part of the statue +--*/ + +protected func Hit(x, y) +{ + StonyObjectHit(x,y); + return true; +} + +public func Definition(proplist def) +{ +} + +local Collectible = false; +local Name = "$Name$"; +local Description = "$Description$"; +local Touchable = 1; + diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/StringTblDE.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/StringTblDE.txt new file mode 100644 index 000000000..43504fce5 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Statuenkopf +Description=Ein wichtiger Teil der Statue. \ No newline at end of file diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/StringTblUS.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/StringTblUS.txt new file mode 100644 index 000000000..005fad0e2 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Head.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Statue head +Description=An important part of the statue. \ No newline at end of file diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Script.c b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Script.c new file mode 100644 index 000000000..94955a398 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/Script.c @@ -0,0 +1,53 @@ +/*-- + Miner's statue + Author: Sven2 + + Impressive piece of rock carving. +--*/ + +local is_broken; + +protected func Hit(x, y) +{ + StonyObjectHit(x,y); + return true; +} + +func SetBroken() +{ + SetGraphics("Broken"); + is_broken = true; + ScheduleCall(this, MinersStatue.Check4Head, 20, 99999999); + return true; +} + +func SetIntact() +{ + SetGraphics(); + is_broken = false; + ClearScheduleCall(this, MinersStatue.Check4Head); + return true; +} + +func Check4Head() +{ + var head; + if (head = FindObject(Find_InRect(-23,-40,46,80), Find_ID(MinersStatue_Head))) + { + SetIntact(); + head->RemoveObject(); + } + return true; +} + +func IsBroken() { return is_broken; } + +public func Definition(proplist def) +{ +} + +local Collectible = false; +local Name = "$Name$"; +local Description = "$Description$"; +local Touchable = 0; +local Plane = 220; \ No newline at end of file diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/StringTblDE.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/StringTblDE.txt new file mode 100644 index 000000000..794d474fd --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Statue +Description=Denkmal zu Ehren von Clunkus, dem berühmten Höhlenforscher. \ No newline at end of file diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/StringTblUS.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/StringTblUS.txt new file mode 100644 index 000000000..7189316ad --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/MinersStatue.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Statue +Description=Memorial in honor of Clunkus, the famour cave explorer. \ No newline at end of file diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/DefCore.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/DefCore.txt new file mode 100644 index 000000000..6328a2eef --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_RepairStatue +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/Graphics.png b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/Graphics.png new file mode 100644 index 000000000..9885dc044 Binary files /dev/null and b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/Script.c b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/Script.c new file mode 100644 index 000000000..0de243d2c --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/Script.c @@ -0,0 +1,59 @@ +/*-- + Repair statue + Author: Sven2 + + Player must repair the statue +--*/ + + +#include Library_Goal + +local statue; + +public func SetStatue(object to_statue) +{ + statue = to_statue; + return true; +} + + +/*-- Goal interface --*/ + +// The goal is fulfilled if a statue has been assigned and it's repaired. +public func IsFulfilled() +{ + return statue && !statue->IsBroken(); +} + +// Shows or hides a message window with information. +public func Activate(int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + var message; + if (IsFulfilled()) + { + message = "@$MsgGoalFulfilled$"; + } + else + { + message = "@$MsgGoalUnfulfilled$"; + } + CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + +//public func GetShortDescription(int plr) { return ""; } + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/StringTblDE.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/StringTblDE.txt new file mode 100644 index 000000000..a0ad35242 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +Name=Statue reparieren + +#Goal window +MsgGoalFulfilled=Glückwunsch; die Statue erstrahlt wieder in vollem Glanz! +MsgGoalUnfulfilled=Bringe das fehlende Teil zurück zur Statue! diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/StringTblUS.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/StringTblUS.txt new file mode 100644 index 000000000..137e11255 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/RepairStatue.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +Name=Repair statue + +#Goal window +MsgGoalFulfilled=Congratulations, the statue is shining in its full glory again! +MsgGoalUnfulfilled=Find the missing statue part and return it to the statue. diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/Scenario.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/Scenario.txt new file mode 100644 index 000000000..fee9c8b86 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/Scenario.txt @@ -0,0 +1,52 @@ +[Head] +Title=DeadlyGrotto +Icon=24 +Version=5,2,0,1 +Difficulty=50 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_RepairStatue=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player2] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player3] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player4] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Landscape] +Sky=Clouds1 +SkyScrollMode=1 +TopOpen=0 +BottomOpen=0 +MapWidth=300 +MapHeight=100 +MapZoom=8 + +[Weather] +Climate=00,0,0,00 +StartSeason=0,0,0,00 +YearSpeed=0,0,0,000 +Wind=100,0,100,100 + diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/Script.c b/planet/Missions.ocf/DeadlyGrotto.ocs/Script.c new file mode 100644 index 000000000..54078f454 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/Script.c @@ -0,0 +1,87 @@ +/* Deadly grotto */ + +func Initialize() +{ + // Goal + var goal = FindObject(Find_ID(Goal_RepairStatue)); + if (!goal) goal = CreateObject(Goal_RepairStatue); + var statue = CreateObject(MinersStatue, 600,736); + statue->SetBroken(); + var statue_head = CreateObject(MinersStatue_Head, 2200,560); + goal->SetStatue(statue); + // Rules + if (!ObjectCount(Find_ID(Rule_TeamAccount))) CreateObject(Rule_TeamAccount); + if (!ObjectCount(Find_ID(Rule_BuyAtFlagpole))) CreateObject(Rule_BuyAtFlagpole); + // Mushrooms before any earth materials, because they create their own caves + LargeCaveMushroom->Place(15, Rectangle(100,0,600,300)); + // Create earth materials + // Create them in big clusters so the whole object arrangement looks a bit less uniform and more interesting + PlaceBatches([Firestone], 5, 100, 10); + PlaceBatches([Rock, Loam, Loam], 10, 200, 10); + // Misc vegetation + SproutBerryBush->Place(5, Rectangle(100,0,600,300)); + Mushroom->Place(5, Rectangle(100,0,600,300)); + return true; +} + +static g_was_player_init; + +func InitializePlayer(int plr) +{ + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,500,350,flag); + SetPlayerViewLock(plr, true); + // First player init base + if (!g_was_player_init) + { + InitBase(plr); + g_was_player_init = true; + } + // Position and materials + var i, crew; + for (i=0; crew=GetCrew(plr,i); ++i) + { + crew->SetPosition(600+Random(40), 736-10); + crew->CreateContents(Shovel); + } + return true; +} + +private func InitBase(int owner) +{ + // Create standard base owned by player + var y=736; + var flag = CreateObject(Flagpole, 670,y, owner); + var lorry = CreateObject(Lorry, 650,y-2, owner); + if (lorry) + { + lorry->CreateContents(Loam, 6); + lorry->CreateContents(Wood, 15); + lorry->CreateContents(Metal, 4); + lorry->CreateContents(WallKit, 2); + lorry->CreateContents(Axe, 1); + lorry->CreateContents(Pickaxe, 1); + lorry->CreateContents(Hammer, 1); + lorry->CreateContents(DynamiteBox, 2); + lorry->CreateContents(Dynamite, 5); + } + return true; +} + +private func PlaceBatches(array item_ids, int n_per_batch, int batch_radius, int n_batches) +{ + // place a number (n_batches) of batches of objects of types item_ids. Each batch has n_per_batch objects. + // fewer batches and/or objects may be placed if no space is found + var loc,loc2,n_item_ids=GetLength(item_ids), n_created=0, obj; + for (var i=0; iSetPosition(loc2.x,loc2.y); + ++n_created; + } + return n_created; +} diff --git a/planet/Missions.ocf/DeadlyGrotto.ocs/Title.txt b/planet/Missions.ocf/DeadlyGrotto.ocs/Title.txt new file mode 100644 index 000000000..3709110f9 --- /dev/null +++ b/planet/Missions.ocf/DeadlyGrotto.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Tödliche Grotte +US:Deadly Grotto \ No newline at end of file diff --git a/planet/Missions.ocf/DescDE.rtf b/planet/Missions.ocf/DescDE.rtf new file mode 100644 index 000000000..56657c2e7 --- /dev/null +++ b/planet/Missions.ocf/DescDE.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset1 Times New Roman;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\froman\fprq0\fcharset0 Times New Roman;}{\f6\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f7\fnil\fprq2\fcharset0 Mangal;}{\f8\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ltrpar\cf0\kerning1\dbch\af9\langfe2052\dbch\af7\afs24\alang1081\loch\f0\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af6\dbch\af7\afs28\loch\f2\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af8 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab709 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ltrpar\cf0\kerning1\dbch\af9\langfe2052\dbch\af7\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 +Missionen} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ltrpar\cf0\kerning1\dbch\af9\langfe2052\dbch\af7\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ltrpar\cf0\kerning1\dbch\af9\langfe2052\dbch\af7\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\b0\kerning1\rtlch \ltrch\loch\fs16\lang1043\loch\f5 +This scenario folder contains settlement rounds where players need to perform challenging tasks. Often you need to find ingenious solutions or engineer technical constructions to solve the problems posed.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/DescUS.rtf b/planet/Missions.ocf/DescUS.rtf new file mode 100644 index 000000000..bf02577ef --- /dev/null +++ b/planet/Missions.ocf/DescUS.rtf @@ -0,0 +1,21 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset1 Times New Roman;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Mangal;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af5\dbch\af6\afs28\loch\f2\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af7 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af7\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af7 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 +Missions} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{{\*\bkmkstart __DdeLink__2_1874761316}\b0\kerning1\rtlch \ltrch\loch\fs16\lang1043\loch\f4{\*\bkmkend __DdeLink__2_1874761316} +This scenario folder contains settlement rounds where players need to perform challenging tasks. Often you need to find ingenious solutions or engineer technical constructions to solve the problems posed.} +\par } \ No newline at end of file diff --git a/planet/Missions.ocf/Folder.txt b/planet/Missions.ocf/Folder.txt new file mode 100644 index 000000000..b7c83d05b --- /dev/null +++ b/planet/Missions.ocf/Folder.txt @@ -0,0 +1,2 @@ +[Head] +Index=3 \ No newline at end of file diff --git a/planet/Missions.ocf/FrostySummit.ocs/DescDE.rtf b/planet/Missions.ocf/FrostySummit.ocs/DescDE.rtf new file mode 100644 index 000000000..11894c9f4 Binary files /dev/null and b/planet/Missions.ocf/FrostySummit.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/FrostySummit.ocs/DescUS.rtf b/planet/Missions.ocf/FrostySummit.ocs/DescUS.rtf new file mode 100644 index 000000000..5244480f4 Binary files /dev/null and b/planet/Missions.ocf/FrostySummit.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/FrostySummit.ocs/Map.c b/planet/Missions.ocf/FrostySummit.ocs/Map.c new file mode 100644 index 000000000..e52a3cc6c --- /dev/null +++ b/planet/Missions.ocf/FrostySummit.ocs/Map.c @@ -0,0 +1,38 @@ +#include Library_Map + +func InitializeMap(map) +{ + // Mountain top + var mountain_shape = { Algo=MAPALGO_Polygon, X=[-100,0,10,30,50,46,46,-100], Y=[80,80,70,90,90,100,200,200] }; + DrawVaried("Ice-ice2", { Algo=MAPALGO_Turbulence, Op={Algo=MAPALGO_Offset, OffY=-5, Op=mountain_shape}, Amplitude=[10, 0], Scale=20}, nil, "Ice-ice3"); + Draw("Snow", {Algo=MAPALGO_Border, Op=Duplicate(), Top=1}); + DrawVaried("Rock", { Algo=MAPALGO_Turbulence, Op=mountain_shape, Amplitude=[20, 0], Scale=10}, nil, "Earth-earth_topSoil"); + + // Sky islands + var sky_islands = CreateLayer(); + var n_islands = 10, x, y; + for (var i=0; i=n_islands/2) wdt=2+Random(wdt); + sky_islands->DrawVaried("Granite", {Algo=MAPALGO_Turbulence, Op={Algo=MAPALGO_Ellipsis, X=x, Y=y, Wdt=wdt, Hgt=hgt}, Amplitude=10, Scale=5}, nil, "Rock"); + } + + // Final ruby island + x = 230+Random(15); y = 15; + sky_islands->Draw("Granite", {Algo=MAPALGO_Ellipsis, X=x, Y=y, Wdt=5, Hgt=2}); + sky_islands->Draw("Ruby", {Algo=MAPALGO_Ellipsis, X=x, Y=y+3, Wdt=3, Hgt=2}); + sky_islands->Draw("Brick", nil, [x-3,y+2,7,1]); + + // Blit islands+snow + Blit(sky_islands); + Draw("Snow", {Algo=MAPALGO_Border, Op=sky_islands, Top=-1}); + + // Starting platform + DrawPlatform("Brick", 34,90,20,10,10); + Draw("Snow", nil, [34,89,5,1]); + + return true; +} \ No newline at end of file diff --git a/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/Ruby.jpg b/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/Ruby.jpg new file mode 100644 index 000000000..c84122ce9 Binary files /dev/null and b/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/Ruby.jpg differ diff --git a/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/Ruby.ocm b/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/Ruby.ocm new file mode 100644 index 000000000..c7a631d97 --- /dev/null +++ b/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/Ruby.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Ruby +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Ruby +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Ruby diff --git a/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/TEXMAP.TXT b/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..208b2c6ee --- /dev/null +++ b/planet/Missions.ocf/FrostySummit.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,46 @@ +OverloadMaterials +OverloadTextures + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore + +40=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +60=Ruby-Ruby + +65=Ice-ice2 +67=Ice-ice3 + +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/Missions.ocf/FrostySummit.ocs/Scenario.txt b/planet/Missions.ocf/FrostySummit.ocs/Scenario.txt new file mode 100644 index 000000000..7914f74b3 --- /dev/null +++ b/planet/Missions.ocf/FrostySummit.ocs/Scenario.txt @@ -0,0 +1,41 @@ +[Head] +Title=FrostySummit +Icon=24 +Version=5,2,0,1 +Difficulty=60 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_SellGems=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Crew=Clonk=1 + +[Player2] +Crew=Clonk=1 + +[Player3] +Crew=Clonk=1 + +[Player4] +Crew=Clonk=1 + +[Landscape] +Sky=Clouds1 +SkyScrollMode=1 +TopOpen=1 +BottomOpen=1 +MapWidth=250 +MapHeight=100 +MapZoom=8 +NoScan=1 + +[Weather] +Climate=100,0,0,0 +StartSeason=100,0,0,0 +YearSpeed=0,0,0,000 +Wind=100,0,100,100 + diff --git a/planet/Missions.ocf/FrostySummit.ocs/Script.c b/planet/Missions.ocf/FrostySummit.ocs/Script.c new file mode 100644 index 000000000..1fd12fbc3 --- /dev/null +++ b/planet/Missions.ocf/FrostySummit.ocs/Script.c @@ -0,0 +1,72 @@ +/* Frosty summit */ + +func Initialize() +{ + // Goal + var goal = FindObject(Find_ID(Goal_SellGems)); + if (!goal) goal = CreateObject(Goal_SellGems); + goal->SetTargetAmount(1); + // Rules + if (!ObjectCount(Find_ID(Rule_TeamAccount))) CreateObject(Rule_TeamAccount); + // Environment + var loc; + for (var i=0; i<5; ++i) + if (loc = FindLocation(Loc_InRect(0,80*8,40*8,20*8), Loc_Material("Earth"))) + CreateObject(Rock, loc.x, loc.y+3); +} + +static g_was_player_init; + +func InitializePlayer(int plr) +{ + // First player init base + if (!g_was_player_init) + { + InitBase(plr); + g_was_player_init = true; + } + // Position and materials + JoinPlayer(plr); + return true; +} + +private func InitBase(int owner) +{ + // Create standard base owned by player + var y=90*8, x=40*8; + var flag = CreateObject(Flagpole, x+85,y, owner); + var hut = CreateObject(ToolsWorkshop, x+45,y, owner); + if (hut) + { + hut->CreateContents(Shovel, 1); + hut->CreateContents(Loam, 1); + } + for (var i=0; i<3; ++i) CreateObject(Boompack, x+20+i*5+Random(4),y, owner); + return true; +} + +func RelaunchPlayer(int plr) +{ + var clonk = CreateObject(Clonk, 50, 1000, plr); + clonk->MakeCrewMember(plr); + SetCursor(plr, clonk); + JoinPlayer(plr); + return true; +} + +func JoinPlayer(int plr) +{ + var i, crew; + for (i=0; crew=GetCrew(plr,i); ++i) + { + crew->SetPosition(40*8+Random(40), 90*8-10); + if (!i) + { + crew->CreateContents(GrappleBow, 2); + crew->CreateContents(WindBag); + crew->CreateContents(TeleGlove); + crew->CreateContents(Dynamite, 2); + } + } + return true; +} diff --git a/planet/Missions.ocf/FrostySummit.ocs/Title.txt b/planet/Missions.ocf/FrostySummit.ocs/Title.txt new file mode 100644 index 000000000..29ac6bfea --- /dev/null +++ b/planet/Missions.ocf/FrostySummit.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Frostiger Gipfel +US:Frosty Summit \ No newline at end of file diff --git a/planet/Missions.ocf/GoldenMountain.ocs/DescDE.rtf b/planet/Missions.ocf/GoldenMountain.ocs/DescDE.rtf new file mode 100644 index 000000000..247d45fb2 Binary files /dev/null and b/planet/Missions.ocf/GoldenMountain.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/GoldenMountain.ocs/DescUS.rtf b/planet/Missions.ocf/GoldenMountain.ocs/DescUS.rtf new file mode 100644 index 000000000..a06606ef3 Binary files /dev/null and b/planet/Missions.ocf/GoldenMountain.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Map.bmp b/planet/Missions.ocf/GoldenMountain.ocs/Map.bmp new file mode 100644 index 000000000..5e33c351e Binary files /dev/null and b/planet/Missions.ocf/GoldenMountain.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Amethyst.jpg b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Amethyst.jpg new file mode 100644 index 000000000..36c0dd8a0 Binary files /dev/null and b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Amethyst.jpg differ diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Amethyst.ocm b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Amethyst.ocm new file mode 100644 index 000000000..0d64a3831 --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Amethyst.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Amethyst +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Amethyst +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Amethyst diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Ruby.jpg b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Ruby.jpg new file mode 100644 index 000000000..c84122ce9 Binary files /dev/null and b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Ruby.jpg differ diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Ruby.ocm b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Ruby.ocm new file mode 100644 index 000000000..c7a631d97 --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/Ruby.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Ruby +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Ruby +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Ruby diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/TEXMAP.TXT b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..880820dff --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,47 @@ +OverloadMaterials +OverloadTextures + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore + +40=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +60=Ruby-Ruby +61=Amethyst-Amethyst + +65=Ice-ice2 +67=Ice-ice3 + +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Objects.c b/planet/Missions.ocf/GoldenMountain.ocs/Objects.c new file mode 100644 index 000000000..6b23ca798 --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Objects.c @@ -0,0 +1,123 @@ +/* Automatically created objects file */ + +func InitializeObjects() +{ + CreateObject(Grass, 443, 199); + CreateObject(Grass, 468, 197); + CreateObject(Grass, 441, 202); + + CreateObject(Tree_Coniferous, 452, 200); + CreateObject(Tree_Coniferous, 391, 200); + CreateObject(Tree_Coniferous, 336, 202); + CreateObject(Tree_Coniferous, 427, 199); + CreateObject(Tree_Coniferous, 367, 201); + + CreateObject(SproutBerryBush, 59, 214); + + CreateObject(Trunk, 301, 202); + + var Rank0029 = CreateObject(Rank, 41, 169); + Rank0029->SetR(18); + Rank0029->SetPosition(41, 166); + var Rank0030 = CreateObject(Rank, 322, 201); + Rank0030->SetR(6); + Rank0030->SetPosition(322, 198); + + CreateObject(SproutBerryBush, 350, 206); + + CreateObject(Rule_TeamAccount, 50, 50); + + CreateObject(Rule_BuyAtFlagpole, 50, 50); + + var Goal_SellGems0037 = CreateObject(Goal_SellGems, 50, 50); + Goal_SellGems0037->SetTargetAmount(30); + + CreateObject(Rule_BuyAtFlagpole, 50, 50); + + var Goal_SellGems0136 = CreateObject(Goal_SellGems, 50, 50); + Goal_SellGems0136->SetTargetAmount(30); + + var Chest0039 = CreateObject(Chest, 200, 469); + var Chest0040 = CreateObject(Chest, 1192, 701); + var Chest0041 = CreateObject(Chest, 1807, 515); + var Chest0042 = CreateObject(Chest, 2360, 484); + + CreateObject(Rock, 335, 362); + CreateObject(Rock, 283, 376); + CreateObject(Rock, 464, 226); + CreateObject(Rock, 31, 103); + CreateObject(Rock, 481, 239); + + Chest0039->CreateContents(Wood); + Chest0039->CreateContents(Wood); + Chest0039->CreateContents(Wood); + Chest0039->CreateContents(Wood); + Chest0039->CreateContents(Wood); + + Chest0042->CreateContents(Loam); + Chest0042->CreateContents(Loam); + Chest0041->CreateContents(Loam); + Chest0041->CreateContents(Loam); + Chest0040->CreateContents(Loam); + Chest0040->CreateContents(Loam); + Chest0039->CreateContents(Loam); + + Chest0039->CreateContents(Dynamite); + Chest0039->CreateContents(Dynamite); + + Chest0040->CreateContents(DynamiteBox); + Chest0042->CreateContents(DynamiteBox); + Chest0042->CreateContents(DynamiteBox); + + Chest0040->CreateContents(Bucket); + Chest0041->CreateContents(Bucket); + Chest0042->CreateContents(Bucket); + + Chest0041->CreateContents(WallKit); + Chest0041->CreateContents(WallKit); + Chest0042->CreateContents(WallKit); + + var Barrel0071 = CreateObject(Barrel, 34, 206); + Barrel0071->SetR(-86); + Barrel0071->SetPosition(34, 203); + + var Seaweed0073 = CreateObject(Seaweed, 53, 503); + Seaweed0073->SetPhase(15); + var Seaweed0076 = CreateObject(Seaweed, 123, 495); + Seaweed0076->SetPhase(38); + + CreateObject(Mushroom, 74, 201); + CreateObject(Mushroom, 14, 199); + CreateObject(Mushroom, 351, 201); + CreateObject(Mushroom, 388, 199); + CreateObject(Mushroom, 419, 199); + CreateObject(Mushroom, 400, 199); + CreateObject(Mushroom, 291, 199); + CreateObject(Mushroom, 376, 198); + + Chest0039->CreateContents(Bread); + Chest0039->CreateContents(Bread); + Chest0040->CreateContents(Bread); + Chest0040->CreateContents(Bread); + Chest0041->CreateContents(Bread); + Chest0041->CreateContents(Bread); + Chest0042->CreateContents(Bread); + Chest0042->CreateContents(Bread); + + CreateObject(Firestone, 51, 85); + CreateObject(Firestone, 168, 146); + CreateObject(Firestone, 17, 261); + CreateObject(Firestone, 394, 253); + CreateObject(Firestone, 278, 240); + CreateObject(Firestone, 143, 439); + CreateObject(Firestone, 618, 225); + CreateObject(Firestone, 653, 231); + CreateObject(Firestone, 500, 245); + CreateObject(Firestone, 633, 236); + CreateObject(Firestone, 32, 277); + CreateObject(Firestone, 32, 266); + CreateObject(Firestone, 17, 238); + CreateObject(Firestone, 153, 149); + CreateObject(Firestone, 585, 241); + return true; +} diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Scenario.txt b/planet/Missions.ocf/GoldenMountain.ocs/Scenario.txt new file mode 100644 index 000000000..9a94043b7 --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Scenario.txt @@ -0,0 +1,54 @@ +[Head] +Title=GoldenMountain +Icon=24 +Version=5,2,0,1 +Difficulty=110 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_SellGems=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; +ValueOverloads=Ruby=5;Amethyst=5; + +[Player1] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;InventorsLab=1;Elevator=1;ToolsWorkshop=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Dynamite=1;Hammer=1;JarOfWinds=1;Shovel=1;TeleGlove=1;GrappleBow=1;Ropeladder=1;Catapult=1;Pickaxe=1;DynamiteBox=1; +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; + +[Player2] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;InventorsLab=1;Elevator=1;ToolsWorkshop=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Dynamite=1;Hammer=1;JarOfWinds=1;Shovel=1;TeleGlove=1;GrappleBow=1;Ropeladder=1;Catapult=1;Pickaxe=1;DynamiteBox=1; +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; + +[Player3] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;InventorsLab=1;Elevator=1;ToolsWorkshop=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Dynamite=1;Hammer=1;JarOfWinds=1;Shovel=1;TeleGlove=1;GrappleBow=1;Ropeladder=1;Catapult=1;Pickaxe=1;DynamiteBox=1; +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; + +[Player4] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;InventorsLab=1;Elevator=1;ToolsWorkshop=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Dynamite=1;Hammer=1;JarOfWinds=1;Shovel=1;TeleGlove=1;GrappleBow=1;Ropeladder=1;Catapult=1;Pickaxe=1;DynamiteBox=1; +HomeBaseMaterial=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; +HomeBaseProduction=Clonk=50;Bread=50;Wood=50;Metal=50;DynamiteBox=50;Dynamite=50; + +[Landscape] +Sky=Clouds1 +SkyScrollMode=1 +TopOpen=0 +BottomOpen=0 +MapWidth=300 +MapHeight=100 +MapZoom=8 +FlatChunkShapes=0 + +[Weather] +Climate=00,0,0,00 +StartSeason=0,0,0,00 +YearSpeed=0,0,0,000 +Wind=100,0,100,100 + diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Script.c b/planet/Missions.ocf/GoldenMountain.ocs/Script.c new file mode 100644 index 000000000..0d95f204e --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Script.c @@ -0,0 +1,69 @@ +/* Golden mountain */ + +func Initialize() +{ + // Goal + var goal = FindObject(Find_ID(Goal_SellGems)); + if (!goal) goal = CreateObject(Goal_SellGems); + goal->SetTargetAmount(30); + // Rules + if (!ObjectCount(Find_ID(Rule_TeamAccount))) CreateObject(Rule_TeamAccount); + if (!ObjectCount(Find_ID(Rule_BuyAtFlagpole))) CreateObject(Rule_BuyAtFlagpole); + return true; +} + +static g_was_player_init; + +func InitializePlayer(int plr) +{ + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,500,350,flag); + SetPlayerViewLock(plr, true); + // First player init base + if (!g_was_player_init) + { + InitBase(plr); + g_was_player_init = true; + } + // Position and materials + var i, crew; + for (i=0; crew=GetCrew(plr,i); ++i) + { + crew->SetPosition(500+Random(100), 200-10); + crew->CreateContents(Shovel); + } + return true; +} + +private func InitBase(int owner) +{ + // Create standard base owned by player + var y=200; + var flag = CreateObject(Flagpole, 590,y, owner); + var windgen = CreateObject(WindGenerator, 500,y, owner); + var chemlab = CreateObject(ChemicalLab, 560,y, owner); + var invlab = CreateObject(InventorsLab, 660,y, owner); + if (invlab) + { + invlab->SetClrModulation(0xff804000); + } + var toolsw = CreateObject(ToolsWorkshop, 620,y, owner); + if (toolsw) + { + toolsw->CreateContents(Wood, 5); + toolsw->CreateContents(Metal, 2); + } + var lorry = CreateObject(Lorry, 690,y-2, owner); + if (lorry) + { + //lorry->CreateContents(GrappleBow, GetStartupPlayerCount()); + //lorry->CreateContents(WindBag, 2); + //lorry->CreateContents(TeleGlove, 1); + lorry->CreateContents(Axe, 1); + lorry->CreateContents(Hammer, 1); + lorry->CreateContents(DynamiteBox, 1); + lorry->CreateContents(Dynamite, 2); + } + return true; +} diff --git a/planet/Missions.ocf/GoldenMountain.ocs/System.ocg/GrappleBow.c b/planet/Missions.ocf/GoldenMountain.ocs/System.ocg/GrappleBow.c new file mode 100644 index 000000000..0322aedfe --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/System.ocg/GrappleBow.c @@ -0,0 +1,5 @@ +// Verbrannte Boegen buggen... +#appendto GrappleBow + +local BlastIncinerate = 0; +local ContactIncinerate = 0; diff --git a/planet/Missions.ocf/GoldenMountain.ocs/Title.txt b/planet/Missions.ocf/GoldenMountain.ocs/Title.txt new file mode 100644 index 000000000..7e0ec00dc --- /dev/null +++ b/planet/Missions.ocf/GoldenMountain.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Goldener Berg +US:Golden Mountain \ No newline at end of file diff --git a/planet/Missions.ocf/MineRescue.ocs/DescUS.rtf b/planet/Missions.ocf/MineRescue.ocs/DescUS.rtf new file mode 100644 index 000000000..9898298d5 Binary files /dev/null and b/planet/Missions.ocf/MineRescue.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/DefCore.txt b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/DefCore.txt new file mode 100644 index 000000000..e28af4860 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_ElevatorEnergy +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/Graphics.png b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/Graphics.png new file mode 100644 index 000000000..e0a28755e Binary files /dev/null and b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/Script.c b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/Script.c new file mode 100644 index 000000000..056ec5602 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/Script.c @@ -0,0 +1,63 @@ +/** + Energy supply + A given object has to be supplied with energy. + + @author ck +*/ + +#include Library_Goal + +local target; + +protected func Initialize() +{ + target = 0; + return inherited(...); +} + +// Set the target object to be supplied with energy +public func SetTarget(object target_) +{ + target = target_; +} + +// The goal is fulfilled if the target has been supplied with energy. +public func IsFulfilled() +{ + //return target->CurrentlyHasPower(); + return target->IsPowerAvailable(target->GetNeededPower()); +} + +// Shows or hides a message window with information. +public func Activate(int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + var message; + if (IsFulfilled()) + message = "@$MsgGoalFulfilled$"; + else + message = "@$MsgGoalUnFulfilled$"; + + CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + +public func GetShortDescription(int plr) +{ + return ""; +} + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/StringTblDE.txt b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/StringTblDE.txt new file mode 100644 index 000000000..24c5a2732 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +Name=Energieversorgung + +#Goal window +MsgGoalFulfilled=Der Fahrstuhl ist in Betrieb. +MsgGoalUnFulfilled=Du hast den Fahrstuhl noch nicht mit Energie versorgt. diff --git a/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/StringTblUS.txt b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/StringTblUS.txt new file mode 100644 index 000000000..9dad331a9 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/ElevatorEnergy.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +Name=Energy Supply + +#Goal window +MsgGoalFulfilled=The elevator is operating. +MsgGoalUnFulfilled=The elevator is not yet supplied with energy. diff --git a/planet/Missions.ocf/MineRescue.ocs/Icon.png b/planet/Missions.ocf/MineRescue.ocs/Icon.png new file mode 100644 index 000000000..055018652 Binary files /dev/null and b/planet/Missions.ocf/MineRescue.ocs/Icon.png differ diff --git a/planet/Missions.ocf/MineRescue.ocs/Map.bmp b/planet/Missions.ocf/MineRescue.ocs/Map.bmp new file mode 100644 index 000000000..879565d93 Binary files /dev/null and b/planet/Missions.ocf/MineRescue.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/MineRescue.ocs/Material.ocg b/planet/Missions.ocf/MineRescue.ocs/Material.ocg new file mode 100644 index 000000000..caca1813a Binary files /dev/null and b/planet/Missions.ocf/MineRescue.ocs/Material.ocg differ diff --git a/planet/Missions.ocf/MineRescue.ocs/Objects.c b/planet/Missions.ocf/MineRescue.ocs/Objects.c new file mode 100644 index 000000000..a1ed88c95 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/Objects.c @@ -0,0 +1,256 @@ +/* Automatically created objects file */ + +func InitializeObjects() +{ + var Grass0001 = CreateObject(Grass, 132, 142); + Grass0001->SetClrModulation(0xff0b1d05); + var Grass0002 = CreateObject(Grass, 142, 139); + Grass0002->SetClrModulation(0xff150b09); + var Grass0003 = CreateObject(Grass, 125, 146); + Grass0003->SetClrModulation(0xff06090a); + var Grass0004 = CreateObject(Grass, 119, 151); + Grass0004->SetClrModulation(0xff201308); + var Grass0005 = CreateObject(Grass, 205, 146); + Grass0005->SetClrModulation(0xff35020b); + var Grass0006 = CreateObject(Grass, 179, 143); + Grass0006->SetClrModulation(0xff3b0e05); + var Grass0007 = CreateObject(Grass, 172, 141); + Grass0007->SetClrModulation(0xff2e150e); + CreateObject(Grass, 1360, 397); + CreateObject(Grass, 1456, 325); + CreateObject(Grass, 1462, 325); + CreateObject(Grass, 1469, 325); + CreateObject(Grass, 1475, 326); + CreateObject(Grass, 1482, 326); + CreateObject(Grass, 1269, 316); + CreateObject(Grass, 1262, 315); + CreateObject(Grass, 1281, 310); + CreateObject(Grass, 1274, 312); + CreateObject(Grass, 1254, 317); + CreateObject(Grass, 1246, 315); + CreateObject(Grass, 1243, 317); + CreateObject(Grass, 32, 155); + CreateObject(Grass, 38, 155); + CreateObject(Grass, 27, 157); + CreateObject(Grass, 1591, 349); + CreateObject(Grass, 1598, 349); + CreateObject(Grass, 1605, 349); + CreateObject(Grass, 1612, 350); + CreateObject(Grass, 1620, 353); + CreateObject(Grass, 1725, 369); + + CreateObject(Tree_Coniferous, 359, 134); + + var Trunk0034 = CreateObject(Trunk, 149, 144); + Trunk0034->SetCon(70); + Trunk0034->SetR(10); + Trunk0034->SetClrModulation(0xff808080); + Trunk0034->SetPosition(149, 127); + var Trunk0035 = CreateObject(Trunk, 119, 161); + Trunk0035->SetCon(85); + Trunk0035->SetClrModulation(0xff806640); + + var Tree_Coniferous0036 = CreateObject(Tree_Coniferous, 21, 159); + Tree_Coniferous0036->SetCon(60); + var Tree_Coniferous0040 = CreateObject(Tree_Coniferous, 50, 158); + Tree_Coniferous0040->SetCon(80); + var Tree_Coniferous0044 = CreateObject(Tree_Coniferous, 553, 70); + Tree_Coniferous0044->SetCon(60); + Tree_Coniferous0044->SetR(-20); + Tree_Coniferous0044->SetPosition(553, 45); + var Tree_Coniferous0048 = CreateObject(Tree_Coniferous, 663, 52); + Tree_Coniferous0048->SetCon(80); + CreateObject(Tree_Coniferous, 682, 52); + CreateObject(Tree_Coniferous, 812, 57); + + CreateObject(Trunk, 778, 81); + + CreateObject(Tree_Coniferous, 547, 407); + CreateObject(Tree_Coniferous, 494, 403); + CreateObject(Tree_Coniferous, 416, 394); + + CreateObject(Trunk, 331, 364); + var Trunk0074 = CreateObject(Trunk, 379, 260); + Trunk0074->SetCon(70); + Trunk0074->SetR(180); + Trunk0074->SetPosition(379, 244); + var Trunk0075 = CreateObject(Trunk, 353, 288); + Trunk0075->SetCon(50); + Trunk0075->SetR(140); + Trunk0075->SetPosition(353, 280); + + var Rank0076 = CreateObject(Rank, 338, 290); + Rank0076->SetR(140); + Rank0076->SetPosition(338, 290); + var Rank0077 = CreateObject(Rank, 618, 122); + Rank0077->SetR(-140); + Rank0077->SetPosition(618, 122); + var Rank0078 = CreateObject(Rank, 585, 104); + Rank0078->SetR(-150); + Rank0078->SetPosition(585, 104); + + var Trunk0079 = CreateObject(Trunk, 643, 153); + Trunk0079->SetCon(60); + Trunk0079->SetR(-150); + Trunk0079->SetPosition(643, 141); + + CreateObject(SproutBerryBush, 458, 406); + + var LargeCaveMushroom0084 = CreateObject(LargeCaveMushroom, 11, 306); + LargeCaveMushroom0084->SetCon(60); + LargeCaveMushroom0084->SetClrModulation(0xffe0ece4); + + CreateObject(Tree_Coniferous, 300, 134); + + var LargeCaveMushroom0092 = CreateObject(LargeCaveMushroom, 114, 394); + LargeCaveMushroom0092->SetCon(40); + LargeCaveMushroom0092->SetClrModulation(0xffd1dedc); + var LargeCaveMushroom0096 = CreateObject(LargeCaveMushroom, 144, 513); + LargeCaveMushroom0096->SetCon(60); + LargeCaveMushroom0096->SetClrModulation(0xff788cc8); + var LargeCaveMushroom0100 = CreateObject(LargeCaveMushroom, 1220, 489); + LargeCaveMushroom0100->SetCon(50); + LargeCaveMushroom0100->SetClrModulation(0xffe5e6ec); + var LargeCaveMushroom0104 = CreateObject(LargeCaveMushroom, 176, 146); + LargeCaveMushroom0104->SetCon(80); + LargeCaveMushroom0104->SetClrModulation(0xff643c28); + + CreateObject(Tree_Coniferous, 1398, 324); + CreateObject(Tree_Coniferous, 1328, 316); + CreateObject(Tree_Coniferous, 1208, 311); + CreateObject(Tree_Coniferous, 1168, 320); + CreateObject(Tree_Coniferous, 1188, 317); + CreateObject(Tree_Coniferous, 1128, 323); + CreateObject(Tree_Coniferous, 1293, 314); + CreateObject(Tree_Coniferous, 1337, 317); + CreateObject(Tree_Coniferous, 1319, 312); + CreateObject(Tree_Coniferous, 1368, 322); + + CreateObject(SproutBerryBush, 1258, 323); + CreateObject(SproutBerryBush, 1579, 358); + + var Trunk0156 = CreateObject(Trunk, 1065, 369); + Trunk0156->SetR(-30); + Trunk0156->SetPosition(1065, 347); + CreateObject(Trunk, 1522, 338); + var Trunk0158 = CreateObject(Trunk, 1001, 520); + Trunk0158->SetR(-80); + Trunk0158->SetPosition(1001, 512); + var Trunk0159 = CreateObject(Trunk, 680, 519); + Trunk0159->SetR(65); + Trunk0159->SetPosition(680, 507); + + CreateObject(BigRock, 523, 405); + var BigRock0161 = CreateObject(BigRock, 711, 530); + BigRock0161->SetR(60); + BigRock0161->SetPosition(711, 527); + CreateObject(BigRock, 1025, 560); + CreateObject(BigRock, 338, 572); + + var Tree_Coniferous0164 = CreateObject(Tree_Coniferous, 261, 133); + Tree_Coniferous0164->SetCon(70); + var Tree_Coniferous0168 = CreateObject(Tree_Coniferous, 171, 197); + Tree_Coniferous0168->SetCon(1); + CreateObject(Tree_Coniferous, 1640, 367); + CreateObject(Tree_Coniferous, 1700, 374); + CreateObject(Tree_Coniferous, 1756, 370); + CreateObject(Tree_Coniferous, 1673, 375); + + CreateObject(Rule_TeamAccount, 50, 50); + + CreateObject(Rule_BuyAtFlagpole, 50, 50); + + CreateObject(Rule_BuyAtFlagpole, 50, 50); + + var Chest0224 = CreateObject(Chest, 534, 543); + var Chest0225 = CreateObject(Chest, 279, 585); + var Chest0226 = CreateObject(Chest, 1185, 447); + var Chest0227 = CreateObject(Chest, 1812, 549); + + var WindGenerator0190 = CreateObject(WindGenerator, 177, 144); + WindGenerator0190->SetCon(80); + WindGenerator0190->SetCategory(C4D_StaticBack); + WindGenerator0190->SetR(92); + WindGenerator0190->SetClrModulation(0xff503c28); + WindGenerator0190->SetPosition(177, 134); + WindGenerator0190->~Destruction(); // shouldn't have a power radius + + var Elevator0228 = CreateObject(Elevator, 69, 159); + Elevator0228->CreateShaft(5); + Elevator0228->SetCasePosition(152); + + var Clonk0236 = CreateObject(Clonk, 134, 396); + Clonk0236->SetColor(0xfff0783c); + Clonk0236->SetDir(DIR_Left); + var Clonk0242 = CreateObject(Clonk, 149, 387); + Clonk0242->SetColor(0xff78f03c); + Clonk0242->SetDir(DIR_Left); + var Clonk0248 = CreateObject(Clonk, 80, 367); + Clonk0248->SetDir(DIR_Right); + Clonk0248->SetColor(0xfff078f0); + var Clonk0254 = CreateObject(Clonk, 520, 553); + Clonk0254->Kill(Clonk0254, true); + Clonk0254->SetDir(DIR_Right); + Clonk0254->SetYDir(20); + Clonk0254->SetColor(0xff503217); + Clonk0254->DoEnergy(-50); + + Chest0225->CreateContents(Rock); + Chest0225->CreateContents(Rock); + Chest0226->CreateContents(Rock); + Chest0226->CreateContents(Rock); + + Chest0224->CreateContents(Coal); + Chest0224->CreateContents(Coal); + + Chest0224->CreateContents(Metal); + Chest0224->CreateContents(Metal); + Chest0226->CreateContents(Metal); + + Chest0225->CreateContents(Nugget); + Chest0226->CreateContents(Nugget); + Chest0226->CreateContents(Nugget); + + Chest0226->CreateContents(Wood); + Chest0226->CreateContents(Wood); + Chest0227->CreateContents(Wood); + Chest0227->CreateContents(Wood); + Chest0227->CreateContents(Wood); + + Chest0224->CreateContents(GoldBar); + + CreateObject(Mushroom, 790, 71); + CreateObject(Mushroom, 799, 67); + CreateObject(Mushroom, 672, 57); + CreateObject(Mushroom, 252, 134); + CreateObject(Mushroom, 137, 144); + CreateObject(Mushroom, 590, 419); + CreateObject(Mushroom, 623, 406); + CreateObject(Mushroom, 548, 542); + CreateObject(Mushroom, 84, 495); + CreateObject(Mushroom, 159, 508); + CreateObject(Mushroom, 223, 535); + CreateObject(Mushroom, 1115, 479); + CreateObject(Mushroom, 1079, 479); + CreateObject(Mushroom, 1049, 478); + CreateObject(Mushroom, 1115, 329); + CreateObject(Mushroom, 1206, 488); + Chest0225->CreateContents(Mushroom); + + Chest0225->CreateContents(Musket); + + Chest0225->CreateContents(LeadShot); + + Chest0224->CreateContents(Dynamite); + Chest0225->CreateContents(Dynamite); + Chest0226->CreateContents(Dynamite); + Chest0226->CreateContents(Dynamite); + Chest0227->CreateContents(Dynamite); + Chest0227->CreateContents(Dynamite); + + Chest0224->CreateContents(Firestone); + Chest0224->CreateContents(Firestone); + Chest0226->CreateContents(Firestone); + + return true; +} diff --git a/planet/Missions.ocf/MineRescue.ocs/Scenario.txt b/planet/Missions.ocf/MineRescue.ocs/Scenario.txt new file mode 100644 index 000000000..74458b6f4 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/Scenario.txt @@ -0,0 +1,50 @@ +[Head] +Icon=23 +Title=LostMine +Version=5,3,90 +Difficulty=55 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Position=193,42 +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;ToolsWorkshop=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;InventorsLab=1;Lorry=1;Cannon=1;Catapult=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1; +HomeBaseMaterial=Clonk=2;Bread=2; +HomeBaseProduction=Clonk=2;Bread=2; + +[Player2] +Position=193,42 +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;ToolsWorkshop=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;InventorsLab=1;Lorry=1;Cannon=1;Catapult=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1 +HomeBaseMaterial=Clonk=2;Bread=2; +HomeBaseProduction=Clonk=2;Bread=2; + +[Player3] +Position=193,42 +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;ToolsWorkshop=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;InventorsLab=1;Lorry=1;Cannon=1;Catapult=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1 +HomeBaseMaterial=Clonk=2;Bread=2; +HomeBaseProduction=Clonk=2;Bread=2; + +[Player4] +Position=193,42 +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;ToolsWorkshop=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;InventorsLab=1;Lorry=1;Cannon=1;Catapult=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1 +HomeBaseMaterial=Clonk=2;Bread=2; +HomeBaseProduction=Clonk=2;Bread=2; + +[Landscape] +BottomOpen=2 +MapWidth=200,0,64,10000 +MapHeight=75,0,40,10000 + +[Weather] +Climate=50,0,50,50 +StartSeason=25,0,25,25 +YearSpeed=0,0,0,0 +Wind=0,100,-100,100 diff --git a/planet/Missions.ocf/MineRescue.ocs/Script.c b/planet/Missions.ocf/MineRescue.ocs/Script.c new file mode 100644 index 000000000..2558d7ce8 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/Script.c @@ -0,0 +1,53 @@ +/** + LostMine + + @authors ck +*/ + +static g_is_initialized; + +func DoInit(int first_player) +{ + var goal = CreateObject(Goal_ElevatorEnergy); + var elevator = FindObject(Find_ID(Elevator)); + goal->SetTarget(elevator.case); + + elevator->CreateShaft(240); + elevator->SetOwner(first_player); + elevator.case->SetPosition(elevator.case->GetX(), elevator.case->GetY()+210); + // Create the start buildings: 2 x flag, windmill, armory, cabin + CreateObject(Flagpole, 193*8, 43*8, first_player); + CreateObject(Flagpole, 221*8, 46*8, first_player); + CreateObject(WoodenCabin, 228*8, 47*8, first_player); + CreateObject(Armory, 212*8, 47*8, first_player); + CreateObject(WindGenerator, 197*8, 44*8, first_player); + // Create start material: Hammer, shovel, axe + var clonk1 = GetCrew(first_player, 0); + var clonk2 = GetCrew(first_player, 1); + clonk1->CreateContents(Shovel); + clonk1->CreateContents(Hammer); + clonk2->CreateContents(Shovel); + clonk2->CreateContents(Axe); + + // Earth objects + for(var i = 0; i < 70; ++i) + { + var stuff = [Firestone, Firestone, Rock, Rock, Rock, Nugget]; + var location = FindLocation(Loc_Material("Earth"));//, Loc_Space(5, false), Loc_Space(5, true)); + if(location) + { + CreateObject(stuff[Random(GetLength(stuff))], location.x, location.y); + } + } + + return true; +} + +func InitializePlayer(int plr) +{ + // Players only + if (GetPlayerType(plr)!=C4PT_User) return; + // Scenario init + if (!g_is_initialized) g_is_initialized = DoInit(plr); + return true; +} diff --git a/planet/Missions.ocf/MineRescue.ocs/System.ocg/Flagpole.c b/planet/Missions.ocf/MineRescue.ocs/System.ocg/Flagpole.c new file mode 100644 index 000000000..526624fb7 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/System.ocg/Flagpole.c @@ -0,0 +1,6 @@ +/* Flagpole */ +// Changes default flag radius + +#appendto Flagpole + +public func GetFlagRadius(){ return 130; } diff --git a/planet/Tests.ocf/Lines.ocs/Teams.txt b/planet/Missions.ocf/MineRescue.ocs/Teams.txt similarity index 100% rename from planet/Tests.ocf/Lines.ocs/Teams.txt rename to planet/Missions.ocf/MineRescue.ocs/Teams.txt diff --git a/planet/Missions.ocf/MineRescue.ocs/Title.txt b/planet/Missions.ocf/MineRescue.ocs/Title.txt new file mode 100644 index 000000000..bd0b7d3a5 --- /dev/null +++ b/planet/Missions.ocf/MineRescue.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Minenrettung +US:Mine Rescue diff --git a/planet/Missions.ocf/MtBrame.ocs/DescDE.rtf b/planet/Missions.ocf/MtBrame.ocs/DescDE.rtf new file mode 100644 index 000000000..4d9615a25 Binary files /dev/null and b/planet/Missions.ocf/MtBrame.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/MtBrame.ocs/DescUS.rtf b/planet/Missions.ocf/MtBrame.ocs/DescUS.rtf new file mode 100644 index 000000000..3a0c61f3b Binary files /dev/null and b/planet/Missions.ocf/MtBrame.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/DefCore.txt b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/DefCore.txt new file mode 100644 index 000000000..8dcf67f50 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/DefCore.txt @@ -0,0 +1,9 @@ +[DefCore] +id=Dialogue +Version=5,2,0,1 +Category=C4D_StaticBack +Width=8 +Height=20 +Offset=-4,-10 + + diff --git a/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Graphics.png b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Graphics.png new file mode 100644 index 000000000..d8e8ac9c6 Binary files /dev/null and b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Portrait1.png b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Portrait1.png new file mode 100644 index 000000000..e41ee72a1 Binary files /dev/null and b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Portrait1.png differ diff --git a/planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/Script.c b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Script.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Crash.ocs/Dialogue.ocd/Script.c rename to planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/Script.c diff --git a/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/StringTblDE.txt b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/StringTblDE.txt new file mode 100644 index 000000000..70e9e33e5 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Dialogue +MsgSpeak=%s ansprechen \ No newline at end of file diff --git a/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/StringTblUS.txt b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/StringTblUS.txt new file mode 100644 index 000000000..d26bbc8a9 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Dialogue.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Dialogue +MsgSpeak=Speak to %s diff --git a/planet/Missions.ocf/MtBrame.ocs/Game.txt b/planet/Missions.ocf/MtBrame.ocs/Game.txt new file mode 100644 index 000000000..fa9645ea9 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Game.txt @@ -0,0 +1,4648 @@ +[Object] +id=Grass +Properties=199;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=143000 +Mass=1 +X=F51904512 +Y=F42926080 +Width=17 +Height=10 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=2359873 + +[Object] +id=Grass +Properties=200;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=139000 +Mass=1 +X=F42387380 +Y=F40142208 +Width=16 +Height=9 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=204;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=141000 +Mass=1 +X=F43011376 +Y=F40460364 +Width=16 +Height=9 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=250;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=121000 +Mass=1 +X=F11510442 +Y=F34871156 +Width=14 +Height=8 +Offset=-7,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 +Graphics=Grass::1 + +[Object] +id=Grass +Properties=254;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=100000 +Mass=1 +X=F5652737 +Y=F32840250 +Width=12 +Height=7 +Offset=-6,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=14942785 + +[Object] +id=Grass +Properties=255;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=148000 +Mass=1 +X=F10770523 +Y=F34620636 +Width=17 +Height=10 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=256;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=100000 +Mass=1 +X=F16258270 +Y=F37341436 +Width=12 +Height=7 +Offset=-6,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=2359873 +Graphics=Grass::1 + +[Object] +id=Grass +Properties=257;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=147000 +Mass=1 +X=F16628230 +Y=F37641984 +Width=17 +Height=10 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=2359873 + +[Object] +id=Grass +Properties=258;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=112000 +Mass=1 +X=F13545227 +Y=F35861592 +Width=13 +Height=7 +Offset=-6,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=259;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=132000 +Mass=1 +X=F15826650 +Y=F37148704 +Width=15 +Height=9 +Offset=-7,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=2359873 +Graphics=Grass::1 + +[Object] +id=Grass +Properties=260;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=104000 +Mass=1 +X=F14655108 +Y=F36478196 +Width=12 +Height=7 +Offset=-6,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=2359873 +Graphics=Grass::1 + +[Object] +id=Grass +Properties=261;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=149000 +Mass=1 +X=F11078823 +Y=F34867276 +Width=17 +Height=10 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=262;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=117000 +Mass=1 +X=F13051946 +Y=F35364440 +Width=14 +Height=8 +Offset=-7,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=14942785 + +[Object] +id=Grass +Properties=266;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=136000 +Mass=1 +X=F14100167 +Y=F35981040 +Width=16 +Height=9 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=2359873 + +[Object] +id=Grass +Properties=270;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=114000 +Mass=1 +X=F14531789 +Y=F36231556 +Width=13 +Height=7 +Offset=-6,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=274;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=121000 +Mass=1 +X=F658280 +Y=F32589730 +Width=14 +Height=8 +Offset=-7,-3 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Grass +Properties=278;false;"Prototype"=DGrass +Category=4097 +Plane=-500 +Size=141000 +Mass=1 +X=F164998 +Y=F32774710 +Width=16 +Height=9 +Offset=-8,-4 +Vertices=1 +VertexY=1 +Picture=0,0,0,0 +OCF=12845633 + +[Object] +id=Library_Power +Properties=41;false;"power_balance"=i50,"power_links"=E1,"neutral"=b1,"Prototype"=DLibrary_Power,"sleeping_links"=E2 +Category=1 +Plane=100 +Size=100000 +Mass=1 +Width=1 +Height=1 +Offset=-1,-1 +Picture=0,0,0,0 +OCF=12845121 + +[Object] +id=ElevatorRope +Properties=47;false;"Action"=E3,"Prototype"=DElevatorRope +Category=1 +Plane=100 +Size=100000 +Mass=1 +X=F31064064 +Y=F44302336 +Width=1 +Height=4 +Offset=0,-2 +Picture=0,0,0,0 +OCF=2359361 +ActionTime=65487 + +[Object] +id=Trunk +Properties=51;false;"Prototype"=DTrunk,"MeshTransformation"=E4 +Category=1 +Plane=100 +Size=100000 +Mass=40 +X=F73173264 +Y=F34136180 +Width=20 +Height=60 +Offset=-10,-30 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=52;false;"Prototype"=DTrunk,"MeshTransformation"=E5,"Action"=n +Category=1 +Plane=100 +Size=80000 +Mass=32 +X=F72078408 +Y=F34735944 +Width=16 +Height=48 +Offset=-8,-24 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=53;false;"Prototype"=DTrunk,"MeshTransformation"=E6,"Action"=n +Category=1 +Plane=100 +Size=65000 +Mass=26 +X=F89325872 +Y=F33963176 +Width=13 +Height=39 +Offset=-6,-19 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=54;false;"Prototype"=DTrunk,"MeshTransformation"=E7,"Action"=n +Category=1 +Plane=100 +Size=40000 +Mass=16 +X=F80994432 +Y=F35136616 +Width=8 +Height=24 +Offset=-4,-12 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=55;false;"Prototype"=DTrunk,"MeshTransformation"=E8 +Category=1 +Plane=100 +Size=100000 +Mass=40 +X=F64443624 +Y=F37240914 +Width=20 +Height=60 +Offset=-10,-30 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=56;false;"Prototype"=DTrunk,"MeshTransformation"=E9 +Category=1 +Plane=100 +Size=100000 +Mass=40 +X=F68832680 +Y=F35964668 +Width=20 +Height=60 +Offset=-10,-30 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=69;false;"Prototype"=DRank,"MeshTransformation"=E10 +Category=1 +Plane=100 +Rotation=220 +Size=100000 +Mass=1 +X=F72386796 +Y=F32964432 +R=F14417920 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexX=0,2 +VertexY=0,-2 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=12845761 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=71;false;"Prototype"=DRank,"MeshTransformation"=E11 +Category=1 +Plane=100 +Rotation=176 +Size=100000 +Mass=1 +X=F92720912 +Y=F18322996 +R=F11534336 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexY=0,-3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=262849 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=72;false;"Prototype"=DRank,"MeshTransformation"=E12 +Category=1 +Plane=100 +Rotation=195 +Size=100000 +Mass=1 +X=F98924680 +Y=F18963320 +R=F12779520 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexX=0,1 +VertexY=0,-3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=12845761 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=73;false;"Prototype"=DRank,"MeshTransformation"=E13 +Category=1 +Plane=100 +Rotation=201 +Size=100000 +Mass=1 +X=F102010704 +Y=F20607922 +R=F13172736 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexX=0,1 +VertexY=0,-3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=12845761 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=74;false;"Prototype"=DRank,"MeshTransformation"=E14 +Category=1 +Plane=100 +Rotation=187 +Size=100000 +Mass=1 +X=F86173784 +Y=F19186260 +R=F12255232 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexY=0,-3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=12845761 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=75;false;"Prototype"=DRank,"MeshTransformation"=E15 +Category=1 +Plane=100 +Rotation=352 +Size=100000 +Mass=1 +X=F103762848 +Y=F29449380 +R=F23068672 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexY=0,3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=12845761 + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=76;false;"Prototype"=DRank,"MeshTransformation"=E16 +Category=1 +Plane=100 +Rotation=334 +Size=100000 +Mass=1 +X=F97690968 +Y=F31195478 +R=F21889024 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexX=0,1 +VertexY=0,3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=2360001 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=81;false;"Prototype"=DTrunk,"MeshTransformation"=E17,"Action"=n +Category=1 +Plane=100 +Rotation=180 +Size=55000 +Mass=22 +X=F90952848 +Y=F18983508 +R=F11796480 +Width=36 +Height=36 +Offset=-18,-18 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=82;false;"Prototype"=DTrunk,"MeshTransformation"=E18,"Action"=n +Category=1 +Plane=100 +Size=66000 +Mass=26 +X=F86222696 +Y=F12668325 +Width=13 +Height=39 +Offset=-6,-19 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=127;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E19 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F34829706 +Y=F34648376 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,127,Tree_Coniferous,719;false;"NoStop"=b1,"Pars"=E20,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=130;false;"Prototype"=DFern,"MeshTransformation"=E21 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F39029512 +Y=F38817884 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=2359489 +Effects=(1,0,350,130,Fern,718;false;"NoStop"=b1,"Pars"=E22,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=140;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E23 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F41462204 +Y=F36813784 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,140,Tree_Coniferous,717;false;"NoStop"=b1,"Pars"=E24,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=143;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E25 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F46891150 +Y=F38486564 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,143,Tree_Coniferous,716;false;"NoStop"=b1,"Pars"=E26,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=146;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E27 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F50044716 +Y=F38403576 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,146,Tree_Coniferous,715;false;"NoStop"=b1,"Pars"=E28,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=149;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E29 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F38043828 +Y=F35708212 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,149,Tree_Coniferous,714;false;"NoStop"=b1,"Pars"=E30,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=152;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E31 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F27041582 +Y=F43063468 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,152,Tree_Coniferous,713;false;"NoStop"=b1,"Pars"=E32,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=155;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E33 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F51729112 +Y=F38192352 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,155,Tree_Coniferous,712;false;"NoStop"=b1,"Pars"=E34,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=167;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E35 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F61225168 +Y=F37351112 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,167,Tree_Coniferous,711;false;"NoStop"=b1,"Pars"=E36,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=170;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E37 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F74324432 +Y=F32000040 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,170,Tree_Coniferous,710;false;"NoStop"=b1,"Pars"=E38,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=173;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E39 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F8001242 +Y=F30308366 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,173,Tree_Coniferous,709;false;"NoStop"=b1,"Pars"=E40,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=176;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E41 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F9006135 +Y=F30998528 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,176,Tree_Coniferous,708;false;"NoStop"=b1,"Pars"=E42,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=179;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E43 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F8573777 +Y=F30811154 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,179,Tree_Coniferous,707;false;"NoStop"=b1,"Pars"=E44,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=182;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E45 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F9959266 +Y=F31466514 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,182,Tree_Coniferous,706;false;"NoStop"=b1,"Pars"=E46,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=185;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E47 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F12410081 +Y=F32617150 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,185,Tree_Coniferous,705;false;"NoStop"=b1,"Pars"=E48,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=188;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E49 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F15157232 +Y=F34072224 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,188,Tree_Coniferous,704;false;"NoStop"=b1,"Pars"=E50,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=191;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E51 +Category=1 +Plane=100 +Size=100500 +Mass=150 +X=F84531312 +Y=F11931963 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,191,Tree_Coniferous,703;false;"NoStop"=b1,"Pars"=E52,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=201;false;"Prototype"=DFern,"MeshTransformation"=E53 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F15803774 +Y=F72157170 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,201,Fern,702;false;"NoStop"=b1,"Pars"=E54,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=214;false;"Prototype"=DFern,"MeshTransformation"=E55 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F32339902 +Y=F75847696 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,214,Fern,701;false;"NoStop"=b1,"Pars"=E56,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=217;false;"Prototype"=DFern,"MeshTransformation"=E57 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F66077920 +Y=F48042828 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,217,Fern,700;false;"NoStop"=b1,"Pars"=E58,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=229;false;"Prototype"=DFern,"MeshTransformation"=E59 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F100301016 +Y=F30211766 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=2359489 +Effects=(1,0,350,229,Fern,699;false;"NoStop"=b1,"Pars"=E60,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=244;false;"Prototype"=DFern,"MeshTransformation"=E61 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F53726852 +Y=F81566968 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,244,Fern,698;false;"NoStop"=b1,"Pars"=E62,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=247;false;"Prototype"=DFern,"MeshTransformation"=E63 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F73743144 +Y=F78898296 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,247,Fern,697;false;"NoStop"=b1,"Pars"=E64,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=279;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E65 +Category=1 +Plane=100 +Size=100003 +Mass=150 +X=F17288178 +Y=F69837832 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,279,Tree_Coniferous,696;false;"NoStop"=b1,"Pars"=E66,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=282;false;"Prototype"=DTree_Coniferous,"MeshTransformation"=E67 +Category=1 +Plane=100 +Size=100003 +Mass=150 +X=F45285376 +Y=F38076416 +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=5 +Effects=(1,0,350,282,Tree_Coniferous,695;false;"NoStop"=b1,"Pars"=E68,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=305;false;"Prototype"=DFern,"MeshTransformation"=E69 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F72094120 +Y=F88449008 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,305,Fern,694;false;"NoStop"=b1,"Pars"=E70,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=308;false;"Prototype"=DFern,"MeshTransformation"=E71 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F70409968 +Y=F88521336 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,308,Fern,693;false;"NoStop"=b1,"Pars"=E72,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=392;false;"Prototype"=DTrunk,"MeshTransformation"=E73,"Action"=n +Category=1 +Plane=100 +Size=80000 +Mass=32 +X=F13828096 +Y=F69795840 +Width=16 +Height=48 +Offset=-8,-24 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=393;false;"Prototype"=DTrunk,"MeshTransformation"=E74,"Action"=n +Category=1 +Plane=100 +Size=70000 +Mass=28 +X=F28704768 +Y=F74055680 +Width=14 +Height=42 +Offset=-7,-21 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=394;false;"Prototype"=DTrunk,"MeshTransformation"=E75 +Category=1 +Plane=100 +Rotation=195 +Size=100000 +Mass=40 +X=F35258368 +Y=F70778880 +R=F12779520 +Width=66 +Height=66 +Offset=-33,-33 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845761 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Tree_Coniferous +Properties=430;false;"Prototype"=DTree_Coniferous +Category=1 +Plane=100 +Size=24503 +Mass=36 +X=F40894464 +Y=F39452672 +Width=14 +Height=26 +Offset=-7,-13 +Vertices=9 +VertexY=10,7,4,2,0,-2,-4,-7,-10 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Picture=0,0,0,0 +OCF=2359937 +Component=Wood=0 +Effects=(1,0,350,430,Tree_Coniferous,689;false;"NoStop"=b1,"Pars"=E76,"Name"=s"IntScheduleCall","Function"=s"Seed"),(1,1720,35,0,None,431;false;"Name"=s"IntGrowth","growth"=i5) + + [Mesh] + Valid=true + +[Object] +id=Rank +Properties=436;false;"Prototype"=DRank,"MeshTransformation"=E77 +Category=1 +Plane=100 +Rotation=202 +Size=100000 +Mass=1 +X=F107093120 +Y=F23798880 +R=F13238272 +Width=32 +Height=32 +Offset=-16,-16 +Vertices=2 +VertexX=0,1 +VertexY=0,-3 +VertexCNAT=3,4 +Picture=0,0,0,0 +OCF=12845761 + + [Mesh] + Valid=true + +[Object] +id=Trunk +Properties=437;false;"Prototype"=DTrunk,"MeshTransformation"=E78,"Action"=n +Category=1 +Plane=100 +Size=30000 +Mass=12 +X=F95454376 +Y=F32981494 +Width=6 +Height=18 +Offset=-3,-9 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 +Picture=0,0,0,0 +OCF=12845697 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Fern +Properties=461;false;"Prototype"=DFern,"MeshTransformation"=E79 +Category=1 +Plane=100 +Size=100100 +Mass=1 +X=F4885737 +Y=F72024312 +Width=28 +Height=10 +Offset=-14,-5 +Vertices=2 +VertexY=0,3 +VertexCNAT=16,8 +Picture=0,0,0,0 +OCF=12845249 +Effects=(1,0,350,461,Fern,686;false;"NoStop"=b1,"Pars"=E80,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Rule_NoPowerNeed +Properties=582;false;"Prototype"=DRule_NoPowerNeed +Category=65 +Plane=100 +Size=100000 +Mass=1 +Picture=0,0,0,0 +OCF=12845121 + +[Object] +id=WoodenCabin +Properties=19;false;"Action"=n,"Prototype"=DWoodenCabin +Category=4098 +Plane=200 +Size=100000 +Mass=4000 +X=F3678560 +Y=F31880976 +Width=94 +Height=40 +Offset=-47,-20 +Vertices=8 +VertexX=-26,26,-22,23,-38,-38,43,40 +VertexY=-7,-6,19,19,4,19,-4,19 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=29625921 +Component=Wood=5;Rock=4 + + [Mesh] + Valid=true + +[Object] +id=Chest +Properties=22;false;"chestanim"=i0,"Prototype"=DChest,"MeshTransformation"=E81 +Category=2 +Plane=200 +Size=100000 +Mass=42 +X=F3631504 +Y=F85028134 +Width=20 +Height=24 +Offset=-10,-12 +Vertices=4 +VertexX=-8,-8,8,8 +VertexY=-2,11,-2,11 +VertexCNAT=5,9,6,10 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=12845121 +Component=Wood=3 +Contents=484;467;465 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=1 + Number=0 + Type=Leaf + Animation=Open + Position=linear(F65,F0,F65,20,Hold,0) + +[Object] +id=Chest +Properties=70;false;"chestanim"=i0,"Prototype"=DChest,"MeshTransformation"=E82 +Category=2 +Plane=200 +Size=100000 +Mass=10 +X=F90509202 +Y=F34297897 +Width=20 +Height=24 +Offset=-10,-12 +Vertices=4 +VertexX=-8,-8,8,8 +VertexY=-2,11,-2,11 +VertexCNAT=5,9,6,10 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=12845121 +Component=Wood=3 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=1 + Number=0 + Type=Leaf + Animation=Open + Position=linear(F65,F0,F65,20,Hold,0) + +[Object] +id=Chest +Properties=83;false;"chestanim"=i0,"Prototype"=DChest,"MeshTransformation"=E83 +Category=2 +Plane=200 +Size=100000 +Mass=60 +X=F40611328 +Y=F56915199 +Width=20 +Height=24 +Offset=-10,-12 +Vertices=4 +VertexX=-8,-8,8,8 +VertexY=-2,11,-2,11 +VertexCNAT=5,9,6,10 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=12845121 +Component=Wood=3 +Contents=486;485;84;85;86 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=1 + Number=0 + Type=Leaf + Animation=Open + Position=linear(F65,F0,F65,20,Hold,0) + +[Object] +id=Chest +Properties=445;false;"chestanim"=i0,"Prototype"=DChest,"MeshTransformation"=E84 +Category=2 +Plane=200 +Size=100000 +Mass=56 +X=F40957928 +Y=F48320368 +Width=20 +Height=24 +Offset=-10,-12 +Vertices=4 +VertexX=-8,-8,8,8 +VertexY=-2,11,-2,11 +VertexCNAT=5,9,6,10 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=12845121 +Component=Wood=3 +Contents=448;449;38;446;447 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=1 + Number=0 + Type=Leaf + Animation=Open + Position=linear(F65,F0,F65,20,Hold,0) + +[Object] +id=Chest +Properties=472;false;"chestanim"=i0,"Prototype"=DChest,"MeshTransformation"=E85 +Category=2 +Plane=200 +Size=100000 +Mass=54 +X=F101777408 +Y=F17589862 +Width=20 +Height=24 +Offset=-10,-12 +Vertices=4 +VertexX=-8,-8,8,8 +VertexY=-2,11,-2,11 +VertexCNAT=5,9,6,10 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=12845121 +Component=Wood=3 +Contents=575;477;475;476;559 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=1 + Number=0 + Type=Leaf + Animation=Open + Position=linear(F65,F0,F65,20,Hold,0) + +[Object] +id=Chest +Properties=579;false;"chestanim"=i0,"MeshTransformation"=E86,"Prototype"=DChest +Category=2 +Plane=200 +Size=100000 +Mass=10 +X=F107912992 +Y=F89740534 +Width=20 +Height=24 +Offset=-10,-12 +Vertices=4 +VertexX=-8,-8,8,8 +VertexY=-2,11,-2,11 +VertexCNAT=5,9,6,10 +VertexFriction=50,50,100,100 +Picture=0,0,0,0 +OCF=12845121 +Component=Wood=3 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=1 + Number=0 + Type=Leaf + Animation=Open + Position=linear(F65,F0,F65,20,Hold,0) + +[Object] +id=Elevator +Properties=39;false;"MeshTransformation"=E87,"Action"=n,"case"=n,"Prototype"=DElevator,"rope"=O47 +Category=1 +Plane=200 +Size=40000 +Mass=600 +X=F76659116 +Y=F34886523 +Width=60 +Height=26 +Offset=-30,-13 +Vertices=5 +VertexX=-25,25,-5,-25,28 +VertexY=-10,-10,12,12,12 +VertexFriction=50,50,100,100,100 +Picture=0,0,0,0 +OCF=12846083 +Component=Wood=1;Metal=0 +ColorMod=4283971116 + + [Mesh] + Valid=true + +[Object] +id=WindGenerator +Properties=48;false;"wind_anim"=i0,"Action"=n,"Prototype"=DWindGenerator,"MeshTransformation"=E88,"last_wind"=i50 +Category=2 +Plane=200 +Size=48000 +Mass=432 +X=F82697104 +Y=F34168479 +Width=24 +Height=33 +Offset=-12,-16 +Vertices=5 +VertexX=0,-9,9,-9,9 +VertexY=-15,-12,-12,16,16 +VertexFriction=50,50,50,100,100 +Picture=0,0,0,0 +OCF=12846723 +Component=Wood=1;Metal=0 +ColorMod=4286213733 +Effects=(1,0,35,48,WindGenerator,675;false;"NoStop"=b1,"Pars"=E89,"Name"=s"IntScheduleCall","Function"=s"Wind2Turn") + + [Mesh] + Valid=true + + [AnimationNode] + Slot=5 + Number=0 + Type=Leaf + Animation=Turn + Position=linear(F4667,F104857,F0,187,Loop,0) + +[Object] +id=Flagpole +Properties=494;false;"lflag"=E90,"Prototype"=DFlagpole,"MeshTransformation"=E91 +Category=2 +Plane=200 +Size=100000 +Mass=100 +Color=4291320338 +X=F7834578 +Y=F2445537 +Width=24 +Height=70 +Offset=-12,-35 +Vertices=5 +VertexX=0,-10,11,-4,5 +VertexY=-34,-29,-29,34,34 +VertexFriction=50,50,50,100,100 +Picture=0,0,0,0 +OCF=12846145 +Component=Wood=3;Metal=1 + + [Mesh] + Valid=true + +[Object] +id=Armory +Properties=583;false;"MeshTransformation"=E92,"Prototype"=DArmory,"Action"=DArmory.ActMap.Default,"queue"=E93 +Category=2 +Plane=200 +Size=100000 +Mass=4500 +X=F86900736 +Y=F32699072 +Width=95 +Height=52 +Offset=-47,-26 +Vertices=6 +VertexX=-1,20,30,-43,-43 +VertexY=-13,-15,-14,24,24,24 +VertexFriction=50,50,50,100,100,100 +Picture=0,0,0,0 +OCF=12846145 +Component=Wood=3;Metal=2;Loam=2 +Effects=(100,0,5,583,Armory,584;false;"Name"=s"ProcessQueue") + + [Mesh] + Valid=true + +[Object] +id=GrappleHook +Properties=474;false;"Prototype"=DGrappleHook +Category=4 +Plane=300 +Size=100000 +Mass=8 +X=F104895576 +Y=F21393821 +Width=5 +Height=6 +Offset=-3 +Vertices=7 +VertexY=3 +VertexFriction=120,120,120,120,120,120,120 +Picture=0,0,0,0 +OCF=577 +Contained=473 + + [Mesh] + Valid=true + +[Object] +id=Clonk +Properties=27;false;"inventory"=E94,"iHandMesh"=E95,"using"=n,"ActualReplace"=E96,"MeshTransformation"=E97,"use_objects"=E98,"mesh_transformation_list"=E99,"Action"=E100,"backpack"=i1,"using_type"=n,"menu"=n,"closed_eyes"=i0,"Prototype"=DClonk,"fBothHanded"=i0,"turn_type"=i1,"PictureTransformation"=E101,"alt"=b0,"Name"=s"Hans-Georg","force_collection"=b0 +Category=8 +Plane=400 +Size=100000 +Mass=50 +Energy=50000 +Breath=252 +Color=4292686880 +X=F10147519 +Y=F64780998 +YDir=F104856 +Width=8 +Height=20 +Offset=-4,-10 +Vertices=7 +VertexX=0,0,0,-2,2,-4,4 +VertexY=2,-7,9,-3,-3,2,2 +VertexCNAT=0,4,8,1,2,1,2 +VertexFriction=300,300,100,300,300,300,300 +AttachX=160 +AttachY=999 +AttachVtx=2 +Picture=0,0,0,0 +OCF=12845281 +ActionTime=72211 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=5 + Number=0 + Type=Leaf + Animation=Dead + Position=linear(F111411,F0,F111411,20,Hold,0) + + [Attached] + Number=1 + ParentBone=3 + ChildBone=0 + AttachTransformation=(F-45875,F0,F0,F0,F0,F45875,F0,F183500,F0,F0,F-26214,F-26214) + ChildMesh=BackpackGraphic:: + + [ChildInstance] + Valid=true + +[Object] +id=Clonk +Properties=401;false;"inventory"=E102,"using"=n,"MeshTransformation"=E103,"ActualReplace"=E104,"no_ladder_counter"=i0,"gender"=i1,"mesh_transformation_list"=E105,"use_objects"=E106,"Action"=E107,"backpack"=i1,"using_type"=n,"menu"=n,"closed_eyes"=i0,"Prototype"=DClonk,"turn_type"=i1,"PictureTransformation"=E108,"alt"=b0,"Name"=s"Sabine","force_collection"=b0 +Category=8 +Plane=400 +Size=100000 +Mass=50 +Energy=50000 +Breath=252 +Color=4281642204 +X=F102301696 +Y=F85157397 +YDir=F104856 +Width=8 +Height=20 +Offset=-4,-10 +Vertices=7 +VertexX=0,0,0,-2,2,-4,4 +VertexY=2,-7,9,-3,-3,2,2 +VertexCNAT=0,4,8,1,2,1,2 +VertexFriction=300,300,100,300,300,300,300 +AttachX=1580 +AttachY=1317 +AttachVtx=2 +Picture=0,0,0,0 +OCF=12845281 +ActionTime=3104 +Graphics=Skin_Farmer:: + + [Mesh] + Valid=true + + [AnimationNode] + Slot=5 + Number=1 + Type=Leaf + Animation=Dead + Position=linear(F111411,F0,F111411,20,Hold,0) + + [Attached] + Number=1 + ParentBone=3 + ChildBone=0 + AttachTransformation=(F-45875,F0,F0,F0,F0,F45875,F0,F183500,F0,F0,F-26214,F-26214) + ChildMesh=BackpackGraphic:: + + [ChildInstance] + Valid=true + +[Object] +id=Loam +Properties=84;false;"Prototype"=DLoam +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F40611328 +Y=F56915199 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexY=3,-3 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=585 +Contained=83 +Component=Earth=2 +Graphics=Loam::1 + +[Object] +id=Loam +Properties=345;false;"Prototype"=DLoam +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F1856209 +Y=F38304782 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexY=3,-3 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Earth=2 +Graphics=Loam::2 + +[Object] +id=Loam +Properties=477;false;"Prototype"=DLoam +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F101777408 +Y=F17589862 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexY=3,-3 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=585 +Contained=472 +Component=Earth=2 +Graphics=Loam::1 + +[Object] +id=Loam +Properties=491;false;"Prototype"=DLoam +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F10114273 +Y=F11829032 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexY=3,-3 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Earth=2 + +[Object] +id=Firestone +Properties=25;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F5502623 +Y=F66672800 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::1 + +[Object] +id=Firestone +Properties=343;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F6213210 +Y=F59532087 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::1 + +[Object] +id=Firestone +Properties=356;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F45575146 +Y=F65628248 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=357;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F56644276 +Y=F83786059 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::1 + +[Object] +id=Firestone +Properties=358;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F59016864 +Y=F46493163 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::1 + +[Object] +id=Firestone +Properties=359;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F85053824 +Y=F62279906 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 + +[Object] +id=Firestone +Properties=360;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F94868992 +Y=F48585644 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 + +[Object] +id=Firestone +Properties=444;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F107773776 +Y=F20796658 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=446;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F40957928 +Y=F48320368 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=73 +Contained=445 +Component=Sulphur=1 +Graphics=Firestone::1 + +[Object] +id=Firestone +Properties=447;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F40957928 +Y=F48320368 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=73 +Contained=445 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=464;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F12651398 +Y=F76763900 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=467;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F3631504 +Y=F85028134 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=73 +Contained=22 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=468;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F37534264 +Y=F40329869 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::1 + +[Object] +id=Firestone +Properties=469;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F75659620 +Y=F44131232 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=471;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F34968688 +Y=F45709882 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Firestone +Properties=581;false;"Prototype"=DFirestone +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F99614720 +Y=F62390272 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=-3,3 +VertexY=1,-1 +VertexFriction=20 +Picture=0,0,0,0 +OCF=2359369 +Component=Sulphur=1 +Graphics=Firestone::2 + +[Object] +id=Axe +Properties=26;false;"Prototype"=DAxe,"hWeaponAnimStrike"=n +Category=16 +Plane=500 +Rotation=99 +Size=100000 +Mass=12 +X=F100728832 +Y=F84574206 +R=F6488064 +Width=14 +Height=14 +Offset=-7,-7 +Vertices=3 +VertexX=0,-3,3 +VertexY=0,2 +VertexFriction=50,50,50 +Picture=0,0,0,0 +OCF=12845641 +Component=Wood=1;Metal=1 + + [Mesh] + Valid=true + +[Object] +id=Shovel +Properties=37;false;"Prototype"=DShovel +Category=16 +Plane=500 +Rotation=123 +Size=100000 +Mass=20 +X=F9043968 +Y=F64117146 +R=F8060928 +Width=20 +Height=20 +Offset=-10,-10 +Vertices=3 +VertexX=6,-8 +VertexY=4,-5 +VertexFriction=50,50,50 +Picture=0,0,0,0 +OCF=2359881 +Component=Wood=1;Metal=1 + + [Mesh] + Valid=true + +[Object] +id=Ropeladder +Properties=38;false;"Prototype"=DRopeladder +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F40957928 +Y=F48320368 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,-3,3 +VertexY=4,-3,-3 +VertexFriction=100,100,100 +Picture=0,0,0,0 +OCF=585 +Contained=445 +Component=Wood=2;Rope=2 + +[Object] +id=Mushroom +Properties=57;false;"Prototype"=DMushroom,"MeshTransformation"=E109 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F98533136 +Y=F30699360 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,57,Mushroom,647;false;"NoStop"=b1,"Pars"=E110,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=60;false;"Prototype"=DMushroom,"MeshTransformation"=E111 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F64159744 +Y=F38430221 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,60,Mushroom,646;false;"NoStop"=b1,"Pars"=E112,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=63;false;"Prototype"=DMushroom,"MeshTransformation"=E113 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F80258468 +Y=F35409616 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,63,Mushroom,645;false;"NoStop"=b1,"Pars"=E114,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=66;false;"Prototype"=DMushroom,"MeshTransformation"=E115 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F70903600 +Y=F35876852 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,66,Mushroom,644;false;"NoStop"=b1,"Pars"=E116,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=78;false;"Prototype"=DMushroom,"MeshTransformation"=E117 +Category=16 +Plane=500 +Size=100203 +Mass=6 +X=F94240768 +Y=F34432614 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=14942273 +Effects=(1,0,350,78,Mushroom,643;false;"NoStop"=b1,"Pars"=E118,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=133;false;"Prototype"=DMushroom,"MeshTransformation"=E119 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F39400184 +Y=F57433759 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,133,Mushroom,642;false;"NoStop"=b1,"Pars"=E120,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=205;false;"Prototype"=DMushroom,"MeshTransformation"=E121 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F13065272 +Y=F69950417 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,205,Mushroom,641;false;"NoStop"=b1,"Pars"=E122,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=208;false;"Prototype"=DMushroom,"MeshTransformation"=E123 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F11822902 +Y=F68383011 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=14942273 +Effects=(1,0,350,208,Mushroom,640;false;"NoStop"=b1,"Pars"=E124,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=211;false;"Prototype"=DMushroom,"MeshTransformation"=E125 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F7625788 +Y=F61438944 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,211,Mushroom,639;false;"NoStop"=b1,"Pars"=E126,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=223;false;"Prototype"=DMushroom,"MeshTransformation"=E127 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F72934160 +Y=F47346584 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,223,Mushroom,638;false;"NoStop"=b1,"Pars"=E128,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=226;false;"Prototype"=DMushroom,"MeshTransformation"=E129 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F70495256 +Y=F47337139 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,226,Mushroom,637;false;"NoStop"=b1,"Pars"=E130,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=235;false;"Prototype"=DMushroom,"MeshTransformation"=E131 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F100410320 +Y=F53826476 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,235,Mushroom,636;false;"NoStop"=b1,"Pars"=E132,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=238;false;"Prototype"=DMushroom,"MeshTransformation"=E133 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F101743092 +Y=F85552797 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,238,Mushroom,635;false;"NoStop"=b1,"Pars"=E134,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=241;false;"Prototype"=DMushroom,"MeshTransformation"=E135 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F103376696 +Y=F86070188 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,241,Mushroom,634;false;"NoStop"=b1,"Pars"=E136,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=251;false;"Prototype"=DMushroom,"MeshTransformation"=E137 +Category=16 +Plane=500 +Size=100203 +Mass=6 +X=F44171264 +Y=F58549862 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,251,Mushroom,633;false;"NoStop"=b1,"Pars"=E138,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=395;false;"Prototype"=DMushroom,"MeshTransformation"=E139 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F43384832 +Y=F75851366 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,395,Mushroom,632;false;"NoStop"=b1,"Pars"=E140,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=398;false;"Prototype"=DMushroom,"MeshTransformation"=E141 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F52363264 +Y=F81028710 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=14942273 +Effects=(1,0,350,398,Mushroom,631;false;"NoStop"=b1,"Pars"=E142,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=438;false;"Prototype"=DMushroom,"MeshTransformation"=E143 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F105919696 +Y=F30108571 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,438,Mushroom,630;false;"NoStop"=b1,"Pars"=E144,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=441;false;"Prototype"=DMushroom,"MeshTransformation"=E145 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F108755528 +Y=F32987027 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,441,Mushroom,629;false;"NoStop"=b1,"Pars"=E146,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=449;false;"Prototype"=DMushroom,"MeshTransformation"=E147 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F40957928 +Y=F48320368 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=65 +Contained=445 +Effects=(1,0,350,449,Mushroom,628;false;"NoStop"=b1,"Pars"=E148,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=452;false;"Prototype"=DMushroom,"MeshTransformation"=E149 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F43188224 +Y=F49374821 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,452,Mushroom,627;false;"NoStop"=b1,"Pars"=E150,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Mushroom +Properties=576;false;"Prototype"=DMushroom,"MeshTransformation"=E151 +Category=16 +Plane=500 +Size=100300 +Mass=6 +X=F105860832 +Y=F90793642 +Width=12 +Height=20 +Offset=-6,-10 +Vertices=2 +VertexY=1,4 +VertexCNAT=16,8 +VertexFriction=10,100 +Picture=0,0,0,0 +OCF=12845121 +Effects=(1,0,350,576,Mushroom,626;false;"NoStop"=b1,"Pars"=E152,"Name"=s"IntScheduleCall","Function"=s"Seed") + + [Mesh] + Valid=true + +[Object] +id=Dynamite +Properties=85;false;"Prototype"=DDynamite +Category=16 +Plane=500 +Size=100000 +Mass=8 +X=F40611328 +Y=F56915199 +Width=3 +Height=10 +Offset=-2,-5 +Vertices=3 +VertexX=-2,2 +VertexY=5,5,-5 +VertexFriction=90,90,90 +Picture=0,0,0,0 +OCF=713 +Contained=83 +Component=Coal=1;Sulphur=1 + +[Object] +id=Dynamite +Properties=86;false;"Prototype"=DDynamite +Category=16 +Plane=500 +Size=100000 +Mass=8 +X=F40611328 +Y=F56915199 +Width=3 +Height=10 +Offset=-2,-5 +Vertices=3 +VertexX=-2,2 +VertexY=5,5,-5 +VertexFriction=90,90,90 +Picture=0,0,0,0 +OCF=713 +Contained=83 +Component=Coal=1;Sulphur=1 + +[Object] +id=Dynamite +Properties=475;false;"Prototype"=DDynamite +Category=16 +Plane=500 +Size=100000 +Mass=8 +X=F101777408 +Y=F17589862 +Width=3 +Height=10 +Offset=-2,-5 +Vertices=3 +VertexX=-2,2 +VertexY=5,5,-5 +VertexFriction=90,90,90 +Picture=0,0,0,0 +OCF=713 +Contained=472 +Component=Coal=1;Sulphur=1 + +[Object] +id=Dynamite +Properties=476;false;"Prototype"=DDynamite +Category=16 +Plane=500 +Size=100000 +Mass=8 +X=F101777408 +Y=F17589862 +Width=3 +Height=10 +Offset=-2,-5 +Vertices=3 +VertexX=-2,2 +VertexY=5,5,-5 +VertexFriction=90,90,90 +Picture=0,0,0,0 +OCF=713 +Contained=472 +Component=Coal=1;Sulphur=1 + +[Object] +id=Nugget +Properties=136;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F44531282 +Y=F58548729 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=12845641 +Component=Nugget=1 +Graphics=Nugget::1 + +[Object] +id=Nugget +Properties=137;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F43280220 +Y=F58088160 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=14942793 +Component=Nugget=1 +Graphics=Nugget::2 + +[Object] +id=Nugget +Properties=138;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F41745952 +Y=F57495380 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=12845641 +Component=Nugget=1 + +[Object] +id=Nugget +Properties=139;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F44730768 +Y=F55335673 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::1 + +[Object] +id=Nugget +Properties=344;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F5940897 +Y=F38236706 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::4 + +[Object] +id=Nugget +Properties=353;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F47083039 +Y=F56054156 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::2 + +[Object] +id=Nugget +Properties=354;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F52569184 +Y=F72109912 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::2 + +[Object] +id=Nugget +Properties=355;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F44390480 +Y=F80240401 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 + +[Object] +id=Nugget +Properties=485;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F40611328 +Y=F56915199 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=585 +Contained=83 +Component=Nugget=1 + +[Object] +id=Nugget +Properties=486;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F40611328 +Y=F56915199 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=585 +Contained=83 +Component=Nugget=1 +Graphics=Nugget::1 + +[Object] +id=Nugget +Properties=487;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F72089600 +Y=F80504422 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::2 + +[Object] +id=Nugget +Properties=488;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F73007104 +Y=F63792742 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::2 + +[Object] +id=Nugget +Properties=489;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F97255424 +Y=F38364774 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::4 + +[Object] +id=Nugget +Properties=490;false;"Prototype"=DNugget +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F23490021 +Y=F26627882 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Nugget=1 +Graphics=Nugget::3 + +[Object] +id=Metal +Properties=465;false;"Prototype"=DMetal +Category=16 +Plane=500 +Size=100000 +Mass=12 +X=F3631504 +Y=F85028134 +Width=12 +Height=4 +Offset=-6,-2 +Vertices=3 +VertexX=-5,5 +VertexCNAT=1,2,16 +VertexFriction=30,30,30 +Picture=0,0,0,0 +OCF=585 +Contained=22 +Component=Ore=1 + +[Object] +id=Rock +Properties=285;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F7166302 +Y=F43151445 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=286;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F5668587 +Y=F56316361 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::3 + +[Object] +id=Rock +Properties=287;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F2027966 +Y=F57829530 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::6 + +[Object] +id=Rock +Properties=288;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F11250999 +Y=F39351774 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::3 + +[Object] +id=Rock +Properties=289;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F8412905 +Y=F68440505 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::6 + +[Object] +id=Rock +Properties=290;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F2397722 +Y=F67529084 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::8 + +[Object] +id=Rock +Properties=291;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F15738604 +Y=F78863182 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::6 + +[Object] +id=Rock +Properties=292;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F29710103 +Y=F77034348 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 + +[Object] +id=Rock +Properties=293;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F33704424 +Y=F80772379 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=294;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F32323938 +Y=F84630976 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::9 + +[Object] +id=Rock +Properties=295;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F43814472 +Y=F77945472 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::7 + +[Object] +id=Rock +Properties=296;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F52012972 +Y=F82669193 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 + +[Object] +id=Rock +Properties=303;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F64425828 +Y=F89812387 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 + +[Object] +id=Rock +Properties=304;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F74361316 +Y=F84047153 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=311;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F78195744 +Y=F82597672 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 + +[Object] +id=Rock +Properties=312;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F67904632 +Y=F73884611 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::2 + +[Object] +id=Rock +Properties=313;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F57411244 +Y=F73759302 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::8 + +[Object] +id=Rock +Properties=314;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F61630388 +Y=F63919252 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::8 + +[Object] +id=Rock +Properties=315;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F43767340 +Y=F60653119 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::1 + +[Object] +id=Rock +Properties=316;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F75502512 +Y=F69685376 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=320;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F68417328 +Y=F52980112 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=321;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F78563248 +Y=F48454444 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=325;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F85521640 +Y=F39614769 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::1 + +[Object] +id=Rock +Properties=326;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F86162600 +Y=F54811667 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::1 + +[Object] +id=Rock +Properties=327;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F94893856 +Y=F41711588 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::9 + +[Object] +id=Rock +Properties=328;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F103473992 +Y=F55932523 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::5 + +[Object] +id=Rock +Properties=329;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F95372680 +Y=F15957488 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::6 + +[Object] +id=Rock +Properties=434;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F43689316 +Y=F46562136 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::7 + +[Object] +id=Rock +Properties=435;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F31132330 +Y=F41509858 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::9 + +[Object] +id=Rock +Properties=448;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F40957928 +Y=F48320368 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=585 +Contained=445 +Component=Rock=1 + +[Object] +id=Rock +Properties=470;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F62127692 +Y=F47210021 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::3 + +[Object] +id=Rock +Properties=484;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F3631504 +Y=F85028134 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=585 +Contained=22 +Component=Rock=1 +Graphics=Rock::4 + +[Object] +id=Rock +Properties=492;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F24873852 +Y=F21720708 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::3 + +[Object] +id=Rock +Properties=493;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F19796338 +Y=F19615489 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::8 + +[Object] +id=Rock +Properties=580;false;"Prototype"=DRock +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F99561552 +Y=F66182116 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Rock=1 +Graphics=Rock::2 + +[Object] +id=Coal +Properties=331;false;"Prototype"=DCoal +Category=16 +Plane=500 +Size=100000 +Mass=9 +X=F10502133 +Y=F43601775 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=75,75 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=2 +Graphics=Coal::4 + +[Object] +id=Coal +Properties=332;false;"Prototype"=DCoal +Category=16 +Plane=500 +Size=100000 +Mass=9 +X=F8715709 +Y=F72833956 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=75,75 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=2 +Graphics=Coal::2 + +[Object] +id=Coal +Properties=336;false;"Prototype"=DCoal +Category=16 +Plane=500 +Size=100000 +Mass=9 +X=F48542064 +Y=F46364438 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=75,75 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=2 +Graphics=Coal::4 + +[Object] +id=Coal +Properties=337;false;"Prototype"=DCoal +Category=16 +Plane=500 +Size=100000 +Mass=9 +X=F70823760 +Y=F42039540 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=75,75 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=2 +Graphics=Coal::2 + +[Object] +id=Coal +Properties=338;false;"Action"=n,"Prototype"=DCoal +Category=16 +Plane=500 +Size=98000 +Mass=8 +Damage=6 +X=F97122608 +Y=F79325624 +Width=8 +Height=7 +Offset=-4,-3 +Vertices=3 +VertexX=0,2,-2 +VertexFriction=75,75 +Picture=0,0,0,0 +OCF=2359945 +Component=Wood=1 + +[Object] +id=Coal +Properties=483;false;"Prototype"=DCoal +Category=16 +Plane=500 +Size=100000 +Mass=9 +X=F39911424 +Y=F77227622 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=75,75 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=2 +Graphics=Coal::2 + +[Object] +id=Sulphur +Properties=346;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F43452004 +Y=F62024765 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 + +[Object] +id=Sulphur +Properties=347;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F58767972 +Y=F62740436 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 +Graphics=Sulphur::2 + +[Object] +id=Sulphur +Properties=348;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F63755504 +Y=F51343404 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 +Graphics=Sulphur::3 + +[Object] +id=Sulphur +Properties=349;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F65060016 +Y=F44066702 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 + +[Object] +id=Sulphur +Properties=350;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F86794208 +Y=F45315089 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 + +[Object] +id=Sulphur +Properties=351;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F101814952 +Y=F49052959 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 + +[Object] +id=Sulphur +Properties=352;false;"Prototype"=DSulphur +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F91290816 +Y=F41909094 +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=40,40 +Picture=0,0,0,0 +OCF=2359881 +Component=Sulphur=1 +Graphics=Sulphur::1 + +[Object] +id=Seaweed +Properties=455;false;"Action"=E153,"Prototype"=DSeaweed +Category=16 +Plane=500 +Size=100000 +Mass=1 +X=F12359017 +Y=F76052185 +YDir=F104856 +Width=6 +Height=16 +Offset=-3,-8 +Vertices=2 +VertexY=-7,7 +VertexCNAT=4,3 +VertexFriction=10,100 +Picture=0,0,0,0 +InLiquid=true +OCF=1310817 +ActionTime=491 +Phase=11 +PhaseDelay=1 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=0 + Number=0 + Type=Leaf + Animation=Sway + Position=action(F15073,455) + +[Object] +id=Seaweed +Properties=456;false;"Action"=E153,"Prototype"=DSeaweed +Category=16 +Plane=500 +Size=100000 +Mass=1 +X=F9311106 +Y=F76174910 +YDir=F104856 +Width=6 +Height=16 +Offset=-3,-8 +Vertices=2 +VertexY=-7,7 +VertexCNAT=4,3 +VertexFriction=10,100 +Picture=0,0,0,0 +InLiquid=true +OCF=1310817 +ActionTime=491 +Phase=11 +PhaseDelay=1 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=0 + Number=0 + Type=Leaf + Animation=Sway + Position=action(F15073,456) + +[Object] +id=Seaweed +Properties=457;false;"Action"=E153,"Prototype"=DSeaweed +Category=16 +Plane=500 +Size=100000 +Mass=1 +X=F34202120 +Y=F42696411 +YDir=F104856 +Width=6 +Height=16 +Offset=-3,-8 +Vertices=2 +VertexY=-7,7 +VertexCNAT=4,3 +VertexFriction=10,100 +Picture=0,0,0,0 +InLiquid=true +OCF=1310817 +ActionTime=491 +Phase=11 +PhaseDelay=1 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=0 + Number=0 + Type=Leaf + Animation=Sway + Position=action(F15073,457) + +[Object] +id=Seaweed +Properties=458;false;"Action"=E153,"Prototype"=DSeaweed +Category=16 +Plane=500 +Size=100000 +Mass=1 +X=F39962220 +Y=F45770635 +YDir=F104856 +Width=6 +Height=16 +Offset=-3,-8 +Vertices=2 +VertexY=-7,7 +VertexCNAT=4,3 +VertexFriction=10,100 +Picture=0,0,0,0 +InLiquid=true +OCF=1310817 +ActionTime=491 +Phase=11 +PhaseDelay=1 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=0 + Number=0 + Type=Leaf + Animation=Sway + Position=action(F15073,458) + +[Object] +id=Seaweed +Properties=459;false;"Action"=E153,"Prototype"=DSeaweed +Category=16 +Plane=500 +Size=100000 +Mass=1 +X=F45693212 +Y=F44259260 +YDir=F104856 +Width=6 +Height=16 +Offset=-3,-8 +Vertices=2 +VertexY=-7,7 +VertexCNAT=4,3 +VertexFriction=10,100 +Picture=0,0,0,0 +InLiquid=true +OCF=1310817 +ActionTime=491 +Phase=11 +PhaseDelay=1 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=0 + Number=0 + Type=Leaf + Animation=Sway + Position=action(F15073,459) + +[Object] +id=Seaweed +Properties=460;false;"Action"=E153,"Prototype"=DSeaweed +Category=16 +Plane=500 +Size=100000 +Mass=1 +X=F50200944 +Y=F45245127 +YDir=F104856 +Width=6 +Height=16 +Offset=-3,-8 +Vertices=2 +VertexY=-7,7 +VertexCNAT=4,3 +VertexFriction=10,100 +Picture=0,0,0,0 +InLiquid=true +OCF=1310817 +ActionTime=491 +Phase=11 +PhaseDelay=1 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=0 + Number=0 + Type=Leaf + Animation=Sway + Position=action(F15073,460) + +[Object] +id=GrappleBow +Properties=473;false;"hook"=O474,"animation_set"=E154,"Prototype"=DGrappleBow,"hook_attach"=i1 +Category=16 +Plane=500 +Size=100000 +Mass=18 +X=F104895576 +Y=F21393821 +Width=8 +Height=6 +Offset=-4,-3 +Vertices=2 +VertexX=-3,3 +VertexFriction=80,80 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=2;Metal=1;Rope=1 +Contents=474 + + [Mesh] + Valid=true + + [AnimationNode] + Slot=5 + Number=0 + Type=Leaf + Animation=Load + Position=const(F76021) + + [Attached] + Number=1 + ParentBone=5 + ChildBone=0 + AttachTransformation=(F65536,F0,F0,F0,F0,F65536,F0,F0,F0,F0,F65536,F0) + ChildObject=474 + +[Object] +id=Wood +Properties=481;false;"Prototype"=DWood +Category=16 +Plane=500 +Size=100000 +Mass=6 +X=F42139648 +Y=F42886758 +Width=12 +Height=12 +Offset=-7,-6 +Vertices=3 +VertexX=4,-5 +VertexY=-1,2 +VertexCNAT=1,2 +VertexFriction=50,50 +Picture=0,0,0,0 +OCF=2360009 +Component=Wood=1 + +[Object] +id=Wood +Properties=482;false;"Prototype"=DWood +Category=16 +Plane=500 +Rotation=22 +Size=100000 +Mass=6 +X=F44040192 +Y=F49676288 +R=F1441792 +YDir=F13107 +RDir=F-19661 +Width=22 +Height=22 +Offset=-11,-11 +Vertices=3 +VertexX=4,-5 +VertexY=1 +VertexCNAT=1,2 +VertexFriction=50,50 +Picture=0,0,0,0 +Mobile=true +OCF=2360009 +Component=Wood=1 + +[Object] +id=Bow +Properties=559;false;"animation_set"=E155,"Prototype"=DBow +Category=16 +Plane=500 +Size=100000 +Mass=10 +X=F101777408 +Y=F17589862 +Width=4 +Height=20 +Offset=-2,-10 +Vertices=4 +VertexX=-2,2,-2,2 +VertexY=-10,-10,10,10 +VertexFriction=100,100,100,100,100 +Picture=0,0,0,0 +OCF=713 +Contained=472 +Component=Wood=3 + + [Mesh] + Valid=true + +[Object] +id=Arrow +Properties=575;false;"Name"=s"15x Arrows","count"=i15,"Prototype"=DArrow +Category=16 +Plane=500 +Rotation=90 +Size=100000 +Mass=8 +X=F101777408 +Y=F17589862 +R=F5898240 +Width=18 +Height=18 +Offset=-9,-9 +Vertices=3 +VertexX=6,-6 +VertexY=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6 +VertexFriction=120,120,120,0,0,0,0,0,0,0,0,0,0,0,0,120,120,120 +OwnVertices=true +Picture=0,0,0,0 +OCF=585 +Contained=472 +Component=Wood=3 +GfxOverlay=11,Icon_Number::1,3,,0,0,(0.40000000596046448,0,8,0,0.40000000596046448,14,1),16777215,0;12,Icon_Number::5,3,,0,0,(0.40000000596046448,0,22,0,0.40000000596046448,14,1),16777215,0 + +[Script] +StaticVariables=11;CON_VC_Players=E156,g_player_cursor_pos=n,Clonk_IdleActions=E157,Scoreboard_keys=n,Scoreboard_data=n,Scoreboard_unique_ids=n,Scoreboard_title_set=n,LibraryFlag_flag_list=E158,Library_Power_power_compounds=E159,g_is_initialized=n,g_intro_initialized=n +Scenario=false;"Prototype"=DScenario.Prototype +Values=a(1;E160),a(1;E161),p(true;"Y"=i0,"Wdt"=i1,"FacetTargetStretch"=i1,"NextAction"=s"Be","Prototype"=E162,"X"=i0,"Procedure"=n,"Hgt"=i4,"Name"=s"Be","Directions"=i1),a(12;i-995,i0,i105,i0,i0,i1000,i0,i0,i-105,i0,i-995,i0),a(12;i-682,i0,i731,i0,i0,i1000,i0,i0,i-731,i0,i-682,i0),a(12;i-999,i0,i-52,i0,i0,i1000,i0,i0,i52,i0,i-999,i0),a(12;i-799,i0,i-602,i0,i0,i1000,i0,i0,i602,i0,i-799,i0),a(12;i940,i0,i-342,i0,i0,i1000,i0,i0,i342,i0,i940,i0),a(12;i934,i0,i-358,i0,i0,i1000,i0,i0,i358,i0,i934,i0),a(12;i809,i0,i588,i0,i0,i1000,i0,i0,i-588,i0,i809,i0),a(12;i-731,i0,i-682,i0,i0,i1000,i0,i0,i682,i0,i-731,i0),a(12;i559,i0,i829,i0,i0,i1000,i0,i0,i-829,i0,i559,i0),a(12;i-629,i0,i-777,i0,i0,i1000,i0,i0,i777,i0,i-629,i0),a(12;i139,i0,i-990,i0,i0,i1000,i0,i0,i990,i0,i139,i0),a(12;i87,i0,i-996,i0,i0,i1000,i0,i0,i996,i0,i87,i0),a(12;i1000,i0,i-17,i0,i0,i1000,i0,i0,i17,i0,i1000,i0),a(12;i-656,i0,i755,i0,i0,i1000,i0,i0,i-755,i0,i-656,i0),a(12;i883,i0,i-469,i0,i0,i1000,i0,i0,i469,i0,i883,i0),a(12;i706,i0,i375,i0,i0,i800,i0,i0,i-375,i0,i706,i0),a(0;),a(12;i-438,i0,i899,i0,i0,i1000,i0,i0,i-899,i0,i-438,i0),a(0;),a(12;i-588,i0,i701,i0,i0,i916,i0,i0,i-701,i0,i-588,i0),a(0;),a(12;i-970,i0,i242,i0,i0,i1000,i0,i0,i-242,i0,i-970,i0),a(0;),a(12;i656,i0,i-755,i0,i0,i1000,i0,i0,i755,i0,i656,i0),a(0;),a(12;i441,i0,i906,i0,i0,i1008,i0,i0,i-906,i0,i441,i0),a(0;),a(12;i-165,i0,i-1046,i0,i0,i1059,i0,i0,i1046,i0,i-165,i0),a(0;),a(12;i-254,i0,i599,i0,i0,i651,i0,i0,i-599,i0,i-254,i0),a(0;),a(12;i891,i0,i-624,i0,i0,i1088,i0,i0,i624,i0,i891,i0),a(0;),a(12;i-372,i0,i920,i0,i0,i993,i0,i0,i-920,i0,i-372,i0),a(0;),a(12;i549,i0,i-280,i0,i0,i617,i0,i0,i280,i0,i549,i0),a(0;),a(12;i-570,i0,i-242,i0,i0,i619,i0,i0,i242,i0,i-570,i0),a(0;),a(12;i301,i0,i618,i0,i0,i688,i0,i0,i-618,i0,i301,i0),a(0;),a(12;i-455,i0,i-728,i0,i0,i859,i0,i0,i728,i0,i-455,i0),a(0;),a(12;i-682,i0,i572,i0,i0,i891,i0,i0,i-572,i0,i-682,i0),a(0;),a(12;i0,i0,i685,i0,i0,i685,i0,i0,i-685,i0,i0,i0),a(0;),a(12;i-426,i0,i-526,i0,i0,i678,i0,i0,i526,i0,i-426,i0),a(0;),a(12;i-669,i0,i-743,i0,i0,i1000,i0,i0,i743,i0,i-669,i0),a(0;),a(12;i-1000,i0,i-17,i0,i0,i1000,i0,i0,i17,i0,i-1000,i0),a(0;),a(12;i990,i0,i-139,i0,i0,i1000,i0,i0,i139,i0,i990,i0),a(0;),a(12;i982,i0,i-191,i0,i0,i1000,i0,i0,i191,i0,i982,i0),a(0;),a(12;i-951,i0,i309,i0,i0,i1000,i0,i0,i-309,i0,i-951,i0),a(0;),a(12;i-988,i0,i156,i0,i0,i1000,i0,i0,i-156,i0,i-988,i0),a(0;),a(12;i-633,i0,i-218,i0,i0,i670,i0,i0,i218,i0,i-633,i0),a(0;),a(12;i497,i0,i-552,i0,i0,i744,i0,i0,i552,i0,i497,i0),a(0;),a(12;i906,i0,i-423,i0,i0,i1000,i0,i0,i423,i0,i906,i0),a(0;),a(12;i-707,i0,i707,i0,i0,i1000,i0,i0,i-707,i0,i-707,i0),a(0;),a(12;i-682,i0,i-731,i0,i0,i1000,i0,i0,i731,i0,i-682,i0),a(12;i-469,i0,i883,i0,i0,i1000,i0,i0,i-883,i0,i-469,i0),a(12;i342,i0,i-940,i0,i0,i1000,i0,i0,i940,i0,i342,i0),a(0;),a(12;i191,i0,i-982,i0,i0,i1000,i0,i0,i982,i0,i191,i0),a(12;i-616,i0,i-788,i0,i0,i1000,i0,i0,i788,i0,i-616,i0),a(12;i788,i0,i-616,i0,i0,i1000,i0,i0,i616,i0,i788,i0),a(0;),a(12;i643,i0,i766,i0,i0,i1000,i0,i0,i-766,i0,i643,i0),a(12;i857,i0,i515,i0,i0,i1000,i0,i0,i-515,i0,i857,i0),a(12;i454,i0,i891,i0,i0,i1000,i0,i0,i-891,i0,i454,i0),a(12;i866,i0,i500,i0,i0,i1000,i0,i0,i-500,i0,i866,i0),a(12;i940,i0,i342,i0,i0,i1000,i0,i0,i-342,i0,i940,i0),a(12;i174,i0,i985,i0,i0,i1000,i0,i0,i-985,i0,i174,i0),a(12;i719,i0,i-695,i0,i0,i1000,i0,i0,i695,i0,i719,i0),a(12;i940,i0,i342,i0,i0,i1000,i0,i0,i-342,i0,i940,i0),a(0;),p(false;"construction_time"=i0,"radius"=i200,"range_markers"=E163,"linked_flags"=E164,"power_helper"=n),a(12;i1000,i0,i0,i0,i0,i1000,i0,i4000,i0,i0,i1000,i0),a(12;i946,i0,i326,i0,i0,i1000,i0,i0,i-326,i0,i946,i0),a(0;),a(1;),a(2;i0,i0),a(6;),a(12;i906,i0,i423,i0,i0,i1000,i0,i0,i-423,i0,i906,i0),a(2;i0,i1),a(1;E97),p(true;"Length"=i1,"Prototype"=E162,"Y"=i240,"Delay"=i0,"StartCall"=s"StartDead","Wdt"=i8,"ObjectDisabled"=i1,"NextAction"=s"Hold","X"=i0,"Hgt"=i20,"Name"=s"Dead","NoOtherAction"=i1,"Directions"=i2),a(12;i342,i0,i940,i0,i0,i1000,i0,i1000,i-940,i0,i342,i5000),a(0;),a(12;i906,i0,i423,i0,i0,i1000,i0,i0,i-423,i0,i906,i0),a(6;),a(1;E103),a(2;i0,i1),p(true;"Length"=i1,"Prototype"=E165,"Y"=i240,"Delay"=i0,"StartCall"=s"StartDead","Wdt"=i8,"ObjectDisabled"=i1,"NextAction"=s"Hold","X"=i0,"Hgt"=i20,"Name"=s"Dead","NoOtherAction"=i1,"Directions"=i2),a(12;i342,i0,i940,i0,i0,i1000,i0,i1000,i-940,i0,i342,i5000),a(12;i985,i0,i174,i0,i0,i1000,i0,i0,i-174,i0,i985,i0),a(0;),a(12;i530,i0,i848,i0,i0,i1000,i0,i0,i-848,i0,i530,i0),a(0;),a(12;i940,i0,i342,i0,i0,i1000,i0,i0,i-342,i0,i940,i0),a(0;),a(12;i-875,i0,i-485,i0,i0,i1000,i0,i0,i485,i0,i-875,i0),a(0;),a(12;i438,i0,i-899,i0,i0,i1000,i0,i0,i899,i0,i438,i0),a(0;),a(12;i-391,i0,i-921,i0,i0,i1000,i0,i0,i921,i0,i-391,i0),a(0;),a(12;i0,i0,i1000,i0,i0,i1000,i0,i0,i-1000,i0,i0,i0),a(0;),a(12;i-777,i0,i629,i0,i0,i1000,i0,i0,i-629,i0,i-777,i0),a(0;),a(12;i743,i0,i669,i0,i0,i1000,i0,i0,i-669,i0,i743,i0),a(0;),a(12;i-999,i0,i-35,i0,i0,i1000,i0,i0,i35,i0,i-999,i0),a(0;),a(12;i-946,i0,i326,i0,i0,i1000,i0,i0,i-326,i0,i-946,i0),a(0;),a(12;i375,i0,i-927,i0,i0,i1000,i0,i0,i927,i0,i375,i0),a(0;),a(12;i777,i0,i-629,i0,i0,i1000,i0,i0,i629,i0,i777,i0),a(0;),a(12;i-998,i0,i-70,i0,i0,i1000,i0,i0,i70,i0,i-998,i0),a(0;),a(12;i-87,i0,i996,i0,i0,i1000,i0,i0,i-996,i0,i-87,i0),a(0;),a(12;i-629,i0,i-777,i0,i0,i1000,i0,i0,i777,i0,i-629,i0),a(0;),a(12;i-819,i0,i574,i0,i0,i1000,i0,i0,i-574,i0,i-819,i0),a(0;),a(12;i515,i0,i857,i0,i0,i1000,i0,i0,i-857,i0,i515,i0),a(0;),a(12;i914,i0,i-407,i0,i0,i1000,i0,i0,i407,i0,i914,i0),a(0;),a(12;i-423,i0,i-906,i0,i0,i1000,i0,i0,i906,i0,i-423,i0),a(0;),a(12;i-545,i0,i839,i0,i0,i1000,i0,i0,i-839,i0,i-545,i0),a(0;),a(12;i-342,i0,i940,i0,i0,i1000,i0,i0,i-940,i0,i-342,i0),a(0;),p(false;"PhaseCall"=s"Check","Wdt"=i8,"Y"=i0,"Delay"=i2,"NextAction"=s"Sway","Prototype"=E166,"X"=i0,"Procedure"=n,"Animation"=s"Sway","Hgt"=i8,"Name"=s"Sway","Directions"=i2,"Length"=i78),p(false;"AnimationAim"=s"CrossbowAimArms","WalkSpeed"=i84,"WalkBack"=i56,"AimMode"=i1,"TurnType"=i1,"ShootTime"=i20,"AimSpeed"=i20,"AnimationShoot"=n),p(false;"AnimationLoad"=s"BowLoadArms","LoadTime2"=i7,"AnimationAim"=s"BowAimArms","AnimationReplacements"=E167,"WalkBack"=i56,"WalkSpeed"=i84,"AimMode"=i1,"TurnType"=i1,"LoadTime"=i30,"ShootTime"=i20,"AnimationShoot"=n),a(1;b0),a(7;E168,E169,E170,E171,E172,E173,E174),a(1;O494),a(1;O41),p(false;"amount"=i50,"obj"=O48),p(false;"amount"=i-50,"obj"=n),p(true;"Procedure"=n,"Step"=i1,"Directions"=i1,"Length"=i1),a(20;),a(0;),p(true;"Procedure"=n,"Step"=i1,"Directions"=i1,"Length"=i1),p(true;"Procedure"=n,"Step"=i1,"Directions"=i1,"Length"=i1),a(5;E175,E176,E177,E178,E179),a(2;s"IdleLookAround",i60),a(2;s"IdleHandwatch",i100),a(2;s"IdleScratch",i70),a(2;s"IdleStrech",i100),a(2;s"IdleShoe",i120),a(2;s"IdleShoeSole",i200),a(2;s"IdleHandstrech",i100),a(2;s"Walk",s"BowWalk"),a(2;s"Walk_Position",i20),a(2;s"Stand",s"BowStand"),a(2;s"Jump",s"BowJump"),a(2;s"KneelDown",s"BowKneel"), diff --git a/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/DefCore.txt b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/DefCore.txt new file mode 100644 index 000000000..624f5a23b --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_GetBack +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/Graphics.png b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/Graphics.png new file mode 100644 index 000000000..25d074045 Binary files /dev/null and b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/Script.c b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/Script.c new file mode 100644 index 000000000..8787ce97e --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/Script.c @@ -0,0 +1,50 @@ +/*-- + Get back goal + Author: ck + + All players have to get back to the hut +--*/ + + +#include Library_Goal + +protected func Initialize() +{ + return inherited(...); +} + +public func IsFulfilled() +{ + var cabin = FindObject(Find_ID(WoodenCabin)); + if (!cabin) + return false; + if (!GetPlayerCount() || GetEffect("IntIntro")) + return false; + + for(var i = 0; i < GetPlayerCount(); ++i) + { + var plr = GetPlayerByIndex(i), obj; + for(var j = 0; obj = GetCrew(plr, j); ++j) + if(ObjectDistance(obj, cabin) > 80) + return false; + } + + return true; +} + +public func Activate(int byplr) +{ + if (IsFulfilled()) + MessageWindow("$MsgGoalFulfilled$", byplr); + else + MessageWindow("$MsgGoalUnFulfilled$", byplr); + return; +} + +public func GetShortDescription(int plr) +{ + return "{{WoodenCabin}}"; // TODO +} + +/*-- Proplist --*/ +local Name = "$Name$"; diff --git a/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/StringTblDE.txt b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/StringTblDE.txt new file mode 100644 index 000000000..075e6f75e --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Finde den Weg zurück +MsgGoalFulfilled=Ihr habt den Weg zurück gefunden. +MsgGoalUnFulfilled=Ihr seid noch nicht zuhause. diff --git a/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/StringTblUS.txt b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/StringTblUS.txt new file mode 100644 index 000000000..655da47c5 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/GoalGetBack.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Find your way back home +MsgGoalFulfilled=You have made your way back home. +MsgGoalUnFulfilled=You are not at home yet. diff --git a/planet/Missions.ocf/MtBrame.ocs/Map.bmp b/planet/Missions.ocf/MtBrame.ocs/Map.bmp new file mode 100644 index 000000000..85fe7b955 Binary files /dev/null and b/planet/Missions.ocf/MtBrame.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/MtBrame.ocs/Scenario.txt b/planet/Missions.ocf/MtBrame.ocs/Scenario.txt new file mode 100644 index 000000000..9f7ceec08 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Scenario.txt @@ -0,0 +1,37 @@ +[Head] +Icon=24 +Title=MtBrame +Version=5,2,90,21 +Difficulty=80 +NoInitialize=true + +[Game] +Rules=Rule_TeamAccount=1;Rule_NoPowerNeed=1 + +[Player1] +Crew=Clonk=1 +Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1 + +[Player2] +Crew=Clonk=1 +Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1 + +[Player3] +Crew=Clonk=1 +Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1 + +[Player4] +Crew=Clonk=1 +Knowledge=Lorry=1;Catapult=1;Pickaxe=1;Axe=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;Loam=1 + +[Landscape] +Sky=Clouds2 +MapWidth=200,0,64,10000 +MapHeight=175,0,40,10000 +NoScan=true +NewStyleLandscape=2 + +[Weather] +Climate=30,10,0,100 +YearSpeed=0,0,0,100 +Wind=0,100,-100,100 diff --git a/planet/Missions.ocf/MtBrame.ocs/Script.c b/planet/Missions.ocf/MtBrame.ocs/Script.c new file mode 100644 index 000000000..bc53b30af --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Script.c @@ -0,0 +1,55 @@ +/** + Mt. Brame + Find a way back to your hut, defeating the dangers of Mt. Brame + + @authors ck +*/ + +static g_is_initialized; + +func Initialize() +{ + if(!ObjectCount(Find_ID(Rule_NoPowerNeed))) CreateObject(Rule_NoPowerNeed, 0, 0, NO_OWNER); +} + +func DoInit(int first_player) +{ + // Set time of day to morning and create some clouds and celestials. + Cloud->Place(20); + CreateObject(Environment_Celestial); + var time = CreateObject(Environment_Time); + time->SetTime(400); + time->SetCycleSpeed(6); + + // Workshop owner + var workshop = FindObject(Find_ID(ToolsWorkshop)); + if (workshop) workshop->SetOwner(first_player); + + // Goal + CreateObject(Goal_GetBack); + + return true; +} + +func InitializePlayer(int plr) +{ + var crew; + // Scenario init + if (!g_is_initialized) g_is_initialized = DoInit(plr); + // Start intro if not yet started + IntroStart(); + // Add player to intro if recently started + if(!IntroAddPlayer(plr)) + { + // Too late for entry? Just start in the valley + var index = 0; + for(var index = 0; crew = GetCrew(plr, index); ++index) + { + var x = 260*8/10 + Random(50); + var y = 1350*8/10; + crew->SetPosition(x , y); + crew->CreateContents(Shovel); + } + } +} + diff --git a/planet/Missions.ocf/MtBrame.ocs/System.ocg/Intro.c b/planet/Missions.ocf/MtBrame.ocs/System.ocg/Intro.c new file mode 100644 index 000000000..754d04f33 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/System.ocg/Intro.c @@ -0,0 +1,198 @@ + +static g_intro_initialized; + +global func IntroStart() +{ + if(!g_intro_initialized && !GetEffect("IntIntro")) + { + AddEffect("IntIntro", nil, 1, 2, nil, nil); + g_intro_initialized = true; + } +} + +global func IntroAddPlayer(int plr) +{ + var effect = GetEffect("IntIntro"); + if(!effect) return false; + if(effect.Time > 30) return false; + + var crew; + for(var index = 0; crew = GetCrew(plr, index); ++index) + { + var skin = crew->GetCrewExtraData("Skin"); + if (skin == nil) skin = GetPlrClonkSkin(plr); + + var container = effect.Cabin->CreateContents(Clonk); + container->SetOwner(plr); + if(skin != nil) container->SetSkin(skin); + container->SetName(crew->GetName()); + container->SetAction("Walk"); + crew->Enter(container); + + SetPlrView(plr, crew); + SetPlayerViewLock(plr, true); + SetPlayerZoomByViewRange(plr, 320, 240); + + container->SetCommand("None", container); + crew->SetCommand("None", crew); + + // Give everyone but the first player a shovel -- the first + // player's shovel can be found in the valley + if(GetLength(effect.Players) != 0) + crew->CreateContents(Shovel); + + effect.Players[GetLength(effect.Players)] = crew; + } + + return true; +} + +global func IntroCreateBoompack(int x, int y, int fuel) +{ + var boompack = CreateObject(Boompack, x, y, NO_OWNER); + boompack->SetFuel(fuel); + boompack->SetDirectionDeviation(8); // make sure direction of boompack is roughly kept + boompack->SetControllable(false); + return boompack; +} + +global func FxIntIntroStart(object target, proplist effect) +{ + effect.Cabin = FindObject(Find_ID(WoodenCabin)); + if(!effect.Cabin) return -1; + + effect.Sister = CreateObject(Clonk, 174, 532, NO_OWNER); + effect.Sister->MakeInvincible(); + effect.Sister->MakeNonFlammable(); + effect.Sister->SetSkin(1); + effect.Sister->SetName("$NameSister$"); + effect.Sister->SetColor(RGB(213, 68, 172)); + effect.Sister->SetObjectLayer(effect.Sister); + effect.Sister->SetDir(DIR_Right); + + effect.Dialog = effect.Sister->SetDialogue("Sister"); + effect.Rock = effect.Sister->CreateContents(Rock); + effect.Rock->SetObjectLayer(0); + effect.Players = []; +} + +global func FxIntIntroTimer(object target, proplist effect, int time) +{ + if(effect.Time == 40) + { + effect.Sister->SetCommand("MoveTo", effect.Sister, effect.Cabin->GetX() + 65 - effect.Sister->GetX(), effect.Cabin->GetY() + 10 - effect.Sister->GetY()); + } + + if(effect.Time == 110) + effect.Dialog->MessageBoxAll("$MsgIntro1$", effect.Sister); + + if(effect.Time == 150) + { + for(var crew in effect.Players) + { + crew = crew->Contained(); + + crew->SetCommand("Exit", crew); + crew->AppendCommand("MoveTo", crew, effect.Cabin->GetX() + RandomX(10,40) - crew->GetX(), effect.Cabin->GetY() - crew->GetY()); + } + } + + if(effect.Time == 200) + effect.Dialog->MessageBoxAll("$MsgIntro2$", GetCrew(GetPlayerByIndex(Random(GetPlayerCount())), 0)); + + if(effect.Time == 270) + { + effect.Dialog->MessageBoxAll("$MsgIntro3$", effect.Sister); + } + + if(effect.Time == 350) + { + effect.Sister->SetCommand("MoveTo", effect.Sister, 214 - effect.Sister->GetX(), 540 - effect.Sister->GetY()); + } + + if(effect.Time == 370) + { + for(var crew in effect.Players) + { + crew = crew->Contained(); + crew->SetCommand("MoveTo", crew, 245 - crew->GetX(), 555 - crew->GetY()); + } + } + + if(effect.Time == 500) + { + effect.Sister->SetCommand("MoveTo", effect.Sister, 214 - effect.Sister->GetX(), 540 - effect.Sister->GetY()); + for(var crew in effect.Players) + crew->Contained()->SetDir(DIR_Left); + effect.Dialog->MessageBoxAll("$MsgIntro4$", GetCrew(GetPlayerByIndex(Random(GetPlayerCount())), 0)); + } + + if(effect.Time == 520) + effect.Sister->SetDir(DIR_Right); + + if(effect.Time == 550) + { + effect.Sister->ObjectCommand("Throw", effect.Rock, 500, 100); + for(var i = 0; i < GetPlayerCount(); ++i) + SetPlrView(GetPlayerByIndex(i), effect.Sister); + } + + if(effect.Time == 556) + { + for(var crew in effect.Players) + crew->Contained()->Fling(3,-3); + } + + if(effect.Time == 570) + { + effect.Dialog->MessageBoxAll("$MsgIntro5$", effect.Sister); + } + + if(effect.Time == 620) + { + effect.Dialog->MessageBoxAll("$MsgIntro6$", GetCrew(GetPlayerByIndex(Random(GetPlayerCount())), 0)); + } + + if(effect.Time == 700) + { + effect.Dialog->MessageBoxAll("$MsgIntro7$", effect.Sister); + } + + if(effect.Time == 800) + { + effect.Dialog->MessageBoxAll("$MsgIntro8$", effect.Sister); + } + + if(effect.Time == 860) + { + effect.Sister->SetCommand("Enter", effect.Cabin); + } + + if(effect.Time == 920) + { + for(var i = 0; i < GetPlayerCount(); ++i) + GetCursor(GetPlayerByIndex(i))->CloseMenu(); + } + + if(effect.Time == 950) + { + for(var crew in effect.Players) + { + SetPlrView(crew->GetOwner(), crew); + SetPlayerViewLock(crew->GetOwner(), true); + var container = crew->Contained(); + crew->Exit(0, 10); + container->RemoveObject(); + } + + for(var i = 0; i < GetPlayerCount(); ++i) + GetCursor(GetPlayerByIndex(i))->CloseMenu(); + } + + if(effect.Time >= 1000) + { + // just to be sure... + effect.Sister->Enter(effect.Cabin); + return -1; + } +} diff --git a/planet/Missions.ocf/MtBrame.ocs/System.ocg/NoPower.c b/planet/Missions.ocf/MtBrame.ocs/System.ocg/NoPower.c new file mode 100644 index 000000000..b412165f7 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/System.ocg/NoPower.c @@ -0,0 +1,3 @@ +#appendto ToolsWorkshop + +private func PowerNeed() { return 0; } diff --git a/planet/Missions.ocf/MtBrame.ocs/System.ocg/StringTblDE.txt b/planet/Missions.ocf/MtBrame.ocs/System.ocg/StringTblDE.txt new file mode 100644 index 000000000..3533f8c4e --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/System.ocg/StringTblDE.txt @@ -0,0 +1,12 @@ +# Intro +NameSister=Ruth + +# Intro +MsgIntro1=Hey ihr Schlafmützen, schaut mal was ich gefunden habe! +MsgIntro2=...was? Wo denn? +MsgIntro3=Dort unten, am Hang! +MsgIntro4=Und was soll hier sein..? +MsgIntro5=Hihi...! +MsgIntro6=Waaaaaah! +MsgIntro7=Hm, war vielleicht doch ein bisschen tief? +MsgIntro8=Egal, die werden schon rausfinden... diff --git a/planet/Missions.ocf/MtBrame.ocs/System.ocg/StringTblUS.txt b/planet/Missions.ocf/MtBrame.ocs/System.ocg/StringTblUS.txt new file mode 100644 index 000000000..afb1e7d82 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/System.ocg/StringTblUS.txt @@ -0,0 +1,11 @@ +NameSister=Ruth + +# Intro +MsgIntro1=Hey sleepyheads! Check out what I found! +MsgIntro2=...What? Where? +MsgIntro3=Down there, at the bottom of the hill! +MsgIntro4=And what's supposed to be here..? +MsgIntro5=Hihi...! +MsgIntro6=Waaaaaah! +MsgIntro7=Hm, maybe that was a bit too deep? +MsgIntro8=Whatever, they'll find their way back... diff --git a/planet/Missions.ocf/MtBrame.ocs/Teams.txt b/planet/Missions.ocf/MtBrame.ocs/Teams.txt new file mode 100644 index 000000000..9c133ec5c --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Teams.txt @@ -0,0 +1,5 @@ +[Teams] +Active=false +Custom=false +AllowHostilityChange=true +AutoGenerateTeams=true diff --git a/planet/Missions.ocf/MtBrame.ocs/Title.txt b/planet/Missions.ocf/MtBrame.ocs/Title.txt new file mode 100644 index 000000000..5289465d7 --- /dev/null +++ b/planet/Missions.ocf/MtBrame.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Mount Brame +US:Mount Brame diff --git a/planet/Missions.ocf/RubyCave.ocs/DescDE.rtf b/planet/Missions.ocf/RubyCave.ocs/DescDE.rtf new file mode 100644 index 000000000..fa4556f40 Binary files /dev/null and b/planet/Missions.ocf/RubyCave.ocs/DescDE.rtf differ diff --git a/planet/Missions.ocf/RubyCave.ocs/DescUS.rtf b/planet/Missions.ocf/RubyCave.ocs/DescUS.rtf new file mode 100644 index 000000000..f9d4b5752 Binary files /dev/null and b/planet/Missions.ocf/RubyCave.ocs/DescUS.rtf differ diff --git a/planet/Missions.ocf/RubyCave.ocs/Icon.png b/planet/Missions.ocf/RubyCave.ocs/Icon.png new file mode 100644 index 000000000..8dcb08d80 Binary files /dev/null and b/planet/Missions.ocf/RubyCave.ocs/Icon.png differ diff --git a/planet/Missions.ocf/RubyCave.ocs/Landscape.txt b/planet/Missions.ocf/RubyCave.ocs/Landscape.txt new file mode 100644 index 000000000..6be63d89f --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Landscape.txt @@ -0,0 +1,97 @@ +/* Ruby cave - by Sven2 */ + +overlay VaryTex { turbulence=10; algo=rndchecker; zoomX=-100; zoomY=-100; }; +overlay GraniteBorders {turbulence=100; mat=Granite; loosebounds=1; VaryTex {mat=Rock; tex=rock_cracked; a=1;};}; + +map CrystalCaves { + // Base background is earth + mat=Earth; tex=earth_rough; + VaryTex { mat=Earth; tex=earth_dry; }; + VaryTex { mat=Earth; tex=earth; }; + + // Resources + VaryTex { mat=Rock; y=50px; zoomX=30; a=3;}; + VaryTex { mat=Granite; y=80px; zoomX=30; a=5;}; + VaryTex { mat=Coal; a=10; }; + VaryTex { mat=Ore; a=10; }; + VaryTex { mat=Firestone; y=40px; a=8; hgt=50px;x=60px;}; + VaryTex { mat=Gold; y=70px; a=20; }; + + // Top caves for mushyrooms + overlay { hgt=32px; mask=1; + overlay { algo=rndchecker; x=55px; hgt=32px; mat=Tunnel; a=3;zoomX=50;zoomY=-20; turbulence=100; loosebounds=1; }; + }; + + // Water. Only in bottom area. + overlay { y=35px; mask=1; + overlay WaterVein { x=100px; turbulence=100; algo=rndchecker; zoomX=-100; zoomY=100; a=5; loosebounds=1; mat=Water; }; + WaterVein { x=70px; rotate=-20; }; + WaterVein { x=30px; rotate=20; }; + }; + + // Rock/granite in mid area + overlay { y=30px; hgt=12px; turbulence=1000; loosebounds=1; mask=1; + VaryTex { mat=Rock; zoomX=-100; }; + VaryTex { mat=Granite; zoomX=-100; }; + }; + + // Granite borders + GraniteBorders { y=-20px; hgt=24px; }; + GraniteBorders { x=146px; }; + GraniteBorders { y=126px; rotate=-10; VaryTex {mat=Water; };}; + GraniteBorders { x=-20px; wdt=24px; }; + + // Ruby cave water basin + overlay { algo=poly; mat=Water; turbulence=10; + point { x=100px; y=120px; }; + point { x=110px; y=90px; }; + point { x=130px; y=85px; }; + point { x=145px; y=95px; }; + point { x=140px; y=105px; }; + point { x=145px; y=130px; }; + point { x=125px; y=140px; }; + point { x=115px; y=140px; }; + }; + // Ruby cave socket + overlay { algo=poly; mat=Granite; turbulence=10; + point { x=100px; y=150px; }; + point { x=115px; y=145px; }; + point { x=117px; y=120px; }; + point { x=123px; y=120px; }; + point { x=125px; y=145px; }; + point { x=140px; y=150px; }; + }; + // Ruby cave rubies! + overlay { algo=poly; mat=Ruby; turbulence=10; + point { x=114px; y=125px; }; + point { x=116px; y=119px; }; + point { x=120px; y=115px; }; + point { x=124px; y=119px; }; + point { x=126px; y=125px; }; + point { x=120px; y=128px; }; + overlay {algo=border; a=2; b=0; turbulence=10; mat=Amethyst; }; + overlay {algo=border; a=1; b=1; mat=Granite; }; + }; + + // Starting cave + overlay { algo=poly; mat=Tunnel; turbulence=10; + hgt=25px; + point { x=-100px; y=10px; }; + point { x=0px; y=10px; }; + point { x=0px; y=10px; }; + point { x=18px; y=5px; }; + point { x=40px; y=15px; }; + point { x=40px; y=20px; }; + point { x=30px; y=35px; }; + point { x=-100px; y=35px; }; + + // sky back + VaryTex { a=2; wdt=23px; }; + // windmill positions + overlay { x=5px; wdt=22px; y=10px; turbulence=10; loosebounds=1;}; + + overlay { y=24px; mat=Brick; }; + + }; + +}; \ No newline at end of file diff --git a/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Amethyst.jpg b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Amethyst.jpg new file mode 100644 index 000000000..36c0dd8a0 Binary files /dev/null and b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Amethyst.jpg differ diff --git a/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Amethyst.ocm b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Amethyst.ocm new file mode 100644 index 000000000..0d64a3831 --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Amethyst.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Amethyst +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Amethyst +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Amethyst diff --git a/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Ruby.jpg b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Ruby.jpg new file mode 100644 index 000000000..c84122ce9 Binary files /dev/null and b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Ruby.jpg differ diff --git a/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Ruby.ocm b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Ruby.ocm new file mode 100644 index 000000000..c7a631d97 --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/Ruby.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Ruby +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Ruby +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Ruby diff --git a/planet/Missions.ocf/RubyCave.ocs/Material.ocg/TEXMAP.TXT b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..880820dff --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,47 @@ +OverloadMaterials +OverloadTextures + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore + +40=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +60=Ruby-Ruby +61=Amethyst-Amethyst + +65=Ice-ice2 +67=Ice-ice3 + +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/Missions.ocf/RubyCave.ocs/Scenario.txt b/planet/Missions.ocf/RubyCave.ocs/Scenario.txt new file mode 100644 index 000000000..5e1ae6c91 --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Scenario.txt @@ -0,0 +1,52 @@ +[Head] +Title=RubyCave +Icon=24 +Version=5,2,0,1 +Difficulty=20 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_SellGems=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player2] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player3] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player4] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1;DynamiteBox=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Landscape] +Sky=Clouds1 +SkyScrollMode=1 +TopOpen=0 +BottomOpen=0 +MapWidth=150 +MapHeight=150 +MapZoom=8 + +[Weather] +Climate=00,0,0,00 +StartSeason=0,0,0,00 +YearSpeed=0,0,0,000 +Wind=100,0,100,100 + diff --git a/planet/Missions.ocf/RubyCave.ocs/Script.c b/planet/Missions.ocf/RubyCave.ocs/Script.c new file mode 100644 index 000000000..3800ce0d6 --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Script.c @@ -0,0 +1,99 @@ +/* Ruby cave */ + +func Initialize() +{ + // Goal + var goal = FindObject(Find_ID(Goal_SellGems)); + if (!goal) goal = CreateObject(Goal_SellGems); + goal->SetTargetAmount(10); + // Rules + if (!ObjectCount(Find_ID(Rule_TeamAccount))) CreateObject(Rule_TeamAccount); + if (!ObjectCount(Find_ID(Rule_BuyAtFlagpole))) CreateObject(Rule_BuyAtFlagpole); + // Mushrooms before any earth materials, because they create their own caves + LargeCaveMushroom->Place(15, Rectangle(400,0,800,200)); + // Create earth materials + // Create them in big clusters so the whole object arrangement looks a bit less uniform and more interesting + PlaceBatches([Firestone], 3, 100, 5); + PlaceBatches([Rock, Loam, Loam], 10, 200, 10); + // Misc vegetation + SproutBerryBush->Place(5, Rectangle(350,0,850,250)); + Mushroom->Place(5, Rectangle(350,0,850,250)); + return true; +} + +static g_was_player_init; + +func InitializePlayer(int plr) +{ + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,500,350,flag); + SetPlayerViewLock(plr, true); + // First player init base + if (!g_was_player_init) + { + InitBase(plr); + g_was_player_init = true; + } + // Position and materials + var i, crew; + for (i=0; crew=GetCrew(plr,i); ++i) + { + crew->SetPosition(100+Random(80), 192-10); + crew->CreateContents(Shovel); + if (!i) + { + crew->CreateContents(Hammer); + } + else if (i==1) + { + crew->CreateContents(Axe); + } + } + return true; +} + +private func InitBase(int owner) +{ + // Create standard base owned by player + var y=192; + var workshop = CreateObject(ToolsWorkshop, 70, y, owner); + if (workshop) + { + workshop->CreateContents(Wood, 3); + workshop->CreateContents(Metal, 1); + workshop->CreateContents(Pipe, 2); + } + var windgenerator = CreateObject(WindGenerator, 150,y, owner); + var flag = CreateObject(Flagpole, 180,y, owner); + var foundry = CreateObject(Foundry, 220,y, owner); + if (foundry) + { + foundry->CreateContents(Coal, 3); + foundry->CreateContents(Metal, 2); + } + var chest = CreateObject(Chest, 260,y, owner); + if (chest) + { + chest->CreateContents(DynamiteBox, 1); + chest->CreateContents(Dynamite, 2); + } + return true; +} + +private func PlaceBatches(array item_ids, int n_per_batch, int batch_radius, int n_batches) +{ + // place a number (n_batches) of batches of objects of types item_ids. Each batch has n_per_batch objects. + // fewer batches and/or objects may be placed if no space is found + var loc,loc2,n_item_ids=GetLength(item_ids), n_created=0, obj; + for (var i=0; iSetPosition(loc2.x,loc2.y); + ++n_created; + } + return n_created; +} diff --git a/planet/Missions.ocf/RubyCave.ocs/Title.txt b/planet/Missions.ocf/RubyCave.ocs/Title.txt new file mode 100644 index 000000000..779cf9a11 --- /dev/null +++ b/planet/Missions.ocf/RubyCave.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Rubinhöhle +US:Ruby Cave \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/DescDE.rtf b/planet/Missions.ocf/Skylands.ocs/DescDE.rtf similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/DescDE.rtf rename to planet/Missions.ocf/Skylands.ocs/DescDE.rtf diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/DescUS.rtf b/planet/Missions.ocf/Skylands.ocs/DescUS.rtf similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/DescUS.rtf rename to planet/Missions.ocf/Skylands.ocs/DescUS.rtf diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Map.bmp b/planet/Missions.ocf/Skylands.ocs/Map.bmp similarity index 60% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Map.bmp rename to planet/Missions.ocf/Skylands.ocs/Map.bmp index c3a904e1f..c4374e765 100644 Binary files a/planet/BeyondTheRocks.ocf/Skylands.ocs/Map.bmp and b/planet/Missions.ocf/Skylands.ocs/Map.bmp differ diff --git a/planet/Missions.ocf/Skylands.ocs/Objects.c b/planet/Missions.ocf/Skylands.ocs/Objects.c new file mode 100644 index 000000000..ca98d70c5 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Objects.c @@ -0,0 +1,217 @@ +/* Automatically created objects file */ + +func InitializeObjects() +{ + CreateObject(Rule_TeamAccount, 50, 50); + + CreateObject(Rule_BuyAtFlagpole, 50, 50); + + CreateObject(Tree_Coniferous, 962, 839); + CreateObject(Tree_Coniferous, 774, 951); + + CreateObject(Tree_SmallConiferous, 46, 441); + var Tree_SmallConiferous0015 = CreateObject(Tree_SmallConiferous, 320, 312); + Tree_SmallConiferous0015->SetR(-30); + Tree_SmallConiferous0015->SetPosition(320, 293); + var Tree_SmallConiferous0019 = CreateObject(Tree_SmallConiferous, 422, 887); + Tree_SmallConiferous0019->SetClrModulation(0xffb0b080); + var Tree_SmallConiferous0023 = CreateObject(Tree_SmallConiferous, 373, 920); + Tree_SmallConiferous0023->SetClrModulation(0xff808080); + var Tree_SmallConiferous0027 = CreateObject(Tree_SmallConiferous, 72, 744); + Tree_SmallConiferous0027->SetClrModulation(0xff808080); + CreateObject(Tree_SmallConiferous, 974, 327); + CreateObject(Tree_SmallConiferous, 1003, 326); + CreateObject(Tree_SmallConiferous, 550, 107); + CreateObject(Tree_SmallConiferous, 632, 128); + var Tree_SmallConiferous0047 = CreateObject(Tree_SmallConiferous, 129, 409); + Tree_SmallConiferous0047->SetR(-5); + Tree_SmallConiferous0047->SetClrModulation(0xffd49d68); + Tree_SmallConiferous0047->SetPosition(129, 387); + CreateObject(Tree_SmallConiferous, 78, 440); + var Tree_SmallConiferous0055 = CreateObject(Tree_SmallConiferous, 182, 408); + Tree_SmallConiferous0055->SetR(-2); + Tree_SmallConiferous0055->SetClrModulation(0xffca999c); + Tree_SmallConiferous0055->SetPosition(182, 386); + var Tree_SmallConiferous0059 = CreateObject(Tree_SmallConiferous, 200, 408); + Tree_SmallConiferous0059->SetR(8); + Tree_SmallConiferous0059->SetClrModulation(0xfff7e5ee); + Tree_SmallConiferous0059->SetPosition(200, 386); + CreateObject(Tree_SmallConiferous, 23, 452); + var Tree_SmallConiferous0067 = CreateObject(Tree_SmallConiferous, 110, 410); + Tree_SmallConiferous0067->SetR(1); + Tree_SmallConiferous0067->SetClrModulation(0xffe9e2b0); + Tree_SmallConiferous0067->SetPosition(110, 388); + var Tree_SmallConiferous0071 = CreateObject(Tree_SmallConiferous, 167, 408); + Tree_SmallConiferous0071->SetR(-4); + Tree_SmallConiferous0071->SetClrModulation(0xffedfa82); + Tree_SmallConiferous0071->SetPosition(167, 386); + var Tree_SmallConiferous0075 = CreateObject(Tree_SmallConiferous, 93, 430); + Tree_SmallConiferous0075->SetR(-10); + Tree_SmallConiferous0075->SetClrModulation(0xffedf4c6); + Tree_SmallConiferous0075->SetPosition(93, 408); + var Tree_SmallConiferous0079 = CreateObject(Tree_SmallConiferous, 36, 446); + Tree_SmallConiferous0079->SetR(-2); + Tree_SmallConiferous0079->SetClrModulation(0xffca90cd); + Tree_SmallConiferous0079->SetPosition(36, 424); + var Tree_SmallConiferous0083 = CreateObject(Tree_SmallConiferous, 151, 406); + Tree_SmallConiferous0083->SetR(-3); + Tree_SmallConiferous0083->SetClrModulation(0xffd8d7e0); + Tree_SmallConiferous0083->SetPosition(151, 384); + var Tree_SmallConiferous0087 = CreateObject(Tree_SmallConiferous, 159, 407); + Tree_SmallConiferous0087->SetClrModulation(0xffd1e168); + var Tree_SmallConiferous0091 = CreateObject(Tree_SmallConiferous, 60, 440); + Tree_SmallConiferous0091->SetR(-10); + Tree_SmallConiferous0091->SetClrModulation(0xffd8c49d); + Tree_SmallConiferous0091->SetPosition(60, 418); + var Tree_SmallConiferous0095 = CreateObject(Tree_SmallConiferous, 355, 313); + Tree_SmallConiferous0095->SetR(10); + Tree_SmallConiferous0095->SetPosition(355, 291); + CreateObject(Tree_SmallConiferous, 132, 726); + var Tree_SmallConiferous0103 = CreateObject(Tree_SmallConiferous, 487, 805); + Tree_SmallConiferous0103->SetR(-30); + Tree_SmallConiferous0103->SetPosition(487, 786); + + var Chest0107 = CreateObject(Chest, 164, 903); + Chest0107->SetClrModulation(0xd0ffffff); + var Chest0108 = CreateObject(Chest, 503, 808); + Chest0108->SetClrModulation(0xd0ffffff); + var Chest0109 = CreateObject(Chest, 611, 1047); + Chest0109->SetClrModulation(0xd0ffffff); + var Chest0110 = CreateObject(Chest, 258, 134); + Chest0110->SetClrModulation(0xd0ffffff); + var Chest0111 = CreateObject(Chest, 990, 327); + Chest0111->SetClrModulation(0xd0ffffff); + var Chest0112 = CreateObject(Chest, 947, 841); + Chest0112->SetClrModulation(0xd0ffffff); + + CreateObject(Plane_Construction, 272, 415); + + var Plane_Wings0115 = CreateObject(Plane_Wings, 600, 129); + Plane_Wings0115->SetR(117); + Plane_Wings0115->SetPosition(600, 118); + + var Plane_Skids0116 = CreateObject(Plane_Skids, 457, 896); + Plane_Skids0116->SetR(13); + Plane_Skids0116->SetPosition(457, 887); + + var Plane_Chassis0117 = CreateObject(Plane_Chassis, 908, 973); + Plane_Chassis0117->SetR(-18); + Plane_Chassis0117->SetPosition(908, 960); + + Chest0110->CreateContents(Rock); + Chest0110->CreateContents(Rock); + Chest0110->CreateContents(Rock); + Chest0110->CreateContents(Rock); + Chest0108->CreateContents(Rock); + Chest0108->CreateContents(Rock); + Chest0108->CreateContents(Rock); + Chest0108->CreateContents(Rock); + Chest0112->CreateContents(Rock); + Chest0112->CreateContents(Rock); + + Chest0107->CreateContents(Nugget); + Chest0107->CreateContents(Nugget); + Chest0107->CreateContents(Nugget); + Chest0111->CreateContents(Nugget); + Chest0111->CreateContents(Nugget); + Chest0111->CreateContents(Nugget); + + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0111->CreateContents(Loam); + Chest0112->CreateContents(Loam); + Chest0108->CreateContents(Loam); + Chest0112->CreateContents(Loam); + Chest0108->CreateContents(Loam); + Chest0112->CreateContents(Loam); + Chest0108->CreateContents(Loam); + Chest0112->CreateContents(Loam); + Chest0108->CreateContents(Loam); + Chest0107->CreateContents(Loam); + Chest0107->CreateContents(Loam); + Chest0109->CreateContents(Loam); + Chest0109->CreateContents(Loam); + Chest0109->CreateContents(Loam); + Chest0110->CreateContents(Loam); + Chest0110->CreateContents(Loam); + Chest0110->CreateContents(Loam); + CreateObject(Loam, 116, 755); + CreateObject(Loam, 183, 480); + CreateObject(Loam, 41, 486); + CreateObject(Loam, 158, 432); + CreateObject(Loam, 552, 187); + CreateObject(Loam, 995, 349); + CreateObject(Loam, 1052, 368); + CreateObject(Loam, 177, 747); + Chest0109->CreateContents(Loam); + Chest0109->CreateContents(Loam); + Chest0109->CreateContents(Loam); + + Chest0111->CreateContents(Wood); + Chest0111->CreateContents(Wood); + Chest0111->CreateContents(Wood); + Chest0112->CreateContents(Wood); + Chest0112->CreateContents(Wood); + Chest0112->CreateContents(Wood); + + Chest0108->CreateContents(Metal); + Chest0108->CreateContents(Metal); + Chest0112->CreateContents(Metal); + Chest0107->CreateContents(Metal); + Chest0109->CreateContents(Metal); + Chest0108->CreateContents(Metal); + Chest0108->CreateContents(Metal); + + Chest0110->CreateContents(GoldBar); + Chest0109->CreateContents(GoldBar); + Chest0109->CreateContents(GoldBar); + Chest0109->CreateContents(GoldBar); + Chest0112->CreateContents(GoldBar); + + var Plane_Propeller0188 = CreateObject(Plane_Propeller, 1031, 334); + Plane_Propeller0188->SetR(20); + Plane_Propeller0188->SetPosition(1031, 329); + + Chest0108->CreateContents(Firestone); + Chest0108->CreateContents(Firestone); + Chest0108->CreateContents(Firestone); + Chest0110->CreateContents(Firestone); + Chest0110->CreateContents(Firestone); + Chest0107->CreateContents(Firestone); + Chest0107->CreateContents(Firestone); + Chest0107->CreateContents(Firestone); + Chest0109->CreateContents(Firestone); + CreateObject(Firestone, 163, 486); + CreateObject(Firestone, 143, 444); + CreateObject(Firestone, 37, 467); + CreateObject(Firestone, 178, 442); + CreateObject(Firestone, 566, 233); + CreateObject(Firestone, 539, 176); + CreateObject(Firestone, 102, 760); + CreateObject(Firestone, 426, 916); + CreateObject(Firestone, 479, 932); + CreateObject(Firestone, 848, 1000); + CreateObject(Firestone, 908, 1012); + CreateObject(Firestone, 1063, 354); + CreateObject(Firestone, 170, 446); + CreateObject(Firestone, 259, 478); + CreateObject(Firestone, 310, 477); + CreateObject(Firestone, 350, 414); + CreateObject(Firestone, 469, 913); + Chest0109->CreateContents(Firestone); + Chest0109->CreateContents(Firestone); + Chest0109->CreateContents(Firestone); + Chest0109->CreateContents(Firestone); + CreateObject(Firestone, 89, 766); + CreateObject(Firestone, 135, 741); + CreateObject(Firestone, 159, 748); + CreateObject(Firestone, 199, 470); + CreateObject(Firestone, 361, 351); + return true; +} diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/DefCore.txt similarity index 72% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/DefCore.txt index 05131447d..bcb3a76f4 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/DefCore.txt +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/DefCore.txt @@ -6,7 +6,8 @@ Width=60 Height=25 Offset=-30,-12 Vertices=6 -VertexX=-25,-25,0,0,27,25 +; VertexX=-25,-25,0,0,27,25 - doesnt fit in double elevator +VertexX=-22,-22,0,0,20,20 VertexY=7,-7,7,-7,-8,1 VertexFriction=30,60,30,60,60,30 Value=40 diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Graphics.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Graphics.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Graphics.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Graphics.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Script.c similarity index 59% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Script.c index 4f00955e4..4789bd8a5 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/Script.c @@ -5,6 +5,9 @@ Used to construct the plane --*/ +#include Library_PlanePart +#include Library_ElevatorControl + private func Hit() { Sound("WoodHit"); @@ -20,3 +23,5 @@ local Collectible = false; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local Touchable = 1; // Later, this could be done with the lift tower. There is no working lift tower at the moment though :( +local HitPoints = 20; diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Chassis.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/DefCore.txt similarity index 92% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/DefCore.txt index 2e85d105e..cbb4bd568 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/DefCore.txt +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/DefCore.txt @@ -14,5 +14,3 @@ Mass=4000 Components=Plane_Propeller=1;Plane_Chassis=1;Plane_Skids=1;Plane_Engine=1;Plane_Wings=1; Construction=0 Rotate=0 -TimerCall=Timer -Timer=10 diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Graphics.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Graphics.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Graphics.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Graphics.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Script.c similarity index 87% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Script.c index 0c46c7a1e..1a2b7afa1 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/Script.c @@ -5,6 +5,8 @@ Used to construct the plane --*/ +#include Library_PlanePart + private func Hit() { Sound("WoodHit"); @@ -22,3 +24,4 @@ local Collectible = true; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local HitPoints = 20; diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Engine.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics1.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics1.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics1.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics1.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics2.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics2.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics2.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics2.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics3.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics3.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics3.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics3.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics4.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics4.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Graphics4.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Graphics4.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/GraphicsSite.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/GraphicsSite.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/GraphicsSite.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/GraphicsSite.10.png diff --git a/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/DefCore.txt new file mode 100644 index 000000000..229a4f5bc --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Library_PlanePart +Version=5,2,2,0 +Category=C4D_StaticBack \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/Graphics.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Libraries.ocd/Plant.ocd/Graphics.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/Graphics.png diff --git a/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/Script.c new file mode 100644 index 000000000..d12d9d93d --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Library_PlanePart.ocd/Script.c @@ -0,0 +1,18 @@ +/** + Plane part Library + * Damage + + @author Sven2 +*/ + +public func Damage(int change, int cause, int cause_plr) +{ + // Only do stuff if the object has the HitPoints property. + if (this && this.HitPoints != nil) + if (GetDamage() >= this.HitPoints) + { + // Destruction callback is made by the engine. + return RemoveObject(); + } + return _inherited(change, cause, cause_plr, ...); +} \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Graphics.20.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Graphics.20.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Graphics.20.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Graphics.20.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Script.c similarity index 86% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Script.c index 0b9ce9da5..c8cea042b 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/Script.c @@ -5,6 +5,8 @@ Used to construct the plane --*/ +#include Library_PlanePart + private func Hit() { Sound("WoodHit"); @@ -20,3 +22,4 @@ local Collectible = true; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local HitPoints = 20; diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Propeller.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Script.c similarity index 97% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Script.c index 1307cad06..527d989bf 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Script.c @@ -10,6 +10,7 @@ local progress, next_part; public func Initialize() { SetProgress(0); + AddTimer("Timer", 10); } func SetProgress(int new_progress) diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Graphics.8.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Graphics.8.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Graphics.8.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Graphics.8.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Script.c similarity index 88% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Script.c index fbcca7879..05c76d4ad 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/Script.c @@ -5,6 +5,7 @@ Used to construct the plane --*/ +#include Library_PlanePart #include Library_ElevatorControl private func Hit() @@ -23,3 +24,4 @@ local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; local Touchable = 1; +local HitPoints = 20; diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Skids.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Graphics.10.png b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Graphics.10.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Graphics.10.png rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Graphics.10.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Script.c similarity index 88% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Script.c index 67fc3e68b..32a416a78 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/Script.c @@ -5,6 +5,7 @@ Used to construct the plane --*/ +#include Library_PlanePart #include Library_ElevatorControl private func Hit() @@ -23,3 +24,4 @@ local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; local Touchable = 1; +local HitPoints = 20; diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/Plane.ocd/Wings.ocd/StringTblUS.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/Graphics.png b/planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/Graphics.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/Graphics.png rename to planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/Graphics.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/Script.c similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/Script.c diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/PlaneGoal.ocd/StringTblUS.txt diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/DefCore.txt new file mode 100644 index 000000000..d829abe49 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Scaffold +Version=5,2,0,1 +Category=C4D_Structure +Width=32 +Height=32 +Offset=-16,-16 +Vertices=4 +VertexX=-15,15,-15,15 +VertexY=-15,-15,15,15 +VertexFriction=50,50,100,100 +Value=20 +Mass=1000 +Components=Wood=1 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Graphics.4.png b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Graphics.4.png new file mode 100644 index 000000000..e75d61bb6 Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Graphics.4.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Script.c new file mode 100644 index 000000000..aa0ff2e8f --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Script.c @@ -0,0 +1,117 @@ +/*-- Scaffold --*/ + +#include Library_Structure + +/* Initialization */ + +func Initialize() +{ + return _inherited(...); +} + +func Destruction() +{ + RemoveWalls(); + return _inherited(...); +} + +func Incineration() +{ + RemoveWalls(); + return _inherited(...); +} + +func RemoveWalls() +{ + if (wall_left) wall_left->RemoveObject(); + if (wall_right) wall_right->RemoveObject(); + if (wall_top) wall_top->RemoveObject(); + if (wall_bottom) wall_bottom->RemoveObject(); + if (wall_right2) wall_right2->RemoveObject(); + if (wall_bottom2) wall_bottom2->RemoveObject(); + return true; +} + +/* Interaction */ + +local wall_left, wall_right, wall_top, wall_bottom; + +local wall_right2, wall_bottom2; // Hack to make Skylands work for now... + +func ControlUp() +{ + if (wall_top) + wall_top->RemoveObject(); + else + (wall_top = CreateObject(ScaffoldWall,0,0,GetOwner()))->SetTop(this); + Sound("DullWoodHit1"); + return true; +} + +func ControlLeft() +{ + if (wall_left) + wall_left->RemoveObject(); + else + (wall_left = CreateObject(ScaffoldWall,0,0,GetOwner()))->SetLeft(this); + Sound("DullWoodHit1"); + return true; +} + +func ControlRight() +{ + if (wall_right) + if (wall_right2) + { + wall_right->RemoveObject(); + wall_right2->RemoveObject(); + } + else + (wall_right2 = CreateObject(ScaffoldWall,0,0,GetOwner()))->SetRight2(this); + else + (wall_right = CreateObject(ScaffoldWall,0,0,GetOwner()))->SetRight(this); + Sound("DullWoodHit1"); + return true; +} + +func ControlDown() +{ + if (wall_bottom) + if (wall_bottom2) + { + wall_bottom->RemoveObject(); + wall_bottom2->RemoveObject(); + } + else + (wall_bottom2 = CreateObject(ScaffoldWall,0,0,GetOwner()))->SetBottom2(this); + else + (wall_bottom = CreateObject(ScaffoldWall,0,0,GetOwner()))->SetBottom(this); + Sound("DullWoodHit1"); + return true; +} + +/* Destruction */ + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 1, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Default", + }, +}; + +func Definition(def) { + +} + +local Name = "$Name$"; +local Description = "$Description$"; +local BlastIncinerate = 100; +local HitPoints = 30; +local Plane = 120; +local Touchable = 1; diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/StringTblDE.txt new file mode 100644 index 000000000..78421d12c --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Geruest +Description=Erlaubt den Bau groesserer Strukturen. \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/StringTblUS.txt new file mode 100644 index 000000000..5f190abb1 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Scaffold +Description=Allows you to build greater structures. \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/DefCore.txt new file mode 100644 index 000000000..b01b59361 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/DefCore.txt @@ -0,0 +1,10 @@ +[DefCore] +id=ScaffoldWall +Version=5,2,0,1 +Category=C4D_Structure | C4D_MouseIgnore +Width=32 +Height=32 +Offset=0,0 +Vertices=1 +Mass=100 +Components=Wood=1 diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/Graphics.4.png b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/Graphics.4.png new file mode 100644 index 000000000..4f653b289 Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/Graphics.4.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsBottom.4.png b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsBottom.4.png new file mode 100644 index 000000000..37250ca7d Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsBottom.4.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsLeft.4.png b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsLeft.4.png new file mode 100644 index 000000000..5811544e0 Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsLeft.4.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsRight.4.png b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsRight.4.png new file mode 100644 index 000000000..9ff954abf Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsRight.4.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsTop.4.png b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsTop.4.png new file mode 100644 index 000000000..802f31e19 Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/GraphicsTop.4.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/Script.c new file mode 100644 index 000000000..44e601a49 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/Script.c @@ -0,0 +1,127 @@ +/*-- Scaffold wall --*/ + +/* Initialization */ + +func SetLeft(object host) +{ + SetGraphics("Left"); + SetAction("Left", host); + SetShape(0,0,4,32); + SetPosition(host->GetX()-16, host->GetY()-16); + SetSolidMask(0,0,2,32); + SetVertexXY(0,1,1); + return true; +} + +func SetRight(object host) +{ + SetGraphics("Right"); + SetAction("Right", host); + SetShape(0,0,4,32); + SetPosition(host->GetX()+12, host->GetY()-16); + SetSolidMask(2,0,2,32,2,0); + SetVertexXY(0,-27,1); + return true; +} + +func SetRight2(object host) +{ + SetGraphics("Right"); + SetAction("Right", host); + SetShape(0,0,4,32); + SetPosition(host->GetX()+15, host->GetY()-48); + SetSolidMask(2,0,2,32,2,0); + SetVertexXY(0,-27-3,1+32); + return true; +} + +func SetTop(object host) +{ + SetGraphics("Top"); + SetAction("Top", host); + SetShape(0,0,32,4); + SetPosition(host->GetX()-16, host->GetY()-16); + SetSolidMask(0,4,32,4); + SetVertexXY(0,1,1); + return true; +} + +func SetBottom(object host) +{ + SetGraphics("Bottom"); + SetAction("Bottom", host); + SetShape(0,0,32,4); + SetPosition(host->GetX()-16, host->GetY()+12); + SetSolidMask(0,4,32,4); + SetVertexXY(0,1,-27); + return true; +} + +func SetBottom2(object host) +{ + SetGraphics("Bottom"); + SetAction("Bottom", host); + SetShape(0,0,32,4); + SetPosition(host->GetX()+13, host->GetY()+12); + SetSolidMask(0,4,32,4); + SetVertexXY(0,1-29,-27); + return true; +} + + +/* Destruction */ + +local ActMap = { + Left = { + Prototype = Action, + Name = "Left", + Procedure = DFA_ATTACH, + Directions = 1, + Length = 1, + Delay = 0, + FacetBase = 0, + X = 0, Y = 0, Wdt=4, Hgt = 32, + NextAction = "Left", + }, + Right = { + Prototype = Action, + Name = "Right", + Procedure = DFA_ATTACH, + Directions = 1, + Length = 1, + Delay = 0, + FacetBase = 0, + X = 0, Y = 0, Wdt=4, Hgt = 32, + NextAction = "Right", + }, + Top = { + Prototype = Action, + Name = "Top", + Procedure = DFA_ATTACH, + Directions = 1, + Length = 1, + Delay = 0, + FacetBase = 0, + X = 0, Y = 0, Wdt=32, Hgt = 4, + NextAction = "Top", + }, + Bottom = { + Prototype = Action, + Name = "Bottom", + Procedure = DFA_ATTACH, + Directions = 1, + Length = 1, + Delay = 0, + FacetBase = 0, + X = 0, Y = 0, Wdt=32, Hgt = 4, + NextAction = "Bottom", + }, +}; + +func Definition(def) { + +} + +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 121; diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/StringTblDE.txt new file mode 100644 index 000000000..92e48da5c --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Geruestwand +Description=Erlaubt den Bau groesserer Strukturen. \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/StringTblUS.txt new file mode 100644 index 000000000..86fa006b0 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scaffold.ocd/Wall.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Scaffold wall +Description=Allows you to build greater structures. \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Scenario.txt b/planet/Missions.ocf/Skylands.ocs/Scenario.txt new file mode 100644 index 000000000..25171a4e0 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Scenario.txt @@ -0,0 +1,51 @@ +[Head] +Icon=25 +Title=Skylands +Version=5,2,90,20 +Difficulty=90 +MaxPlayer=30 +NoInitialize=true + +[Game] +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1 +ValueOverloads=Nugget=10;GoldBar=50; + +[Player1] +Wealth=50,0,0,250 +Crew=Clonk=2 +Knowledge=Plane_Engine=1;Scaffold=1;Foundry=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Pump=1 +HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 +HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 + +[Player2] +Wealth=50,0,0,250 +Crew=Clonk=2 +Knowledge=Plane_Engine=1;Scaffold=1;Foundry=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Pump=1HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 +HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 + +[Player3] +Wealth=50,0,0,250 +Crew=Clonk=2 +Knowledge=Plane_Engine=1;Scaffold=1;Foundry=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Pump=1HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 +HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 + +[Player4] +Wealth=50,0,0,250 +Crew=Clonk=2 +Knowledge=Plane_Engine=1;Scaffold=1;Foundry=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Pump=1HomeBaseMaterial=Loam=99;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 +HomeBaseProduction=Loam=10;Wood=5;Metal=3;Shovel=2;Axe=2;Hammer=2;Clonk=5;Bread=5;Firestone=5 + +[Landscape] +Sky=Clouds2 +BottomOpen=true +MapWidth=100,0,64,10000 +MapHeight=200,0,40,10000 +NewStyleLandscape=2 +AutoScanSideOpen=0 +LeftOpen=1200 +RightOpen=1200 + +[Weather] +Climate=0,10,0,100 +YearSpeed=0,0,0,100 +Wind=-100,0,-100,-100 diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Script.c b/planet/Missions.ocf/Skylands.ocs/Script.c similarity index 79% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Script.c rename to planet/Missions.ocf/Skylands.ocs/Script.c index 05e5cfb03..10872f309 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/Script.c @@ -5,20 +5,24 @@ @authors Sven2 */ -static const LOAM_Bridge_Amount = 65; // longer bridges! - static g_is_initialized; static g_intro_initialized; func DoInit(int first_player) { + // Test + //CreateObject(LiftTower, 178,405, first_player); // Set time of day to evening and create some clouds and celestials. Cloud->Place(15); EnsureObject(Environment_Celestial,0,0,-1); EnsureObject(Rule_BuyAtFlagpole,0,0,-1); + SetSkyAdjust(0xff000000); + var storm = EnsureObject(Storm,0,0,NO_OWNER); + storm->SetStorm(-20,0,1000); + SetSkyParallax(1); // move background with the wind var time = EnsureObject(Environment_Time,0,0,-1); time->SetTime(600); - time->SetCycleSpeed(12); + time->SetCycleSpeed(20); // Goal CreateObject(Goal_Plane); // Plane part restore @@ -54,7 +58,8 @@ func InitializePlayer(int plr) else { crew->CreateContents(Axe); - crew->CreateContents(GrappleBow); + crew->CreateContents(Wood,3); + crew->CreateContents(Metal,2); } index++; } @@ -64,6 +69,6 @@ func InitializePlayer(int plr) func OnPlaneFinished(object plane) { // todo: outro - plane->CreateObject(Plane, 0,12, NO_OWNER); + plane->CreateObject(Plane, 0,0, NO_OWNER); plane->RemoveObject(); } diff --git a/planet/Missions.ocf/Skylands.ocs/Sky.jpg b/planet/Missions.ocf/Skylands.ocs/Sky.jpg new file mode 100644 index 000000000..a529b06ee Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Sky.jpg differ diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/DefCore.txt similarity index 77% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/DefCore.txt index 64ee95336..d045bb0f6 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/DefCore.txt +++ b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Tree_SmallConiferous Version=5,2,0,1 Category=C4D_StaticBack -Timer=350 -TimerCall=Seed Width=30 Height=55 Offset=-15,-27 @@ -12,11 +10,9 @@ VertexX=0,0,0,0,0,0,0,0,0 VertexY=22,15,10,5,0,-5,-10,-15,-22 VertexCNAT=8,16,16,16,16,16,16,16,4 VertexFriction=50,50,25,25,25,25,50,50,50 -Components=Wood=4 +Components=Wood=8 Mass=80 StretchGrowth=1 Oversize=1 -ContactIncinerate=3 -BlastIncinerate=1 Float=1 Rotate=1 \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Graphics.mesh b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Graphics.mesh similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Graphics.mesh rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Graphics.mesh diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Scene.material b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Scene.material similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Scene.material rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Scene.material diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Script.c similarity index 71% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Script.c rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Script.c index aa963dded..f3ce88de1 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Script.c +++ b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Script.c @@ -1,9 +1,10 @@ /*-- Small Coniferous Tree --*/ #include Library_Plant +#include Library_Tree -private func SeedAreaSize() { return 400; } -private func SeedChance() { return 50; } +private func SeedChance() { return 500; } +private func SeedArea() { return 400; } private func SeedAmount() { return 12; } func Construction() @@ -17,8 +18,6 @@ private func Initialize() SetProperty("MeshTransformation", Trans_Mul(Trans_Scale(500,500,500), Trans_Rotate(RandomX(0,359),0,1,0))); } -public func IsTree() { return true; } - public func ChopDown() { // Remove the bottom vertex @@ -29,4 +28,6 @@ public func ChopDown() } local Name = "$Name$"; -local Touchable = 0; \ No newline at end of file +local Touchable = 0; +local BlastIncinerate = 1; +local ContactIncinerate = 3; \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.png b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.png rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.skeleton b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.skeleton similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.skeleton rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/Soniferous.skeleton diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblDE.txt rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblUS.txt rename to planet/Missions.ocf/Skylands.ocs/SmallConiferous.ocd/StringTblUS.txt diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/DefCore.txt b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/DefCore.txt similarity index 55% rename from planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/DefCore.txt rename to planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/DefCore.txt index f0b8ff46e..5ff5b7116 100644 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/DefCore.txt +++ b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/DefCore.txt @@ -1,8 +1,6 @@ [DefCore] -id=LiftTower_Rope +id=Storm_DebugDisplay Version=5,2,0,1 Category=C4D_StaticBack Vertices=2 -Width=2 -Height=12 -Offset=-1,-6 \ No newline at end of file +Line=2 diff --git a/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/Graphics.png b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/Graphics.png new file mode 100644 index 000000000..753695654 Binary files /dev/null and b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/Graphics.png differ diff --git a/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/Script.c b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/Script.c new file mode 100644 index 000000000..71cc077e0 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/DebugDisplay.ocd/Script.c @@ -0,0 +1,25 @@ +/*-- Storm debug display --*/ + +func Initialize() +{ + SetAction("Connect"); +} + +func ShowData(array x, array y) +{ + while (RemoveVertex()) {} + for (var i=0; iRemoveObject(); + streams = nil; + n_streams = 0; + map = nil; +} + +private func InitMap() +{ + // init empty wind map according to parameters + // determine coordinate borders + var wdt=LandscapeWidth()-1, hgt = LandscapeHeight()-1; + var w1_min = Min(Min(MapXYToW1(0,0),MapXYToW1(0,hgt)),Min(MapXYToW1(wdt,0),MapXYToW1(wdt,hgt))); + var w1_max = Max(Max(MapXYToW1(0,0),MapXYToW1(0,hgt)),Max(MapXYToW1(wdt,0),MapXYToW1(wdt,hgt))); + var w2_min = Min(Min(MapXYToW2(0,0),MapXYToW2(0,hgt)),Min(MapXYToW2(wdt,0),MapXYToW2(wdt,hgt))); + var w2_max = Max(Max(MapXYToW2(0,0),MapXYToW2(0,hgt)),Max(MapXYToW2(wdt,0),MapXYToW2(wdt,hgt))); + // implement to cover complete border range + map_res1 = StormStream.dir_len; + map_res2 = stream_density; + map_off1 = w1_min - map_res1/2; + map_off2 = w2_min - map_res2/2; + map_size1 = (w1_max - map_off1) / map_res1 + 1; + map_size2 = (w2_max - map_off2) / map_res2 + 1; + // allocate map + map = CreateArray(map_size1 * map_size2); + //debug_map = CreateArray(map_size1 * map_size2); + return true; +} + +private func MapXYToIdx(int x, int y) +{ + if (x<0 || x>=LandscapeWidth() || y<0 || y>=LandscapeHeight()) return -1; + return (MapXYToW1(x, y)-map_off1)/map_res1 + ((MapXYToW2(x, y)-map_off2)/map_res2) * map_size1; +} + +private func MapXYToW1(int x, int y) +{ + // coordinate transform from x/y space to in-wind-direction coordinate + return (x*StormStream.dir_x + y*StormStream.dir_y) / StormStream.dir_len; +} + +private func MapXYToW2(int x, int y) +{ + // coordinate transform from x/y space to perpendicular-to-wind-direction coordinate + return (x*StormStream.dir_y - y*StormStream.dir_x) / StormStream.dir_len; +} + +// dir_*: vector pointing in storm direction. vector length is equal to segment intervals. +// strength: how much to fling objects +func SetStorm(int dir_x, int dir_y, int astrength) +{ + // clear old + Clear(); + // add new + var d = Distance(dir_x, dir_y); + if (!astrength || !d) return; + strength = astrength; + StormStream.dir_x = dir_x; + StormStream.dir_y = dir_y; + StormStream.dir_len = d; + // init map + InitMap(); + // create streams + n_streams = ((Abs(LandscapeWidth()*dir_y) + Abs(LandscapeHeight()*dir_x))/d - 2*stream_border_dist) / stream_density; + streams = CreateArray(n_streams); + var i_stream = 0, s, x0, y0, sgn_x=1, sgn_y=1; + var wdt = LandscapeWidth()-1, hgt = LandscapeHeight()-1; + if (dir_y<0) { y0 = hgt; sgn_y = -1; } + if (dir_x<0) { x0 = wdt; sgn_x = -1; } + //Log("creating %d streams", n_streams); + for (var i = 0; i0); // initial stream is blocked and will be unblocked on first execution + } + // Create stream data struct + var stream_debug; + if (storm_debug) stream_debug = CreateObject(Storm_DebugDisplay,0,0,NO_OWNER); + var new_stream = { + Prototype = StormStream, + "x0" = x0, "y0" = y0, // "a"=a because Guenther said so + "len" = len, + "x" = x, "y" = y, + "is_blocked" = is_blocked, + "debug" = stream_debug, + }; + return new_stream; +} + +private func ExecuteStream(proplist s) +{ + //Log("ExecStream %v", s); + // Execute stream against wind direction, so changes dont propagate immediately but only segment-by-segment + var do_particles = !Random(3); + for (var i_segment = s.len-2; i_segment>=0; --i_segment) + { + // propagate block + if (s.is_blocked[i_segment]) + { + //Log("segment %d", i_segment); + if (!s.is_blocked[i_segment+1]) StreamBlockVertex(s, i_segment+1); + if (storm_debug) + CreateParticle("SphereSpark", s.x[i_segment], s.y[i_segment], 0, 0, 36, {Size = 12}); + continue; + } + // current segment base point + var x = s.x[i_segment], y = s.y[i_segment]; + var tx = s.x[i_segment+1], ty = s.y[i_segment+1]; + // determine direction of current segment + var vx = tx - x; + var vy = ty - y; + + // determine where we want to go + var want_vx = s.x0+(i_segment+1)*s.dir_x - x; + var want_vy = s.y0+(i_segment+1)*s.dir_y - y; + + var want_stretch = (s.dir_x*want_vy-s.dir_y*want_vx) / s.dir_len; + //if (i_segment==8) Log("%v", want_stretch); + // can turn? + if (Abs(want_stretch) > s.max_segment_stretch_want) + { + // We cannot go all the way...turn as much as we can + var stretch_dir = Abs(want_stretch)/want_stretch; // sign of direction + want_stretch = s.max_segment_stretch_want * stretch_dir; + } + // check from want_v alternating in both directions for a free path + var search_range = (Abs(want_stretch) + s.max_segment_stretch); + var search_off, has_found = false; + for (var search_offset = 0; search_offset <= search_range; search_offset = search_offset * s.search_steps_mult/100 + s.search_steps) + { + // search up + search_off = want_stretch - search_offset; + if (search_off >= -s.max_segment_stretch) + if (StreamCheckPathFree(s,x,y,search_off)) { has_found=true; break; } + if (!search_offset) continue; // don't check direction -0 and +0 twice + // search down + search_off = want_stretch + search_offset; + if (search_off <= s.max_segment_stretch) + if (StreamCheckPathFree(s,x,y,search_off)) { has_found=true; break; } + } + // did we find a path? + if (has_found) + { + // path found + if (s.is_blocked[i_segment+1]) StreamUnblockVertex(s, i_segment+1); + var new_tx = x + s.dir_x - search_off * s.dir_y / s.dir_len; + var new_ty = y + s.dir_y + search_off * s.dir_x / s.dir_len; + if (new_tx != tx || new_ty != ty) StreamMoveVertex(s, i_segment+1, tx, ty, new_tx, new_ty); + tx = new_tx; ty = new_ty; + // determine storm density at this position + var map_idx = MapXYToIdx(tx, ty), local_strength; + if (map_idx>=0) local_strength = map[map_idx]; else local_strength=1; + // fling objects along path + vx = vx * strength / s.dir_len; + vy = vy * strength / s.dir_len; // - 20; + var fling_objs = FindObjects(find_mask, Find_OnLine(x,y,new_tx,new_ty)), obj; + for (obj in fling_objs) if (obj->GetID()==ElevatorCase) { fling_objs = []; break; } // do not fling stuff in elevator case + for (obj in fling_objs) + { + // check if object can be pushed + if (obj->Stuck()) continue; + if (!PathFree(x,y,obj->GetX(),obj->GetY())) continue; // don't push through solid + // determine push strength. subsequent pushes of overlapping storm pathes stack diminishingly + var push_strength = strength/20,pushfx; + if (pushfx=GetEffect("StormPush",obj)) + { + push_strength /= pushfx.count++; + if (!push_strength) continue; + } + else + { + pushfx=AddEffect("StormPush", obj, 1, 5, this); + if (pushfx) pushfx.count = 1; + } + // now push + var ovx = obj->GetXDir(100); + var ovy = obj->GetYDir(100); + // check max speed + if (Distance(ovx,ovy,vx,vy) > push_strength*6) + { + if (Distance(ovx,ovy) > 500) + obj->Fling(BoundBy(vx-ovx,-push_strength,push_strength),BoundBy(vy-ovy,-push_strength,push_strength),100,true); + else + { + obj->SetXDir(ovx+BoundBy(vx-ovx,-push_strength,push_strength),100); + obj->SetYDir(ovy+BoundBy(vy-ovy,-push_strength,push_strength),100); + } + } + } + // Gfx + if (do_particles && map_idx>=0) + { + if (local_strength >= 1) + { + // Two streams coincide here. Gfx! + vx = tx-x; vy = ty-y; + var v = Distance(vx,vy); + vx = vx * s.dir_len / v; + vy = vy * s.dir_len / v / 2; + CreateParticle("Dust", PV_Random(x - 10, x + 10), PV_Random(y - 10, y + 10), PV_Random(vx * 80 / 100, vx * 120 / 100), PV_Random(vy, vy * 140 / 100), PV_Random(20, 40), storm_particles,local_strength); + } + } + } + else + { + // path not found. segment blocked. + if (!s.is_blocked[i_segment+1]) StreamBlockVertex(s, i_segment+1); + } + } + if (s.debug) s.debug->ShowData(s.x, s.y); +} + +private func StreamCheckPathFree(proplist s, int x, int y, int offset) +{ + // determine target coordinates + var tx = x + s.dir_x - offset * s.dir_y / s.dir_len; + var ty = y + s.dir_y + offset * s.dir_x / s.dir_len; + // check path + return PathFree(x,y,tx,ty); +} + +private func StreamMoveVertex(proplist s, int i, int old_x, int old_y, int new_x, int new_y) +{ + //Log("moving %d/%d to %d/%d", old_x, old_y, new_x, new_y); + // adjust vertex + s.x[i] = new_x; s.y[i] = new_y; + // adjust map + var idx = MapXYToIdx(old_x, old_y); + if (idx>=0) --map[idx]; + //DebugMapAdd(idx, Format("m%d.%d", s.y0, i)); + idx = MapXYToIdx(new_x, new_y); + if (idx>=0) ++map[idx]; + //DebugMapAdd(idx, Format("M%d.%d", s.y0, i)); + return true; +} + +private func StreamBlockVertex(proplist s, int i) +{ + //Log("blocking at %d/%d", s.x[i], s.y[i]); + // adjust vertex + s.is_blocked[i] = true; + // adjust map + var idx = MapXYToIdx(s.x[i], s.y[i]); + if (idx>=0) --map[idx]; + //DebugMapAdd(idx, Format("X%d.%d", s.y0, i)); + return true; +} + +private func StreamUnblockVertex(proplist s, int i) +{ + //Log("unblocking at %d/%d", s.x[i], s.y[i]); + // adjust vertex + s.is_blocked[i] = false; + // adjust map + var idx = MapXYToIdx(s.x[i], s.y[i]); + if (idx>=0) ++map[idx]; + //DebugMapAdd(idx, Format("O%d.%d", s.y0, i)); + return true; +} + +private func DumpStreamInfo(int i) +{ + var s = streams[i], q=[], idcs = []; + for (var j=0; jGetWindEx(x+GetX(),y+GetY()); + return _inherited(x,y,...); +} \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Storm.ocd/StringTblDE.txt b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/StringTblDE.txt new file mode 100644 index 000000000..3f08cc433 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Sturm +Description=Blaest alles weg. \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/Storm.ocd/StringTblUS.txt b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/StringTblUS.txt new file mode 100644 index 000000000..2ac3e7093 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Storm.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Storm +Description=Blows you away! \ No newline at end of file diff --git a/planet/Missions.ocf/Skylands.ocs/System.ocg/LongLoam.c b/planet/Missions.ocf/Skylands.ocs/System.ocg/LongLoam.c new file mode 100644 index 000000000..6ff37b538 --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/System.ocg/LongLoam.c @@ -0,0 +1,5 @@ +/* Longer loam bridges */ + +#appendto Loam + +local BridgeLength = 65; diff --git a/planet/Missions.ocf/Skylands.ocs/Teams.txt b/planet/Missions.ocf/Skylands.ocs/Teams.txt new file mode 100644 index 000000000..9c133ec5c --- /dev/null +++ b/planet/Missions.ocf/Skylands.ocs/Teams.txt @@ -0,0 +1,5 @@ +[Teams] +Active=false +Custom=false +AllowHostilityChange=true +AutoGenerateTeams=true diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/Title.txt b/planet/Missions.ocf/Skylands.ocs/Title.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/Title.txt rename to planet/Missions.ocf/Skylands.ocs/Title.txt diff --git a/planet/Missions.ocf/Title.png b/planet/Missions.ocf/Title.png new file mode 100644 index 000000000..708827f35 Binary files /dev/null and b/planet/Missions.ocf/Title.png differ diff --git a/planet/Missions.ocf/Title.txt b/planet/Missions.ocf/Title.txt new file mode 100644 index 000000000..165cf54f7 --- /dev/null +++ b/planet/Missions.ocf/Title.txt @@ -0,0 +1,2 @@ +DE:Missionen +US:Missions diff --git a/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Butterfly_Wing.png b/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Butterfly_Wing.png index a1c9589d9..8914464b6 100644 Binary files a/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Butterfly_Wing.png and b/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Butterfly_Wing.png differ diff --git a/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/DefCore.txt b/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/DefCore.txt index 9a718ec0c..ca83706f1 100644 --- a/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/DefCore.txt +++ b/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/DefCore.txt @@ -2,7 +2,6 @@ id=Butterfly Version=5,2,0,1 Category=C4D_Living -TimerCall=Activity ContactCalls=1 Width=6 Height=4 @@ -14,11 +13,7 @@ VertexX=0,0,-3,3 VertexY=-2,2,0,0 VertexCNAT=4,8,1,2 VertexFriction=100,100,100,100,100,100 -Placement=2 -ContactIncinerate=0 Float=1 BorderBound=7 StretchGrowth=1 -NoBurnDecay=1 -IncompleteActivity=1 - +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Script.c b/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Script.c index ad13382b9..998aa9987 100644 --- a/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Script.c +++ b/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Script.c @@ -21,6 +21,11 @@ protected func Initialize() SetAction("Fly"); SetComDir(COMD_None); MoveToTarget(); + AddTimer("Activity"); + + // Make butterflies a bit more colorful. + SetClrModulation(HSL(Random(256), 255, 100 + Random(60))); + return 1; } @@ -29,8 +34,6 @@ func FxButterflyTurnTimer(object target, int num, int timer) TurnButterfly(); } -/* TimerCall */ - private func Activity() { // Underwater @@ -101,7 +104,7 @@ private func MoveToTarget() { var x = Random(LandscapeWidth()); var y = Random(GetHorizonHeight(x)-60)+30; - SetCommand("MoveTo",0,x,y); + SetCommand("MoveTo",nil,x,y); return 1; } @@ -113,6 +116,14 @@ private func GetHorizonHeight(int x) return height; } +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + props->Remove("ClrModulation"); // randomized in Initialize + SaveScenarioObjectAction(props); + return true; +} + local ActMap = { Fly = { @@ -156,6 +167,8 @@ Flutter = { local Name = "Butterfly"; local MaxEnergy = 40000; local MaxBreath = 125; +local Placement = 2; +local NoBurnDecay = 1; func Definition(def) { SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(20,1,0,0),Trans_Rotate(70,0,1,0)), def); diff --git a/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/bird3.material b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/bird3.material new file mode 100644 index 000000000..ac619bc7c --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/bird3.material @@ -0,0 +1,55 @@ + +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 + } + } + } +} diff --git a/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/color.png b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/color.png new file mode 100644 index 000000000..e8f169f45 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/color.png differ diff --git a/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/flightless_bird_mesh.mesh b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/flightless_bird_mesh.mesh new file mode 100644 index 000000000..d57d2deb0 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/flightless_bird_mesh.mesh differ diff --git a/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/flightless_bird_mesh.skeleton b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/flightless_bird_mesh.skeleton new file mode 100644 index 000000000..8d488d95f Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/FlightlessBird.ocd/flightless_bird_mesh.skeleton differ diff --git a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/DefCore.txt b/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/DefCore.txt deleted file mode 100644 index 880f61d58..000000000 --- a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/DefCore.txt +++ /dev/null @@ -1,4 +0,0 @@ -[DefCore] -id=Skin_Alchemist -Version=5,2,0,1 -Category=C4D_StaticBack \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemist.png b/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemist.png deleted file mode 100644 index 20516d813..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemist.png and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c b/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c index e9785b087..c4eabd979 100644 --- a/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c +++ b/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c @@ -82,7 +82,7 @@ func FxIntTurnTimer(pTarget, effect, iTime) { // Check wether the clonk wants to turn (Not when he wants to stop) var iRot = effect.rot; - if( (effect.dir != GetDirection() && GetAction() != "Jump") || effect.turn_type != lAnim.turnType) + if( (effect.dir != GetDirection() && (GetAction() != "Jump") || this->~IsAiming()) || effect.turn_type != lAnim.turnType) { effect.dir = GetDirection(); if(effect.dir == COMD_Right) @@ -216,7 +216,7 @@ public func ReplaceAction(string action, byaction) } } } - SetProperty(action, byaction, PropAnimations); + else SetProperty(action, byaction, PropAnimations); // if(ActualReplace != nil) // SetAnimationWeight(ActualReplace, Anim_Const(byaction[2])); ResetAnimationEffects(); @@ -383,10 +383,16 @@ func Footstep() Sound("StepHard?"); else { - var dir = GetXDir() / Abs(GetXDir()); + var dir = Sign(GetXDir()); var clr = GetAverageTextureColor(GetTexture(0,10)); - CreateParticle("Dust2", dir*-4, 8, dir*-2, -2, 25+Random(5), DoRGBaValue(clr,-150,0)); - CreateParticle("Dust2", dir*-4, 8, dir*-3, -3, 25+Random(5), DoRGBaValue(clr,-150,0)); + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + }; + CreateParticle("Dust", PV_Random(dir * -2, dir * -1), 8, PV_Random(dir * 2, dir * 1), PV_Random(-2, -3), PV_Random(36, 2 * 36), particles, 5); Sound("StepSoft?"); } } @@ -399,8 +405,15 @@ func GetWalkAnimationPosition(string anim, int pos) if(PropAnimations != nil) if(GetProperty(Format("%s_Position", anim), PropAnimations)) { - var length = GetAnimationLength(anim); - if(GetProperty(anim, PropAnimations)) length = GetAnimationLength(GetProperty(anim, PropAnimations)); + var length = GetAnimationLength(anim), replacement; + if(replacement = GetProperty(anim, PropAnimations)) + { + // at this point /replacement/ may contain an array of two animations that signal a merge + // in that case, just take the first one.. + if(GetType(replacement) == C4V_Array) + replacement = replacement[0]; + length = GetAnimationLength(replacement); + } return Anim_X(pos, 0, length, GetProperty(Format("%s_Position", anim), PropAnimations)*dir); } // TODO: Choose proper starting positions, depending on the current @@ -442,7 +455,7 @@ func FxIntWalkStart(pTarget, effect, fTmp) func FxIntWalkTimer(pTarget, effect) { // Test Waterlevel - if(GBackLiquid(0, -5) && !Contained()) + if(InLiquid() && GBackLiquid(0, -5) && !Contained()) { SetAction("Swim"); if(GetComDir() == COMD_Left) @@ -556,20 +569,11 @@ func StopScale() if(GetAction() != "Scale") RemoveEffect("IntScale", this); } -func CheckPosition(int off_x, int off_y) -{ - var free = 1; - SetPosition(GetX()+off_x, GetY()+off_y); - if(Stuck()) free = 0; - SetPosition(GetX()-off_x, GetY()-off_y); - return free; -} - func CheckScaleTop() { // Test whether the clonk has reached a top corner - if(GBackSolid(-8+16*GetDir(),-8)) return false; - if(!CheckPosition(-7*(-1+2*GetDir()),-17)) return false; + // That is, the leg vertices are the only ones attached to the wall + if(GBackSolid(-3+6*GetDir(),-3) || GBackSolid(-5+10*GetDir(),2)) return false; return true; } @@ -588,24 +592,20 @@ func FxIntScaleTimer(target, number, time) { // If the animation is not already set var dist = 0; - while(!GBackSolid(-8+16*GetDir(),dist-8) && dist < 10) dist++; + while(!(GBackSolid(-3+6*GetDir(),dist-3) || GBackSolid(-5+10*GetDir(),dist+2)) && dist < 8) dist++; dist *= 100; - dist += GetY(100)-GetY()*100; + // add the fractional part of the position (dist counts in the opposite direction of y) + dist -= GetY(100)-GetY()*100; if(number.animation_mode != 1) { - number.animation_id = PlayAnimation("ScaleTop", 5, Anim_Const(GetAnimationLength("ScaleTop")*dist/1000), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); + number.animation_id = PlayAnimation("ScaleTop", 5, Anim_Const(GetAnimationLength("ScaleTop")*dist/800), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); number.animation_mode = 1; } this.dist = dist; - SetAnimationPosition(number.animation_id, Anim_Const(GetAnimationLength("ScaleTop")*dist/1000)); + SetAnimationPosition(number.animation_id, Anim_Const(GetAnimationLength("ScaleTop")*dist/800)); // The animation's graphics has to be shifet a bit to adjust to the clonk movement var pos = GetAnimationPosition(number.animation_id); - //var percent = pos*1000/GetAnimationLength("ScaleTop"); - var offset_list = [[0,0], [0,-1], [-1,-2], [-2,-3], [-2,-5], [-2,-7], [-4,-8], [-6,-10], [-7,-9], [-8,-8]]; - var offset = offset_list[dist/100-1]; - var rot = 0; - if(dist/100-1 > 5) rot = 5*dist/100-25; - SetScaleRotation(0, -offset[0]*(-1+2*GetDir())*1000, offset[1]*1000, -rot*(-1+2*GetDir()), 0, 1); + SetScaleRotation(0, 0, 0, 0, 0, 1); } else if(!GBackSolid(-10+20*GetDir(), 8)) { @@ -728,17 +728,20 @@ func StartJump() UpdateAttach(); // Set proper turn type SetTurnType(0); - //Dive jump - var flight = SimFlight(AbsX(GetX()), AbsY(GetY()), GetXDir()*2, GetYDir()*2, 25); //I have no clue why the dirs must be doubled... but it seems to fix it - if(GBackLiquid(flight[0] - GetX(), flight[1] - GetY()) && GBackLiquid(flight[0] - GetX(), flight[1] + GetDefHeight() / 2 - GetY())) - { - PlayAnimation("JumpDive", 5, Anim_Linear(0, 0, GetAnimationLength("JumpDive"), 60, ANIM_Hold), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); - return 1; - } + //Dive jump (only if not aiming) + if(!this->~IsAiming()) + { + var flight = SimFlight(AbsX(GetX()), AbsY(GetY()), GetXDir()*2, GetYDir()*2, 25); //I have no clue why the dirs must be doubled... but it seems to fix it + if(GBackLiquid(flight[0] - GetX(), flight[1] - GetY()) && GBackLiquid(flight[0] - GetX(), flight[1] + GetDefHeight() / 2 - GetY())) + { + PlayAnimation("JumpDive", 5, Anim_Linear(0, 0, GetAnimationLength("JumpDive"), 60, ANIM_Hold), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); + return 1; + } + } - if(!GetEffect("Fall", this)) - AddEffect("Fall",this,1,1,this); - RemoveEffect("WallKick",this); + if(!GetEffect("Fall", this)) + AddEffect("Fall",this,1,1,this); + RemoveEffect("WallKick",this); } func FxFallEffect(string new_name, object target) @@ -840,6 +843,8 @@ func FxIntHangleStop(pTarget, effect, iReasonm, fTmp) { PopActionSpeed("Hangle"); if(fTmp) return; + // Delayed stop request + if (effect.request_stop) SetComDir(COMD_Stop); } func FxIntHangleTimer(pTarget, effect, iTime) @@ -915,15 +920,32 @@ func StartSwim() { /* if(Clonk_SwimStates == nil) Clonk_SwimStates = ["SwimStand", "Swim", "SwimDive", "SwimTurn", "SwimDiveTurn", "SwimDiveUp", "SwimDiveDown"];*/ + if(!InLiquid()) return; if(!GetEffect("IntSwim", this)) AddEffect("IntSwim", this, 1, 1, this); - SetVertex(1,VTX_Y,-4,2); + + return SetSwimmingVertices(true); } func StopSwim() { if(GetAction() != "Swim") RemoveEffect("IntSwim", this); - SetVertex(1,VTX_Y,-7,2); + + return SetSwimmingVertices(false); +} + +func SetSwimmingVertices(bool is_swimming) +{ + var vtx_list = [[0,2,0], [0,-7,4], [0,9,11], [-2,-3,1], [2,-3,2], [-4,2,1], [4,2,2], [-2,6,1], [2,6,2]]; + if (is_swimming) + vtx_list = [[0,3,0], [0,-2,4], [0,7,11], [-4,0,1], [4,0,2], [-5,3,1], [5,3,2], [-4,4,1], [4,4,2]]; + for (var i = 0; i < GetVertexNum(); i++) + { + SetVertex(i, VTX_X, vtx_list[i][0], 2); + SetVertex(i, VTX_Y, vtx_list[i][1], 2); + SetVertex(i, VTX_CNAT, vtx_list[i][2], 2); + } + return; } func FxIntSwimStart(pTarget, effect, fTmp) @@ -966,14 +988,23 @@ func FxIntSwimTimer(pTarget, effect, iTime) percent = (percent%100); if( percent < 40 ) { - for(var i = 0; i < 2; i++) - CreateParticle("Splash", (-1+2*GetDir())*7+RandomX(-5,5), -4, (RandomX(-5,5)-(-1+2*GetDir())*4)/4, -2, RandomX(30,50), RGB(240+Random(10),240+Random(10),255)); if(iTime%5 == 0) { - var particle_name = "WaveLeft"; - if( GetDir() == 1 ) particle_name = "WaveRight"; + var phases = PV_Linear(0, 7); + if (GetDir() == 1) phases = PV_Linear(8, 15); var color = GetAverageTextureColor(GetTexture(0, 0)); - CreateParticle(particle_name, (0), -4, (RandomX(-5,5)-(-1+2*GetDir())*4)/4, 0, 100, color, this, 1); + var particles = + { + Size = 16, + Phase = phases, + CollisionVertex = 750, + OnCollision = PC_Die(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + Attach = ATTACH_Front, + }; + CreateParticle("Wave", 0, -4, (RandomX(-5,5)-(-1+2*GetDir())*4)/4, 0, 16, particles); } Sound("Splash?"); } @@ -1042,8 +1073,14 @@ func Hit(int iXSpeed, int iYSpeed) if (GetMaterialVal("DigFree", "Material", GetMaterial(0,10))) { var clr = GetAverageTextureColor(GetTexture(0,10)); - for(var i = -3; i < 4; i++) - CreateParticle("Dust2", i, 8, i*2, -3, 40+Random(10), DoRGBaValue(clr,-150,0)); + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + }; + CreateParticle("Dust", PV_Random(-4, 4), 8, PV_Random(-3, 3), PV_Random(-2, -4), PV_Random(36, 2 * 36), particles, 12); } } } @@ -1053,8 +1090,14 @@ func Hit(int iXSpeed, int iYSpeed) if (GetMaterialVal("DigFree", "Material", GetMaterial(0,10))) { var clr = GetAverageTextureColor(GetTexture(0,10)); - for(var i = -3; i < 4; i++) - CreateParticle("Dust2", i, 8, i*2, -3, 40+Random(10), DoRGBaValue(clr,-150,0)); + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + }; + CreateParticle("Dust", PV_Random(-4, 4), 8, PV_Random(-3, 3), PV_Random(-2, -4), PV_Random(36, 2 * 36), particles, 12); } } } @@ -1115,8 +1158,15 @@ func FxRollingTimer(object target, int num, int timer) { var clr = GetAverageTextureColor(GetTexture(0,10)); var dir = GetDir()*2-1; - CreateParticle("Dust2", dir*-3, 8, dir*-3, -3, 60+Random(10), DoRGBaValue(clr,-150,0)); - CreateParticle("Dust2", dir*-2, 8, dir*-2, -4, 60+Random(10), DoRGBaValue(clr,-150,0)); + + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + }; + CreateParticle("Dust", PV_Random(dir * -2, dir * -1), 8, PV_Random(dir * 2, dir * 1), PV_Random(-2, -5), PV_Random(36, 2 * 36), particles, 6); } } @@ -1391,4 +1441,4 @@ func StartEat() PlayAnimation("Eat", 10, Anim_Linear(0,0, GetAnimationLength("Eat"), 45, ANIM_Remove), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); // Update carried items UpdateAttach(); -} \ No newline at end of file +} diff --git a/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/BackpackTexture.jpg b/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/BackpackTexture.jpg new file mode 100644 index 000000000..0188a6602 Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/BackpackTexture.jpg differ diff --git a/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/BackpackTexture.png b/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/BackpackTexture.png deleted file mode 100644 index 583b416b6..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/BackpackTexture.png and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/Scene.material b/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/Scene.material index eada970d7..c069262ed 100644 --- a/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/Scene.material +++ b/planet/Objects.ocd/Clonk.ocd/Backpack.ocd/Scene.material @@ -12,7 +12,7 @@ material BackpackTexture emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture BackpackTexture.png + texture BackpackTexture.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Clonk.ocd/Clonk.jpg b/planet/Objects.ocd/Clonk.ocd/Clonk.jpg new file mode 100644 index 000000000..ff059f9f0 Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/Clonk.jpg differ diff --git a/planet/Objects.ocd/Clonk.ocd/Clonk.png b/planet/Objects.ocd/Clonk.ocd/Clonk.png deleted file mode 100644 index a290d3e28..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Clonk.png and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/Clonk.skeleton b/planet/Objects.ocd/Clonk.ocd/Clonk.skeleton index ab161f77c..fd13b71af 100644 Binary files a/planet/Objects.ocd/Clonk.ocd/Clonk.skeleton and b/planet/Objects.ocd/Clonk.ocd/Clonk.skeleton differ diff --git a/planet/Objects.ocd/Clonk.ocd/DefCore.txt b/planet/Objects.ocd/Clonk.ocd/DefCore.txt index 9f911da4a..237fc4e35 100644 --- a/planet/Objects.ocd/Clonk.ocd/DefCore.txt +++ b/planet/Objects.ocd/Clonk.ocd/DefCore.txt @@ -5,22 +5,20 @@ Category=C4D_Living Width=8 Height=20 Offset=-4,-10 -Vertices=7 -VertexX=0,0,0,-2,2,-4,4 -VertexY=2,-7,9,-3,-3,2,2 -VertexCNAT=0,4,8,1,2,1,2 -VertexFriction=300,300,100,300,300,300,300 +Vertices=9 +VertexX= 0, 0, 0, -2, 2, -4, 4, -2, 2 +VertexY= 2, -7, 9, -3, -3, 2, 2, 6, 6 +VertexCNAT= 0, 4, 11, 1, 2, 1, 2, 1, 2 +VertexFriction=300,300,100,300,300,300,300,300,300 Value=25 Mass=50 Collection=-8,-10,16,27 -ContactIncinerate=10 CrewMember=1 NoGet=1 Float=-2 ColorByOwner=1 BorderBound=1 StretchGrowth=1 -NoBurnDecay=1 IncompleteActivity=1 Oversize=1 diff --git a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/DefCore.txt b/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/DefCore.txt deleted file mode 100644 index 40c018bb2..000000000 --- a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/DefCore.txt +++ /dev/null @@ -1,4 +0,0 @@ -[DefCore] -id=Skin_Farmer -Version=5,2,0,1 -Category=C4D_StaticBack \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmer.png b/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmer.png deleted file mode 100644 index 2b7e6eb48..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmer.png and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmer.skeleton b/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmer.skeleton deleted file mode 100644 index ab161f77c..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmer.skeleton and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/Graphics.mesh b/planet/Objects.ocd/Clonk.ocd/Graphics.mesh index 9df31ca52..f93cce1a3 100644 Binary files a/planet/Objects.ocd/Clonk.ocd/Graphics.mesh and b/planet/Objects.ocd/Clonk.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/Graphics.mesh b/planet/Objects.ocd/Clonk.ocd/GraphicsAlchemist.mesh similarity index 99% rename from planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/Graphics.mesh rename to planet/Objects.ocd/Clonk.ocd/GraphicsAlchemist.mesh index e31f85cdf..6a813e89a 100644 Binary files a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/Graphics.mesh and b/planet/Objects.ocd/Clonk.ocd/GraphicsAlchemist.mesh differ diff --git a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/Graphics.mesh b/planet/Objects.ocd/Clonk.ocd/GraphicsFarmer.mesh similarity index 81% rename from planet/Objects.ocd/Clonk.ocd/Farmer.ocd/Graphics.mesh rename to planet/Objects.ocd/Clonk.ocd/GraphicsFarmer.mesh index c548ef6d2..053556a1b 100644 Binary files a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/Graphics.mesh and b/planet/Objects.ocd/Clonk.ocd/GraphicsFarmer.mesh differ diff --git a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/Graphics.mesh b/planet/Objects.ocd/Clonk.ocd/GraphicsSteampunk.mesh similarity index 98% rename from planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/Graphics.mesh rename to planet/Objects.ocd/Clonk.ocd/GraphicsSteampunk.mesh index 60c6a55e4..253ddfe83 100644 Binary files a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/Graphics.mesh and b/planet/Objects.ocd/Clonk.ocd/GraphicsSteampunk.mesh differ diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/DefCore.txt b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/DefCore.txt new file mode 100644 index 000000000..5395715a0 --- /dev/null +++ b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Clonk_Grave +Version=5,2,0,1 +Category=C4D_Object|C4D_MouseSelect +Width=8 +Height=12 +Offset=-4,-6 +Vertices=2 +VertexX=0,0 +VertexY=-5,5 +VertexFriction=40,100 +Value=0 +Mass=10 +Components=Rock=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Graphics.mesh b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Graphics.mesh new file mode 100644 index 000000000..34e053fdf Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Gravestone.material b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Gravestone.material new file mode 100644 index 000000000..d3057705b --- /dev/null +++ b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Gravestone.material @@ -0,0 +1,20 @@ +material Gravestone +{ + receive_shadows on + technique + { + pass + { + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.0 0.0 0.0 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + texture_unit + { + texture graveStone.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Script.c b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Script.c new file mode 100644 index 000000000..9b6fec9ba --- /dev/null +++ b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/Script.c @@ -0,0 +1,24 @@ +/** + Gravestone + Epitaph for the dead. + + @author Ringwaul +*/ + +public func IsInteractable() { return true; } + +public func Interact(object clonk) +{ + if(!Contents(0) || !Contents(0)->~IsClonk()) return false; + + var deathMessage = Contents(0)->GetObjCoreDeathMessage(); + + var graveInscription; + if(deathMessage) + { + graveInscription = Format("$Epitaph$ %s.|\"%s\"", Contents(0)->~GetName(), deathMessage); + } else { + graveInscription = Format("$Epitaph$ %s.", Contents(0)->~GetName()); + } + PlayerMessage(clonk->GetController(), graveInscription); +} \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/StringTblDE.txt b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/StringTblDE.txt new file mode 100644 index 000000000..dd2770820 --- /dev/null +++ b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Epitaph=Hier liegt \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/StringTblUS.txt b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/StringTblUS.txt new file mode 100644 index 000000000..a0a8273be --- /dev/null +++ b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Epitaph=Here lies \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Grave.ocd/graveStone.png b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/graveStone.png new file mode 100644 index 000000000..80c37e9a3 Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/Grave.ocd/graveStone.png differ diff --git a/planet/Objects.ocd/Clonk.ocd/Scene.material b/planet/Objects.ocd/Clonk.ocd/Scene.material index 5e07816cd..dc31a5f0f 100644 --- a/planet/Objects.ocd/Clonk.ocd/Scene.material +++ b/planet/Objects.ocd/Clonk.ocd/Scene.material @@ -21,7 +21,7 @@ material Clonk_Body } texture_unit Clonk { - texture Clonk.png + texture Clonk.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture @@ -30,10 +30,11 @@ material Clonk_Body } texture_unit Light { - // apply lighting + // apply lighting -- note this texture unit does not need an + // actual texture image: no hardware TIU will be used. colour_op_ex modulate src_current src_diffuse alpha_op_ex modulate src_current src_diffuse } } } -} \ No newline at end of file +} diff --git a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/Scene.material b/planet/Objects.ocd/Clonk.ocd/SceneAlchemist.material similarity index 96% rename from planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/Scene.material rename to planet/Objects.ocd/Clonk.ocd/SceneAlchemist.material index 2f66ef229..23af4a7f3 100644 --- a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/Scene.material +++ b/planet/Objects.ocd/Clonk.ocd/SceneAlchemist.material @@ -21,7 +21,7 @@ material clonkAlchemist } texture_unit Clonk { - texture clonkAlchemist.png + texture clonkAlchemist.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture @@ -62,7 +62,7 @@ material clonkAlchemistTunic } texture_unit Clonk { - texture clonkAlchemist.png + texture clonkAlchemist.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture diff --git a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/Scene.material b/planet/Objects.ocd/Clonk.ocd/SceneFarmer.material similarity index 97% rename from planet/Objects.ocd/Clonk.ocd/Farmer.ocd/Scene.material rename to planet/Objects.ocd/Clonk.ocd/SceneFarmer.material index d9c9cdcb4..9c3c21a2a 100644 --- a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/Scene.material +++ b/planet/Objects.ocd/Clonk.ocd/SceneFarmer.material @@ -21,7 +21,7 @@ material farmerClonk } texture_unit Clonk { - texture clonkFarmer.png + texture clonkFarmer.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture diff --git a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/Scene.material b/planet/Objects.ocd/Clonk.ocd/SceneSteampunk.material similarity index 96% rename from planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/Scene.material rename to planet/Objects.ocd/Clonk.ocd/SceneSteampunk.material index f4478c821..2ef1ec511 100644 --- a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/Scene.material +++ b/planet/Objects.ocd/Clonk.ocd/SceneSteampunk.material @@ -21,7 +21,7 @@ material clonkSteampunk } texture_unit Clonk { - texture clonkSteampunk.png + texture clonkSteampunk.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture diff --git a/planet/Objects.ocd/Clonk.ocd/Script.c b/planet/Objects.ocd/Clonk.ocd/Script.c index dc0be0396..7d94f5462 100644 --- a/planet/Objects.ocd/Clonk.ocd/Script.c +++ b/planet/Objects.ocd/Clonk.ocd/Script.c @@ -2,7 +2,7 @@ Clonk Author: Randrian - The protoganist of the game. Witty and nimble if skillfully controled ;-) + The protoganist of the game. Witty and nimble if skillfully controlled ;-) */ @@ -45,19 +45,21 @@ protected func Construction() AddEffect("IntEyes", this, 1, 35+Random(4), this); AttachBackpack(); + iHandMesh = [0,0]; + + SetSkin(0); } - - /* When adding to the crew of a player */ protected func Recruitment(int iPlr) { //The clonk's appearance - //In your clonk file: "ExtraData=1;Skin=iX" (X = chosen skin) + //Player settings can be overwritten for individual Clonks. In your clonk file: "ExtraData=1;Skin=iX" (X = chosen skin) var skin = GetCrewExtraData("Skin"); if (skin == nil) skin = GetPlrClonkSkin(iPlr); - if(skin) SetSkin(skin); + if(skin != nil) SetSkin(skin); + else SetSkin(Random(GetSkinCount())); // Broadcast for crew GameCallEx("OnClonkRecruitment", this, iPlr); @@ -118,7 +120,7 @@ protected func Hurt() if(gender == 0) Sound("Hurt?"); else - Sound("FHurt?"); //female 'ouch' sounds TODO :/ + Sound("FHurt?"); } protected func Grab(object pTarget, bool fGrab) @@ -148,11 +150,13 @@ protected func Death(int killed_by) if (GetAlive()) return; + // Some effects on dying. if(gender == 0) Sound("Die"); else Sound("FDie"); - + CloseEyes(1); + DeathAnnounce(); return; } @@ -196,13 +200,21 @@ public func Eat(object food) } } +func DigOutObject(object obj) +{ + // Collect fragile objects when dug out + if (obj->GetDefFragile()) + return Collect(obj,nil,nil,true); + return false; +} + /* Status */ // TODO: Make this more sophisticated, readd turn animation and other // adaptions public func IsClonk() { return true; } -public func IsJumping(){return GetProcedure() == "FLIGHT";} +public func IsJumping(){return WildcardMatch(GetAction(), "*Jump*");} public func IsWalking(){return GetProcedure() == "WALK";} /* Carry items on the clonk */ @@ -244,7 +256,6 @@ func DetachHandItem(bool secondary) func AttachHandItem(bool secondary) { - if(!iHandMesh) iHandMesh = [0,0]; DetachHandItem(secondary); UpdateAttach(); } @@ -449,7 +460,7 @@ func SetMeshTransformation(array transformation, int layer) if(GetLength(mesh_transformation_list) < layer) SetLength(mesh_transformation_list, layer+1); mesh_transformation_list[layer] = transformation; - var all_transformations = 0; + var all_transformations = nil; for(var trans in mesh_transformation_list) { if(!trans) continue; @@ -492,7 +503,7 @@ func OnMaterialChanged(int new, int old) var oldliquid = (olddens >= C4M_Liquid) && (olddens < C4M_Solid); // into water if(newliquid && !oldliquid) - AddEffect("Bubble", this, 1, 52, this); + AddEffect("Bubble", this, 1, 8, this); // out of water else if(!newliquid && oldliquid) RemoveEffect("Bubble", this); @@ -502,8 +513,21 @@ func FxBubbleTimer(pTarget, effect, iTime) { if(GBackLiquid(0,-5)) { + var mouth_off = GetCon()/11; var iRot = GetSwimRotation(); - Bubble(1, +Sin(iRot, 9), Cos(iRot, 9)); + var mouth_off_x = Sin(iRot, mouth_off), mouth_off_y = Cos(iRot, mouth_off); + // Search for bubbles to breath from + var bubble = FindObject(Find_Func("CanBeBreathed", this), Find_AtRect(mouth_off_x-mouth_off/2, mouth_off_y, mouth_off, mouth_off/3)); + if (bubble) + { + bubble->~OnClonkBreath(this); + } + else if (!Random(6)) + { + // Make your own bubbles + + Bubble(1, mouth_off_x, mouth_off_y); + } } } @@ -536,17 +560,17 @@ func SetSkin(int skin) //Steampunk if(skin == 1) - { SetGraphics(nil, Skin_Steampunk); + { SetGraphics("Steampunk"); gender = 1; } //Alchemist if(skin == 2) - { SetGraphics(nil, Skin_Alchemist); + { SetGraphics("Alchemist"); gender = 0; } //Farmer if(skin == 3) - { SetGraphics(nil, Skin_Farmer); + { SetGraphics("Farmer"); gender = 1; } RemoveBackpack(); //add a backpack @@ -555,6 +579,37 @@ func SetSkin(int skin) return skin; } +func GetSkinCount() { return 4; } + +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + // Direction is randomized at creation and there's no good way to find + // out if the user wanted that specific direction. So just always save + // it, because that's what scenario designer usually wants. + if (!props->HasProp("Dir")) props->AddCall("Dir", this, "SetDir", GetConstantNameByValueSafe(GetDir(),"DIR_")); + return true; +} + + +/* AI editor helper */ + +func EditCursorSelection() +{ + var ai = S2AI->GetAI(this); + if (ai) Call(S2AI.EditCursorSelection, ai); + return _inherited(...); +} + +func EditCursorDeselection() +{ + var ai = S2AI->GetAI(this); + if (ai) Call(S2AI.EditCursorDeselection, ai); + return _inherited(...); +} + /* Act Map */ @@ -630,7 +685,6 @@ Scale = { Procedure = DFA_SCALE, Speed = 60, Accel = 20, - Attach = CNAT_MultiAttach, Directions = 2, Length = 1, Delay = 0, @@ -882,9 +936,11 @@ Eat = { }; local Name = "Clonk"; local MaxEnergy = 50000; -local MaxBreath = 252; // Clonk can breathe for 7 seconds under water. +local MaxBreath = 720; // Clonk can breathe for 20 seconds under water. local JumpSpeed = 400; local ThrowSpeed = 294; +local NoBurnDecay = 1; +local ContactIncinerate = 10; func Definition(def) { // Set perspective diff --git a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/DefCore.txt b/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/DefCore.txt deleted file mode 100644 index 76ee5a878..000000000 --- a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/DefCore.txt +++ /dev/null @@ -1,4 +0,0 @@ -[DefCore] -id=Skin_Steampunk -Version=5,2,0,1 -Category=C4D_StaticBack \ No newline at end of file diff --git a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunk.png b/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunk.png deleted file mode 100644 index 6ed91245c..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunk.png and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunk.skeleton b/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunk.skeleton deleted file mode 100644 index ab161f77c..000000000 Binary files a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunk.skeleton and /dev/null differ diff --git a/planet/Objects.ocd/Clonk.ocd/clonkAlchemist.jpg b/planet/Objects.ocd/Clonk.ocd/clonkAlchemist.jpg new file mode 100644 index 000000000..0880cbdfa Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/clonkAlchemist.jpg differ diff --git a/planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemistOverlay.png b/planet/Objects.ocd/Clonk.ocd/clonkAlchemistOverlay.png similarity index 100% rename from planet/Objects.ocd/Clonk.ocd/Alchemist.ocd/clonkAlchemistOverlay.png rename to planet/Objects.ocd/Clonk.ocd/clonkAlchemistOverlay.png diff --git a/planet/Objects.ocd/Clonk.ocd/clonkFarmer.jpg b/planet/Objects.ocd/Clonk.ocd/clonkFarmer.jpg new file mode 100644 index 000000000..f8179e7af Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/clonkFarmer.jpg differ diff --git a/planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmerOverlay.png b/planet/Objects.ocd/Clonk.ocd/clonkFarmerOverlay.png similarity index 100% rename from planet/Objects.ocd/Clonk.ocd/Farmer.ocd/clonkFarmerOverlay.png rename to planet/Objects.ocd/Clonk.ocd/clonkFarmerOverlay.png diff --git a/planet/Objects.ocd/Clonk.ocd/clonkSteampunk.jpg b/planet/Objects.ocd/Clonk.ocd/clonkSteampunk.jpg new file mode 100644 index 000000000..499462b9c Binary files /dev/null and b/planet/Objects.ocd/Clonk.ocd/clonkSteampunk.jpg differ diff --git a/planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunkOverlay.png b/planet/Objects.ocd/Clonk.ocd/clonkSteampunkOverlay.png similarity index 100% rename from planet/Objects.ocd/Clonk.ocd/Steampunk.ocd/clonkSteampunkOverlay.png rename to planet/Objects.ocd/Clonk.ocd/clonkSteampunkOverlay.png diff --git a/planet/Objects.ocd/Effects.ocd/Air.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/Air.ocd/Graphics.png new file mode 100644 index 000000000..695a0d476 Binary files /dev/null and b/planet/Objects.ocd/Effects.ocd/Air.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/Air.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Air.ocd/Particle.txt new file mode 100644 index 000000000..33dbc378e --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/Air.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Air +Face=0,0,32,32,-16,-16 diff --git a/planet/Objects.ocd/Effects.ocd/Bubble.ocd/Script.c b/planet/Objects.ocd/Effects.ocd/Bubble.ocd/Script.c index 95d234055..b59619faa 100644 --- a/planet/Objects.ocd/Effects.ocd/Bubble.ocd/Script.c +++ b/planet/Objects.ocd/Effects.ocd/Bubble.ocd/Script.c @@ -1,5 +1,6 @@ /*-- Bubble --*/ +local creator; // The object that has created this bubble. Used to prevent Clonk from breathing from his own bubbles. global func Bubble(int amount, int x, int y) { @@ -7,10 +8,18 @@ global func Bubble(int amount, int x, int y) amount=3; for (var i = 0; i < amount; i++) - CreateObject(Fx_Bubble, x, y, NO_OWNER); + { + var bubble = CreateObject(Fx_Bubble, x, y, NO_OWNER); + if (bubble) bubble.creator = this; + } return; } +global func CastBubbles(int num, int level, int x, int y) +{ + return CastObjects(Fx_Bubble, num, level, x, y); +} + protected func Initialize() { DoCon(RandomX(25, 100)); @@ -65,3 +74,17 @@ public func FxFadeTimer(object target, effect) effect.alpha = alpha - 5; return 1; } + +func OnClonkBreath(object clonk) +{ + // A Clonk is breathing us in + clonk->DoBreath(GetCon()); // sound would be cool + RemoveObject(); + return true; +} + +// Bubbles can be breathed in by anything but their creator +func CanBeBreathed(object by_clonk) { return !creator || (by_clonk != creator); } + +// No need to blow up scenario object list with bubble spam +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Cloud.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Cloud.ocd/Particle.txt index 19d958f33..ba96adab9 100644 --- a/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Cloud.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Cloud.ocd/Particle.txt @@ -1,11 +1,3 @@ [Particle] Name=Cloud -MaxCount=50 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std Face=0,0,512,350,-256,-175 -Delay=0 -Repeats=1 -WindDrift=20 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Script.c b/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Script.c index b42ac9648..5ae78f7bd 100644 --- a/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Script.c +++ b/planet/Objects.ocd/Effects.ocd/Cloud.ocd/Script.c @@ -14,27 +14,37 @@ func Show(int clr, int layer, int size,bool diffuse) if(layer < 100) SetCategory(GetCategory()|C4D_Background); else SetCategory(GetCategory()|C4D_Foreground); - if(!size) size = 1800; + if(!size) size = 360; var clrmod = clr; var count = 5; + var particles = + { + Prototype = Particles_Cloud(), + Alpha = (clr >> 24) & 0xff, + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + Size = PV_Random(size - 20, size + 20) + }; + // Create some clouds for(var i=0; iRemove("Fire"); + return true; +} diff --git a/planet/Objects.ocd/Effects.ocd/Flash.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Flash.ocd/Particle.txt index 1026daf4f..4053606cb 100644 --- a/planet/Objects.ocd/Effects.ocd/Flash.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/Flash.ocd/Particle.txt @@ -1,12 +1,3 @@ [Particle] Name=Flash -MaxCount=6200 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -Reverse=0 -AlphaFade=48 -Additive=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticle.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/ItemSpark.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticle.ocd/Graphics.png rename to planet/Objects.ocd/Effects.ocd/ItemSpark.ocd/Graphics.png diff --git a/planet/Objects.ocd/Effects.ocd/ItemSpark.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/ItemSpark.ocd/Particle.txt new file mode 100644 index 000000000..dae166fa3 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/ItemSpark.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=ItemSpark +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Graphics.png index 78e723fc1..ed033ad30 100644 Binary files a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Graphics.png and b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Particle.txt index 28ab51e31..e96139317 100644 --- a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/Magic.ocd/Particle.txt @@ -1,17 +1,3 @@ [Particle] Name=Magic -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=20 -AlphaFade=8 -Additive=1 -RByV=3 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Graphics.png index 1aace6bb8..476820962 100644 Binary files a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Graphics.png and b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Particle.txt index e6214388d..45fe56bc9 100644 --- a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicFire.ocd/Particle.txt @@ -1,17 +1,3 @@ [Particle] Name=MagicFire -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std Face=0,0,128,128,-64,-64 -Delay=0 -Repeats=1 -GravityAcc=-4 -VertexCount=1 -VertexY=64 -AlphaFade=18 -Additive=1 -RByV=0 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Graphics.png index 695109f23..0e68870f2 100644 Binary files a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Graphics.png and b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Particle.txt index c0bc6f0f3..0b4c4e92d 100644 --- a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicRing.ocd/Particle.txt @@ -1,17 +1,3 @@ [Particle] Name=MagicRing -MaxCount=1000 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=20 -AlphaFade=35 -Additive=1 -RByV=3 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSmoke.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSmoke.ocd/Graphics.png deleted file mode 100644 index 2a1971e6b..000000000 Binary files a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSmoke.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSmoke.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSmoke.ocd/Particle.txt deleted file mode 100644 index 52429089f..000000000 --- a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSmoke.ocd/Particle.txt +++ /dev/null @@ -1,12 +0,0 @@ -[Particle] -Name=FireballSmoke -MaxCount=800 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -WindDrift=1 -Repeats=1 -AlphaFade=2 -FadeDelay=2 diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Graphics.png index ef5872545..f16104dec 100644 Binary files a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Graphics.png and b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Particle.txt index 1648d627e..17eb15577 100644 --- a/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/MagicParticlesCollection.ocd/MagicSpark.ocd/Particle.txt @@ -1,17 +1,3 @@ [Particle] Name=MagicSpark -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=-4 -VertexCount=1 -VertexY=16 -AlphaFade=12 -Additive=1 -RByV=1 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/MaterialParticle.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MaterialParticle.ocd/Graphics.png deleted file mode 100644 index 32c4c56bc..000000000 Binary files a/planet/Objects.ocd/Effects.ocd/MaterialParticle.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Effects.ocd/MaterialParticle.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MaterialParticle.ocd/Particle.txt deleted file mode 100644 index 61c3b8b24..000000000 --- a/planet/Objects.ocd/Effects.ocd/MaterialParticle.ocd/Particle.txt +++ /dev/null @@ -1,14 +0,0 @@ -[Particle] -Name=MaterialParticle -MaxCount=350 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -CollisionFn=Die -Face=0,0,28,43,-15,-5 -Repeats=10 -GravityAcc=70 -RByV=1 -Delay=175 -VertexCount=1 -AlphaFade=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/MuzzleFlash.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/MuzzleFlash.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/MuzzleFlash.ocd/Graphics.png rename to planet/Objects.ocd/Effects.ocd/MuzzleFlash.ocd/Graphics.png diff --git a/planet/Objects.ocd/Effects.ocd/MuzzleFlash.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/MuzzleFlash.ocd/Particle.txt new file mode 100644 index 000000000..f099045e6 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/MuzzleFlash.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=MuzzleFlash +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Effects.ocd/Shockwave.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/Shockwave.ocd/Graphics.png new file mode 100644 index 000000000..2ec1c152d Binary files /dev/null and b/planet/Objects.ocd/Effects.ocd/Shockwave.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/Shockwave.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Shockwave.ocd/Particle.txt new file mode 100644 index 000000000..648f5bc55 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/Shockwave.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Shockwave +Face=0,0,256,256,-128,-128 diff --git a/planet/Objects.ocd/Effects.ocd/Smoke.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Smoke.ocd/Particle.txt index e3a9c407c..c3537d015 100644 --- a/planet/Objects.ocd/Effects.ocd/Smoke.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/Smoke.ocd/Particle.txt @@ -1,9 +1,3 @@ [Particle] Name=Smoke -MaxCount=150 -MinLifetime=120 -MaxLifetime=180 -InitFn=SmokeInit -ExecFn=SmokeExec -DrawFn=Smoke -Face=0,0,64,64,-32,-32 \ No newline at end of file +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Effects.ocd/SmokeDirty.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/SmokeDirty.ocd/Graphics.png new file mode 100644 index 000000000..903c3773e Binary files /dev/null and b/planet/Objects.ocd/Effects.ocd/SmokeDirty.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/SmokeDirty.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/SmokeDirty.ocd/Particle.txt new file mode 100644 index 000000000..9ddeb705c --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/SmokeDirty.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=SmokeDirty +Face=0,0,256,256,-128,-128 diff --git a/planet/Objects.ocd/Effects.ocd/Explosion.ocd/ExploSmoke.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/SmokeThick.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Effects.ocd/Explosion.ocd/ExploSmoke.ocd/Graphics.png rename to planet/Objects.ocd/Effects.ocd/SmokeThick.ocd/Graphics.png diff --git a/planet/Objects.ocd/Effects.ocd/SmokeThick.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/SmokeThick.ocd/Particle.txt new file mode 100644 index 000000000..db0c81325 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/SmokeThick.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=SmokeThick +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/PSpark.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/SphereSpark.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/PSpark.ocd/Graphics.png rename to planet/Objects.ocd/Effects.ocd/SphereSpark.ocd/Graphics.png diff --git a/planet/Objects.ocd/Effects.ocd/SphereSpark.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/SphereSpark.ocd/Particle.txt new file mode 100644 index 000000000..062f778b9 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/SphereSpark.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=SphereSpark +Face=0,0,140,140,-60,-60 diff --git a/planet/Objects.ocd/Effects.ocd/StarFlash.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/StarFlash.ocd/Graphics.png new file mode 100644 index 000000000..747f45f3c Binary files /dev/null and b/planet/Objects.ocd/Effects.ocd/StarFlash.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/StarFlash.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/StarFlash.ocd/Particle.txt new file mode 100644 index 000000000..ea83ec5b8 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/StarFlash.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=StarFlash +Face=0,0,128,128,-64,-64 diff --git a/planet/Objects.ocd/Effects.ocd/StarSpark.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/StarSpark.ocd/Particle.txt index 554ce75a8..fbfe6a824 100644 --- a/planet/Objects.ocd/Effects.ocd/StarSpark.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/StarSpark.ocd/Particle.txt @@ -1,17 +1,3 @@ [Particle] Name=StarSpark -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=50 -VertexCount=1 -VertexY=0 -AlphaFade=8 -Additive=1 -RByV=3 -Attach=1 \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Straw.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/Straw.ocd/Graphics.png similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Straw.ocd/Graphics.png rename to planet/Objects.ocd/Effects.ocd/Straw.ocd/Graphics.png diff --git a/planet/Objects.ocd/Effects.ocd/Straw.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Straw.ocd/Particle.txt new file mode 100644 index 000000000..64651c527 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/Straw.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Straw +Face=0,0,32,32,-16,-16 diff --git a/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Aimer.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Aimer.ocd/Graphics.png deleted file mode 100644 index 51b19588a..000000000 Binary files a/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Aimer.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Aimer.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Aimer.ocd/Particle.txt deleted file mode 100644 index 7ffb0e151..000000000 --- a/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Aimer.ocd/Particle.txt +++ /dev/null @@ -1,11 +0,0 @@ -[Particle] -Name=Trajectory -MaxCount=1000 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,32,32,-32,-32 -Delay=0 -Additive=1 -Attach=1 -RByV=2 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Script.c b/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Script.c index 75a2ed99e..79a39b809 100644 --- a/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Script.c +++ b/planet/Objects.ocd/Effects.ocd/Trajectory.ocd/Script.c @@ -34,17 +34,28 @@ global func AddTrajectory(object pObj, int iX, int iY, int iXDir, int iYDir, int iYDir *= 5; iXDir *= 5; iY -= 4*iFaktor; iXOld = iX; iYOld = iY; + if (!spacing) spacing = 10; + + // particle setup + var particles = + { + Prototype = Particles_Trajectory(), + R = (iColor >> 16) & 0xff, + G = (iColor >> 8) & 0xff, + B = (iColor >> 0) & 0xff, + Alpha = (iColor >> 24) & 0xff + }; + // Trajectory simulation while(++i < 500) { // Speed and gravity offset iX += iXDir; - iY += iYDir + GetGravity() * i / 20; + iY += iYDir + GetGravity() * i / 22; // If we are far enough away insert a new point - if(!spacing) spacing = 10; if(Distance((iXOld - iX) / iFaktor, (iYOld - iY) / iFaktor) >= spacing) { - CreateParticle("Trajectory", iX/iFaktor - pTrajectory->GetX(), iY/iFaktor - pTrajectory->GetY(), iXDir/500, iYDir/500, 15, iColor, pTrajectory); + pTrajectory->CreateParticle("Magic", iX/iFaktor - pTrajectory->GetX(), iY/iFaktor - pTrajectory->GetY(), 0, 0, 0, particles); iXOld = iX; iYOld = iY; } // Or is it here already? @@ -59,6 +70,9 @@ public func AttachTargetLost() RemoveObject(); } +// Don't save in scenarios +func SaveScenarioObject() { return false; } + local ActMap = { Attach = { Prototype = Action, diff --git a/planet/Objects.ocd/Effects.ocd/Wave.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/Wave.ocd/Graphics.png index 3f0175985..fee255d55 100644 Binary files a/planet/Objects.ocd/Effects.ocd/Wave.ocd/Graphics.png and b/planet/Objects.ocd/Effects.ocd/Wave.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Effects.ocd/Wave.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Wave.ocd/Particle.txt index a645a7911..10e5c7107 100644 --- a/planet/Objects.ocd/Effects.ocd/Wave.ocd/Particle.txt +++ b/planet/Objects.ocd/Effects.ocd/Wave.ocd/Particle.txt @@ -1,16 +1,3 @@ [Particle] -Name=WaveLeft -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std +Name=Wave Face=0,0,100,50,-50,-25 -Delay=2 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=20 -AlphaFade=0 -RByV=0 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Effects.ocd/Wave.ocd/WaveRight.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/Wave.ocd/WaveRight.ocd/Graphics.png deleted file mode 100644 index 0203eb2cb..000000000 Binary files a/planet/Objects.ocd/Effects.ocd/Wave.ocd/WaveRight.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Effects.ocd/Wave.ocd/WaveRight.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/Wave.ocd/WaveRight.ocd/Particle.txt deleted file mode 100644 index 8f0b0f062..000000000 --- a/planet/Objects.ocd/Effects.ocd/Wave.ocd/WaveRight.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=WaveRight -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,100,50,-50,-25 -Delay=2 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=20 -AlphaFade=0 -RByV=0 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/WoodChip.ocd/Graphics.png b/planet/Objects.ocd/Effects.ocd/WoodChip.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/WoodChip.ocd/Graphics.png rename to planet/Objects.ocd/Effects.ocd/WoodChip.ocd/Graphics.png diff --git a/planet/Objects.ocd/Effects.ocd/WoodChip.ocd/Particle.txt b/planet/Objects.ocd/Effects.ocd/WoodChip.ocd/Particle.txt new file mode 100644 index 000000000..a0f1b3584 --- /dev/null +++ b/planet/Objects.ocd/Effects.ocd/WoodChip.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=WoodChip +Face=0,0,16,16,-8,-8 diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/DefCore.txt new file mode 100644 index 000000000..1403548dd --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Ambience +Version=4,10,0,0 +Category=C4D_StaticBack +Width=1 +Height=1 +Offset=-1,-1 + diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Graphics.png new file mode 100644 index 000000000..d1dd3b672 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Info.txt b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Info.txt new file mode 100644 index 000000000..d538c836c --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Info.txt @@ -0,0 +1,5 @@ +This folder contains objects that have purely decorative purpose, so that they can be added and removed from any scenario without having any impact on the gameplay. +That means that if you decide to give objects in this folder a meaning beyond decoration, you should move them out into a proper place and also remove them from the proplist "Environment_Attributes" found in Ambience.ocd/Script.c - by the conventions you are guaranteed that nothing will break when you do that. +For example you could move Ambience_Zicadas into Animals.ocd, give them the ID "Zicadas" and remove the "Zicadas" entry from the proplist - or just set the "ID" field of the "Zicadas" entry to "nil". + +You are encouraged to use objects from this folder through the function "CreateEnvironmentObjects" which guarantees full backwards and forwards compatibility. However, all objects in this folder also have Place()-methods if you need to place them manually. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Script.c new file mode 100644 index 000000000..bcc00bcc7 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Script.c @@ -0,0 +1,108 @@ +/** + Ambience + Cares about the placement of purely visual objects. + The placement uses categories and thus is forward-compatible. +*/ + +// this proplist defines the selectable environment objects +// "ID" might be nil or a valid id +// "includes" specifies what objects are created when the selected object is created (no specific order) +// any entry of "Environment_Attributes" might be nil or false instead of a proplist +// nil will log a warning on creating that object and false will silently ignore it +// thus something like Environment_Attributes["Foobar"] = false; will work to disable certain features +static const Environment_Attributes = +{ + All = { + ID = nil, + includes = ["Temperate", "Desert"], + }, + + Temperate = { + ID = nil, + includes = ["Zicadas", "Frogs", "BackgroundBirds"], + }, + + Desert = { + ID = nil, + includes = ["Zicadas"], + }, + + Zicadas = { + ID = Ambience_Zicadas, + }, + + Frogs = { + ID = nil /* not yet implemented: Environment_Frogs */, + }, + + BackgroundBirds = { + ID = nil /* not yet implemented: Environment_BackgroundBirds */, + }, +}; + + + +// provides a simple interface for creation of environment objects and decoration with standard values +// the objects are placed on a best-effort-basis. That means f.e. objects that rely on water will not be placed when there is no water in the landscape. +global func CreateEnvironmentObjects( + what /* array of strings or single string: what objects will be created, standard: "All" */ + , proplist area /* area where objects will be created, format {x = ??, y = ??, w = ??, h = ??}, standard: whole landscape */ + , int amount_percentage /* what percentage of the standard amount will be created, standard: 100 */ + ) +{ +/* +// half desert, half temperate - but birds everywhere +CreateEnvironmentObjects(["Desert", "BackgroundBirds"], Rectangle(0, 0, LandscapeWidth()/2, LandscapeHeight())); +CreateEnvironmentObjects("Temperate", Rectangle(LandscapeWidth()/2, 0, LandscapeWidth()/2, LandscapeHeight())); +*/ + what = what ?? "All"; + area = area ?? Rectangle(0, 0, LandscapeWidth(), LandscapeHeight()); + amount_percentage = amount_percentage ?? 100; + + // might be a string to allow CreateEnvironmentObjects("All") + if(GetType(what) != C4V_Array) + what = [what]; + + // iteratively find all the objects that are included in the selection + while(true) + { + var changed = false; + var to_add = []; + + // go through every object in the list + for(var obj in what) + { + var p = Environment_Attributes[obj]; + if(p == nil) {Log("Warning: Environment object %s does not exist!", obj);} + else if(p == false) continue; // disabled by the scenario designer + + // add all objects included to the temporary list if existing + if(!p["includes"]) continue; + to_add = Concatenate(to_add, p["includes"]); + } + + // add every unique item from the temporary list to the object list + for(var obj in to_add) + { + if(IsValueInArray(what, obj)) continue; + + if(!!Environment_Attributes[obj]["includes"]) + changed = true; // found changes, need further checking + + PushBack(what, obj); + } + + if(!changed) + break; + } + + // now create all the selected objects + for(var obj in what) + { + var p, p_id; + if(!(p = Environment_Attributes[obj])) continue; + if(!(p_id = p["ID"])) continue; + + p_id->Place(amount_percentage, area); + } +} \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/DefCore.txt new file mode 100644 index 000000000..8d05ddd17 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Ambience_Zicadas +Version=4,10,0,0 +Category=C4D_StaticBack +Width=1 +Height=1 +Offset=-1,-1 diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/Graphics.png new file mode 100644 index 000000000..d1dd3b672 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/Script.c new file mode 100644 index 000000000..da97c0c5a --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/Script.c @@ -0,0 +1,26 @@ +/** + Zicadas + Zicada sounds. +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +func Place(int amount_percentage, proplist area) +{ + area = area ?? Rectangle(0, 0, LandscapeWidth(), LandscapeHeight()); + amount_percentage = amount_percentage ?? 100; + + // calculate amount that has to be placed + var amount = LandscapeWidth() / 100; + amount = (amount_percentage * amount) / 100; + if(!amount) return; + + while(--amount) + { + // search for zicada spot position + // .. + // place zicada spot + // .. + } +} \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/StringTblDE.txt new file mode 100644 index 000000000..40f58a979 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Zikaden +Description=Zikadengeräusche. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/StringTblUS.txt new file mode 100644 index 000000000..65f65c1a1 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Ambience.ocd/Zicadas.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Zicadas +Description=Zicada sounds. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/Script.c index 97c44e2c2..f61afd49e 100644 --- a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/Script.c @@ -43,6 +43,14 @@ public func SetP(int p) dir=p; } +// Edges in saved scenarios +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (dir) props->AddCall("P", this, "SetP", dir); + return true; +} + public func GetD() { return dir; } global func MakeEdgeFunction(bool fExact) diff --git a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/SolidMask.png b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/SolidMask.png new file mode 100644 index 000000000..29057e6a3 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/BrickEdge.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Graphics.4.png b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Graphics.4.png index cfc54c918..2a11249d4 100644 Binary files a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Graphics.4.png and b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Script.c index 7c9d12d43..a9f7bf85b 100644 --- a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/Script.c @@ -28,6 +28,8 @@ public func SetSize(int to_size) // Update graphics. var graph = Format("Size%dN%d", size, 1 + Random(1)); SetGraphics(graph); + // Update solid + SetSolidMask(0,size*8-8,10*size,8); return; } @@ -41,12 +43,13 @@ public func SetMoveSpeed(int speed) public func MoveHorizontal(int left, int right, int speed) { + RemoveEffect("MoveHorizontal", this); RemoveEffect("MoveVertical", this); var effect = AddEffect("MoveHorizontal", this, 100, 1, this); effect.Left = left; effect.Right = right; if (speed != nil) SetMoveSpeed(10 * speed); - SetComDir(COMD_Left); + if (GetComDir() != COMD_Right) SetComDir(COMD_Left); return; } @@ -67,12 +70,13 @@ private func FxMoveHorizontalTimer(object target, proplist effect) public func MoveVertical(int top, int bottom, int speed) { + RemoveEffect("MoveHorizontal", this); RemoveEffect("MoveVertical", this); var effect = AddEffect("MoveVertical", this, 100, 1, this); effect.Top = top; effect.Bottom = bottom; if (speed != nil) SetMoveSpeed(10 * speed); - SetComDir(COMD_Up); + if (GetComDir() != COMD_Down) SetComDir(COMD_Up); return; } @@ -89,6 +93,30 @@ private func FxMoveVerticalTimer(object target, proplist effect) return 1; } +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (size != 4) props->AddCall("Size", this, "SetSize", size); + if (ActMap.Moving.Speed != GetID().ActMap.Moving.Speed) props->AddCall("MoveSpeed", this, "SetMoveSpeed", ActMap.Moving.Speed); + if (GetComDir() == COMD_None) props->Remove("ComDir"); + return true; +} + +func FxMoveHorizontalSaveScen(obj, fx, props) +{ + props->AddCall("Move", obj, "MoveHorizontal", fx.Left, fx.Right); + return true; +} + +func FxMoveVerticalSaveScen(obj, fx, props) +{ + props->AddCall("Move", obj, "MoveVertical", fx.Top, fx.Bottom); + return true; +} + +/* Properties */ local ActMap = { Moving = { diff --git a/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/SolidMask.png b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/SolidMask.png new file mode 100644 index 000000000..17c4c4c5c Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Bricks.ocd/MovingBrick.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/LightningBolt.ocd/Particle.txt b/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/LightningBolt.ocd/Particle.txt index 18d7c0962..66ae9ebc9 100644 --- a/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/LightningBolt.ocd/Particle.txt +++ b/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/LightningBolt.ocd/Particle.txt @@ -1,14 +1,4 @@ [Particle] Name=LightningBolt -MaxCount=16384 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std Face=0,0,32,32,-16,-16 -Delay=2 -Repeats=10 -GravityAcc=0 -WindDrift=0 -Additive=1 -AlphaFade=10 -RByV=2 + diff --git a/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/Script.c index 80ed8fe71..a02ef5cdc 100644 --- a/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Lightning.ocd/Script.c @@ -53,13 +53,19 @@ protected func FxLightningMoveTimer() AddVertex(newx, newy); // Draw the new line with lightning particles. - DrawRotatedParticleLine("LightningBolt", oldx, oldy, newx, newy, strength / 30, 2 * strength / 3, 0xa0f0f0f0); + DrawRotatedParticleLine("LightningBolt", oldx, oldy, newx, newy, strength / 30, strength / 3, 0xa0f0f0f0); // Strike objects on the line. for (var obj in FindObjects(Find_OnLine(oldx, oldy, newx, newy), Find_NoContainer(), Find_Layer(GetObjectLayer()))) { - if (!obj->~LightningStrike(3 + strength / 10)) - Punch(obj, 3 + strength / 10); + if (obj && !obj->~LightningStrike(3 + strength / 10)) + { + if (GetOCF() & OCF_Alive) + Punch(obj, 3 + strength / 10); + else + // Todo: Lightning strikes may have controllers? Pass them for kill tracing. + obj->DoDamage(3 + strength / 10, FX_Call_DmgScript); + } } // Remove lightning, if struck landscape. @@ -96,26 +102,37 @@ private func Redraw() var newx = GetVertex(vtx, 0); var newy = GetVertex(vtx, 1); //Log("Lightning %d: Redraw vtx %d->%d %d/%d->%d/%d", ObjectNumber(), vtx-1, vtx, oldx, oldy, newx, newy); - DrawRotatedParticleLine("LightningBolt", oldx, oldy, newx, newy, strength/5, strength*2, 0xa0f0f0f0); + DrawRotatedParticleLine("LightningBolt", oldx, oldy, newx, newy, strength/5, strength / 3, 0xa0f0f0f0); oldx = newx; oldy = newy; } } -private func DrawRotatedParticleLine(string particle, int x1, int y1, int x2, int y2, int distance, int sizeFifths, int color) +private func DrawRotatedParticleLine(string particle, int x1, int y1, int x2, int y2, int distance, int size, int color) { distance = Max(distance, 1); var angle = Angle(x1, y1, x2, y2); - var xdir = Sin(angle, 10); - var ydir = -Cos(angle, 10); // Need at least two particles: start and end var count = Max(2, Distance(x1, y1, x2, y2) / distance); var deltax = x2 - x1, deltay = y2 - y1; //Log("DrawRPL: %s in %d steps, angle %d xdir %d ydir %d", particle, count, angle, xdir, ydir); + var particle_prop = + { + R = GetRGBaValue(color, 1), + G = GetRGBaValue(color, 2), + B = GetRGBaValue(color, 3), + Alpha = PV_Linear(128, 0), + Size = size, + Rotation = angle, + BlitMode = GFX_BLIT_Additive + }; for (var i = count+1; --i; ) { - CreateParticle(particle, x1 + deltax * i / count, y1 + deltay * i / count, xdir, ydir, sizeFifths, color); + CreateParticle(particle, x1 + deltax * i / count, y1 + deltay * i / count, 0, 0, 18, particle_prop); } } +// Don't save in scenarios +func SaveScenarioObject() { return false; } + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Script.c index c714d64b0..cb9bb846c 100644 --- a/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Cloud.ocd/Script.c @@ -24,6 +24,11 @@ local rain_mat; // Precipitation type from scenario or other. local rain_amount; // Precipitation amount from scenario or other. local rain_max; // Max rain the cloud can hold. +local cloud_shade; // Cloud shade. +local cloud_alpha; // Cloud alpha. + +// This is an environment object (e.g., shouldn't be a target for the lift tower) +public func IsEnvironment() { return true; } protected func Initialize() { @@ -37,6 +42,8 @@ protected func Initialize() // Cloud defaults lightning_chance = 0; + cloud_shade = 0; + cloud_alpha = 255; evap_x = 0; DoCon(Random(75)); @@ -45,14 +52,15 @@ protected func Initialize() SetComDir(COMD_None); SetPhase(RandomX(1,16)); - //Push low flying clouds up to proper height - while(MaterialDepthCheck(GetX(),GetY(),"Sky",150)!=true) + // Push low flying clouds up to proper height + while (MaterialDepthCheck(GetX(), GetY(), "Sky", 150) != true) { - SetPosition(GetX(),GetY()-1); + SetPosition(GetX(), GetY()-1); } - //Failsafe for stupid grounded clouds - if (GetMaterial(0,30)!=Material("Sky")) SetPosition(GetX(), GetY()-180); + // Failsafe for stupid grounded clouds + if (GetMaterial(0, 30) != Material("Sky")) + SetPosition(GetX(), GetY() - 180); // Add effect to process all cloud features. AddEffect("ProcessCloud", this, 100, 5, this); @@ -93,7 +101,7 @@ public func SetPrecipitation(string mat, int amount) rain_mat = mat; rain_amount = amount; // Also change rain content. - rain = amount * rain_max / 100; + rain = BoundBy(amount * rain_max / 100, 0, 960); } return; } @@ -165,19 +173,24 @@ protected func FxProcessCloudTimer() private func MoveCloud() { + // Get wind speed from various locations of the cloud. + var con = GetCon(); + var wdt = GetDefWidth() * con / 250; + var hgt = GetDefHeight() * con / 350; + var wind = (GetWind() + GetWind(wdt, hgt) + GetWind(wdt, -hgt) + GetWind(-wdt, -hgt) + GetWind(-wdt, hgt) + GetWind(nil, nil, true)) / 6; + // Move according to wind. - var wind = GetWind(); - if (wind >= 7) - SetXDir(Random(355), 1000); - else if (wind <= -7) - SetXDir(-Random(355), 1000); + if (Abs(wind) < 7) + SetXDir(0); else - SetXDir(); + SetXDir(wind * 10, 1000); + // Loop clouds around the map. if (GetX() >= LandscapeWidth() - 10) SetPosition(12, GetY()); if (GetX() <= 10) SetPosition(LandscapeWidth()-12, GetY()); + // Some other safety. if (GetY() <= 5) SetPosition(0, 6); @@ -195,8 +208,8 @@ private func Precipitation() // Precipitaion: water or snow. if (rain > 0) { - RainDrop(rain_mat); - rain--; + if (RainDrop(rain_mat)); + rain--; } // If out of liquids, skip mode. if (rain == 0) @@ -207,15 +220,22 @@ private func Precipitation() // Raindrop somewhere from the cloud. private func RainDrop(string mat) { + // Find Random Position. + var con = GetCon(); + var wdt = GetDefWidth() * con / 500; + var hgt = GetDefHeight() * con / 700; + var x = RandomX(-wdt, wdt); + var y = RandomX(-hgt, hgt); + if (!GBackSky(x, y)) + return false; // Check if liquid is maybe in frozen form. var temp = GetTemperature(); var melt_temp = GetMaterialVal("BelowTempConvert", "Material", Material(mat)); if (temp < melt_temp) - mat = GetMaterialVal("BelowTempConvertTo", "Material", Material(mat)); - // Create rain drop. - var angle = RandomX(0, 359); - var dist = Random(51); - CastPXS(mat, 1, 1, Sin(angle,dist),Cos(angle,dist)); + mat = GetMaterialVal("BelowTempConvertTo", "Material", Material(mat)); + // Create rain drop. + CastPXS(mat, 1, 1, x, y); + return true; } // Launches possibly one thunder strike from the cloud. @@ -224,7 +244,7 @@ private func ThunderStrike() // Determine whether to launch a strike. if (rain < 100) return; - if (Random(100) >= lightning_chance || Random(15)) + if (Random(100) >= lightning_chance || Random(80)) return; // Find random position in the cloud. @@ -233,6 +253,14 @@ private func ThunderStrike() var hgt = GetDefHeight() * con / 350; var x = GetX() + RandomX(-wdt, wdt); var y = GetY() + RandomX(-hgt, hgt); + + var pix = 0; + // Check if there is sky for at least 60 pixels. + while (GBackSky(x - GetX(), y - GetY() + pix) && pix <= 60) + pix++; + if (pix < 60) + return; + var str = 2 * con / 3 + RandomX(-15, 15); // Launch lightning. return LaunchLightning(x, y, str, 0, str / 5, str / 10, str / 10, true); @@ -278,16 +306,43 @@ protected func Evaporation() //Shades the clouds based on iSize: the water density value of the cloud. private func ShadeCloud() { - var shade = Min((rain+50)*425/1000, 255); - var shade2 = Min(rain-600, 255); + var alpha = (cloud_alpha + ((rain + 40) * 255) / 960) / 2; + var alpha = Min(alpha, 255); + var shade = BoundBy(cloud_shade, 0, 255); - if (rain <= 600) - SetObjAlpha(shade); - if (rain > 600) - SetClrModulation(RGBa(255-shade2, 255-shade2, 255-shade2, 255)); - return; + SetClrModulation(RGBa(255-shade, 255-shade, 255-shade, alpha)); } +// Utilized by time to make clouds invisible at night +public func SetLightingShade(int darkness) +{ + cloud_shade = darkness; +} + +// Utilized by time to make clouds invisible at night +public func SetCloudAlpha(int alpha) +{ + cloud_alpha = BoundBy(alpha, 0, 255); +} + + +/* Scenartio saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (GetComDir() == COMD_None) props->Remove("ComDir"); + props->Remove("Con"); + props->Remove("ClrModulation"); + if (rain_mat) props->AddCall("Precipitation", this, "SetPrecipitation", Format("%v", rain_mat), rain_amount); + if (lightning_chance) props->AddCall("Lightning", this, "SetLightning", lightning_chance); + if (rain) props->AddCall("Rain", this, "SetRain", rain); + return true; +} + + +/* Properties */ + local ActMap = { Fly = { Prototype = Action, diff --git a/planet/Objects.ocd/Environment.ocd/Earthquake.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Earthquake.ocd/Script.c index 209025778..6e9d251ab 100644 --- a/planet/Objects.ocd/Environment.ocd/Earthquake.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Earthquake.ocd/Script.c @@ -1,62 +1,48 @@ -/*-- - Earthquake - Author: Maikel - - This is the earthquake control object, earthquakes are realized through a global effect. - Earthquakes can be activated in Scenario.txt under [Environment], Earthquake=x will result - in a 10*x % earthquake level. You can also just create the control object and modify the - chance with Get/Set/DoChance. The third option is to directly launch an earthquake with - LaunchEarthquake(int x, int y, int strength) at the global coordinates (x,y). ---*/ +/** + Earthquake + Trembles the earth. + + @author Maikel +*/ /*-- Disaster Control --*/ -protected func Initialize() +public func SetChance(int chance) { - // Check for other control objects. - var ctrl = FindObject(Find_ID(GetID()), Find_Exclude(this)); - if (ctrl) - { - ctrl->DoChance(10); - RemoveObject(); - } - else - { - AddEffect("IntEarthquakeControl", this, 100, 35, this); - SetChance(10); - } + if (this != Earthquake) + return; + var effect = GetEffect("IntEarthquakeControl"); + if (!effect) + effect = AddEffect("IntEarthquakeControl", nil, 100, 20, nil, Earthquake); + effect.chance = chance; return; } public func GetChance() { - var effect = GetEffect("IntEarthquakeControl", this); - return effect.chance; -} - -public func SetChance(int chance) -{ - var effect = GetEffect("IntEarthquakeControl", this); - effect.chance = BoundBy(chance, 0, 100); + if (this != Earthquake) + return; + var effect = GetEffect("IntEarthquakeControl"); + if (effect) + return effect.chance; return; } -public func DoChance(int chance) +protected func FxIntEarthquakeControlTimer(object target, proplist effect, int time) { - SetChance(GetChance() + chance); - return; -} - -protected func FxIntEarthquakeControlTimer(object target, effect, int time) -{ - var chance = effect.chance; - if (!Random(8)) - if (Random(100) < chance) - LaunchEarthquake(Random(LandscapeWidth()), Random(LandscapeHeight()), Random(40) + 35); + if (Random(100) < effect.chance && !Random(10)) + LaunchEarthquake(Random(LandscapeWidth()), Random(LandscapeHeight()), Random(40) + 35); return FX_OK; } +// Scenario saving +func FxIntEarthquakeControlSaveScen(obj, fx, props) +{ + props->Add("Earthquake", "Earthquake->SetChance(%d)", fx.chance); + return true; +} + // Launches an earthquake with epicenter (x,y). global func LaunchEarthquake(int x, int y, int strength) { @@ -66,7 +52,7 @@ global func LaunchEarthquake(int x, int y, int strength) // Minimum strength is 15, maximum strength is 100. strength = BoundBy(strength, 15, 100); // The earthquake is handled by a global effect. - var effect = AddEffect("IntEarthquake", 0, 100, 1, nil, Earthquake); + var effect = AddEffect("IntEarthquake", nil, 100, 1, nil, Earthquake); effect.x = x; // Epicentre x coordinate. effect.y = y; // Epicentre y coordinate. effect.strength = strength / 3; // Earthquake strength. @@ -74,19 +60,21 @@ global func LaunchEarthquake(int x, int y, int strength) return true; } -/*-- Earthquake control --*/ +/*-- Earthquake --*/ protected func FxIntEarthquakeStart(object target, effect) { // Start sound at quake local coordinates. - //Sound("Earthquake", true, 100, nil, 1); + // < Maikel> Global until someone implements non-object local sounds + Sound("Earthquake", true, 100, nil, 1); return FX_OK; } protected func FxIntEarthquakeStop(object target, effect) { // Stop sound. - //Sound("Earthquake", true, 100, nil, -1); + Sound("Earthquake", true, 100, nil, -1); + Sound("EarthquakeEnd",true); return FX_OK; } diff --git a/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/DefCore.txt new file mode 100644 index 000000000..ba9e3122f --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Landscape_Cave +Version=4,10,0,0 +Category=C4D_StaticBack +Width=1 +Height=1 +Offset=-1,-1 diff --git a/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/Graphics.png new file mode 100644 index 000000000..a28d190b8 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/Script.c new file mode 100644 index 000000000..2e5b37dd2 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Landscape.ocd/Cave.ocd/Script.c @@ -0,0 +1,101 @@ +/** + Cave + Creates a nice cave. +*/ + +/* + Randomly places a cave without a border unless specified otherwise. + + Custom properties are: + + width, height: + size of the cave's bounding box + borderwidth, borderheight: + thickness of the border + bordersize: + implicit borderwidth and borderheight + bordermat: + material of the border, f.e. "Rock" + bordertex: + texture of the border, f.e. "rock_cracked" + +*/ +public func Place(int amount, proplist rectangle, proplist settings) +{ +/* + var caves = Landscape_Cave->Place(1, nil, {width = 100, height = 50, borderheight = 5, bordermat = "Earth", bordertex = "earth_topSoil" } ); + if (GetLength(caves) == 0) FatalError("No cave placed!"); +*/ + var caves = []; + amount = amount ?? ((LandscapeHeight() * LandscapeWidth()) / 1000); + + var width = settings.width ?? 100; + var height = settings.height ?? 100; + var realwidth = 50, realheight = 50; + + if(width < height) + { + var aspect = (100 * width) / height; + realwidth = (aspect * realheight) / 100; + } + else + { + var aspect = (100 * height) / width; + realheight = (aspect * realwidth) / 100; + } + var x = (100 - realwidth) / 2; + var y = (100 - realheight) / 2; + + var borderstring = ""; + if (settings.bordersize || settings.borderwidth || settings.borderheight) + { + var bordermat = settings.bordermat ?? "Rock"; + var bordertex = settings.bordertex ?? "rock"; + var borderwidth = settings.borderwidth ?? settings.bordersize ?? 0; + var borderheight = settings.borderheight ?? settings.bordersize ?? 0; + borderstring = Format("overlay { mat = %s; tex = %s; algo = border; a = %d; b = %d; loosebounds = 1; };", bordermat, bordertex, borderwidth, borderheight); + } + + var map = Format("overlay { x = %d; y = %d; wdt = %d; hgt = %d; mat = Tunnel; loosebounds = 1; turbulence = 500; %s };", x, y, realwidth, realheight, borderstring); + + var failsafe = 100; + + while((--failsafe > 0) && amount > 0) + { + var spot = FindLocation(Loc_Solid(), Loc_Func(Landscape_Cave.IsGoodCaveSpot), Loc_InRect(rectangle)); + if (!spot) continue; + + DrawMap(spot.x - width, spot.y - height, 2 * width, 2 * height, Format("map Cave { %s };", map)); + var cave = CreateObject(Landscape_Cave, spot.x, spot.y, NO_OWNER); + PushBack(caves, cave); + + // project free objects down to the ground + for (var obj in FindObjects(Find_InRect(spot.x - width, spot.y - height, 2 * width, 2 * height), Find_Category(C4D_Object))) + { + var originaly = obj->GetY(); + var max = height; + while ((!obj->GetContact(-1, CNAT_Bottom)) && !obj->Stuck() && (--max > 0)) + { + obj->SetPosition(obj->GetX(), obj->GetY() + 1); + } + if (max <= 0) obj->SetPosition(obj->GetX(), originaly); + } + + --amount; + } + + return caves; +} + +func IsGoodCaveSpot(int x, int y) +{ + // cave must be "far" underground! + var no_sky_distance = 200; + for (var yd = 0; yd <= no_sky_distance; yd += 10) + if (GBackSky(x, y - yd)) return false; + + var cave = FindObjects(Find_ID(Landscape_Cave), Sort_Distance(x, y)); + if (GetLength(cave) == 0) return true; + cave = cave[0]; + return Distance(x, y, cave->GetX(), cave->GetY()) > 100; +} \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Meteor.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/DefCore.txt new file mode 100644 index 000000000..1dfa9e83c --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Meteor +Version=5,2,0,1 +Category=C4D_Object|C4D_Environment +Width=20 +Height=20 +Offset=-10,-10 +Vertices=4 +VertexX=-7,-7,7,7 +VertexY=-7,7,-7,7 +VertexFriction=50,50,50,50 +Rotate=1 +NoStabilize=1 +StretchGrowth=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Meteor.ocd/Graphics.8.png b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/Graphics.8.png new file mode 100644 index 000000000..6e1527948 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Meteor.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/Script.c new file mode 100644 index 000000000..1dd69dabd --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/Script.c @@ -0,0 +1,141 @@ +/** + Meteor + A burning rock falling from the sky, explodes on impact. + + @author Maikel +*/ + + +/*-- Disaster Control --*/ + +public func SetChance(int chance) +{ + if (this != Meteor) + return; + var effect = GetEffect("IntMeteorControl"); + if (!effect) + effect = AddEffect("IntMeteorControl", nil, 100, 20, nil, Meteor); + effect.chance = chance; + return; +} + +public func GetChance() +{ + if (this != Meteor) + return; + var effect = GetEffect("IntMeteorControl"); + if (effect) + return effect.chance; + return; +} + +protected func FxIntMeteorControlTimer(object target, proplist effect, int time) +{ + if (Random(100) < effect.chance && !Random(10)) + { + // Launch a meteor. + var meteor = CreateObject(Meteor); + var x = Random(LandscapeWidth()); + var y = 0; + var size = RandomX(60, 90); + var xdir = RandomX(-22, 22); + var ydir = RandomX(28, 36); + meteor->Launch(x, y, size, xdir, ydir); + } + return FX_OK; +} + +// Scenario saving +func FxIntMeteorControlSaveScen(obj, fx, props) +{ + props->Add("Meteor", "Meteor->SetChance(%d)", fx.chance); + return true; +} + +global func LaunchMeteor(int x, int y, int size, int xdir, int ydir) +{ + var meteor = CreateObject(Meteor); + return meteor->Launch(x, y, size, xdir, ydir); +} + +/*-- Meteor --*/ + +public func Launch(int x, int y, int size, int xdir, int ydir) +{ + // Launch from indicated position. + SetPosition(x, y); + // Set the meteor's size. + SetCon(BoundBy(size, 20, 100)); + // Set the initial velocity. + SetXDir(xdir); + SetYDir(ydir); + // Set random rotation. + SetR(Random(360)); + SetRDir(RandomX(-10, 10)); + // Safety check. + if (!IsLaunchable()) + return false; + // Set right action. + AddEffect("IntMeteor", this, 100, 1, this); + return true; +} + +private func IsLaunchable() +{ + if (GBackSemiSolid() || Stuck()) + { + RemoveObject(); + return false; + } + return true; +} + +protected func FxIntMeteorTimer() +{ + var size = GetCon(); + // Air drag. + var ydir = GetYDir(100); + ydir -= size * ydir ** 2 / 11552000; // Magic number. + SetYDir(ydir, 100); + // Smoke trail. + CreateParticle("Smoke", PV_Random(-2, 2), PV_Random(-2, 2), PV_Random(-3, 3), PV_Random(-3, 3), 30 + Random(60), Particles_SmokeTrail(), 5); + // Fire trail. + CreateParticle("MagicSpark", 0, 0, PV_Random(-20, 20), PV_Random(-20, 20), 16, Particles_SparkFire(), 4); + CreateParticle("Fire", PV_Random(-size / 8, size / 8), PV_Random(-size / 8, size / 8), PV_Random(-1, 1), PV_Random(-1, 1), 30, Particles_FireTrail(), 6 + size / 10); + // Sound. + + // Burning and friction decrease size. + if (size > 10 && !Random(5)) + DoCon(-1); + + return 1; +} + +protected func Hit(int xdir, int ydir) +{ + var size = 10 + GetCon(); + var speed2 = 20 + (xdir ** 2 + ydir ** 2) / 10000; + // Some fire sparks. + var particles = + { + Prototype = Particles_Fire(), + Attach = nil + }; + CreateParticle("Fire", PV_Random(-size / 4, size / 4), PV_Random(-size / 4, size / 4), PV_Random(-size/4, size/4), PV_Random(-size/4, size/4), 30, particles, 20 + size); + // Explode meteor, explode size scales with the energy of the meteor. + var dam = size * speed2 / 500; + dam = BoundBy(size/2, 5, 30); + Explode(dam); + return; +} + +// Scenario saving +func FxIntMeteorSaveScen(obj, fx, props) +{ + props->AddCall("Meteor", obj, "AddEffect", "\"IntMeteor\"", obj, 100, 1, obj); + return true; + } + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Environment.ocd/Meteor.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/StringTblDE.txt new file mode 100644 index 000000000..3bb6aa868 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Meteor diff --git a/planet/Objects.ocd/Environment.ocd/Meteor.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/StringTblUS.txt new file mode 100644 index 000000000..3bb6aa868 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Meteor.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Meteor diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/DefCore.txt index f505f243d..5920fdb62 100644 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/DefCore.txt +++ b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/DefCore.txt @@ -2,9 +2,9 @@ id=Moon Version=5,2,0,1 Category=C4D_StaticBack|C4D_Background|C4D_Parallax -Width=64 -Height=64 -Offset=-32,32 +Width=128 +Height=128 +Offset=-64,-64 Vertices=1 VertexY=0 Mass=1 diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics.2.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics.2.png deleted file mode 100644 index 1fae23ac2..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics.2.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics.png new file mode 100644 index 000000000..29bd60a1a Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics1.2.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics1.2.png deleted file mode 100644 index a6e8b3845..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics1.2.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics2.2.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics2.2.png deleted file mode 100644 index 24990e04a..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics2.2.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics3.2.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics3.2.png deleted file mode 100644 index 2624e5a9b..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics3.2.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics4.2.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics4.2.png deleted file mode 100644 index f8fc4e238..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Graphics4.2.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Script.c index 5c21b43d2..0c146e5f9 100644 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/Script.c @@ -7,44 +7,63 @@ protected func Initialize() var alpha=0; if(GetTime() < 300 || GetTime() > 1140) alpha=255; SetClrModulation(RGBa(255,255,255,alpha)); - phase = 1; - Phase(true); - this["Parallaxity"] = [40,40]; + SetAction("Be"); + Update(); + this["Parallaxity"] = [30,30]; } -public func Phase(bool noAdvance) +public func NextMoonPhase() { - if(noAdvance!=true) - { - if(phase <= 5) phase = phase + 1; - if(phase >= 6) phase = 1; - } - - if(phase == 1) SetGraphics(); - if(phase > 1) SetGraphics(Format("%d",phase - 1)); - if(phase == 1) SetPosition(LandscapeWidth() / 4,LandscapeHeight() / 4); - if(phase == 2) SetPosition(LandscapeWidth() / 3,LandscapeHeight() / 5); - if(phase == 3) SetPosition(LandscapeWidth() / 2,LandscapeHeight() / 6); - if(phase == 4) SetPosition(LandscapeWidth() - LandscapeWidth() / 3, LandscapeHeight() / 5); - if(phase == 5) SetPosition(LandscapeWidth() - LandscapeWidth() / 4, LandscapeHeight() / 4); + SetMoonPhase(phase+1); } -//Get phase can also be used to modify the phase... ie: QueryPhase(3) would set -//the phase of the moon to phase 3. QueryPhase() will simply return the current moon phase. -public func GetPhase(int iphase) +/** @return values from 0..100, depending on the full-ness of the moon */ +public func GetMoonLightness() { - var moonphase = phase; - if(iphase != nil && iphase < 6) SetPhase(iphase); - return moonphase; -} -//ties global to local func -public func SetPhase(int iphase) -{ - phase = iphase; - Phase(true); + return 100 - Abs(100 * phase / this.ActMap.Be.Length - 50); } -//only appears during the night +public func GetMoonPhase() +{ + return phase; +} +public func SetMoonPhase(int iphase) +{ + phase = iphase % this.ActMap.Be.Length; + Update(); +} + +private func Update() { + SetPhase(phase); + + var phases = this.ActMap.Be.Length; + + var x = phase - phases/2; + var height = LandscapeHeight() / (6 - (x*x)/phases); + var width = 100 + phase * (LandscapeWidth()-200) / phases; + + SetPosition(width,height); +} + +// only appears during the night public func IsCelestial() { return true; } -local Name = "$Name$"; +// Not stored by itself because it's created by the time environment +func SaveScenarioObject() { return false; } + + +local ActMap = { + +Be = { + Prototype = Action, + Name = "Be", + Procedure = DFA_FLOAT, + Length = 8, + Delay = 0, + X = 0, + Y = 0, + Wdt = 128, + Hgt = 128, + NextAction = "Hold" +} +}; diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/StringTblDE.txt deleted file mode 100644 index df9e2a394..000000000 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Mond diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/StringTblUS.txt deleted file mode 100644 index ecd69fe56..000000000 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Moon.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Moon \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Time.ocd/Script.c index 45baf1989..0860a5715 100644 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Time.ocd/Script.c @@ -1,4 +1,4 @@ -/*-- +/**-- Time Controller Author:Ringwall @@ -11,37 +11,41 @@ local time; +local advance_seconds_per_tick; -// Sets the current time using a 24*60 minute clock scheme. +/** Sets the current time using a 24*60 minute clock scheme. */ public func SetTime(int to_time) { // Set time. - time = to_time % (24 * 60); + time = (to_time*60) % (24 * 60 * 60); + // hide celestials during day + if(Inside(time, time_set["SunriseEnd"], time_set["SunsetStart"])) + HideCelestials(); + else + ShowCelestials(); + // Adjust to time. AdjustToTime(); return; } -// Returns the time in minutes. +/** Returns the time in minutes. */ public func GetTime() { - return time; + return time / 60; } -// Sets the number of frames per clonk-minute. -// Standard is 18 frames per minute, making a day-night cycle of 12 minutes. -// Setting minute lenght to 0 will stop day-night cycle. -public func SetCycleSpeed(int speed) +/** Sets the number of seconds the day will advance each tick (10 frames). + Setting to 0 will stop day-night cycle. Default is 30 seconds. */ +public func SetCycleSpeed(int seconds_per_tick) { - //GetEffect("IntTimeCycle", this).Interval = Max(0, speed); - RemoveEffect("IntTimeCycle", this); - AddEffect("IntTimeCycle", this, 100, Max(0, speed), this); - return; + advance_seconds_per_tick = seconds_per_tick; } +/** Returns the number of seconds the day advances each tick (10 frames). */ public func GetCycleSpeed() { - return GetEffect("IntTimeCycle", this).Interval; + return advance_seconds_per_tick; } local time_set; @@ -54,25 +58,25 @@ protected func Initialize() return RemoveObject(); time_set = { - SunriseStart = 180, - SunriseEnd = 540, - SunsetStart = 900, - SunsetEnd = 1260, + SunriseStart = 10800, // 3:00 + SunriseEnd = 32400, // 9:00 + SunsetStart = 54000, // 15:00 + SunsetEnd = 75600, // 21:00 }; - - // Add effect that controls time cycle. - AddEffect("IntTimeCycle", this, 100, 18, this); - - // Set the time to midday (12:00). - time = 720; // Create moon and stars. if (FindObject(Find_ID(Environment_Celestial))) { - CreateObject(Moon, LandscapeWidth() / 2, LandscapeHeight() / 6); PlaceStars(); + CreateObject(Moon, LandscapeWidth() / 2, LandscapeHeight() / 6); } - return; + + // Set the time to midday (12:00). + SetTime(43200); + + // Add effect that controls time cycle. + SetCycleSpeed(30); + AddEffect("IntTimeCycle", this, 100, 10, this); } public func IsDay() @@ -95,17 +99,26 @@ public func IsNight() private func PlaceStars() { + // since stars are almost completely parallax (=in screen coordinates), we only need + // to place stars for max. a reasonable maximum resolution. Lets say 1600x1200 + var lw = Min(LandscapeWidth(), 1600); + var lh = Min(LandscapeHeight(),1200); + //Star Creation - var maxamount = LandscapeWidth() * LandscapeHeight() / 40000; - var amount = 0; + var maxfailedtries = lw * lh / 40000; + var failed = 0; - while (amount != maxamount) + while (failed != maxfailedtries) { - var pos; - if (pos = FindPosInMat("Sky", 0, 0, LandscapeWidth(), LandscapeHeight())) - CreateObject(Star, pos[0], pos[1]); - amount++; + var pos = [Random(lw), Random(lh)]; + if(!FindObject(Find_ID(Stars),Find_AtPoint(pos[0],pos[1]))) + { + CreateObject(Stars, pos[0], pos[1]); + continue; + } + failed++; } + return; } @@ -116,45 +129,186 @@ protected func FxIntTimeCycleTimer(object target) AdjustToTime(); // Advance time. - time++; - time %= (24 * 60); + time += advance_seconds_per_tick; + time %= (24 * 60 * 60); return 1; } -// Adjusts the sky, celestial and others to the current time. -private func AdjustToTime() +private func HideCelestials() { - var skyshade; - // Sunrise - if (Inside(time, time_set["SunriseStart"], time_set["SunriseEnd"])) - { - skyshade = Sin((GetTime() - 180) / 4, 255); - if (time == 540) - if (FindObject(Find_ID(Moon))) - FindObject(Find_ID(Moon))->Phase(); - } - // Day - else if (Inside(time, time_set["SunriseEnd"], time_set["SunsetStart"])) - skyshade = 255; - //Sunset - else if (Inside(time, time_set["SunsetStart"], time_set["SunsetEnd"])) - skyshade = 255 - Sin((GetTime() - 900) / 4, 255); - // Night - else if (time > time_set["SunsetEnd"] || time < time_set["SunriseStart"]) - skyshade = 0; - - // Shade sky. - SetSkyAdjust(RGB(skyshade, skyshade, skyshade)); - - // Adjust celestial objects. + // hide celestial objects, they will not be drawn during the day for (var celestial in FindObjects(Find_Func("IsCelestial"))) - celestial->SetObjAlpha(255 - skyshade); - - // Adjust clouds, TODO remedie this special case of white clouds on black sky. - - - return; + { + celestial.Visibility = VIS_None; + celestial->SetObjAlpha(0); + } } +private func ShowCelestials() +{ + // show celestial objects + for (var celestial in FindObjects(Find_Func("IsCelestial"))) + { + celestial.Visibility = VIS_All; + } +} + +private func OnSunriseEnd() +{ + // next moon phase + var satellite = FindObject(Find_ID(Moon)); + if(satellite) + satellite->NextMoonPhase(); + + HideCelestials(); +} + +private func OnSunsetStart() +{ + ShowCelestials(); +} + +private func DoSkyShade() +{ + // first determine the time phase we are in + var sunrise, sunset, night, day; + sunrise = sunset = night = day = false; + + if (Inside(time, time_set["SunriseStart"], time_set["SunriseEnd"])) + sunrise = true; + else if(Inside(time, time_set["SunriseEnd"], time_set["SunsetStart"])) + day = true; + else if(Inside(time, time_set["SunsetStart"], time_set["SunsetEnd"])) + sunset = true; + else + night = true; + + var skyshade = [0,0,0,0]; //R,G,B,A + var nightcolour = [10,25,40]; // default darkest-night colour + var daycolour = [255,255,255]; + var sunsetcolour = [140,45,10]; + var sunrisecolour = [140,100,70]; + + if (!day) + { + // Darkness of night dependent on the moon-phase + var satellite = FindObject(Find_ID(Moon)); + if(satellite) + { + var lightness = satellite->GetMoonLightness(); + nightcolour = [ 6 * lightness / 100, 8 + 25 * lightness / 100, 15 + 60 * lightness / 100 ]; + } + } + + // Sunrise + if (sunrise) + { + var time_since_sunrise = time - time_set["SunriseStart"]; + // progress in 0..1800 + var progress = time_since_sunrise * 1800 / (time_set["SunriseEnd"] - time_set["SunriseStart"]); + + for(var i=0; i<3; ++i) + { + var nightfade = Cos(progress/2, nightcolour[i],10); + var dayfade = daycolour[i] - Cos(progress/2, daycolour[i],10); + var sunrisefade = Sin(progress, sunrisecolour[i],10); + + skyshade[i] = Min(255,dayfade + nightfade + sunrisefade); + } + + skyshade[3] = Min(255,progress/2); + } + // Day + else if (day) + { + skyshade[0] = 255; + skyshade[1] = 255; + skyshade[2] = 255; + + skyshade[3] = 255; + } + // Sunset + else if (sunset) + { + var time_since_sunset = time - time_set["SunsetStart"]; + // progress in 0..1800 + var progress = time_since_sunset * 1800 / (time_set["SunsetEnd"] - time_set["SunsetStart"]); + + for(var i=0; i<3; ++i) + { + var dayfade = Cos(progress/2, daycolour[i],10); + var nightfade = nightcolour[i] - Cos(progress/2, nightcolour[i],10); + var sunsetfade = Sin(progress, sunsetcolour[i],10); + + skyshade[i] = Min(255,dayfade + nightfade + sunsetfade); + } + + skyshade[3] = Min(255,900-progress/2); + } + // Night + else if (night) + { + skyshade[0] = nightcolour[0]; + skyshade[1] = nightcolour[1]; + skyshade[2] = nightcolour[2]; + + skyshade[3] = 0; + } + + // Shade sky. + SetSkyAdjust(RGB(skyshade[0], skyshade[1], skyshade[2])); + + // Shade landscape. + var gamma = [0,0,0]; + var min_gamma = [30,75,120]; + gamma[0] = BoundBy(skyshade[0], min_gamma[0], 128); + gamma[1] = BoundBy(skyshade[1], min_gamma[1], 128); + gamma[2] = BoundBy(skyshade[2], min_gamma[2], 128); + + SetGamma(0, RGB(gamma[0], gamma[1], gamma[2]), RGB(127+gamma[0], 127+gamma[1], 127+gamma[2]), 3); + + if(!day && !night) + { + // Adjust celestial objects. + for (var celestial in FindObjects(Find_Func("IsCelestial"))) + celestial->SetObjAlpha(255 - skyshade[3]); + + // Adjust clouds + for(var cloud in FindObjects(Find_ID(Cloud))){ + cloud->SetLightingShade(255 - skyshade[2]); + } + } +} + +// Adjusts the sky, celestial and others to the current time. Use SetTime() at runtime, not this. +private func AdjustToTime() +{ + if (Abs(time - time_set["SunriseEnd"]) <= advance_seconds_per_tick) + OnSunriseEnd(); + else if (Abs(time - time_set["SunsetStart"]) <= advance_seconds_per_tick) + OnSunsetStart(); + + DoSkyShade(); +} + + +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + // Initialize function depends on this object implicitely + // So make sure it's created before this + var celestial_env = FindObject(Find_ID(Environment_Celestial)); + if (celestial_env) celestial_env->MakeScenarioSaveName(); + // Save time props + if (GetTime() != 43200) props->AddCall("Time", this, "SetTime", GetTime()); + if (GetCycleSpeed() != 30) props->AddCall("CycleSpeed", this, "SetCycleSpeed", GetCycleSpeed()); + return true; +} + + +/* Properties */ + local Name = "Time"; diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/DefCore.txt deleted file mode 100644 index 079015f9d..000000000 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/DefCore.txt +++ /dev/null @@ -1,11 +0,0 @@ -[DefCore] -id=Star -Version=5,2,0,1 -Category=C4D_StaticBack|C4D_Background -Width=2 -Height=2 -Offset=-1,1 -Vertices=1 -VertexY=0 -Mass=1 -StretchGrowth=1 diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/Graphics.8.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/Graphics.8.png deleted file mode 100644 index d4ea7398e..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/Graphics.8.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/Script.c deleted file mode 100644 index 85bd5badf..000000000 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/Script.c +++ /dev/null @@ -1,17 +0,0 @@ -/*-- Star --*/ - -protected func Initialize() -{ - DoCon(-30+Random(50)); - SetR(Random(359)); - var alpha=0; - if(GetTime()<300 || GetTime()>1140) alpha=255; - SetClrModulation(RGBa(255,255,255,alpha)); - this["Parallaxity"] = [10,10]; - - SetCategory(GetCategory() | C4D_Parallax | C4D_Background); -} - -public func IsCelestial() { return true; } - -local Name = "$Name$"; diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/StringTblDE.txt deleted file mode 100644 index df38595ca..000000000 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Sterne \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/StringTblUS.txt deleted file mode 100644 index e3e80d234..000000000 --- a/planet/Objects.ocd/Environment.ocd/Time.ocd/Star.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Stars \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/DefCore.txt new file mode 100644 index 000000000..7e5c01bcb --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Stars +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Background|C4D_Parallax +Width=128 +Height=128 +Offset=-64,64 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics.png new file mode 100644 index 000000000..3be009e70 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics2.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics2.png new file mode 100644 index 000000000..13340a9bd Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics2.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics3.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics3.png new file mode 100644 index 000000000..31cd7050f Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics3.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics4.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics4.png new file mode 100644 index 000000000..bb72798a6 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics4.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics5.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics5.png new file mode 100644 index 000000000..6ff70f3e9 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics5.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics6.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics6.png new file mode 100644 index 000000000..599174e2b Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics6.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics7.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics7.png new file mode 100644 index 000000000..4f8ca81b6 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics7.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics8.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics8.png new file mode 100644 index 000000000..c81b60b0e Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics8.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics9.png b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics9.png new file mode 100644 index 000000000..a4caf376a Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Graphics9.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Script.c new file mode 100644 index 000000000..a09bec840 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Time.ocd/Stars.ocd/Script.c @@ -0,0 +1,21 @@ +/*-- Stars --*/ + +protected func Initialize() +{ + var alpha=0; + if(GetTime()<300 || GetTime()>1140) alpha=255; + var g = RandomX(1,9); + if(g > 1) SetGraphics(Format("%d",g)); + SetClrModulation(RGBa(255,255,255,alpha)); + SetObjectBlitMode(GFX_BLIT_Additive); + var parallax = RandomX(8,12); + this["Parallaxity"] = [parallax,parallax]; +} + +public func IsCelestial() { return true; } + +// Not stored by itself because it's created by the time environment +// (Also, a million stars in Objects.c would suck) +func SaveScenarioObject() { return false; } + +local Name = "Stars"; diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Script.c deleted file mode 100644 index ba182e0b2..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Script.c +++ /dev/null @@ -1,22 +0,0 @@ -/*-- Fern --*/ - -#include Library_Plant - -func Construction() -{ - StartGrowth(1); - inherited(...); -} - -private func Initialize() -{ - SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); -} - -public func Incineration() -{ - CastParticles("Grass",10,35,0,0,30,50,RGB(255,255,255),RGB(255,255,255)); - RemoveObject(); -} - -local Name = "$Name$"; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Particle.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Particle.txt deleted file mode 100644 index 2e89adf9d..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Grass -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=20 -AlphaFade=0 -RByV=3 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt deleted file mode 100644 index 66e08b86f..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt +++ /dev/null @@ -1,15 +0,0 @@ -[Particle] -Name=Lichen -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -GravityAcc=33 -VertexCount=1 -VertexY=0 -AlphaFade=15 -RByV=3 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/StringTblUS.txt deleted file mode 100644 index 712360b1f..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Lichen -Description=Sprawls in dark, wet tunnels. Gives moss when harvested. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/StringTblDE.txt deleted file mode 100644 index 35dbde50c..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Pilz -PickMushroom=Pilz pflücken \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/StringTblUS.txt deleted file mode 100644 index bab557812..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Mushroom -PickMushroom=Pick mushroom \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/mushroom.png b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/mushroom.png deleted file mode 100644 index 24151468b..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/mushroom.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Script.c deleted file mode 100644 index 5427f8749..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Script.c +++ /dev/null @@ -1,9 +0,0 @@ -/*-- Rank --*/ - -private func Initialize() -{ - SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); - SetR(RandomX(-30,30)); -} - -local Name = "$Name$"; diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Script.c deleted file mode 100644 index e3459fd92..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Script.c +++ /dev/null @@ -1,54 +0,0 @@ -/*-- Seaweed --*/ - -/* -#include Library_Plant - -private func SeedChance() { return 300; } -private func SeedAreaSize() { return 600; } -private func SeedAmount() { return 4; } -*/ - -private func Initialize() -{ - SetAction("Sway"); -} - -private func Check() -{ - if(!GBackLiquid()) SetAction("Limp"); -} - -func Definition(def) { - SetProperty("Name", "$Name$", def); - SetProperty("ActMap", { -Sway = { - Prototype = Action, - Name = "Sway", - Procedure = DFA_NONE, - Directions = 2, - Length = 78, - Delay = 2, - X = 0, - Y = 0, - Wdt = 8, - Hgt = 8, - PhaseCall= "Check", - NextAction = "Sway", - Animation = "Sway", -}, -Limp = { - Prototype = Action, - Name = "Limp", - Procedure = DFA_NONE, - Directions = 2, - Length = 1, - Delay = 1, - X = 0, - Y = 0, - Wdt = 6, - Hgt = 6, - NextAction = "Limp", - InLiquidAction = "Sway", - Animation = "Limp", -}, }, def); -} diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblUS.txt deleted file mode 100644 index 49820b76e..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Sprout-Berry bush -Description=A very fast-growing and water-loving bush that produces tasty berries which have to be eaten fast. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Graphics.mesh b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Graphics.mesh deleted file mode 100644 index d4eec1be2..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Graphics.mesh and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Script.c deleted file mode 100644 index a608997d3..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Script.c +++ /dev/null @@ -1,32 +0,0 @@ -/*-- Coniferous Tree --*/ - -#include Library_Plant - -private func SeedAreaSize() { return 400; } -private func SeedChance() { return 50; } -private func SeedAmount() { return 12; } - -func Construction() -{ - StartGrowth(5); - inherited(...); -} - -private func Initialize() -{ - SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); -} - -public func IsTree() { return true; } - -public func ChopDown() -{ - // Remove the bottom vertex - SetVertex(0, VTX_Y, 0, 1); - RemoveVertex(0); - - _inherited(...); -} - -local Name = "$Name$"; -local Touchable = 0; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/coniferous.png b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/coniferous.png deleted file mode 100644 index e3e2fa69b..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/coniferous.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Title.png b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Title.png deleted file mode 100644 index 3746acee6..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Title.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Script.c deleted file mode 100644 index ea9b1d94f..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Script.c +++ /dev/null @@ -1,8 +0,0 @@ -/*-- Trunk --*/ - -private func Initialize() -{ - SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); -} - -local Name = "$Name$"; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/trunk.png b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/trunk.png deleted file mode 100644 index 7f2cb0d57..000000000 Binary files a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/trunk.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/StringTblUS.txt deleted file mode 100644 index c916ac53f..000000000 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Wheat -Description=Provides seeds for flour production. Growing faster if watered. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/DefCore.txt new file mode 100644 index 000000000..bd716030e --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Volcano +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Environment \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/Graphics.png new file mode 100644 index 000000000..8581750b4 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/DefCore.txt new file mode 100644 index 000000000..f6aaf63ee --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/DefCore.txt @@ -0,0 +1,16 @@ +[DefCore] +id=LavaChunk +Version=5,2,1,0 +Category=C4D_Object +Width=12 +Height=12 +Offset=-6,-6 +Vertices=4 +VertexX=-3,-3,2,3 +VertexY=-3,2,-1,3 +VertexFriction=20,20,20,20 +Mass=15 +Picture=0,0,12,12 +Rotate=1 +StretchGrowth=1 +Oversize=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/Graphics.4.png b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/Graphics.4.png new file mode 100644 index 000000000..5e4cefd39 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/Script.c new file mode 100644 index 000000000..849dcd1d8 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/Script.c @@ -0,0 +1,45 @@ +/** + Chunk of Lava + Hot molten stone from the inner earth. + + @author Maikel +*/ + +local mat; + +protected func Initialize() +{ + AddEffect("IntEvaporate", this, 100, 1, this); + // Lava chunk is on fire. + //Incinerate(); // TODO: Wait for decent graphics + return; +} + +protected func Hit() +{ + if (!mat) + mat="DuroLava"; + CastPXS(mat, GetCon()/2, 35); + return RemoveObject(); +} + +private func FxIntEvaporateTimer(object target, proplist effect, int time) +{ + // Some smoke trail. + Smoke(0, 0, 5); + Smoke(0, -5, Random(7)); + if (time > 75) + { + Hit(); + return -1; + } + return 1; +} + +// Volcanoes aren't stored. But store lava chunks because authors might use them +// in other places. +//func func SaveScenarioObject() { return false; } + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/StringTblDE.txt new file mode 100644 index 000000000..e1526d154 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Lavaklumpen diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/StringTblUS.txt new file mode 100644 index 000000000..900d9f375 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/LavaChunk.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Chunk of lava diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/Script.c new file mode 100644 index 000000000..397d7375a --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/Script.c @@ -0,0 +1,238 @@ +/** + Volcano + Destructive eruptions of lava originating from the centre of the earth. + + @author Maikel +*/ + + +/*-- Disaster Control --*/ + +public func SetChance(int chance) +{ + if (this != Volcano) + return; + var effect = GetEffect("IntVolcanoControl"); + if (!effect) + effect = AddEffect("IntVolcanoControl", nil, 100, 20, nil, Volcano); + effect.chance = chance; + return; +} + +public func GetChance() +{ + if (this != Volcano) + return; + var effect = GetEffect("IntVolcanoControl"); + if (effect) + return effect.chance; + return; +} + +public func SetMaterial(string material) +{ + if (this != Volcano) + return; + var effect = GetEffect("IntVolcanoControl"); + if (effect) + effect.material = material; + return; +} + +protected func FxIntVolcanoControlStart(object target, proplist effect, int temp) +{ + // Default to lava as material. + if (!temp) + effect.material = "Lava"; + return FX_OK; +} + +protected func FxIntVolcanoControlTimer(object target, proplist effect, int time) +{ + if (Random(100) < effect.chance && !Random(10)) + LaunchVolcano(Random(LandscapeWidth()), LandscapeHeight(), Random(40) + 35, effect.material, RandomX(-10, 10)); + return FX_OK; +} + +// Scenario saving +func FxIntVolcanoControlSaveScen(obj, fx, props) +{ + props->Add("Volcano", "Volcano->SetChance(%d)", fx.chance); + if (fx.material && fx.material != "Lava") props->Add("Volcano", "Volcano->SetMaterial(%v)", fx.material); + return true; +} + + +global func LaunchVolcano(int x, int y, int strength, string material, int angle) +{ + var volcano = CreateObject(Volcano); + return volcano->Launch(x, y, strength, material, angle); +} + +/*-- Volcano --*/ + +local str; // Volcano strength, max 100. +local mat; // Volcano material, string. +local angle; // Direction of the volcano. +local oldx, oldy; // Old coordinates. + +// returns true on a succesful volcano launch, false otherwise. +public func Launch(int x, int y, int strength, string material, int angle) +{ + // Initial coordinates of the volcano. + SetPosition(x, y); + // Strength of the volcano. + str = BoundBy(strength, 1, 100); + // Volcano material. + mat = Material(material); + // Direction of the volcano. + this.angle = angle; + // Safety check. + if (!InGround()) + { + RemoveObject(); + return false; + } + // Launch volcano. + SetAction("Advance"); + return true; +} + +// Advance action call: Used for underground advancing. +private func Advance() +{ + // Branch volcano. + if (!Random((120 - str) / 12)) + Branch(); + // Store old coordinates. + oldx = GetX(); + oldy = GetY(); + // Advance volcano. + angle += RandomX(-12, 12); // Slight angle distortion. + var adv = 12 + Random(6) + Random(str / 16); + var advx, advy; + var above_ground = false; + for (var x = 1; x <= adv; x++) + { + advx = Sin(angle, x); + advy = -Cos(angle, x); + SetPosition(oldx + advx, oldy + advy); + if (!InGround()) + { + above_ground = true; + break; + } + } + // Draw volcano. + var strx = Abs(Cos(angle, str)); + var stry = Abs(Sin(angle, str)); + DrawMaterialQuad(MaterialName(mat), + GetX() - strx / 4, GetY() - stry / 4, + GetX() + strx / 4, GetY() + stry / 4, + oldx + strx / 4, oldy + stry / 4, + oldx - strx / 4, oldy - stry / 4, true); + // Drag Objects along. + for (var pObj in FindObjects(Find_OCF(OCF_Collectible), Find_InRect())) + { + pObj->SetXDir(advx); + pObj->SetYDir(advy); + } + // Shake free possible top layer. + if (above_ground) + ShakeFree(GetX(), GetY(), str / 4); + // Reduce strength + str -= Random(2); + if (str <= 0) + return RemoveObject(); + // Above ground -> start Erupting. + if (above_ground) + SetAction("Erupt"); + // Finished. + return; +} + +// Erupt action call: Used for surface eruptions. +private func Erupt() +{ + // Build up banks at the sides. + //CastPXS("Coal", str/4, str/4); + //CastPXS("Coal", str/4, str/4); + + // Cast volcano material. + CastPXS(MaterialName(mat), 2 * str, 3 * str); + + // Cast other particles (lava chunks, ashes, ashclouds). + if (!Random(6)) + if (WildcardMatch(MaterialName(mat), "*Lava*")) + CastObjects(LavaChunk, 1, 60, 0, 0, 0, 40); + + // Reduce strength. + if(!Random(3)) + str--; + if (str <= 0) + return RemoveObject(); + // If in ground -> start advancing. + if (InGround()) + SetAction("Advance"); + return; +} + +// The volcano mainline branches into mainline + sideline. +private func Branch() +{ + // Branch volcano. + var side = 2 * Random(2) - 1; // At which side the volcano branches. + var new_str = Max(Random(str / 2), 4); // Strength of the branch. + var x = side * Cos(angle, str / 4 - new_str / 4); + var y = side * Sin(angle, str / 4 - new_str / 4); + var new_mat = MaterialName(mat); + var new_angle = angle + side * RandomX(5, 15); + var volcano = CreateObject(Volcano, x, y, NO_OWNER); + volcano->Launch(GetX() + x, GetY() + y, new_str, new_mat, new_angle); + // Reset volcano. + str -= new_str; + x = side * Cos(new_angle, new_str / 4); + y = side * Sin(new_angle, new_str / 4); + SetPosition(GetX() + x, GetY() + y); + return; +} + +// returns whether the volcano is in ground. +private func InGround() +{ + if (GBackSolid(0, -2)) + return true; + if (GetMaterial(0, -2) == mat) + return true; + return false; +} + +// Individual volcanoes not stored in scenario. It would look weird because the +// lava already drawn would not appear on the recreated created map. +// Only the controller effect is saved (see FxIntVolcanoControlSaveScen). +public func SaveScenarioObject() { return false; } + + +/*-- Proplist --*/ + +local Name = "$Name$"; +local ActMap = { + Advance = { + Prototype = Action, + Name = "Advance", + Procedure = DFA_NONE, + Delay = 2, + NextAction = "Advance", + StartCall = "Advance", + // Sound = "VolcanoAdvance", + }, + Erupt = { + Prototype = Action, + Name = "Erupt", + Procedure = DFA_NONE, + Delay = 2, + NextAction = "Erupt", + StartCall = "Erupt", + // Sound = "VolcanoErupt", + }, +}; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/StringTblDE.txt new file mode 100644 index 000000000..8bd191e52 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Vulkan diff --git a/planet/Objects.ocd/Environment.ocd/Volcano.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/StringTblUS.txt new file mode 100644 index 000000000..a341d1229 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Volcano.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Volcano diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt similarity index 76% rename from planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/DefCore.txt rename to planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt index 4db29fbd4..bf1ae022d 100644 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/DefCore.txt +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt @@ -1,4 +1,4 @@ [DefCore] -id=WeaponSpawn +id=Waterfall Version=5,2,0,1 Category=C4D_StaticBack diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Graphics.png new file mode 100644 index 000000000..c58baf4e3 Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c new file mode 100644 index 000000000..c2b999a14 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c @@ -0,0 +1,138 @@ +/*-- + Waterfall + Author: Maikel + + Waterfall object, use to place waterfalls in the landscape. +--*/ + + +protected func Initialize() +{ + + return; +} + +/*-- Waterfall --*/ + +global func CreateWaterfall(int x, int y, int strength, string mat) +{ + var fall = CreateObject(Waterfall, x, y, NO_OWNER); + if(!mat) mat = "Water"; + AddEffect("IntWaterfall", fall, 100, 1, fall, nil, x, y, strength, mat); + return fall; +} + +protected func FxIntWaterfallStart(object target, proplist effect, int temporary, int x, int y, int strength, string mat) +{ + if (temporary) + return 1; + effect.X = x; + effect.Y = y; + effect.Strength = strength; + effect.Material = mat; + // Start sound. + target->Sound("Waterfall", false, 10 * effect.Strength, nil, 1); + return 1; +} + +protected func FxIntWaterfallTimer(object target, proplist effect) +{ + // Insert liquid at location every frame. + for (var i = 0; i < effect.Strength / 2; i++) + InsertMaterial(Material(effect.Material), AbsX(effect.X), AbsY(effect.Y), effect.XDir + Random(effect.XVar), effect.YDir + Random(effect.YVar)); + return 1; +} + +protected func FxIntWaterfallStop(object target, proplist effect, bool temporary) +{ + if (temporary) + return 1; + // Stop sound. + target->Sound("Waterfall", false, 10 * effect.Strength, nil, -1); + return 1; +} + +public func SetStrength(int strength) +{ + var effect = GetEffect("IntWaterfall", this); + if (effect) + effect.Strength = BoundBy(strength, 0, 100); + return; +} + +public func SetMaterial(int material) +{ + var effect = GetEffect("IntWaterfall", this); + if (effect) + effect.Material = material; + return; +} + +public func SetDirection(int xdir, int ydir, int xvar, int yvar) +{ + var effect = GetEffect("IntWaterfall", this); + if (effect) + { + effect.XDir = xdir; + effect.YDir = ydir; + effect.XVar = xvar; + effect.YVar = yvar; + } + return; +} + +public func SetSoundLocation(int x, int y) +{ + SetPosition(x, y); + return; +} + +// Scenario saving +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + var fx_waterfall = GetEffect("IntWaterfall", this), fx_drain = GetEffect("IntLiquidDrain", this); + if (!fx_waterfall && !fx_drain) return false; // effects lost? don't save dead object then + // Waterfall has its own creation procedure + props->RemoveCreation(); + if (fx_waterfall) + { + props->Add(SAVEOBJ_Creation, "CreateWaterfall(%d,%d,%d,%v)",fx_waterfall.X, fx_waterfall.Y, fx_waterfall.Strength, fx_waterfall.Material); + if (fx_waterfall.X != GetX() || fx_waterfall.Y != GetY()) props->AddCall("Position", this, "SetSoundLocation", GetX(), GetY()); + if (fx_waterfall.XDir || fx_waterfall.YDir || fx_waterfall.XVar || fx_waterfall.YVar) + props->AddCall("Direction", this, "SetDirection", fx_waterfall.XDir, fx_waterfall.YDir, fx_waterfall.XVar, fx_waterfall.YVar); + } + if (fx_drain) props->Add(SAVEOBJ_Creation, "CreateLiquidDrain(%d,%d,%d);",fx_drain.X, fx_drain.Y, fx_drain.Strength); + return true; +} + + + +/*-- Liquid Drain --*/ + +global func CreateLiquidDrain(int x, int y, int strength) +{ + var drain = CreateObject(Waterfall, x, y, NO_OWNER); + AddEffect("IntLiquidDrain", drain, 100, 1, drain, nil, x, y, strength); + return drain; +} + +protected func FxIntLiquidDrainStart(object target, proplist effect, int temporary, int x, int y, int strength) +{ + if (temporary) + return 1; + effect.X = x; + effect.Y = y; + effect.Strength = strength; + return 1; +} + +protected func FxIntLiquidDrainTimer(object target, proplist effect) +{ + ExtractLiquidAmount(AbsX(effect.X), AbsY(effect.Y),effect.Strength / 2); + return 1; +} + + + +local Name = "$Name$"; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt new file mode 100644 index 000000000..b889168f3 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Wasserfall diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt new file mode 100644 index 000000000..8a8423e80 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Waterfall diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Waterfall.ogg b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Waterfall.ogg new file mode 100644 index 000000000..0edf7e80b Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Waterfall.ogg differ diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/authors.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/authors.txt new file mode 100644 index 000000000..b2163b820 --- /dev/null +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/authors.txt @@ -0,0 +1 @@ +Waterfall.wav by volivieri CC-BY-3.0 (http://www.freesound.org/people/volivieri/sounds/38390/) \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/DefCore.txt index a409b8008..e8d08d604 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/DefCore.txt +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/DefCore.txt @@ -5,7 +5,8 @@ Category=C4D_Vehicle Width=16 Height=26 Offset=-5,-13 +# note: the fifth vertex is used to attach the flag to the Clonk Vertices=5 -VertexX=-5,-6,-7,7 -VertexY=13,0,-13,-6 -VertexFriction=100,100,100,50 +VertexX=-5,-6,-7,7, 0 +VertexY=13,0,-13,-6, 0 +VertexFriction=100,100,100,50, 0 diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/FlagTracer.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/FlagTracer.ocd/Graphics.png deleted file mode 100644 index 78e723fc1..000000000 Binary files a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/FlagTracer.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/FlagTracer.ocd/Particle.txt b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/FlagTracer.ocd/Particle.txt deleted file mode 100644 index 89e5e2fb2..000000000 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/FlagTracer.ocd/Particle.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Particle] -Name=FlagTracer -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=20 -AlphaFade=1 -Additive=1 -RByV=3 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/Script.c index 38f22f2c1..baf81c028 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Flag.ocd/Script.c @@ -78,14 +78,25 @@ protected func FxFlagReturnDelayTimer() { return -1; } protected func FxFlagCarriedStart(object target, effect, int temp) { ReducePhysicals(target, effect); - if (temp == 0) + if (temp) return; + + effect.x=target->GetX(); + effect.y=target->GetY(); + var trans = Trans_Mul(Trans_Translate(0, -17000, 0), Trans_Rotate(-90, 0, 1, 0)); + effect.mesh_id = target->AttachMesh(this, "pos_back1", "main", trans); + this.Visibility = VIS_None; + + var color = GetTeamColor(this->GetTeam()); + effect.tracer_particles = { - effect.x=target->GetX(); - effect.y=target->GetY(); - var trans = Trans_Mul(Trans_Translate(0, -17000, 0), Trans_Rotate(-90, 0, 1, 0)); - effect.mesh_id = target->AttachMesh(this, "pos_back1", "main", trans); - this.Visibility = VIS_None; - } + Size = PV_KeyFrames(0, 0, 0, 200, 5, 900, 10, 1000, 0), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + Alpha = 200, + Attach = ATTACH_Back + }; + return 1; } @@ -99,9 +110,9 @@ protected func FxFlagCarriedTimer(object target, effect) var newx = target->GetX(); var newy = target->GetY(); // Draw partical line following the flag. - if (Distance(x, y, newx, newy) > 2) + if (Distance(x, y, newx, newy) > 5) { - DrawParticleLine("FlagTracer",AbsX(x),AbsY(y),AbsX(newx),AbsY(newy),4,30-Random(4),GetTeamColor(this->GetTeam()) | 255 <<24,GetTeamColor(this->GetTeam()) | 255 <<24); + target->CreateParticle("SphereSpark", 0, 0, 0, 0, PV_Random(36 * 3, 36 * 3 + 10), effect.tracer_particles); effect.x=newx; effect.y=newy; } @@ -198,6 +209,19 @@ private func BeamFlag(bool msg) return; } +func StartAttachCarrier() +{ + // attach fourth vertex of the flag to third vertex of Clonk + // this results in the best overlapping of the shapes + SetActionData((4 << 8) + 3); +} + +func StartAttachBase() +{ + // reset possible action data + SetActionData(0); +} + local Name = "$Name$"; local ActMap = { AttachCarrier = { @@ -206,8 +230,9 @@ local ActMap = { Procedure = DFA_ATTACH, Length = 1, Delay = 0, - NextAction = "Attach", + NextAction = "AttachCarrier", Animation = "Wave", + StartCall = "StartAttachCarrier" }, AttachBase = { Prototype = Action, @@ -215,13 +240,14 @@ local ActMap = { Procedure = DFA_ATTACH, Length = 1, Delay = 0, - NextAction = "Attach", + NextAction = "AttachBase", Animation = "Wave", + StartCall = "StartAttachBase" }, }; protected func Definition(def) { - SetProperty("MeshTransformation", Trans_Mul(Trans_Translate(-79000, 1000, 0), Trans_Rotate(60, 0, 1, 0)), def); + SetProperty("MeshTransformation", Trans_Mul(Trans_Translate(-9000, 1000, 0), Trans_Rotate(60, 0, 1, 0)), def); SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(60, 0, 1, 0), Trans_Scale(1200), Trans_Translate(-4000, 6500, -3000)), def); } diff --git a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c index c6b48bba4..833edacc3 100644 --- a/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/CaptureTheFlag.ocd/Script.c @@ -3,7 +3,6 @@ Author: Maikel Capture the flag of the opposing team and bring it to your base to gain points. - TODO: Scoreboard. --*/ @@ -11,10 +10,24 @@ local score_list; +func ScoreboardTeamID(int team) +{ + return team + 1000; +} + protected func Initialize() { score_list = []; - + + // init scoreboard + Scoreboard->Init( + [ + {key = "title", title = "Teams"}, + {key = "ctf", title = Goal_CaptureTheFlag, sorted = true, desc = true, default = 0, priority = 80} + ] + ); + Scoreboard->SetTitle("Capture the Flag"); + return _inherited(...); } @@ -39,7 +52,9 @@ public func SetFlagBase(int team, int x, int y) public func AddTeamScore(int team) { score_list[team]++; - UpdateScoreboard(team); + + Scoreboard->SetData(ScoreboardTeamID(team), "ctf", score_list[team]); + if (score_list[team] >= GetScoreGoal()) EliminateOthers(team); return; @@ -57,11 +72,14 @@ private func EliminateOthers(int win_team) return; } -protected func InitializePlayer(int plr) +protected func InitializePlayer(int plr, int x, int y, object base, int team) { // Join new clonk. JoinPlayer(plr); - InitScoreboard(GetPlayerTeam(plr)); + + // make scoreboard entry for team + Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team)); + // Broadcast to scenario. GameCall("OnPlayerRelaunch", plr); return _inherited(plr, ...); @@ -172,33 +190,4 @@ private func GetPlayerInTeamCount(int team) return cnt; } -/*-- Scoreboard --*/ - -static const SBRD_Score = 1; - -private func InitScoreboard(int team) -{ - // Scoreboard caption - if (GetScoreGoal() == 1) - SetScoreboardData(SBRD_Caption, SBRD_Caption, "$MsgScoreboard1$", SBRD_Caption); - else - SetScoreboardData(SBRD_Caption, SBRD_Caption, Format("$MsgScoreboardX$", GetScoreGoal()), SBRD_Caption); - // Team name - SetScoreboardData(team, SBRD_Caption, GetTaggedTeamName(team), team); - // Team score - SetScoreboardData(SBRD_Caption, SBRD_Score, "{{Goal_CaptureTheFlag}}", SBRD_Caption); - SetScoreboardData(team, SBRD_Score, Format("%d", 0), 0); - return; -} - -private func UpdateScoreboard(int team) -{ - // Update the team's score. - var score = score_list[team]; - SetScoreboardData(team, SBRD_Score, Format("%d", score), score); - // Sort descending w.r.t. score. - SortScoreboard(SBRD_Score, true); - return; -} - local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c index 7503a77b0..e6942d4d9 100644 --- a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/Script.c @@ -9,7 +9,6 @@ #include Scoreboard_KillStreak #include Scoreboard_Death #include Scoreboard_Kill -#include Scoreboard_Player local maxkills; @@ -45,10 +44,7 @@ protected func RelaunchPlayer(int plr, int killer) JoinPlayer(plr); // Scenario script callback. GameCall("OnPlayerRelaunch", plr); - // Show scoreboard for a while & sort. - SortScoreboard(Scoreboard_KillStreak->GetKillStreakCol(), true); - SortScoreboard(Scoreboard_Death->GetDeathCol(), true); - SortScoreboard(Scoreboard_Kill->GetKillCol(), true); + // Show scoreboard for a while DoScoreboardShow(1, plr + 1); Schedule(this,Format("DoScoreboardShow(-1, %d)", plr + 1), 35 * MIME_ShowBoardTime); NotifyHUD(); @@ -120,21 +116,30 @@ public func Activate(int byplr) var score = GetRelativeScore(byplr); if(score.kills > 0) MessageWindow(Format("$MsgAhead$", score.kills, GetPlayerName(score.best)), byplr); else if(score.kills < 0) MessageWindow(Format("$MsgBehind$", -score.kills,GetPlayerName(score.best)), byplr); + else if(score.best == byplr) MessageWindow(Format("$MsgYouAreBest$", score.kills), byplr); else MessageWindow(Format("$MsgEqual$", GetPlayerName(score.best)), byplr); } } private func GetRelativeScore(int player) { - var bestplayer = -1, bestscore = 1<<31; + var bestplayer = -1, bestscore = -1; for(var i = 0; i < GetPlayerCount(); ++i) { var plr = GetPlayerByIndex(i); - if(plr != player && GetKillCount(plr) > bestscore) { + if(plr != player && ((GetKillCount(plr) > bestscore) || (bestplayer == -1))) { bestplayer = plr; bestscore = GetKillCount(plr); } } + + // special case if there is only one player in the game + if(bestplayer == -1) + { + bestplayer = player; + bestscore = GetKillCount(player); + } + return {best: bestplayer, kills: GetKillCount(player)-bestscore}; } diff --git a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblDE.txt b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblDE.txt index 1183ebea9..48c9c9e74 100644 --- a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblDE.txt @@ -1,6 +1,7 @@ Name=Deathmatch MsgVictory=Der Sieg gebührt deinem Team. -MsgAhead=Du bist %d kills voraus. Dein stärkster Verfolger ist %s. -MsgBehind=Du hast %d kills rückstand auf %s. -MsgEqual=Du liegst mit %s gleichauf. \ No newline at end of file +MsgAhead=Du bist %d Kills voraus. Dein stärkster Verfolger ist %s. +MsgBehind=Du hast %d Kills Rückstand auf %s. +MsgEqual=Du liegst mit %s gleichauf. +MsgYouAreBest=Du führst mit %d Kills! diff --git a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblUS.txt index 6bad0ae7f..4cae09c5b 100644 --- a/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Goals.ocd/DeathMatch.ocd/StringTblUS.txt @@ -3,4 +3,5 @@ Name=Deathmatch MsgVictory=You won. MsgAhead=You are %d kills ahead. The closest follower is %s. MsgBehind=You are %d kills behind %s. -MsgEqual=%s scored as often as you. \ No newline at end of file +MsgEqual=%s scored as often as you. +MsgYouAreBest=You are leading with %d kills! diff --git a/planet/Objects.ocd/Goals.ocd/Expansion.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/DefCore.txt new file mode 100644 index 000000000..4bb419573 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_Expansion +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Objects.ocd/Goals.ocd/Expansion.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/Graphics.png new file mode 100644 index 000000000..42102deca Binary files /dev/null and b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Goals.ocd/Expansion.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/Script.c new file mode 100644 index 000000000..902199042 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/Script.c @@ -0,0 +1,149 @@ +/** + Expansion + A certain amount of the map must be claimed by constructing flags. + This is tested by a Monte Carlo simulation over the whole map, + checking whether the point is covered by a flagpole. + + @author Maikel +*/ + +#include Library_Goal + + +local expansion_goal; +local mc_data; + +protected func Initialize() +{ + expansion_goal = 0; + // Start running the monte carlo simulation. + mc_data = []; + AddEffect("IntAreaMonteCarlo", this, 100, 1, this); + return inherited(...); +} + +// Set the expansion goal in promillage of the total map. +public func SetExpansionGoal(int exp_area) +{ + expansion_goal = exp_area; + return; +} + +// Returns the expansion goal in promillage of the total map. +public func GetExpansionGoal() +{ + return expansion_goal; +} + +// Scenario saving +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (expansion_goal) props->AddCall("Goal", this, "SetExpansionGoal", expansion_goal); + return true; +} + +/*-- Goal interface --*/ + +// The goal is fulfilled if the expansio goal is covered by flags. +public func IsFulfilled() +{ + // Check if goal is fulfilled. + if (GetExpansionArea() >= GetExpansionGoal()) + return true; + // Not yet fulfilled. + return false; +} + +// Returns the promillage of the total map covered by flags. +private func GetExpansionArea() +{ + // Evaluate mc simulation. + var area = 0, cnt = 0; + for (var mc in mc_data) + { + if (mc != nil) + { + area += mc; + cnt++; + } + } + if (!cnt) + return 0; + return area / cnt; +} + +// Monte Carlo simulation to determine the area covered by flagpoles. +// There is thin balance between the accuracy of the simulation, the +// number of simulations per frame and the refresh rate of the data, +// or equivalently how long past data is stored. +private func FxIntAreaMonteCarloTimer() +{ + // Perform simulations and store them. + var cnt = 40; // Perform 40 simulations per frame. + var store = 500; // Store last 500 events. + var rate = 0; + for (var i = 0; i < cnt; i++) + { + var x = Random(LandscapeWidth()); + var y = Random(LandscapeHeight()); + if (CoveredByFlag(x, y)) + rate++; + } + var promille = 1000 * rate / cnt; + // Add new montecarlo data to the end the data list and remove old entry. + for (var i = 0; i < store - 1; i++) + { + mc_data[i] = mc_data[i+1]; + } + mc_data[store - 1] = promille; + return; +} + +// Returns whether the point (x,y) is covered by a flagpole. +private func CoveredByFlag(int x, int y) +{ + for (var flag in FindObjects(Find_Func("IsFlagpole"), Sort_Distance(x - GetX(), y - GetY()))) + if (Distance(flag->GetX(), flag->GetY(), x, y) < flag->GetFlagRadius()) + return true; + return false; +} + +// Shows or hides a message window with information. +public func Activate(int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + var message; + if (GetExpansionArea() >= GetExpansionGoal()) + message = Format("@$MsgGoalFulfilled$"); + else + message = Format("@$MsgGoalUnFulfilled$", 100 * GetExpansionArea() / GetExpansionGoal()); + + CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + +public func GetShortDescription(int plr) +{ + // Show expansion percentage. + var perc = Min(100, 100 * GetExpansionArea() / GetExpansionGoal()); + var clr = RGB(255, 0, 0); + if (perc >= 100) + clr = RGB(0, 255, 0); + var msg = Format("%d%", clr, perc); + return msg; +} + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/Expansion.ocd/StringTblDE.txt b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/StringTblDE.txt new file mode 100644 index 000000000..1f6a22ace --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +Name=Ausdehnung + +#Goal window +MsgGoalFulfilled=Du hast deine Ausdehnungsziele erreicht. +MsgGoalUnFulfilled=Dehne deine Herrschaft aus, durch das bauen der Flaggen. Momentan kontrollierst du erst %d% der gefragter Herrschaft. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/Expansion.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/StringTblUS.txt new file mode 100644 index 000000000..78a3b182b --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/Expansion.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +Name=Expansion + +#Goal window +MsgGoalFulfilled=You have reached your expansion goals. +MsgGoalUnFulfilled=Expand your control region by constructing flags. Currently you only control %d% of the demanded region. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/DefCore.txt index 3aab7009e..f92f2e528 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/DefCore.txt +++ b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/DefCore.txt @@ -3,7 +3,7 @@ id=KingOfTheHill_Marker Version=5,2,0,1 #Category=C4D_StaticBack | C4D_Foreground | C4D_IgnoreFoW Category=C4D_StaticBack | C4D_IgnoreFoW -Width=15 -Height=15 -Offset=-7,-7 +Width=16 +Height=16 +Offset=-8,-8 diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Graphics.mesh b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Graphics.mesh deleted file mode 100644 index dd2d16207..000000000 Binary files a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Graphics.mesh and /dev/null differ diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Graphics.png new file mode 100644 index 000000000..26cf6427c Binary files /dev/null and b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Script.c index 72a9e4bbd..fb3a85469 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillMarker.ocd/Script.c @@ -8,6 +8,7 @@ local origin; func Initialize() { AddEffect("Timer", this, 10, 1, this); + SetGraphics(nil, KingOfTheHill_Star, 0); } func SetOrigin(object o) @@ -50,4 +51,6 @@ func FxTimerTimer() this->SetClrModulation(origin->GetStarColor(Sin(this->GetActTime(), 50))); } +public func SaveScenarioObject() { return false; } + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/DefCore.txt index 6d8af699a..416fe7fb6 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/DefCore.txt +++ b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/DefCore.txt @@ -2,7 +2,7 @@ id=KingOfTheHill_Star Version=5,2,0,1 Category=C4D_StaticBack | C4D_IgnoreFoW -Width=30 -Height=30 -Offset=-7,-7 +Width=16 +Height=16 +Offset=-8,-8 Rotate=1 diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Graphics.4.png b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Graphics.4.png new file mode 100644 index 000000000..9209f0d9d Binary files /dev/null and b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Graphics.png deleted file mode 100644 index d319a434f..000000000 Binary files a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Script.c index 15f008582..b9ffa1733 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/KingOfTheHillStar.ocd/Script.c @@ -7,23 +7,19 @@ local origin; local number; func Init(o, n) -{ - SetObjectBlitMode(GFX_BLIT_Mod2); - origin=o; - number=n; +{ + origin = o; + number = n; SetR(Angle(origin->GetX(), origin->GetY(), this->GetX(), this->GetY()) + 45); + + AddEffect("Timer", this, 1, 1+Random(3), this); } -func Initialize() -{ - SetGraphics(0, KingOfTheHill_Marker); - AddEffect("Timer", this, 10, 1, this); - SetGraphics(nil, KingOfTheHill_Marker); -} - -func FxTimerTimer() +func FxTimerTimer(target, effect, time) { SetClrModulation(origin->GetStarColor(number)); } +public func SaveScenarioObject() { return false; } + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/Script.c index 4e691a154..9da915b61 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/KingOfTheHillLocation.ocd/Script.c @@ -155,4 +155,7 @@ func CreateStarCircle() } } +// stored by main goal +public func SaveScenarioObject() { return false; } + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/Script.c index cc4a717c0..cf18243c4 100644 --- a/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/KingOfTheHill.ocd/Script.c @@ -20,6 +20,7 @@ SearchPosition(); */ #include Library_Goal +#include Scoreboard_Death local player_points; local player_deaths; @@ -37,6 +38,10 @@ func Initialize() SetRadius(300); SetPointLimit(10); + Scoreboard->Init( + [{key = "koth", title = Goal_KingOfTheHill, sorted = true, desc = true, default = 0, priority = 80}] + ); + Scoreboard->SetTitle("King of the Hill"); //CalculatePosition(); ScheduleCall(this, "PostInitialize", 3); return _inherited(...); @@ -44,7 +49,6 @@ func Initialize() func PostInitialize() { - ScheduleCall(this, "RefreshScoreboard", 1); Init(); } @@ -113,23 +117,25 @@ func DoPoint(int player, int count) if (count == nil) count = 1; player_points[player] = Max(player_points[player] + count, 0); + Scoreboard->SetPlayerData(player, "koth", player_points[player]); } -protected func InitializePlayer(plr) +protected func InitializePlayer(int plr, int x, int y, object base, int team) { - ScheduleCall(this, "RefreshScoreboard", 1); + Scoreboard->NewPlayerEntry(plr); player_suicides[plr]=0; - return Goal_Melee->InitializePlayer(plr, ...); // TODO + + Goal_Melee->MakeHostileToAll(plr, team); + return inherited(plr, x, y, base, team, ...); } public func IsFulfilled() { - return Goal_Melee->IsFulfilled(); // TODO + return Goal_Melee->IsFulfilled(); // the same condition as a normal melee } func OnClonkDeath(object clonk, int killer) { - ScheduleCall(this, "RefreshScoreboard", 1); if (clonk->GetAlive()) return; if (GetPlayerName(clonk->GetOwner())) @@ -222,19 +228,19 @@ public func Activate(int byplr) return MessageWindow(msg, byplr); } +// returns a list of the teams ingame private func GetTeamList() { - // Count enemy players. var teams=[]; for(var i = 0; i < GetPlayerCount(); i++) { var p=GetPlayerByIndex(i); var t=GetPlayerTeam(p); - var found=false; + + var found = false; for(var x=0;xAddCall("Goal", this, "SetPointLimit", GetPointLimit()); + if (GetRadius() != 300) props->AddCall("Goal", this, "SetRadius", GetRadius()); + return true; +} + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt index 0f1ec3d0e..7ab83eac6 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/DefCore.txt @@ -3,3 +3,4 @@ id=RelaunchContainer Version=5,2,0,1 Category=C4D_StaticBack ClosedContainer=2 +Picture=0,0,92,92 \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png index c58baf4e3..e69712f47 100644 Binary files a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png and b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c index eba0438fa..592044221 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c @@ -13,6 +13,8 @@ local menu; local hold; local has_selected; +local crew; + protected func Initialize() { time = 36 * 10; @@ -37,9 +39,15 @@ public func StartRelaunch(object clonk) { if (!clonk) return; + // only 1 clonk can be inside + if(crew) + return; + // save clonk for later use + crew = clonk; clonk->Enter(this); ScheduleCall(this, "OpenWeaponMenu", 36, 0, clonk); AddEffect("IntTimeLimit", this, 100, 36, this); + return true; } @@ -50,11 +58,11 @@ private func OpenWeaponMenu(object clonk) if (!menu) { var weapons = WeaponList(); - if(weapons) + if (weapons) { - menu = clonk->CreateRingMenu(Clonk, this); + menu = clonk->CreateRingMenu(this, this); for (var weapon in weapons) - menu->AddItem(weapon); + menu->AddItem(weapon, 1); menu->Show(); menu->SetUncloseable(); } @@ -63,7 +71,7 @@ private func OpenWeaponMenu(object clonk) func FxIntTimeLimitTimer(object target, effect, int fxtime) { - var clonk = Contents(); + var clonk = crew; if (!clonk) { RemoveObject(); @@ -71,7 +79,7 @@ func FxIntTimeLimitTimer(object target, effect, int fxtime) } if (fxtime >= time) { - if (!has_selected) + if (!has_selected && WeaponList()) GiveWeapon(WeaponList()[Random(GetLength(WeaponList()))]); RelaunchClonk(); return -1; @@ -88,10 +96,17 @@ public func Selected(object menu, object selector, bool alt) if (!selector) return false; - for (var i = 0; i < selector->GetAmount(); i++) + var amount = selector->GetAmount(); + if (amount > 1) + alt = nil; + + for (var i = 0; i < amount; i++) GiveWeapon(selector->GetSymbol(), alt); has_selected = true; + // Close menu manually, to prevent selecting more weapons. + if (menu) + menu->Close(true); if (!hold) RelaunchClonk(); @@ -100,7 +115,7 @@ public func Selected(object menu, object selector, bool alt) private func RelaunchClonk() { - var clonk = Contents(); + var clonk = crew; clonk->Exit(); GameCall("OnClonkLeftRelaunch", clonk); if (menu) @@ -117,8 +132,10 @@ private func GiveWeapon(id weapon_id, bool alt) newobj->CreateContents(Arrow); if (weapon_id == Musket) newobj->CreateContents(LeadShot); - Contents()->Collect(newobj, nil, alt); + crew->Collect(newobj, nil, alt); return; } +public func SaveScenarioObject() { return false; } + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt index babe88679..04f6fccd2 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/StringTblUS.txt @@ -1,3 +1,3 @@ Name=Relaunch container -MsgRelaunch=You will be relaunched in %d seconds. +MsgRelaunch=You will relaunch in %d seconds. MsgWeapon=You have %d seconds to choose a weapon. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c index ce565219e..fb2501b8f 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Script.c @@ -4,7 +4,7 @@ Premade goal for simple melees with relaunches. Callbacks made to scenario script: - * OnPlrRelaunch(int plr) made when the player is relaunched and at game start plr init. + * OnPlayerRelaunch(int plr) made when the player is relaunched and at game start plr init. * RelaunchCount() should return the number of relaunches. * KillsToRelaunch() should return how many kills will earn the player an extra relaunch. --*/ @@ -17,7 +17,6 @@ #include Scoreboard_Kill //#include Scoreboard_Death #include Scoreboard_Relaunch -#include Scoreboard_Player // Some static constants. static const MIME_RelaunchCount = 5; // Number of relaunches. @@ -87,10 +86,7 @@ protected func RelaunchPlayer(int plr, int killer) JoinPlayer(plr); // Scenario script callback. GameCall("OnPlayerRelaunch", plr); - // Show scoreboard for a while & sort. - SortScoreboard(Scoreboard_KillStreak->GetKillStreakCol(), true); - SortScoreboard(Scoreboard_Kill->GetKillCol(), true); - SortScoreboard(Scoreboard_Relaunch->GetRelaunchCol(), true); + // Show scoreboard for a while. DoScoreboardShow(1, plr + 1); Schedule(this,Format("DoScoreboardShow(-1, %d)", plr + 1), 35 * MIME_ShowBoardTime); return; // _inherited(plr, killer, ...); diff --git a/planet/Objects.ocd/Goals.ocd/Melee.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Melee.ocd/Script.c index 6e7eead9d..1c63599d7 100644 --- a/planet/Objects.ocd/Goals.ocd/Melee.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Melee.ocd/Script.c @@ -2,7 +2,7 @@ #include Library_Goal -protected func InitializePlayer(int newplr, int x, int y, object base, int team) +func MakeHostileToAll(int newplr, int team) { // If the player is in a team, don't change hostility. if (team) return; @@ -16,6 +16,11 @@ protected func InitializePlayer(int newplr, int x, int y, object base, int team) SetHostility(newplr, plr, true, true); SetHostility(plr, newplr, true, true); } +} + +protected func InitializePlayer(int newplr, int x, int y, object base, int team) +{ + MakeHostileToAll(newplr, team); return inherited(newplr, x, y, base, team, ...); } diff --git a/planet/Objects.ocd/Goals.ocd/Melee.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/Melee.ocd/StringTblUS.txt index fbd0c35a5..27b385c98 100644 --- a/planet/Objects.ocd/Goals.ocd/Melee.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Goals.ocd/Melee.ocd/StringTblUS.txt @@ -1,4 +1,4 @@ Name=Melee MsgGoalFulfilled=All opponents eliminated. -MsgGoalUnfulfilled=Still %d opponents in the game. +MsgGoalUnfulfilled=There are still %d opponents in the game. diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Arrow.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Arrow.ocd/Script.c index 5b33e8d5c..47fc6f53c 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Arrow.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Arrow.ocd/Script.c @@ -6,6 +6,8 @@ protected func Initialize() return; } +public func SaveScenarioObject() { return false; } + /*-- Proplist --*/ local ActMap = { diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Cleared.ogg b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Cleared.ogg new file mode 100644 index 000000000..5e129cccc Binary files /dev/null and b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Cleared.ogg differ diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Cleared.wav b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Cleared.wav deleted file mode 100644 index 77f0f4344..000000000 Binary files a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Cleared.wav and /dev/null differ diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/PSpark.ocd/Particle.txt b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/PSpark.ocd/Particle.txt deleted file mode 100644 index 52d4cf16e..000000000 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/PSpark.ocd/Particle.txt +++ /dev/null @@ -1,13 +0,0 @@ -[Particle] -Name=PSpark -MaxCount=2000 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,140,140,-60,-60 -Delay=0 -Repeats=1 -GravityAcc=0 -AlphaFade=12 -Additive=0 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Script.c index 946e31d31..88777a17d 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/CheckPoint.ocd/Script.c @@ -26,6 +26,9 @@ static const PARKOUR_CP_Ordered = 16; static const PARKOUR_CP_Team = 32; static const PARKOUR_CP_Bonus = 64; +// particle definition used for the effect around the check point +local checkpoint_particles; + public func SetCPMode(int mode) { // PARKOUR_CP_Start always occurs alone. @@ -87,6 +90,12 @@ local cleared_by_plr; // Array to keep track of players which were already here. protected func Initialize() { + checkpoint_particles = + { + Size = PV_KeyFrames(0, 0, 0, 250, 10, 500, 0, 750, 10), + Alpha = PV_KeyFrames(0, 0, 255, 500, 0, 501, 255, 1000, 0), + BlitMode = GFX_BLIT_Additive + }; cleared_by_plr = []; cp_mode = PARKOUR_CP_Check; cp_size = 20; @@ -250,7 +259,7 @@ protected func DoGraphics() { // Clear all overlays first. for (var i = 1; i <= 3; i++) - SetGraphics(0, 0, i); + SetGraphics(nil, nil, i); // Start & Finish. if (cp_mode & PARKOUR_CP_Start || cp_mode & PARKOUR_CP_Finish) { @@ -282,10 +291,10 @@ protected func UpdateGraphics(int time) // Create two sparks at opposite sides. var angle = (time * 10) % 360; var color = GetColorByAngle(angle); - CreateParticle("PSpark", Sin(angle, cp_size), -Cos(angle, cp_size), 0, 0, 32, color); - angle = (angle + 180) % 360; - var color = GetColorByAngle(angle); - CreateParticle("PSpark", Sin(angle, cp_size), -Cos(angle, cp_size), 0, 0, 32, color); + checkpoint_particles.R = (color >> 16) & 0xff; + checkpoint_particles.G = (color >> 8) & 0xff; + checkpoint_particles.B = (color >> 0) & 0xff; + CreateParticle("SphereSpark", Sin(angle, cp_size), -Cos(angle, cp_size), 0, 0, 18 * 5, checkpoint_particles); return; } @@ -336,5 +345,34 @@ public func ClearCPBack() return; } +// Storing checkpoints in Objects.c +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + var v = GetCPSize(); + if (v != 20) props->AddCall("Checkpoint", this, "SetCPSize", v); + // Checkpoints without a goal? Use regular saving. + if (!cp_con) + { + + if (v = GetCPMode()) props->AddCall("Checkpoint", this, "SetCPMode", GetBitmaskNameByValue(v, "PARKOUR_CP_")); + if (v = GetCPNumber()) props->AddCall("Checkpoint", this, "SetCPNumber", v); + return true; + } + // Special checkpoints + props->RemoveCreation(); + if (cp_mode & PARKOUR_CP_Start) + props->AddCall(SAVEOBJ_Creation, cp_con, "SetStartpoint", GetX(), GetY()); + else if (cp_mode & PARKOUR_CP_Finish) + props->AddCall(SAVEOBJ_Creation, cp_con, "SetFinishpoint", GetX(), GetY(), !!(cp_mode & PARKOUR_CP_Team)); + else + { + var other_cp_modes = cp_mode & (~PARKOUR_CP_Finish) & (~PARKOUR_CP_Start); + props->AddCall(SAVEOBJ_Creation, cp_con, "AddCheckpoint", GetX(), GetY(), GetBitmaskNameByValue(other_cp_modes, "PARKOUR_CP_")); + } + return true; +} + + /*-- Proplist --*/ local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c index 91a35888d..5f75615b6 100644 --- a/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Parkour.ocd/Script.c @@ -24,12 +24,14 @@ local respawn_list; // List of last reached respawn CP per player. local plr_list; // Number of checkpoints the player completed. local team_list; // Number of checkpoints the team completed. local time_store; // String for best time storage in player file. +local no_respawn_handling; // set to true if this goal should not handle respawn /*-- General --*/ protected func Initialize() { finished = false; + no_respawn_handling = false; cp_list = []; cp_count = 0; respawn_list = []; @@ -79,6 +81,7 @@ public func SetFinishpoint(int x, int y, bool team) cp->SetCPController(this); cp_count++; cp_list[cp_count] = cp; + UpdateScoreboardTitle(); return cp; } @@ -105,9 +108,33 @@ public func AddCheckpoint(int x, int y, int mode) cp_list[cp_count + 1] = cp; } cp_count++; + UpdateScoreboardTitle(); return cp; } +public func DisableRespawnHandling() +{ + // Call this to disable respawn handling by goal + // This might be useful if + // a) you don't want any respawns or + // b) the scenario already provides an alternate respawn handling + no_respawn_handling = true; + return true; +} + +/*-- Scenario saving --*/ + +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + // force dependency on restartr rule + var restart_rule = FindObject(Find_ID(Rule_Restart)); + if (restart_rule) restart_rule->MakeScenarioSaveName(); + if (no_respawn_handling) props->AddCall("Goal", this, "DisableRespawnHandling"); + return true; +} + + /*-- Checkpoint interaction --*/ // Called from a finish CP to indicate that plr has reached it. @@ -324,7 +351,7 @@ protected func InitializePlayer(int plr, int x, int y, object base, int team) if (!team_list[team]) team_list[team] = 0; // Scoreboard. - InitScoreboard(); + Scoreboard->NewPlayerEntry(plr); UpdateScoreboard(plr); DoScoreboardShow(1, plr + 1); JoinPlayer(plr); @@ -335,6 +362,7 @@ protected func InitializePlayer(int plr, int x, int y, object base, int team) protected func RelaunchPlayer(int plr) { + if (no_respawn_handling) return; var clonk = CreateObject(Clonk, 0, 0, plr); clonk->MakeCrewMember(plr); SetCursor(plr, clonk); @@ -378,16 +406,24 @@ protected func RemovePlayer(int plr) static const SBRD_Checkpoints = 0; static const SBRD_BestTime = 1; -private func InitScoreboard() +private func UpdateScoreboardTitle() { if (cp_count > 0) var caption = Format("$MsgCaptionX$", cp_count); else var caption = "$MsgCaptionNone$"; - // The above row. - SetScoreboardData(SBRD_Caption, SBRD_Caption, caption, SBRD_Caption); - SetScoreboardData(SBRD_Caption, SBRD_Checkpoints, Format("{{%i}}", ParkourCheckpoint), SBRD_Caption); - SetScoreboardData(SBRD_Caption, SBRD_BestTime, "T", SBRD_Caption); + return Scoreboard->SetTitle(caption); +} + +private func InitScoreboard() +{ + Scoreboard->Init( + [ + {key = "checkpoints", title = ParkourCheckpoint, sorted = true, desc = true, default = 0, priority = 80}, + {key = "besttime", title = "T", sorted = true, desc = true, default = 0, priority = 70} + ] + ); + UpdateScoreboardTitle(); return; } @@ -396,14 +432,9 @@ private func UpdateScoreboard(int plr) if (finished) return; var plrid = GetPlayerID(plr); - // The player name. - SetScoreboardData(plrid, SBRD_Caption, GetTaggedPlayerName(plr), SBRD_Caption); - // The player scores. - SetScoreboardData(plrid, SBRD_Checkpoints, Format("%d", plr_list[plrid]), plr_list[plrid]); - SetScoreboardData(plrid, SBRD_BestTime, TimeToString(GetPlrExtraData(plr, time_store)), GetPlrExtraData(plr, time_store)); - // Sort. - SortScoreboard(SBRD_BestTime, false); - SortScoreboard(SBRD_Checkpoints, true); + Scoreboard->SetPlayerData(plr, "checkpoints", plr_list[plrid]); + var bt = GetPlrExtraData(plr, time_store); + Scoreboard->SetPlayerData(plr, "besttime", TimeToString(bt), bt); return; } diff --git a/planet/Objects.ocd/Goals.ocd/Resource.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Resource.ocd/Script.c index d5b6f8753..e37b9567d 100644 --- a/planet/Objects.ocd/Goals.ocd/Resource.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Resource.ocd/Script.c @@ -33,6 +33,17 @@ public func SetResource(string resource) return; } +/*-- Scenario saving --*/ + +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + for (var resource in resource_list) + props->AddCall("Goal", this, "SetResource", Format("%v", resource)); + return true; +} + + /*-- Goal interface --*/ // The goal is fulfilled if all specified resource have been mined. diff --git a/planet/Objects.ocd/Goals.ocd/Resource.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/Resource.ocd/StringTblUS.txt index f26508aa3..5698f2316 100644 --- a/planet/Objects.ocd/Goals.ocd/Resource.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Goals.ocd/Resource.ocd/StringTblUS.txt @@ -2,5 +2,5 @@ Name=Resource extraction #Goal window MsgGoalFulfilled=Congratulations, all resources have been successfully extracted. -MsgGoalExtraction=Successful completion of this goal includes the extraction of the following resources: +MsgGoalExtraction=Successful completion of this scenario requires the extraction of the following resources: MsgGoalResource=|{{%i}} %d units of solid material and %d chunks. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/DefCore.txt new file mode 100644 index 000000000..b66ec5a61 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_RubyHunt +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/Graphics.png new file mode 100644 index 000000000..35f3dc083 Binary files /dev/null and b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/Script.c new file mode 100644 index 000000000..466a351f5 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/Script.c @@ -0,0 +1,99 @@ +/*-- + Ruby hunt + Author: Sven2 + + Mine one ruby and return to start +--*/ + + +#include Library_Goal + +local goal_rect, has_winner; + +protected func Initialize() +{ + return inherited(...); +} + +func SetGoalRect(r) +{ + goal_rect = r; + return true; +} + + +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (goal_rect) props->AddCall("Goal", this, "SetGoalRect", goal_rect); + return true; +} + + +/*-- Goal interface --*/ + +// The goal is fulfilled if a ruby is in the goal rectangle +public func IsFulfilled() +{ + var winner=NO_OWNER, winners, winner_teams; + if (has_winner) return true; + for (var ruby in FindObjects(Find_InRect(goal_rect.x, goal_rect.y, goal_rect.w, goal_rect.h), Find_ID(Ruby))) + { + if (ruby->Contained()) winner = ruby->Contained()->GetOwner(); + if (winner==NO_OWNER) winner = ruby->GetController(); + if (winner==NO_OWNER) continue; + if (!winners) winners = [winner]; else winners[GetLength(winners)] = winner; + var team = GetPlayerTeam(winner); + if (team) if (!winner_teams) winner_teams = [team]; else winner_teams[GetLength(winner_teams)] = team; + } + if (!winners) return false; + has_winner = true; + var iplr=GetPlayerCount(); + while (iplr--) + { + var plr = GetPlayerByIndex(iplr); + // Free view when game is over + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,LandscapeWidth(),LandscapeWidth(),flag); + SetPlayerViewLock(plr, false); + if (GetIndexOf(winners, plr) >= 0) continue; + if (winner_teams) if (GetIndexOf(winner_teams, GetPlayerTeam(plr)) >= 0) continue; + EliminatePlayer(plr); + } + return true; +} + +// Shows or hides a message window with information. +public func Activate(int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + var message; + if (IsFulfilled()) + message = "@$MsgGoalFulfilled$"; + else + message = "@$MsgGoalUnfulfilled$"; + + CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + +public func GetShortDescription(int plr) +{ + return nil; +} + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/StringTblDE.txt b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/StringTblDE.txt new file mode 100644 index 000000000..e7af46ffd --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/StringTblDE.txt @@ -0,0 +1,4 @@ +Name=Rubinsuche +#Goal window +MsgGoalFulfilled=Ein Rubin wurde abgeliefert. +MsgGoalUnfulfilled=Noch kein Rubin am Start. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/StringTblUS.txt new file mode 100644 index 000000000..85eb7f232 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/RubyHunt.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +Name=Sell gems + +#Goal window +MsgGoalFulfilled=A ruby has been delivered. +MsgGoalUnfulfilled=Mine a ruby and deliver it to the starting platform. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/SellGems.ocd/DefCore.txt b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/DefCore.txt new file mode 100644 index 000000000..9b0478527 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Goal_SellGems +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Goal +Picture=0,0,128,128 diff --git a/planet/Objects.ocd/Goals.ocd/SellGems.ocd/Graphics.png b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/Graphics.png new file mode 100644 index 000000000..7faa986ac Binary files /dev/null and b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Goals.ocd/SellGems.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/Script.c new file mode 100644 index 000000000..189a050d3 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/Script.c @@ -0,0 +1,87 @@ +/*-- + Sell Gems + Author: Sven2 + + Sell n gems at flagpole. +--*/ + + +#include Library_Goal + +local gems_to_sell; + +protected func Initialize() +{ + gems_to_sell = 20; // default + return inherited(...); +} + +func SetTargetAmount(int new_amount) +{ + gems_to_sell = new_amount; + return true; +} + +func OnGemSold() +{ + // A gem was sold. Subtract. + gems_to_sell = Max(gems_to_sell-1); + return true; +} + + +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (gems_to_sell) props->AddCall("Goal", this, "SetTargetAmount", gems_to_sell); + return true; +} + + +/*-- Goal interface --*/ + +// The goal is fulfilled if no more gems need to be sold +public func IsFulfilled() +{ + return (gems_to_sell<=0); +} + +// Shows or hides a message window with information. +public func Activate(int plr) +{ + // If goal message open -> hide it. + if (GetEffect("GoalMessage", this)) + { + CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter); + RemoveEffect("GoalMessage", this); + return; + } + // Otherwise open a new message. + AddEffect("GoalMessage", this, 100, 0, this); + var message; + if (IsFulfilled()) + message = "@$MsgGoalFulfilled$"; + else + message = Format("@$MsgGoalUnfulfilled$", gems_to_sell); + + CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter); + return; +} + +protected func FxGoalMessageStart() {} + +public func GetShortDescription(int plr) +{ + // Show acquired wealth compared to goal. + var clr = RGB(255, 0, 0); + if (gems_to_sell<=0) + clr = RGB(0, 255, 0); + var msg = Format("%d{{%i}}", clr, gems_to_sell, Ruby); + return msg; +} + +/*-- Proplist --*/ + +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Goals.ocd/SellGems.ocd/StringTblDE.txt b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/StringTblDE.txt new file mode 100644 index 000000000..f39e067b2 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/StringTblDE.txt @@ -0,0 +1,4 @@ +Name=Edelsteine verkaufen +#Goal window +MsgGoalFulfilled=Ihr habt genug Edelsteine verkauft! +MsgGoalUnfulfilled=Ihr müsst noch %d Edelsteine verkaufen. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/SellGems.ocd/StringTblUS.txt b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/StringTblUS.txt new file mode 100644 index 000000000..3b3f4dfd1 --- /dev/null +++ b/planet/Objects.ocd/Goals.ocd/SellGems.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +Name=Sell gems + +#Goal window +MsgGoalFulfilled=You've sold enough gems! +MsgGoalUnfulfilled=You need to sell %d more gems. \ No newline at end of file diff --git a/planet/Objects.ocd/Goals.ocd/Wealth.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Wealth.ocd/Script.c index 02baf5c20..4bb950267 100644 --- a/planet/Objects.ocd/Goals.ocd/Wealth.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Wealth.ocd/Script.c @@ -29,6 +29,19 @@ public func GetWealthGoal() return wealth_goal; } + +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + var v = GetWealthGoal(); + if (v) props->AddCall("Goal", this, "SetWealthGoal", v); + return true; +} + + + /*-- Goal interface --*/ // The goal is fulfilled if all players have the specfied wealth. @@ -74,7 +87,7 @@ public func GetShortDescription(int plr) var wealth = GetWealth(plr); var goal = GetWealthGoal(); var clr = RGB(255, 0, 0); - if (wealth > goal) + if (wealth >= goal) clr = RGB(0, 255, 0); var msg = Format("%d{{%i}}", clr, goal, GUI_Wealth); return msg; diff --git a/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/ContentsMenuController.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/ContentsMenuController.ocd/Script.c index 5c934d75b..a5e239c9a 100644 --- a/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/ContentsMenuController.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/ContentsMenuController.ocd/Script.c @@ -1,5 +1,6 @@ /** Control object for content menus. + This is not a regular menu, because it creates other menus to do the work for it. @author Newton, Maikel */ @@ -13,6 +14,8 @@ local menu_object; local crew_count; local container_count; +static const MENU_Contents_MaxCrewDist = 20; + /** Creates a content menu for the calling object. This is supposed to be a crew member, controlled by a player. @return a pointer to the created menu, or \c nil if failed. @@ -35,7 +38,7 @@ global func CreateContentsMenus() controller->AddContentMenu(this, index, true); // add all nearby crewmembers - var teammates = FindObjects(Find_Distance(20), Find_OCF(OCF_CrewMember), Find_Owner(GetOwner()), Find_Exclude(this)); + var teammates = FindObjects(Find_Distance(MENU_Contents_MaxCrewDist), Find_OCF(OCF_CrewMember), Find_Owner(GetOwner()), Find_Exclude(this)); index = 1; for(var t in teammates) controller->AddContentMenu(t, index++, true); @@ -50,6 +53,9 @@ global func CreateContentsMenus() return controller; } +/** Returns the object for which the menu is shown. */ +public func GetMenuObject() { return menu_object; } + global func SortInventoryObjs() { // left: crew members @@ -62,14 +68,16 @@ global func SortInventoryObjs() public func IsContentMenu() { return true; } -func SetMenuObject(object menu_object) +func SetMenuObject(object menuObject) { - menu_object = menu_object; + menu_object = menuObject; } func Construction() { circ_menus = []; + container_count = 0; + crew_count = 0; } func Close() @@ -84,7 +92,8 @@ func Destruction() // remove all menu objects for(var prop in circ_menus) { - prop.Object->~OnContentMenuClosed(); + if(prop.Object) + prop.Object->~OnContentMenuClosed(); prop.Menu->RemoveObject(); } } @@ -103,7 +112,7 @@ func Hide() { for (var prop in circ_menus) { - prop.Object->~OnContentMenuClosed(); + if (prop.Object) prop.Object->~OnContentMenuClosed(); prop.Menu->Hide(); } } @@ -117,8 +126,10 @@ func AddContentMenu(object container, int pos, bool isCrew) menu->SetCommander(this); menu->SetDragDropMenu(true); + var dist = ObjectDistance(menu_object, container); + PutContentsIntoMenu(menu, container); - circ_menus[pos] = {Object = container, Menu = menu, IsCrew = isCrew}; + circ_menus[pos] = {Object = container, Menu = menu, IsCrew = isCrew, Distance = dist}; if(isCrew) crew_count++; @@ -126,12 +137,41 @@ func AddContentMenu(object container, int pos, bool isCrew) container_count++; // Track external changes in containers. - AddEffect("ContainerTracker", container, 100, 1, this, nil, menu); + AddEffect("ContainerTracker", container, 100, 1, this, nil, menu, container->GetPosition()); - UpdateContentMenus(); + UpdateContentMenus(); return; } +func RemoveContentMenu(int index) +{ + var length = GetLength(circ_menus); + if(index >= length) + return; + + // remove menu + if(circ_menus[index].IsCrew) + crew_count--; + else + container_count--; + + circ_menus[index].Menu->RemoveObject(); + + // for debugging, we'll set debug information here. In case something doesn't work as intended or setLength breaks. + circ_menus[index] = {Debug="RemoveContentMenu was called", Index=index}; + + // close the gap + for(var i=index; i < length-1; i++) + circ_menus[i] = circ_menus[i+1]; + + SetLength(circ_menus, length-1); + + // and update + UpdateContentMenus(); + for(var prop in circ_menus) + prop.Menu->UpdateMenu(); +} + // Draws the contents menus to the right positions. private func UpdateContentMenus() { @@ -197,9 +237,13 @@ private func PutContentsIntoMenu(object menu, object container) if (!AddContentsMenuItem(stack[0], menu, stack)) return; } + + // TODO: find an extra-entry or something like that to display this. + if(container->~IsCarryingHeavy()) + AddContentsMenuItem(container->GetCarryHeavy(), menu); } -private func AddContentsMenuItem(object symbol, object menu, array stack) +private func AddContentsMenuItem(object obj, object menu, array stack) { // Into the menu item, all the objects of the stack are saved as an array into it's extradata. var item = CreateObject(GUI_MenuItem); @@ -208,10 +252,10 @@ private func AddContentsMenuItem(object symbol, object menu, array stack) item->RemoveObject(); return false; } - item->SetSymbol(symbol); + item->SetSymbol(obj); if (stack == nil) { - item->SetData([symbol]); + item->SetData([obj]); } else { @@ -268,83 +312,156 @@ private func CanStackObjIntoMenuItem(object menu, object obj) { /*-- Content tracking --*/ // TODO: Implement this more carefully and cover all corner cases. - -public func FxContainerTrackerStart(object target, proplist effect, int temporary, object menu) +// Todo: Replace this with Fx*Collection if it ever gets implemented. +public func FxContainerTrackerStart(object target, proplist effect, int temporary, object menu, array position) { - if (temporary == 0) - { - effect.Menu = menu; - // Initialize content list. - effect.ContentList = []; - var index = 0; - while (target->Contents(index)) - { - effect.ContentList[index] = target->Contents(index); - index++; - } - } + if (temporary) + return 1; + + effect.Menu = menu; + effect.Position = position; + // Initialize content list. + EffectCall(target, effect, "Update"); + return 1; } public func FxContainerTrackerTimer(object target, proplist effect) { + // check if the target moved + if(effect.Position[0] != target->GetX() || effect.Position[1] != target->GetY()) + { + effect.CommandTarget->~OnContainerMovement(effect.Menu, target); + effect.Position = target->GetPosition(); + + // if it's the clonk that moved + if(target == effect.CommandTarget.menu_object) + // check all distances. + effect.CommandTarget->~OnClonkMovement(); + + return 1; + } + + var change = false; + var index = 0; + // Match current contents to actual list, first trivial test. if (GetLength(effect.ContentList) != target->ContentsCount()) - // Stop the effect, the contoller is notified in the stop call. - return -1; + change = true; // Test both ways around, cause either container can be empty. + else + { + for(index=0; target->Contents(index); index++) + { + if (effect.ContentList[index] != target->Contents(index)) + { + change = true; + break; + } + } + } + if(!change) + { + for (index = 0; index < GetLength(effect.ContentList); index++) + { + if (effect.ContentList[index] != target->Contents(index)) + { + change = true; + break; + } + } + } + + if(change) + { + EffectCall(target, effect, "Update"); + effect.CommandTarget->~OnContentChange(effect.Menu, target); + } + return 1; +} + +public func FxContainerTrackerStop(object target, proplist effect, int reason, bool tmp) +{ + if(tmp) + return; + + if(reason == 3 || reason == 4) + effect.CommandTarget->~OnContainerRemoved(effect.Menu, target); + + return 1; +} + +public func FxContainerTrackerUpdate(object target, proplist effect) +{ + effect.ContentList = []; var index = 0; while (target->Contents(index)) { - if (effect.ContentList[index] != target->Contents(index)) - { - // Stop the effect, the contoller is notified in the stop call. - return -1; - } + effect.ContentList[index] = target->Contents(index); index++; } - for (index = 0; index < GetLength(effect.ContentList); index++) - { - if (effect.ContentList[index] != target->Contents(index)) - { - // Stop the effect, the contoller is notified in the stop call. - return -1; - } - } - return 1; } -public func FxContainerTrackerStop(object target, proplist effect, int reason) +/** Called when the position of the clonk that opened the menu changed. + Checks if containers are still in range, and removes menu if necessary. +*/ +public func OnClonkMovement() { - // Notify content menu if the effect has ended regularly, the menu will be deleted - // and a new effect for that menu will be added. - if (reason == 0) - effect.CommandTarget->~OnExternalContentChange(effect.Menu, target); - - return 1; + for(var prop in circ_menus) + OnContainerMovement(prop.Menu, prop.Object); } -public func OnExternalContentChange(object menu, object container) +/** Called when the position of a container with an open menu changed. + Checks if object still is in range, and removes menu if necessary. +*/ +public func OnContainerMovement(object menu, object container) +{ + var index = FindMenuPos(menu); + if(index < 0) + return; + + // check distance + if(menu.isCrew) + { + Log("%s - %s: %d", menu_object->GetName(), container->GetName(), ObjectDistance(menu_object, container)); + if(ObjectDistance(menu_object, container) > MENU_Contents_MaxCrewDist) + RemoveContentMenu(index); + } + else + { + // todo: reverse-find_at_point or something more performant than InFrontOf. + if(!menu_object->InFrontOf(container)) + RemoveContentMenu(index); + } +} + +/** Called when a container with an open menu got removed. + Removes the Menu and fixes ordering. +*/ +public func OnContainerRemoved(object menu, object container) +{ + var index = FindMenuPos(menu); + if(index < 0) + return; + + // remove menu and reorder other menus + RemoveContentMenu(index); +} + +/** Called when the content of a container with an open menu changed. + Updates menu. +*/ +public func OnContentChange(object menu, object container) { // Find changed menu and remove it. - var length = GetLength(circ_menus); - var index = 0; - for (index = 0; index < length; index++) - if (circ_menus[index].Menu == menu) - { - circ_menus[index].Menu->RemoveObject(); - break; - } - - // Reopen the changed menu. - var isCrew = container->GetOCF() & OCF_CrewMember; - if(isCrew) - crew_count--; - else - container_count--; - AddContentMenu(container, index, isCrew); - Show(true); + var index = FindMenuPos(menu); + if(index < 0) + return; + + menu->Clear(); + PutContentsIntoMenu(menu, container); + return; } @@ -362,7 +479,7 @@ private func TransferObjects(proplist p_source, proplist p_target, object menu_i return 0; // Determine actual amount that may be transfered. - var objects = menu_item->GetExtraData(); + var objects = menu_item->GetExtraData(); // will always be at least [object] amount = BoundBy(amount, 0, GetLength(objects)); // Move to object from source container to target container. @@ -376,6 +493,9 @@ private func TransferObjects(proplist p_source, proplist p_target, object menu_i // Try to enter the object, but check for some collect callbacks. if (p_target.Object->~RejectCollect(obj->GetID(), obj) && !p_target.Object->~AllowTransfer(obj)) continue; + // see if the container actually allows taking it out + if(p_source.Object->~RefuseTransfer(obj)) + continue; if (obj->Enter(p_target.Object)) { moved_to_target[GetLength(moved_to_target)] = obj; @@ -424,47 +544,17 @@ private func ExchangeObjects() } -private func UpdateAfterTakenObjects(proplist p_source, object menuItem) -{ - var objects = menuItem->GetExtraData(); - // update menu item in source menu: remove all objects in extradata which are not in - // container anymore - var c = 0; - var i; - for (i = 0; i < GetLength(objects); ++i) - { - var obj = objects[i]; - if (obj->Contained() != p_source.Object) - { - objects[i] = nil; - c++; - } - } - - // removed all? -> remove menu item - if (c == GetLength(objects)) - { - p_source.Menu->RemoveItem(menuItem); - } - else if(c > 0) - { - // otherwise, update - - // repair "holes" - var remaining_objects = objects[:]; - RemoveHoles(remaining_objects); - //Log("%v",remaining_objects); - - menuItem->SetData(remaining_objects); - menuItem->SetCount(GetLength(remaining_objects)); - menuItem->SetSymbol(remaining_objects[0]); - } -} private func MoveObjects(proplist p_source, proplist p_target, object menuItem, int amount) { + // move object to new menu TransferObjects(p_source, p_target, menuItem, amount); - UpdateAfterTakenObjects(p_source, menuItem); + // Update menus + OnContentChange(p_source.Menu, p_source.Object); + OnContentChange(p_target.Menu, p_target.Object); + + EffectCall(p_source.Object, GetEffect("ContainerTracker", p_source.Object), "Update"); + EffectCall(p_target.Object, GetEffect("ContainerTracker", p_target.Object), "Update"); } /* Interface to menu item as commander_object */ @@ -488,6 +578,10 @@ public func OnItemSelection(object menu, object item) var p_source_menu = circ_menus[index]; var p_target_menu = GetNextMenu(index, false); + // safety + if(!p_target_menu) + return false; + var amount = 1; MoveObjects(p_source_menu, p_target_menu, item, amount); return true; @@ -503,6 +597,10 @@ public func OnItemSelectionAlt(object menu, object item) var p_source_menu = circ_menus[index]; var p_target_menu = GetNextMenu(index, true); + // safety. + if(!p_target_menu) + return false; + var amount = 1; MoveObjects(p_source_menu, p_target_menu, item, amount); return true; @@ -511,27 +609,41 @@ public func OnItemSelectionAlt(object menu, object item) private func GetNextMenu(int index, bool alt) { var last = GetLength(circ_menus) - 1; + // Only one menu: to nothing if (last <= 0) return nil; if(alt) { + // the clonk itself or one of the crewmembers (except leftmost) if(index < crew_count-1) index++; + // leftmost crewmember (could be the clonk itself too) else if(index == crew_count-1) - index = last; + { + // go to rightmost container + if(container_count == 0) + index = 0; + else + index = last; + } + // leftmost container else if(index == crew_count) - index = 0; + index = 0; // go to clonk itself + // a container else index--; } else { + // the clonk itself if(index == 0) - index = crew_count; + index = crew_count; // go to first container + // a crewmember else if(index < crew_count) index--; + // a container else index++; } @@ -576,6 +688,8 @@ func OnItemDragDone(object menu, object dragged, object on_item) var p_source_menu = circ_menus[index]; - UpdateAfterTakenObjects(p_source_menu, dragged); + OnContentChange(menu, p_source_menu.Object); + EffectCall(p_source_menu.Object, GetEffect("ContainerTracker", p_source_menu.Object), "Update"); + return true; } diff --git a/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/Script.c index 38c3ff2df..0918be500 100644 --- a/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/CircleMenu.ocd/Script.c @@ -20,6 +20,8 @@ protected func Construction() { inherited(...); } + +/** Sets the symbol that is displayed in the menu background */ public func SetSymbol(symbol) { SetGraphics("BG", this, 2, GFXOV_MODE_Base); @@ -43,7 +45,7 @@ public func SetSymbol(symbol) -// Determines the item position for the nth circle for a certain number of circles. +/** Determines the item position for the nth circle for a certain number of circles. */ private func GetItemPosition(int n, int total) { // Safety. @@ -53,7 +55,7 @@ private func GetItemPosition(int n, int total) // Packing 7 or less circles. if (total <= 7) { - if (n == 7) + if (n == 0) return [0, 0]; else { @@ -66,7 +68,7 @@ private func GetItemPosition(int n, int total) // Packing 19 or less circles. if (total <= 19) { - if (n == 7) + if (n == 0) return [0, 0]; else if (n < 7) { @@ -76,8 +78,8 @@ private func GetItemPosition(int n, int total) } else { - var x = -Cos(30 * (n-5) + 15, 31 * MENU_Radius / 40); - var y = -Sin(30 * (n-5) + 15, 31 * MENU_Radius / 40); + var x = -Cos(30 * (n-4) + 15, 31 * MENU_Radius / 40); + var y = -Sin(30 * (n-4) + 15, 31 * MENU_Radius / 40); return [x, y]; } } @@ -85,7 +87,7 @@ private func GetItemPosition(int n, int total) // Packing 37 or less circles. if (total <= 37) { - if (n == 7) + if (n == 0) return [0, 0]; else if (n < 7) { @@ -93,16 +95,16 @@ private func GetItemPosition(int n, int total) var y = -Sin(60 * (n+1), 2 * MENU_Radius / 7); return [x, y]; } - else if (n <= 19) + else if (n < 19) { - var x = -Cos(30 * (n-5) + 15, 31 * MENU_Radius / 56); - var y = -Sin(30 * (n-5) + 15, 31 * MENU_Radius / 56); + var x = -Cos(30 * (n-4) + 15, 31 * MENU_Radius / 56); + var y = -Sin(30 * (n-4) + 15, 31 * MENU_Radius / 56); return [x, y]; } else { - var x = -Cos(30 * (n-17), 61 * MENU_Radius / 72); - var y = -Sin(30 * (n-17), 61 * MENU_Radius / 72); + var x = -Cos(30 * (n-16), 61 * MENU_Radius / 72); + var y = -Sin(30 * (n-16), 61 * MENU_Radius / 72); return [x, y]; } } @@ -110,7 +112,7 @@ private func GetItemPosition(int n, int total) return; } -// Gives the radius for an item. +/** Gives the radius for an item. */ private func GetItemRadius(int total) { if (total <= 7) @@ -122,6 +124,7 @@ private func GetItemRadius(int total) return 1; } +/** Redraws the menu */ public func UpdateMenu() { // Safety: check for items. @@ -134,7 +137,7 @@ public func UpdateMenu() for (var i = 0; i < item_count; i++) { - var pos = GetItemPosition(i + 1, item_count); + var pos = GetItemPosition(i, item_count); var item = menu_items[i]; if (item) { @@ -146,6 +149,7 @@ public func UpdateMenu() } public func OnMouseOverItem(object item, object dragged) + { // make it appear bigger item->SetObjDrawTransform(1100, 0, 0, 0, 1100, 0, 1); diff --git a/planet/Objects.ocd/HUD.ocd/Controller.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Controller.ocd/Script.c index 0776c9313..56ce6faf1 100644 --- a/planet/Objects.ocd/HUD.ocd/Controller.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Controller.ocd/Script.c @@ -2,9 +2,7 @@ HUD Controller Controls the player HUD and all its subsystems, which are: - * Backpack - * Hand items - * Energy/Breath tubes + * Inventory (=) * Actionbar * Crew selectors * Goal @@ -12,34 +10,34 @@ Creates and removes the crew selectors as well as reorders them and manages when a crew changes it's controller. Responsible for taking - care of the action (inventory) bar. + care of the action bar. @authors Newton, Mimmo_O */ -local actionbar; -local wealth; -//local deco; -local markers; -local backpack; -local carryheavy; +// Local variables containing the GUI-Elements +local actionbar; // Array, action-buttons at the bottom +local inventory; // Array, inventory-buttons at the left side +local markers; // Array, the gui-markers. +local carryheavy; // Object, optional inventory-button only shown when clonk is carrying a carry-heavy object +local wealth; // Object, displays wealth of the player -// Button that locks/unlocks the inventory -local lockbutton; -local hoverhelper; // the hover-thingie for showing the inventory. a helper. +local progress_bar_links; -// Tubes. -local healthtube; -local breathtube; +static const GUI_MAX_ACTIONBAR = 10; // maximum amount of actionbar-slots protected func Construction() { actionbar = []; markers = []; - backpack = []; + inventory = []; + progress_bar_links = []; + + // ensure object is not close to the bottom right border, so subobjects won't be created outside the landscape + SetPosition(0,0); // find all clonks of this crew which do not have a selector yet (and can have one) - for(var i=GetCrewCount(GetOwner())-1; i >= 0; --i) + for(var i=0; i < GetCrewCount(GetOwner()); ++i) { var crew = GetCrew(GetOwner(),i); if(!(crew->HUDAdapter())) continue; @@ -52,78 +50,73 @@ protected func Construction() // reorder the crew selectors ReorderCrewSelectors(); - // background decoration - //deco = CreateObject(GUI_Background,0,0,GetOwner()); - //deco->SetPosition(1,-1); - //deco->SetControllerObject(this); // wealth display wealth = CreateObject(GUI_Wealth,0,0,GetOwner()); wealth->SetPosition(-16-GUI_Wealth->GetDefHeight()/2,8+GUI_Wealth->GetDefHeight()/2); wealth->Update(); - // breathtube - //MakeBreathTube(); - - // healthtube - //MakeHealthTube(); - - // manatube - // MakeManaTube(); - - // backpack display - - MakeBackpack(); + // inventory display + MakeInventory(); } -// How many slots the inventory has, for overloading -private func BackpackSize() { return 7; } +/* Destruction */ -private func ScheduleUpdateBackpack() +// Remove all HUD-Objects +protected func Destruction() { - ScheduleCall(this, "UpdateBackpack", 1, 0); + // remove all hud objects that are managed by this object + if(wealth) + wealth->RemoveObject(); + if(actionbar) + { + for(var i=0; iRemoveObject(); + } + } + + if(inventory) + for(var i=0; iRemoveObject(); + } + + if(markers) + { + for(var i=0; iRemoveObject(); + } + } + + var HUDgoal = FindObject(Find_ID(GUI_Goal),Find_Owner(GetOwner())); + if(HUDgoal) + HUDgoal->RemoveObject(); + + var crew = FindObjects(Find_ID(GUI_CrewSelector), Find_Owner(GetOwner())); + for(var o in crew) + o->RemoveObject(); } /* Inventory-Bar stuff */ -private func MakeBackpack() + +// Updates the Inventory in 1 frame +private func ScheduleUpdateInventory() +{ + ScheduleCall(this, "UpdateInventory", 1, 0); +} + +private func MakeInventory() { // distance between slots var d = 72; // upper barrier - //var y = -225-35 - d*BackpackSize(); var y = 200; - // create background - /* - hoverhelper = CreateObject(GUI_Backpack_Background,0,0,GetOwner()); - hoverhelper->SetHUDController(this); - hoverhelper->SetPosition(0,y-10); - hoverhelper->SetShape(0,0,40+48/2+25, d*BackpackSize() - 48 - 20); - hoverhelper.Visibility = VIS_None; -*/ - - // create backpack slots - for(var i=0; iSetHUDController(this); - bt->SetPosition(40, y + d*i); - bt->SetSlotId(i); - //bt->SetCon(115); - - CustomMessage(Format("@%d.", i+1), bt, nil, -40, 54); - backpack[GetLength(backpack)] = bt; - } - - // and the lock-button - /* - var bt = CreateObject(GUI_Lock_Button,0,0,GetOwner()); - bt->SetHUDController(this); - bt->SetPosition(60,y-55); - - lockbutton = bt; - */ - // and the carry heavy slot var bt = CreateObject(GUI_Backpack_Slot_Icon,0,0,GetOwner()); bt->SetHUDController(this); @@ -131,102 +124,9 @@ private func MakeBackpack() bt->SetSlotId(-1); bt.Visibility = VIS_None; - carryheavy = bt; } -public func ShowInventory() -{ - return; - /* - var effect; - if(effect = GetEffect("InventoryTransition", this)) - effect.position = 40; - else - AddEffect("InventoryTransition", this, 150, 1, this, GUI_Controller, 40, backpack[0]); - - hoverhelper.Visibility = VIS_None; - - ClearScheduleCall(this, "HideInventory"); - */ -} - -public func HideInventory() -{ - return; - /* - // don't hide if the inventory is locked - if(lockbutton->IsLocked()) - return; - - var effect; - if(effect = GetEffect("InventoryTransition", this)) - effect.position = 0; - else - AddEffect("InventoryTransition", this, 150, 1, this, GUI_Controller, 0, backpack[0]); - - hoverhelper.Visibility = VIS_Owner; - */ -} - -public func ScheduleHideInventory() -{ - return; - //ScheduleCall(this, "HideInventory", 120); -} - - -private func FxInventoryTransitionStart(object target, proplist effect, int tmp, int pos, object ref) -{ - if(tmp != 0) - return; - - // make stuff visible. It wants to be seen transitioning! - var bt; - for(bt in backpack) - bt.Visibility = VIS_Owner; - - effect.position = pos; - effect.reference = ref; -} - -private func FxInventoryTransitionTimer(object target, proplist effect, int time) -{ - // don't move in the initial frame - used if the moving is aborted by hovering - if(time < 1) - return; - - var dist = effect.position - effect.reference->GetX(); - var dir = BoundBy(dist, -8,8); - - // if we haven't reached our destination yet, we move everything - if(dir != 0) - { - var bt; - for(bt in backpack) - bt->MovePosition(dir, 0); - - bt = lockbutton; - bt->MovePosition(dir, 0); - } - // else the effect is allowed to cease existing - else - return -1; -} - -private func FxInventoryTransitionStop(object target, proplist effect, int reason, int tmp) -{ - if(tmp != 0) - return; - - if(effect.position == 0) - { - var bt; - for(bt in backpack) - bt.Visibility = VIS_None; - } -} - /*-- Wealth --*/ protected func OnWealthChanged(int plr) @@ -249,68 +149,17 @@ public func OnGoalUpdate(object goal) } else { - if (!HUDgoal) HUDgoal = CreateObject(GUI_Goal, 0, 0, GetOwner()); - HUDgoal->SetPosition(-64-16-GUI_Goal->GetDefHeight()/2,8+GUI_Goal->GetDefHeight()/2); + if (!HUDgoal) + { + HUDgoal = CreateObject(GUI_Goal, 0, 0, GetOwner()); + HUDgoal->SetPosition(-64-16-GUI_Goal->GetDefHeight()/2,8+GUI_Goal->GetDefHeight()/2); + } HUDgoal->SetGoal(goal); } } -/*-- Health tube --*/ - -private func MakeHealthTube() -{ - var tube = CreateObject(GUI_HealthTube, 0, 0, GetOwner()); - tube->MakeTube(); - tube->Update(); - healthtube = tube; - return; -} - -public func UpdateHealthTube() -{ - if (healthtube) - healthtube->Update(); - return; -} - -/*-- Breath tube --*/ - -private func MakeBreathTube() -{ - var tube = CreateObject(GUI_BreathTube, 0, 0, GetOwner()); - tube->MakeTube(); - tube->Update(); - breathtube = tube; - return; -} - -public func UpdateBreathTube() -{ - if (breathtube) - breathtube->Update(); - return; -} - -/* -protected func MakeManaTube() -{ - var tube = CreateObject(GUI_ManaTube,0,0,this->GetOwner()); - tube->SetPosition(1,-1); - tube->SetAction("Swirl"); - var ftube = CreateObject(GUI_ManaTube,0,0,this->GetOwner()); - ftube->SetPosition(1,-1); - ftube->MakeTop(); - //tube->SetTubes(btube,ftube); - tube->SetTubes(ftube); - tube->Update(); - AddEffect("Update",tube,100,1,tube); - - tubes[GetLength(tubes)] = tube; - tubes[GetLength(tubes)] = ftube; - -} -*/ +/* Markers */ public func GetFreeMarkerPosition() { @@ -339,62 +188,70 @@ global func AddHUDMarker(int player, picture, string altpicture, string text, in return hud.markers[number]; } -func UpdateBackpack() +/* Inventory stuff */ +func UpdateInventory() { + // only display if we have a clonk var c = GetCursor(GetOwner()); if(!c) return 1; - - ShowInventory(); - // update backpack-slots - for(var i=0; iSetSymbol(c->GetItem(backpack[i]->GetSlotId())); - backpack[i]->SetUnselected(); + var old_progress_bar_links = progress_bar_links[:]; + progress_bar_links = []; + + for(var bar in old_progress_bar_links) + { + if(!bar.effect) continue; + PushBack(progress_bar_links, bar); + } + } + + // update inventory-slots + for(var i=0; iGetItem(inventory[i]->GetSlotId()); + inventory[i]->SetSymbol(item); + inventory[i]->SetUnselected(); + + inventory[i]->ClearProgressBarLink(); + // re-add progress bar if possible + for(var bar in progress_bar_links) + { + if(bar.obj != item) continue; + inventory[i]->SetProgressBarLink(bar.effect); + break; + } } // update hand-indicator - if(c->IsCarryingHeavy()) + if(c->~IsCarryingHeavy()) { carryheavy->SetSelected(-1); } else - for(var i=0; i < c->HandObjects(); ++i) - backpack[c->GetHandItemPos(i)]->SetSelected(i); - - /* - if(!lockbutton->IsLocked()) - { - ScheduleHideInventory(); - } - */ + for(var i=0; i < c->~HandObjects(); ++i) + { + var handpos = c->GetHandItemPos(i); + if(inventory[handpos]) + inventory[handpos]->SetSelected(i); + } } -/* -global func FxUpdateBackpackTimer(target) { - if(!target) return -1; - if(!GetCursor(target->GetOwner())) return 1; - if(!GetCursor(target->GetOwner())->~HUDShowItems()) - { - for (var i = 0; i < GetLength(target.backpack); i++) - target.backpack[i]->SetNothing(); - return 1; - } - for(var i=0; iSetAmount(0); - target.backpack[i]->SetSymbol(GetCursor(target->GetOwner())->GetItem(target.backpack[i]->GetExtraData())); - target.backpack[i]->SetGraphics(nil,nil,9); - target.backpack[i]->SetGraphics(nil,nil,10); - target.backpack[i]->SetGraphics(nil,nil,11); - target.backpack[i]->SetGraphics(nil,nil,12); - } -}*/ +// sets the link of the progress bar for a certain slot +// the link is an effect that has the properties "max" and "current" +func SetProgressBarLinkForObject(object what, proplist e) +{ + PushBack(progress_bar_links, {obj = what, effect = e}); + ScheduleUpdateInventory(); +} // Shows the Carryheavy-Inventoryslot if obj is set // Removes it if it's nil func OnCarryHeavyChange(object obj) { + if (!carryheavy) return; // safety if called during construction/destruction process carryheavy->SetSymbol(obj); if(obj == nil) @@ -405,10 +262,31 @@ func OnCarryHeavyChange(object obj) else this.Visibility = VIS_Owner; - UpdateBackpack(); + UpdateInventory(); } -protected func OnClonkRecruitment(object clonk, int plr) +/* Hotkey Control */ + +// executes the mouseclick onto an actionbutton through hotkeys +public func ControlHotkey(int hotindex) +{ + // button exists? + if(!actionbar[hotindex]) return false; + + // button is assigned to a clonk? + var clonk = actionbar[hotindex]->GetCrew(); + if(!clonk) return false; + + // press the button + actionbar[hotindex]->~MouseSelection(GetOwner()); + + return true; +} + +/** Callbacks **/ + +// insert new clonk into crew-selectors on recruitment +public func OnCrewRecruitment(object clonk, int plr) { // not my business if(plr != GetOwner()) return; @@ -440,12 +318,10 @@ protected func OnClonkRecruitment(object clonk, int plr) ReorderCrewSelectors(); // update - ScheduleUpdateBackpack(); - UpdateHealthTube(); - UpdateBreathTube(); + ScheduleUpdateInventory(); } -protected func OnClonkDeRecruitment(object clonk, int plr) +public func OnCrewDeRecruitment(object clonk, int plr) { // not my business if(plr != GetOwner()) return; @@ -454,7 +330,7 @@ protected func OnClonkDeRecruitment(object clonk, int plr) OnCrewDisabled(clonk); } -protected func OnClonkDeath(object clonk, int killer) +public func OnCrewDeath(object clonk, int killer) { if(clonk->GetController() != GetOwner()) return; if(!(clonk->~HUDAdapter())) return; @@ -462,6 +338,13 @@ protected func OnClonkDeath(object clonk, int killer) OnCrewDisabled(clonk); } +public func OnCrewDestruction(object clonk) +{ + if(clonk->GetController() != GetOwner()) return; + if(!(clonk->~HUDAdapter())) return; + + OnCrewDisabled(clonk); +} // called from engine on player eliminated @@ -477,58 +360,6 @@ public func RemovePlayer(int plr, int team) return RemoveObject(); } -public func Destruction() -{ - // remove all hud objects that are managed by this object - if(wealth) - wealth->RemoveObject(); - if(actionbar) - { - for(var i=0; iRemoveObject(); - } - } - - if(hoverhelper) - hoverhelper->RemoveObject(); - if(lockbutton) - lockbutton->RemoveObject(); - - if(backpack) - for(var i=0; iRemoveObject(); - } - - if(healthtube) - healthtube->RemoveObject(); - - if (breathtube) - breathtube->RemoveObject(); - - if(markers) - { - for(var i=0; iRemoveObject(); - } - } - - var HUDgoal = FindObject(Find_ID(GUI_Goal),Find_Owner(GetOwner())); - if(HUDgoal) - HUDgoal->RemoveObject(); - //if(deco) - //deco->RemoveObject(); - - var crew = FindObjects(Find_ID(GUI_CrewSelector), Find_Owner(GetOwner())); - for(var o in crew) - o->RemoveObject(); -} - public func OnCrewDisabled(object clonk) { // notify the hud and reorder @@ -540,50 +371,40 @@ public func OnCrewDisabled(object clonk) } // update - ScheduleUpdateBackpack(); - UpdateHealthTube(); - UpdateBreathTube(); + ScheduleUpdateInventory(); } public func OnCrewEnabled(object clonk) { - CreateSelectorFor(clonk); + if (!clonk->GetSelector()) CreateSelectorFor(clonk); ReorderCrewSelectors(); } + // call from HUDAdapter (Clonk) public func OnCrewSelection(object clonk, bool deselect) { // selected if(!deselect) { - // fill actionbar - // inventory - var i; - // var deco = CreateObject(GUI_ObjectSelector_Background,0,0,clonk->GetOwner()); - // deco->SetPosition(337,-38); - - /*for(i = 0; i < Min(2,clonk->HandObjects()); ++i) - { - ActionButton(clonk,i,clonk->GetHandItem(i),ACTIONTYPE_INVENTORY); - } - ClearButtons(i);*/ - ClearButtons(0); - // and start effect to monitor vehicles and structures... - AddEffect("IntSearchInteractionObjects",clonk,1,10,this,nil,i); + AddEffect("IntSearchInteractionObjects",clonk,1,10,this,nil,0); + + // clear inventory buttons + UpdateInventoryButtons(clonk); } else { // remove effect - RemoveEffect("IntSearchInteractionObjects",clonk,0); - ClearButtons(); + RemoveEffect("IntSearchInteractionObjects",clonk); } + // clear actionbuttons + ClearActionButtons(); + // update - ScheduleUpdateBackpack(); - UpdateHealthTube(); - UpdateBreathTube(); + ScheduleUpdateInventory(); + OnCarryHeavyChange(clonk->~GetCarryHeavy()); } public func FxIntSearchInteractionObjectsEffect(string newname, object target) @@ -599,6 +420,7 @@ public func FxIntSearchInteractionObjectsStart(object target, effect, int temp, EffectCall(target,effect,"Timer",target,effect,0); } +// takes care of displaying the interactions public func FxIntSearchInteractionObjectsTimer(object target, effect, int time) { @@ -609,22 +431,40 @@ public func FxIntSearchInteractionObjectsTimer(object target, effect, int time) //var hotkey = i+1-target->HandObjects(); var hotkey = i+1; + // Get custom interactions from the clonk + // extra interactions are an array of proplists. proplists have to contain at least a function pointer "f", a description "desc" and an "icon" definition/object. Optional "front"-boolean for sorting in before/after other interactions. + var extra_interactions = target->~GetExtraInteractions()??[]; // if not present, just use []. Less error prone than having multiple if(!foo). + // we could sort the interactions, but there usually will only be like 1-3. Not really worth it. + // Add buttons: // all except structures only if outside if(!target->Contained()) { + // add extra-interactions Priority 0 + for(var interaction in extra_interactions) + if(interaction.Priority == 0) + ActionButton(target, i++, interaction.Object, ACTIONTYPE_EXTRA, hotkey++, nil, interaction); // add interactables (script interface) var interactables = FindObjects(Find_AtPoint(target->GetX()-GetX(),target->GetY()-GetY()),Find_Func("IsInteractable",target),Find_NoContainer(), Find_Layer(target->GetObjectLayer())); + var j, icnt; for(var interactable in interactables) { - ActionButton(target,i++,interactable,ACTIONTYPE_SCRIPT,hotkey++); + icnt = interactable->~GetInteractionCount(); + if(!icnt) + icnt = 1; + + for(j=0; j < icnt; j++) + { + ActionButton(target,i++,interactable,ACTIONTYPE_SCRIPT,hotkey++, j); + } } - // if carrying heavy, add drop-carry-heavy-button - if(target->~IsCarryingHeavy()) - ActionButton(target, i++, target->GetCarryHeavy(), ACTIONTYPE_CARRYHEAVY, hotkey++); + // add extra-interactions Priority 1 + for(var interaction in extra_interactions) + if(interaction.Priority == 1) + ActionButton(target, i++, interaction.Object, ACTIONTYPE_EXTRA, hotkey++, nil, interaction); // add vehicles var vehicles = FindObjects(Find_AtPoint(target->GetX()-GetX(),target->GetY()-GetY()),Find_OCF(OCF_Grab),Find_NoContainer(), Find_Layer(target->GetObjectLayer())); @@ -632,6 +472,11 @@ public func FxIntSearchInteractionObjectsTimer(object target, effect, int time) { ActionButton(target,i++,vehicle,ACTIONTYPE_VEHICLE,hotkey++); } + + // add extra-interactions Priority 2 + for(var interaction in extra_interactions) + if(interaction.Priority == 2) + ActionButton(target, i++, interaction.Object, ACTIONTYPE_EXTRA, hotkey++, nil, interaction); } // add structures @@ -641,7 +486,12 @@ public func FxIntSearchInteractionObjectsTimer(object target, effect, int time) ActionButton(target,i++,structure,ACTIONTYPE_STRUCTURE,hotkey++); } - ClearButtons(i); + // add extra-interactions after everything + for(var interaction in extra_interactions) + if(interaction.Priority == nil || interaction.Priority > 2) + ActionButton(target, i++, interaction.Object, ACTIONTYPE_EXTRA, hotkey++, nil, interaction); + + ClearActionButtons(i); return; } @@ -658,79 +508,107 @@ public func OnSelectionChanged(int old, int new) // call from HUDAdapter or inventory-buttons public func OnHandSelectionChange(int old, int new, int handslot) { - backpack[old]->SetUnselected(); - backpack[new]->SetSelected(handslot); + if(inventory[old]) + inventory[old]->SetUnselected(); + if(inventory[new]) + inventory[new]->SetSelected(handslot); OnSlotObjectChanged(handslot); } protected func OnInventoryHotkeyPress(int slot) { - backpack[slot]->OnMouseOver(GetOwner()); + if(inventory[slot]) + inventory[slot]->OnMouseOver(GetOwner()); } protected func OnInventoryHotkeyRelease(int slot) { - backpack[slot]->OnMouseOut(GetOwner()); + if(inventory[slot]) + inventory[slot]->OnMouseOut(GetOwner()); } // call from HUDAdapter (Clonk) public func OnSlotObjectChanged(int slot) -{ - /* - //Log("slot %d changed", slot); - var cursor = GetCursor(GetOwner()); - if(!cursor) return; - var obj = cursor->GetHandItem(slot); - actionbar[slot]->SetObject(obj, ACTIONTYPE_INVENTORY, slot); - - // refresh backpack - */ - ScheduleUpdateBackpack(); +{ + // refresh inventory + ScheduleUpdateInventory(); } -private func ActionButton(object forClonk, int pos, object interaction, int actiontype, int hotkey) +/** Helper Functions **/ + +// Insert an inventory slot into the inventory-bar +private func InventoryButton() { - //var size = GUI_ObjectSelector->GetDefWidth(); - //var spacing = deco.padding; +// distance between slots + var d = 72; + // upper barrier + var y = 200; + + // index + var i = GetLength(inventory); + + // create inventory slots + var bt = CreateObject(GUI_Backpack_Slot_Icon,0,0,GetOwner()); + bt->SetHUDController(this); + bt->SetPosition(40, y + d*i); + bt->SetSlotId(i); + + CustomMessage(Format("@%d.", i+1), bt, nil, -40, 54); + inventory[i] = bt; + + return bt; +} + +// sets the inventory size to the currently selected clonk +private func UpdateInventoryButtons(object clonk) +{ + if(!clonk) return; + + var size = clonk->~MaxContentsCount(); + + // need to create more inventory buttons? + if(size > GetLength(inventory)) + for(var i=0; i < size; ++i) + if(!inventory[i]) + InventoryButton(); + + // need to remove some inventory buttons? + if(size < GetLength(inventory)) + for(i=GetLength(inventory)-1; i >= size; i--) + inventory[i]->RemoveObject(); + + SetLength(inventory, size); +} + +// Insert a button into the actionbar at pos +private func ActionButton(object forClonk, int pos, object interaction, int actiontype, int hotkey, int num, proplist extra) +{ + // the actionbar has a maximum size + if(pos >= GUI_MAX_ACTIONBAR) + return nil; + var spacing = 100; var bt = actionbar[pos]; + // no object yet... create it if(!bt) { bt = CreateObject(GUI_ObjectSelector,0,0,GetOwner()); - //bt->SetGraphics("Slot", GUI_Background); } -/* - if(pos==0) - { - bt->SetGraphics("None"); - bt->SetPosition(288, -48); - } - else if(pos==1) - { - bt->SetPosition(381, -48); - bt->SetGraphics("None"); - } - else - { - bt->SetCon(90); - bt->SetPosition(491 + (pos-2) * spacing, -45); - } - */ - - //bt->SetCon(90); + bt->SetPosition(401 + pos * spacing, -45); bt->SetCrew(forClonk); - bt->SetObject(interaction,actiontype,pos,hotkey); + bt->SetObject(interaction,actiontype,pos,hotkey, num, extra); actionbar[pos] = bt; return bt; } -private func ClearButtons(int start) +/** Removes all actionbar buttons after start */ +private func ClearActionButtons(int start) { // make rest invisible @@ -738,13 +616,11 @@ private func ClearButtons(int start) { // we don't have to remove them all the time, no? if(actionbar[j]) - actionbar[j]->Clear(); + actionbar[j]->Disable(); } - //if(deco->GetSlotNumber() != -1) - //if(deco->GetSlotNumber() != GetRealActionbarLength()) - //deco->SlideTo(GetRealActionbarLength()); } +/** Returns how many actionbar-buttons are actually visible */ private func GetRealActionbarLength() { var i=0; @@ -753,7 +629,8 @@ private func GetRealActionbarLength() return i; } -public func ClearButtonMessages() +/** Removes all messages that the actionbuttons show */ +private func ClearButtonMessages() { for(var i = 0; i < GetLength(actionbar); ++i) { @@ -762,19 +639,9 @@ public func ClearButtonMessages() } } -// hotkey control -public func ControlHotkey(int hotindex) -{ - if(!actionbar[hotindex]) return false; - var clonk = actionbar[hotindex]->GetCrew(); - if(!clonk) return false; - //hotindex += clonk->HandObjects(); - if(!actionbar[hotindex]) return false; - // only if it is not already used - actionbar[hotindex]->~MouseSelection(GetOwner()); - return true; -} - +/** Creates a crew selector for the given clonk. + Should be followed by a ReorderCrewSelectors call +*/ private func CreateSelectorFor(object clonk) { var selector = CreateObject(GUI_CrewSelector,10,10,-1); @@ -784,13 +651,11 @@ private func CreateSelectorFor(object clonk) } - -public func ReorderCrewSelectors(object leaveout) +/** Rearranges the CrewSelectors in the correct order */ +private func ReorderCrewSelectors(object leaveout) { - // somehow new crew gets sorted at the beginning - // because we dont want that, the for loop starts from the end var j = 0; - for(var i=GetCrewCount(GetOwner())-1; i >= 0; --i) + for(var i=0; i < GetCrewCount(GetOwner()); ++i) { var spacing = 12; var crew = GetCrew(GetOwner(),i); @@ -807,3 +672,20 @@ public func ReorderCrewSelectors(object leaveout) } } + + +/* When loading a savegame, make sure the GUI still works */ +func OnSynchronized() +{ + ScheduleCall(this, "Reset", 1); +} + +private func Reset() +{ + // The simple way: A full UI reset \o/ + Destruction(); + Construction(); + + if(GetCursor(GetOwner())) + OnCrewSelection(GetCursor(GetOwner())); +} diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/DefCore.txt deleted file mode 100644 index c17c928df..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=GUI_Background -Version=5,2,0,1 -Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax -Width=440 -Height=210 -Offset=-1,-209 - diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/Graphics.png deleted file mode 100644 index df2619418..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsAlt1.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsAlt1.png deleted file mode 100644 index 462fcaf92..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsAlt1.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsAlt2.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsAlt2.png deleted file mode 100644 index 9f07a2f9b..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsAlt2.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsLine.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsLine.png deleted file mode 100644 index fd2da42d8..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsLine.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsSlot.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsSlot.png deleted file mode 100644 index 22108511d..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsSlot.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsSmallSlot.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsSmallSlot.png deleted file mode 100644 index 54c8561e9..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/GraphicsSmallSlot.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/Script.c deleted file mode 100644 index 0951f3ea8..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Background.ocd/Script.c +++ /dev/null @@ -1,76 +0,0 @@ -/** - HUD Background - - Decoration for the action bar, inventory items and backpack. - Used layers: - 0 - unused - 1 - horizontal connection - 5-15 - Extra Slots - 50 - Actual Graphic - - @authors Mimmo_O -*/ - -local current; //extendation by 5 -local desired; -local padding; -local parent; - -protected func Construction() -{ - // parallaxity - this.Parallaxity = [0, 0]; - // visibility - this.Visibility = VIS_Owner; - padding = 90; - - SetGraphics(0,GetID(),50,GFXOV_MODE_Base); - SetGraphics("",GUI_Controller,0); - SetGraphics("Line",GetID(),1,GFXOV_MODE_Base); - - for(var i=5; i<20; i++) - SetGraphics("Slot",GetID(),i,GFXOV_MODE_Base); - - SetObjDrawTransform(4000,0,0,0,1000,118*1000,1); - SetObjDrawTransform(1000,0,352*1000,0,1000,115*1000,5); - for(var i=6; i<20; i++) - SetObjDrawTransform(1000,0,100*1000,0,1000,115*1000,i); -} - -func SetControllerObject(object p) { parent=p; } - -func SlideTo(int number) -{ - if(number*5 == current) return false; - current=number*5; - //for(var i = 2; iHideSelector(); - SetObjDrawTransform(4000 + current*padding*2,0,0,0,1000,118*1000,1); - - for(var i=5; i<20; i++) - SetObjDrawTransform(1000,0,(352 + ((padding/5)*current) - (i-5) * padding) * 1000,0,1000,115*1000,i); - //if(!GetEffect("BackDecoSlider",this)) AddEffect("BackDecoSlider",this,100,1,this); -} - - -func FxBackDecoSliderTimer() -{ - if(current==desired) - { - for(var i = 2; iShowsItem()) parent.actionbar[i]->ShowSelector(); - return -1; - } - var movingSpeed = (Abs(current-desired)/5)+1; - if(current>desired) current-=movingSpeed; - else current+=movingSpeed; - - - SetObjDrawTransform(4000 + current*padding*2,0,0,0,1000,118*1000,1); - - for(var i=5; i<20; i++) - SetObjDrawTransform(1000,0,(352 + ((padding/5)*current) - (i-5) * padding) * 1000,0,1000,115*1000,i); -} - -func IsEngaged(){ if(current%5) return false; else return true; } -func GetSlotNumber(){ if(IsEngaged()) return desired*5; else return -1;} diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/DefCore.txt deleted file mode 100644 index f9caebcc9..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=GUI_Backpack_Background -Version=4,10,0,0 -Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax | C4D_MouseSelect -Width=2 -Height=2 -Offset=-1,-1 - diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/Script.c deleted file mode 100644 index 63a6de30b..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Background.ocd/Script.c +++ /dev/null @@ -1,29 +0,0 @@ -/** - Backpack_Background - The background of the backpack area. Also doubles as hover-area for showing the backpack-slots. - - @author boni -*/ - -local controller; - -public func SetHUDController(object c) { controller = c; } - -public func Initialize() -{ - // Visibility - this.Visibility = VIS_Owner; - // Parallaxity - this.Parallaxity = [0, 0]; - - SetName(""); -} - -public func OnMouseOver(int plr) -{ - if(!controller || GetOwner() == NO_OWNER) - return nil; - - controller->ShowInventory(); - controller->ScheduleHideInventory(); -} \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/DefCore.txt index a9b0367f3..4c30634df 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/DefCore.txt +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/DefCore.txt @@ -7,4 +7,7 @@ Height=64 Offset=-32,-32 StretchGrowth=1 Rotate=1 -Oversize=1 \ No newline at end of file +Oversize=1 +Vertices=1 +VertexX=0 +VertexY=0 \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/Script.c index 260046cf1..4e995dc5b 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Backpack_Slot.ocd/Script.c @@ -7,6 +7,8 @@ local selected; local position; local controller; +local progress_bar, progress_bar_last_max; + public func SetHUDController(object c) { controller = c; } protected func Construction() @@ -50,7 +52,6 @@ public func SetUnselected() SetGraphics(nil,nil,5); } - // SetSymbol from GUI_RingMenu_Icon public func SetSymbol(obj) { @@ -63,11 +64,12 @@ public func SetSymbol(obj) //SetGraphics(nil, nil, 3); SetName(""); this.MouseDragImage = nil; + this.Tooltip = nil; } else { if (GetType(obj) == C4V_C4Object) - SetGraphics(nil, nil, 2, GFXOV_MODE_ObjectPicture, 0, 0, obj); + SetGraphics(nil, nil, 2, GFXOV_MODE_ObjectPicture, nil, 0, obj); else SetGraphics(nil,obj, 2, GFXOV_MODE_IngamePicture); @@ -77,7 +79,6 @@ public func SetSymbol(obj) SetGraphics(nil, nil, 1, GFXOV_MODE_ObjectPicture, nil, nil, obj->Contents()); SetClrModulation(RGBa(255,255,255,200),1); SetObjDrawTransform(900,0,0,0,900,0,1); - //SetObjDrawTransform(1000,0,32000,0,1000,-28000,2); } // or otherwise, remove it else @@ -87,6 +88,11 @@ public func SetSymbol(obj) SetName(obj->GetName()); this.MouseDragImage = obj->GetID(); + + // set tooltip + var desc = obj.UsageHelp; + if(!desc) desc = obj.Description; + this.Tooltip = desc; } } @@ -167,15 +173,13 @@ public func OnMouseDragDone(self, object target) } } -// highlight and block hiding +// highlight public func OnMouseOver(int plr) { if(!controller || GetOwner() == NO_OWNER) return nil; SetGraphics("Focussed", GUI_Backpack_Slot_Icon); - - controller->ShowInventory(); } public func OnMouseOut(int plr) @@ -184,6 +188,61 @@ public func OnMouseOut(int plr) return nil; SetGraphics(nil, nil); - - controller->ScheduleHideInventory(); +} + +// progress bar handling +// "link" always refers to an effect with the properties "max" and "current" +func ClearProgressBarLink() +{ + if(GetEffect("UpdateProgressBar", this)) + RemoveEffect("UpdateProgressBar", this); + if(progress_bar) + { + progress_bar->Close(); + progress_bar = nil; + } +} + +func SetProgressBarLink(proplist effect) +{ + if(GetEffect("UpdateProgressBar", this)) return; // not another one + AddEffect("UpdateProgressBar", this, 1, Min(effect.Interval, 25), this, nil, effect); +} + +func FxUpdateProgressBarStart(target, effect, temp, delegate) +{ + if(temp) return; + effect.other = delegate; +} + +func FxUpdateProgressBarTimer(target, effect, time) +{ + if(!effect.other) return -1; + SetProgressBarValue(effect.other.current, effect.other.max); +} + +public func SetProgressBarValue(int value, int max) +{ + if(value == nil) + { + if(progress_bar) progress_bar->Close(); + return true; + } + + if(progress_bar_last_max != max) + if(progress_bar) + { + progress_bar->Close(); + progress_bar = nil; + } + progress_bar_last_max = max; + + if(!progress_bar) + { + progress_bar = this->CreateProgressBar(GUI_PieProgressBar, max, value, 30, GetOwner(), {x=0, y=0}, VIS_Owner, {size=1600, color = RGB(100, 255, 25), back_color = RGBa(100, 50, 0, 100)}); + progress_bar->MakeHUDElement(); + progress_bar->SetPlane(this.Plane-1); + } + progress_bar->SetValue(value); + return true; } diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Graphics.png index c5f9630d4..b1ecc7e85 100644 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Graphics.png and b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsBackground.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsBackground.png new file mode 100644 index 000000000..c3326855f Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsBackground.png differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsFocussed.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsFocussed.png new file mode 100644 index 000000000..261e37be5 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsFocussed.png differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsHurt.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsHurt.png new file mode 100644 index 000000000..7dc570147 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/GraphicsHurt.png differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Script.c index 8cb2253f8..cb78d30ce 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/CrewSelector.ocd/Script.c @@ -24,10 +24,11 @@ public func MagicBarHeight() { return 14; } usage of layers: ----------------- layer 0 - unused - layer 1 - title - layer 2,3 - health bar - layer 4,5 - breath bar - layer 6,7 - magic bar + layer 2 - title + layer 1,3 - background-effects + layer 4,5 - health bar + layer 6,7 - breath bar + layer 8,9 - magic bar layer 10 - rank layer 12 - hotkey @@ -47,9 +48,22 @@ public func MagicBarHeight() { return 14; } */ +static const GUI_CS_Base = 0; +static const GUI_CS_Title = 2; +static const GUI_CS_BreathBG = 1; +static const GUI_CS_HealthBG = 3; +static const GUI_CS_HealthBar = 4; +static const GUI_CS_HealthText = 5; +static const GUI_CS_BreathBar = 6; +static const GUI_CS_BreathText = 7; +static const GUI_CS_SpecialBar = 8; +static const GUI_CS_SpecialText = 9; +static const GUI_CS_Rank = 10; +static const GUI_CS_Hotkey = 12; + protected func Construction() { - _inherited(); + _inherited(...); breathbar = false; magicbar = false; @@ -64,10 +78,10 @@ protected func Construction() this["Visibility"] = VIS_None; // health bar - SetBarLayers(2,0); + SetBarLayers(GUI_CS_HealthBar,0); SetBarOffset(0,BarOffset(0),0); SetBarDimensions(GetDefWidth(),HealthBarHeight(),0); - SetClrModulation(RGB(200,0,0),3); + SetClrModulation(RGB(200,0,0),GUI_CS_HealthText); } public func MouseSelection(int plr) @@ -85,6 +99,10 @@ public func MouseSelection(int plr) public func SetCrew(object c) { + // reset old crew, if there + if(crew) + RemoveEffect("GUIHealthMonitor", crew); + crew = c; UpdateHealthBar(); UpdateBreathBar(); @@ -96,22 +114,35 @@ public func SetCrew(object c) UpdateName(); this["Visibility"] = VIS_Owner; + + ScheduleCall(this, "AddMonitorEffect", 1); +} + +private func AddMonitorEffect() +{ + if(!crew) + return; + + AddEffect("GUIHealthMonitor", crew, 50, 0, this); } public func SetHotkey(int num) { if(num < 0 || num > 9) { - SetGraphics(nil,nil,12); + SetGraphics(nil,nil,GUI_CS_Hotkey); hotkey = false; return; } + var kx = 1000 * GetDefWidth()/2 - 10000; + var ky = -1000 * GetDefWidth()/2 + 10000; + hotkey = true; var name = Format("%d",num); - SetGraphics(name,Icon_Number,12,GFXOV_MODE_IngamePicture); - SetObjDrawTransform(300,0,1000*GetDefWidth()/4,0,300,-1000*GetDefWidth()/4, 12); - SetClrModulation(HSL(0,0,180),12); + SetGraphics(name,Icon_Number,GUI_CS_Hotkey,GFXOV_MODE_IngamePicture); + SetObjDrawTransform(300,0,kx,0,300,ky, GUI_CS_Hotkey); + SetClrModulation(HSL(0,0,180),GUI_CS_Hotkey); } public func CrewGone() @@ -139,7 +170,8 @@ public func UpdateController() SetOwner(crew->GetController()); // name var fullname = Format("%s %s",crew->GetObjCoreRankName(),crew->GetName()); - SetName(Format("$TxtSelect$",fullname)); + SetName(crew->GetName()); + this.Tooltip = Format("$TxtSelect$",fullname); } public func UpdateSelectionStatus() @@ -149,11 +181,11 @@ public func UpdateSelectionStatus() if(crew == GetCursor(crew->GetOwner())) { - SetObjDrawTransform(1200,0,0,0,1200,0, 1); + SetObjDrawTransform(1100,0,0,0,1100,0, GUI_CS_Title); } else { - SetObjDrawTransform(900,0,0,0,900,0, 1); + SetObjDrawTransform(800,0,0,0,800,0, GUI_CS_Title); } } @@ -161,11 +193,11 @@ public func UpdateRank() { if(!crew) return; - var rankx = -1000 * GetDefWidth()/2 + 10000; - var ranky = -15000; + var rankx = -1000 * GetDefWidth()/2 + 12000; + var ranky = -13000; - SetGraphics(nil,0,10,GFXOV_MODE_Rank,0,0,crew); - SetObjDrawTransform(1000,0,rankx,0,1000,ranky, 10); + SetGraphics(nil,nil,GUI_CS_Rank,GFXOV_MODE_Rank,nil,0,crew); + SetObjDrawTransform(1000,0,rankx,0,1000,ranky, GUI_CS_Rank); } public func UpdateTitleGraphic() @@ -174,7 +206,7 @@ public func UpdateTitleGraphic() //SetGraphics(nil,crew->GetID(),1,GFXOV_MODE_Object,nil,nil,crew); - SetGraphics(nil,crew->GetID(),1,GFXOV_MODE_ObjectPicture, 0, 0, crew); + SetGraphics(nil,crew->GetID(),GUI_CS_Title,GFXOV_MODE_ObjectPicture, nil, 0, crew); // doesn't work: //SetColorDw(crew->GetColorDw()); @@ -199,7 +231,7 @@ public func UpdateBreathBar() if(!crew) return; var phys = crew->GetMaxBreath(); var promille; - if(phys == 0) promille = 0; + if(!phys) promille = 0; else promille = 1000 * crew->GetBreath() / phys; // remove breath bar if full breath @@ -215,6 +247,10 @@ public func UpdateBreathBar() AddBreathBar(); SetBarProgress(promille,1); + var clr = GetAverageTextureColor(crew->GetTexture(0,0)); + + SetClrModulation(clr, GUI_CS_BreathBG); + //SetClrModulation(255-(1000-promille)*76/1000), GUI_CS_BreathBG); } } @@ -264,17 +300,21 @@ private func AddBreathBar() if(magicbar) num = 2; // breath bar - SetBarLayers(4,1); + SetBarLayers(GUI_CS_BreathBar,1); SetBarOffset(0,BarOffset(num),1); SetBarDimensions(GetDefWidth(),BreathBarHeight(),1); - SetClrModulation(RGB(0,200,200),5); + SetClrModulation(RGB(0,200,200),GUI_CS_BreathText); breathbar = true; + + // also enable background-coloring + SetGraphics("Background", GUI_CrewSelector, GUI_CS_BreathBG, GFXOV_MODE_Base); } private func RemoveBreathBar() { - RemoveBarLayers(4); + RemoveBarLayers(GUI_CS_BreathBar); + SetGraphics(nil, nil, GUI_CS_BreathBG); breathbar = false; @@ -285,10 +325,10 @@ private func RemoveBreathBar() private func AddMagicBar() { - SetBarLayers(6,2); + SetBarLayers(GUI_CS_SpecialBar,2); SetBarOffset(0,BarOffset(1),2); SetBarDimensions(GetDefWidth(),MagicBarHeight(),2); - SetClrModulation(RGB(0,0,200),7); + SetClrModulation(RGB(0,0,200),GUI_CS_SpecialText); magicbar = true; @@ -299,7 +339,115 @@ private func AddMagicBar() private func RemoveMagicBar() { - RemoveBarLayers(6); + RemoveBarLayers(GUI_CS_SpecialBar); magicbar = false; } + + +// highlight +public func OnMouseOver(int plr) +{ + if(GetOwner() != plr) + return nil; + + SetGraphics("Focussed", GUI_CrewSelector); +} + +public func OnMouseOut(int plr) +{ + if(GetOwner() != plr) + return nil; + + SetGraphics(nil, nil); +} + +public func FxGUIHealthMonitorDamage(object target, proplist effect, int damage, int cause) +{ + var change = Abs(damage)/((target->GetMaxEnergy()*10) || 1); + // for really small changes, like fire or higher precision DoEnergy + if(change == 0) + change = 3; + + //if(!GetEffect("GUIHealthMonitorWorker", this)) + if(!effect.worker) + { + effect.worker = AddEffect("GUIHealthMonitorWorker", target, 150, 4, this); + effect.worker.intensity = change+20; + } + else + effect.worker.intensity += change; + + effect.worker.intensity = BoundBy(effect.worker.intensity, 0, 80); + + // heal + if(damage > 0) + effect.worker.type = 1; + // damage + else + effect.worker.type = 0; + + // fire + if(cause == FX_Call_DmgFire || cause == FX_Call_EngFire) + effect.worker.type = 2; + + + return damage; +} + +public func FxGUIHealthMonitorWorkerStart(object target, proplist effect, bool tmp) +{ + if(tmp) return; + + SetGraphics("Hurt", GUI_CrewSelector, GUI_CS_HealthBG, GFXOV_MODE_Base, nil, GFX_BLIT_Additive); + EffectCall(target, effect, "Timer"); +} + +public func FxGUIHealthMonitorWorkerTimer(object target, proplist effect, int time) +{ + // do graphical effect + var a = BoundBy(effect.intensity*7, 20, 255); + // damage + if(effect.type == 0) + { + var r = Min(200 + effect.intensity, 255); + SetClrModulation(RGBa(r,0,0,a), GUI_CS_HealthBG); + } + // heal + else if(effect.type == 1) + { + var g = Min(100 + effect.intensity, 255); + a = Min(a+100, 255); + SetClrModulation(RGBa(50,g,50,a), GUI_CS_HealthBG); + } + // fire! + else if(effect.type == 2) + { + var r = Min(150 + effect.intensity, 255); + var g = Min(effect.intensity, 100); + a = Min(a+100, 255); + SetClrModulation(RGBa(r,g,0,a), GUI_CS_HealthBG); + } + // not set yet? might happen at the start sometimes. we just hide in that case. + else + SetClrModulation(RGBa(0,0,0,0), GUI_CS_HealthBG); + + var dec = 3; + + // fade faster if huge numbers + if(effect.intensity > 60) + dec += 2; + + effect.intensity = effect.intensity-dec; + + // we're done, remove effect + if(effect.intensity <= 0) + return -1; +} + +public func FxGUIHealthMonitorWorkerStop(object target, proplist effect, int reason, bool tmp) +{ + if(tmp) return; + + SetGraphics(nil, nil, GUI_CS_HealthBG); +} diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/DefCore.txt deleted file mode 100644 index 3e3800910..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/DefCore.txt +++ /dev/null @@ -1,7 +0,0 @@ -[DefCore] -id=GUI_Lock_Button -Version=5,2,0,1 -Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax | C4D_MouseSelect -Width=32 -Height=32 -Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/Graphics.png deleted file mode 100644 index a731c56aa..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/GraphicsReleased.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/GraphicsReleased.png deleted file mode 100644 index f900358b0..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/GraphicsReleased.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/Script.c deleted file mode 100644 index 0e2d2af6a..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/Script.c +++ /dev/null @@ -1,81 +0,0 @@ -/** - ExpandButton - Locks/Unlocks the inventory bar. - - @author boni -*/ - -local Name = "$Name$"; -local Description = "$Description$"; - -local locked; -local controller; - -public func SetHUDController(object c) { controller = c; } -public func IsLocked() { return locked; } - -public func Initialize() -{ - // Lock-Buttons need an owner for extradata - var owner = GetOwner(); - if(owner == NO_OWNER) - return; - - // Visibility - this.Visibility = VIS_Owner; - // Parallaxity - this.Parallaxity = [0, 0]; - - locked = GetPlrExtraData(owner, "Inventory_Lock"); - if(locked == nil) - locked = true; - if(!locked) - SetGraphics("Released", GetID()); -} - -public func MouseSelection(int plr) -{ - // we need a controller to report back to - if(!controller) - return nil; - if(plr != GetOwner()) - return nil; - - if(locked) - Unlock(); - else - Lock(); -} - -public func Lock() -{ - if(!controller || GetOwner() == NO_OWNER) - return nil; - - locked = true; - - // tell controller to do its stuff - controller->ShowInventory(); - - // update graphics - SetGraphics(nil, GetID()); - - // and save the result. - SetPlrExtraData(GetOwner(), "Inventory_Lock", true); -} - -public func Unlock() -{ - if(!controller || GetOwner() == NO_OWNER) - return nil; - - locked = false; - - // tell controller to do its stuff - controller->ScheduleHideInventory(); - - // update graphics - SetGraphics("Released", GetID()); - - SetPlrExtraData(GetOwner(), "Inventory_Lock", false); -} diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/StringTblDE.txt deleted file mode 100644 index a6c14c3c5..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=LockButton -Description=Sperrt/Entsperrt die Inventar-Leiste \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/StringTblUS.txt deleted file mode 100644 index 74a00a3a9..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/LockButton.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=LockButton -Description=Locks/Unlocks the inventory bar. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Marker.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Marker.ocd/Script.c index 89ea5bb3a..24298b9f8 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Marker.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Marker.ocd/Script.c @@ -41,7 +41,7 @@ protected func Construction() // visibility this["Visibility"] = VIS_Owner; - SetGraphics(0,GetID(),2,GFXOV_MODE_Base); + SetGraphics(nil,GetID(),2,GFXOV_MODE_Base); SetGraphics("",GUI_Controller,0); SetGraphics("Line",GetID(),1,GFXOV_MODE_Base); SetObjDrawTransform(1000,0,-225*100,0,1000,0,1); @@ -59,7 +59,7 @@ public func SetVisual(picture, altpicture) { if (GetType(picture) == C4V_C4Object) { - SetGraphics(nil, nil, 10, GFXOV_MODE_ObjectPicture, 0, 0, picture); + SetGraphics(nil, nil, 10, GFXOV_MODE_ObjectPicture, nil, 0, picture); SetObjDrawTransform(780, 0, 0, 0, 780, 0, 10); if (picture->~HasExtraSlot()) { @@ -68,7 +68,7 @@ public func SetVisual(picture, altpicture) var content = picture->Contents(0); if (content) { - SetGraphics(nil, nil, 12, GFXOV_MODE_ObjectPicture, 0, 0, content); + SetGraphics(nil, nil, 12, GFXOV_MODE_ObjectPicture, nil, 0, content); SetObjDrawTransform(1500/3, 0, 16*780, 0, 1500/3, 16*780, 12); } else diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/ExtraSlot.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/ExtraSlot.ocd/Script.c index 855c0df2f..09349de89 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/ExtraSlot.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/ExtraSlot.ocd/Script.c @@ -26,7 +26,8 @@ public func MouseSelectionAlt(int plr) { if(!myobject) return; - var desc = myobject->GetProperty("Description"); + var desc = myobject.UsageHelp; + if(!desc) desc = myobject.Description; // fall back to general description // close other messages... crew->OnDisplayInfoMessage(); @@ -110,7 +111,7 @@ public func SetObject(object obj) } else { - SetGraphics(nil,nil,1,GFXOV_MODE_ObjectPicture,0,0,myobject); + SetGraphics(nil,nil,1,GFXOV_MODE_ObjectPicture,nil,0,myobject); this.MouseDragImage = myobject; SetName(myobject->GetName()); diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/Script.c index a62ab9fce..3b226dbdd 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/ObjectSelector.ocd/Script.c @@ -26,13 +26,14 @@ */ -local selected, crew, hotkey, myobject, actiontype, subselector, position; +local selected, crew, hotkey, myobject, actiontype, subselector, position, modus; +local extra; // function to call and desc for extra-types static const ACTIONTYPE_INVENTORY = 0; static const ACTIONTYPE_VEHICLE = 1; static const ACTIONTYPE_STRUCTURE = 2; static const ACTIONTYPE_SCRIPT = 3; -static const ACTIONTYPE_CARRYHEAVY = 3; +static const ACTIONTYPE_EXTRA = 4; private func HandSize() { return 400; } private func IconSize() { return 500; } @@ -69,7 +70,8 @@ public func MouseSelectionAlt(int plr) { if(!myobject) return; - var desc = myobject->GetProperty("Description"); + var desc = myobject.UsageHelp; + if(!desc) desc = myobject.Description; // fall back to general description // close other messages... crew->OnDisplayInfoMessage(); @@ -140,14 +142,14 @@ public func MouseSelection(int plr) { if(myobject->~IsInteractable(crew)) { - myobject->Interact(crew); + myobject->Interact(crew, modus); return true; } } - if(actiontype == ACTIONTYPE_CARRYHEAVY) + if(actiontype == ACTIONTYPE_EXTRA) { - if(myobject == crew->~GetCarryHeavy()) - myobject->Drop(); + if(extra) + extra.Object->Call(extra.Fn, crew); } } @@ -258,7 +260,7 @@ public func OnMouseDrop(int plr, obj) -public func Clear() +public func Disable() { myobject = nil; actiontype = -1; @@ -276,7 +278,7 @@ public func ClearMessage() CustomMessage("",subselector,GetOwner()); } -public func SetObject(object obj, int type, int pos, int hot) +public func SetObject(object obj, int type, int pos, int hot, int number, proplist xtra) { this.Visibility = VIS_Owner; @@ -289,6 +291,13 @@ public func SetObject(object obj, int type, int pos, int hot) actiontype = type; myobject = obj; hotkey = hot; + modus = number; + + // extra stuff + if(xtra) + extra = xtra; + else + extra = nil; // Set mousedrag for inventory objects if (actiontype == ACTIONTYPE_INVENTORY) @@ -305,8 +314,8 @@ public func SetObject(object obj, int type, int pos, int hot) } else { - SetGraphics("Slot", GUI_Background); - SetGraphics(nil,nil,1,GFXOV_MODE_ObjectPicture, 0, 0, myobject); + SetGraphics("Slot", GUI_ObjectSelector); + SetGraphics(nil,nil,1,GFXOV_MODE_ObjectPicture, nil, 0, myobject); SetName(Format("$TxtSelect$",myobject->GetName())); this.MouseDragImage = myobject; @@ -392,23 +401,26 @@ public func UpdateSelectionStatus() // determine... var sel = 0; - if(actiontype == ACTIONTYPE_CARRYHEAVY) + if(actiontype == ACTIONTYPE_EXTRA) { - SetGraphics("LetGo",GetID(),2,GFXOV_MODE_Base); - SetName(Format("$TxtUnGrab$",myobject->GetName())); + if(extra) + { + SetGraphics(extra.IconName,extra.IconID,2,GFXOV_MODE_IngamePicture); + this.Tooltip = extra.Description; + } } // script... else if(actiontype == ACTIONTYPE_SCRIPT) { - var metainfo = myobject->~GetInteractionMetaInfo(crew); + var metainfo = myobject->~GetInteractionMetaInfo(crew, modus); if(metainfo) { SetGraphics(metainfo["IconName"],metainfo["IconID"],2,GFXOV_MODE_IngamePicture); SetObjDrawTransform(IconSize(),0,-16000,0,IconSize(),20000, 2); var desc = metainfo["Description"]; - if(desc) SetName(desc); + if(desc) this.Tooltip = desc; if(metainfo["Selected"]) SetObjDrawTransform(1200,0,0,0,1200,0,1); @@ -444,12 +456,12 @@ public func UpdateSelectionStatus() if(actiontype == ACTIONTYPE_VEHICLE) { SetGraphics("LetGo",GetID(),2,GFXOV_MODE_Base); - SetName(Format("$TxtUnGrab$",myobject->GetName())); + this.Tooltip = Format("$TxtUnGrab$",myobject->GetName()); } else if(actiontype == ACTIONTYPE_STRUCTURE) { SetGraphics("Exit",GetID(),2,GFXOV_MODE_Base); - SetName(Format("$TxtExit$",myobject->GetName())); + this.Tooltip = Format("$TxtExit$",myobject->GetName()); } } else @@ -465,18 +477,18 @@ public func UpdateSelectionStatus() if(!(myobject->Contained())) { SetGraphics("Grab",GetID(),2,GFXOV_MODE_Base); - SetName(Format("$TxtGrab$",myobject->GetName())); + this.Tooltip = Format("$TxtGrab$",myobject->GetName()); } else { SetGraphics("Exit",GetID(),2,GFXOV_MODE_Base); - SetName(Format("$TxtPushOut$",myobject->GetName())); + this.Tooltip = Format("$TxtPushOut$",myobject->GetName()); } } if(actiontype == ACTIONTYPE_STRUCTURE) { SetGraphics("Enter",GetID(),2,GFXOV_MODE_Base); - SetName(Format("$TxtEnter$",myobject->GetName())); + this.Tooltip = Format("$TxtEnter$",myobject->GetName()); } } SetObjDrawTransform(IconSize(),0,-16000,0,IconSize(),20000, 2); diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/DefCore.txt deleted file mode 100644 index cc53c6a44..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=GUI_BreathTube -Version=5,2,0,1 -Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax -Width=500 -Height=250 -Offset=-250,-248 -Rotate=1 diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/Graphics.png deleted file mode 100644 index e84cc6441..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/GraphicsBack.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/GraphicsBack.png deleted file mode 100644 index 954076f80..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/GraphicsBack.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/GraphicsFront.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/GraphicsFront.png deleted file mode 100644 index 459886bb8..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/GraphicsFront.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/Script.c deleted file mode 100644 index 1f94bf56e..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/Script.c +++ /dev/null @@ -1,169 +0,0 @@ -/** - Breath Tube - Displays the breath of the controlled clonk in the HUD. - - @authors Mimmo_O, Clonkonaut -*/ - -// Current crew and breath -local crew; -// Store additional tubes. -local btube, ftube; - -protected func Initialize() -{ - // Set parallaxity - this.Parallaxity = [0, 0]; - // Set visibility - this.Visibility = VIS_Owner; - return; -} - -public func MakeTube() -{ - // Action and position. - SetPosition(1, -1); - SetAction("Swirl"); - - // Store crew. - crew = GetCursor(GetOwner()); - - // Add additional tubes. - //btube = CreateObject(GUI_HealthTube); - //btube->SetPosition(1,-1); - //btube->SetGraphics("Back"); - - ftube = CreateObject(GUI_BreathTube); - ftube->SetPosition(1, -1); - ftube->SetGraphics("Front"); - - // Hide tube. - UpdateTube(1000); - HideTube(); - return; -} - -protected func Destruction() -{ - // Remove additional tubes. - if (btube) - btube->RemoveObject(); - if (ftube) - ftube->RemoveObject(); - return; -} - -public func Update() -{ - // Add update on cursor. - if (!GetEffect("UpdateTube", this)) - AddEffect("UpdateTube", this, 100, 1, this); - return; -} - -protected func FxUpdateTubeStart(object target, proplist effect, int temporary) -{ - if (temporary != 0) - return 1; - - // Don't do anything if breath is full - crew = GetCursor(); - if (!crew) - return -1; - if (crew->GetBreath() == crew->GetMaxBreath()) - return -1; - - // Load breath tube. - LoadTube(); - - return 1; -} - -protected func FxUpdateTubeTimer(object target, proplist effect, int time) -{ - crew = GetCursor(); - if (!crew) - { - HideTube(); - return -1; - } - - if (!crew->GetMaxBreath()) - { - HideTube(); - return -1; - } - - var breath = crew->GetBreath(); - var promille = 1000 * breath / crew->GetMaxBreath(); - UpdateTube(promille); - - // Full breath: remove effect and tube. - if (breath == crew->GetMaxBreath()) - { - FadeTube(); - return -1; - } - - return 1; -} - -private func UpdateTube(int promille) -{ - var rot = - 210 - 69 * promille / 100; - var fsin = Sin(rot, 1000, 10); - var fcos = Cos(rot, 1000, 10); - // Rotate via draw transform. - SetObjDrawTransform (+fcos, +fsin, 0, -fsin, +fcos, 0); - return; -} - -private func LoadTube() -{ - SetR(0); - if (btube) btube->SetR(0); - if (ftube) ftube->SetR(0); - return; -} - -private func HideTube() -{ - SetR(110); - if (btube) btube->SetR(110); - if (ftube) ftube->SetR(110); - return; -} - -private func FadeTube() -{ - AddEffect("FadeTube", this, 100, 1, this); - return; -} - -protected func FxFadeTubeTimer(object target, proplist effect, int time) -{ - var rot = GetR() + 10; - // Rotate tubes. - SetR(rot); - if (btube) btube->SetR(rot); - if (ftube) ftube->SetR(rot); - // Stop effect if done. - if (rot >= 110) - return -1; - return 1; -} - -local ActMap = { - Swirl = { - Prototype = Action, - Name = "Swirl", - Procedure = DFA_NONE, - Length = 25, - Delay = 2, - X = 0, - Y = 0, - Wdt = 500, - Hgt = 250, - NextAction = "Swirl", - }, -}; diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/StringTblDE.txt deleted file mode 100644 index 5ce936a02..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Atemsanzeige - diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/StringTblUS.txt deleted file mode 100644 index 00fa1e68e..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/BreathTube.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Breathe Bar - diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/DefCore.txt deleted file mode 100644 index 377db0b9c..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=GUI_HealthTube -Version=5,2,0,1 -Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax -Width=450 -Height=225 -Offset=-225,-224 -Rotate=1 diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/Graphics.png deleted file mode 100644 index 00d22e6f3..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/GraphicsBack.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/GraphicsBack.png deleted file mode 100644 index 61dca63eb..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/GraphicsBack.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/GraphicsFront.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/GraphicsFront.png deleted file mode 100644 index e714cbaf9..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/GraphicsFront.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/Script.c deleted file mode 100644 index f17e125e8..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/Script.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - Health Tube - Displays the health of the controlled clonk in the HUD. - - @authors Mimmo_O, Clonkonaut -*/ - - -// Current crew and energy -local crew, energy; -// Store additional tubes. -local btube, ftube; - -protected func Initialize() -{ - // Set parallaxity - this.Parallaxity = [0, 0]; - // Set visibility - this.Visibility = VIS_Owner; - return; -} - -public func MakeTube() -{ - // Action and position. - SetPosition(1, -1); - SetAction("Swirl"); - - // Store crew and current energy. - crew = GetCursor(GetOwner()); - if (crew) - energy = crew->GetEnergy(); - - // Add additional tubes. - btube = CreateObject(GUI_HealthTube); - btube->SetPosition(1,-1); - btube->SetGraphics("Back"); - - ftube = CreateObject(GUI_HealthTube); - ftube->SetPosition(1,-1); - ftube->SetGraphics("Front"); - return; -} - -protected func Destruction() -{ - // Remove additional tubes. - if (btube) - btube->RemoveObject(); - if (ftube) - ftube->RemoveObject(); - return; -} - -public func Update() -{ - var cursor = GetCursor(GetOwner()); - if (!cursor) - return; - if (crew != cursor) - { - // New clonk. - crew = cursor; - energy = crew->GetEnergy(); - if (!crew->GetMaxEnergy()) - return; - var promille = 1000 * energy / crew->GetMaxEnergy(); - UpdateTube(promille); - UpdateNumber(); - RemoveEffect("UpdateTube", this); - } - // Update on existing clonk. - if (!GetEffect("UpdateTube", this)) - AddEffect("UpdateTube", this, 100, 1, this); - return; -} - -protected func FxUpdateTubeTimer(object target, proplist effect, int time) -{ - if (!crew->GetMaxEnergy()) - return -1; - - if (energy == crew->GetEnergy()) - return -1; - - if (Abs(energy - crew->GetEnergy()) > 6 ) - if (energy > crew->GetEnergy()) - energy -= 3; - else - energy += 3; - else - if (energy > crew->GetEnergy()) - energy -= 1; - else - energy += 1; - - var promille = 1000 * energy / crew->GetMaxEnergy(); - UpdateTube(promille); - UpdateNumber(); - - return 1; -} - -private func UpdateNumber() -{ - CustomMessage(Format("@%d", energy), this, GetOwner(), 16, -72); - return; -} - -private func UpdateTube(int promille) -{ - var rot = - 210 - 69 * promille / 100; - var fsin = Sin(rot, 1000, 10); - var fcos = Cos(rot, 1000, 10); - // Rotate via draw transform. - SetObjDrawTransform (+fcos, +fsin, 0, -fsin, +fcos, 0); - return; -} - -local ActMap = { - Swirl = { - Prototype = Action, - Name = "Swirl", - Procedure = DFA_NONE, - Length = 25, - Delay = 3, - X = 0, - Y = 0, - Wdt = 450, - Hgt = 225, - NextAction = "Swirl", - }, -}; - - diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/StringTblDE.txt deleted file mode 100644 index 4f8a0b781..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Lebensanzeige diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/StringTblUS.txt deleted file mode 100644 index d41ec0ac4..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/HealthTube.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Life Bar diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/DefCore.txt deleted file mode 100644 index 1da9f5667..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=GUI_ManaTube -Version=5,2,0,1 -Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax -Width=400 -Height=200 -Offset=-200,-199 -Rotate=1 diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Graphics.png deleted file mode 100644 index 058c1356f..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Graphics2.png b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Graphics2.png deleted file mode 100644 index 5c0b44180..000000000 Binary files a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Graphics2.png and /dev/null differ diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Script.c deleted file mode 100644 index efa8962f5..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/Script.c +++ /dev/null @@ -1,143 +0,0 @@ -/** - Mana Tube - Displays the mana of the controlled clonk in the HUD. - - @authors Mimmo_O -*/ - -local current; -local visual; -local btub,ftub; -local crew; - -protected func Initialize() -{ - // Set parallaxity - this.Parallaxity = [0, 0]; - // Set visibility - this.Visibility = VIS_Owner; - visual = 0; - return; -} - - -public func FxUpdateTimer() { Update(); } - -public func Update() -{ - - if(!GetCursor(GetOwner())) return 1; - - if(GetCursor(GetOwner()) != crew) - { - crew = GetCursor(GetOwner()); - current = GetCursor(GetOwner())->GetBreath(); - if(current != crew->GetMaxBreath()) - for(var i=0; i<11; i++) - InstantFadeIn(); - else - for(var i=0; i<36; i++) - InstantFadeOut(); - var r = -210 - ((( current * 1000) / crew->GetMaxBreath()) * 69) / 100; - var fsin=Sin(r, 1000,10), fcos=Cos(r, 1000,10); - // set matrix values - SetObjDrawTransform ( - +fcos, +fsin, 0, - -fsin, +fcos, 0 - ); - } - if(current == crew->GetMaxBreath() && crew->GetAction()!="Swim") - { - FadeOut(); - } - else if(visual>-36) FadeIn(); - - if(Abs(current - crew->GetBreath())) current+=BoundBy(crew->GetBreath()-current,-1,7); - if(visual<0) - CustomMessage(Format("%v",current),ftub,crew->GetOwner(),16,-63); - else - CustomMessage("",this,crew->GetOwner()); - var r = -210 - ((( current * 1000) / crew->GetMaxBreath()) * 69) / 100; - var fsin=Sin(r, 1000,10), fcos=Cos(r, 1000,10); - // set matrix values - SetObjDrawTransform ( - +fcos, +fsin, 0, - -fsin, +fcos, 0 - ); -} - -public func SetTubes(b) -{ -//btub=a; -ftub=b; -} - -public func FadeOut() -{ - if(visual>11) return ; - visual++; - if(visual<1) return; - SetR(GetR()+10); - //btub->SetR(btub->GetR()+10); - ftub->SetR(ftub->GetR()+10); - - return ; -} -public func FadeIn() -{ - if(visual>-36) visual--; - if(visual<0) return ; - SetR(GetR()-10); - //btub->SetR(btub->GetR()-10); - ftub->SetR(ftub->GetR()-10); - - return ; -} - -public func InstantFadeOut() -{ - visual=11; - SetR(110); - //btub->SetR(110); - ftub->SetR(110); - return ; -} - -public func InstantFadeIn() -{ - visual=-36; - SetR(0); - //btub->SetR(0); - ftub->SetR(0); - return ; -} - -public func MakeHolders() -{ - CreateObject(GetID(),GetX(),GetY())->MakeTop(); -} - -public func MakeTop() -{ - SetGraphics("2"); -} - -public func MakeBot() -{ - SetGraphics("1"); -} - -local ActMap = { - Swirl = { - Prototype = Action, - Name = "Swirl", - Procedure = DFA_NONE, - Length = 25, - Delay = 3, - X = 0, - Y = 0, - Wdt = 400, - Hgt = 220, - NextAction = "Swirl", - }, -}; diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/StringTblDE.txt deleted file mode 100644 index 1ee9dc842..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Manaanzeige - diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/StringTblUS.txt deleted file mode 100644 index 13ef18d97..000000000 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Tubes.ocd/ManaTube.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Mana Bar diff --git a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Wealth.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Wealth.ocd/Script.c index dc7f29ac9..0e5145afc 100644 --- a/planet/Objects.ocd/HUD.ocd/Elements.ocd/Wealth.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Elements.ocd/Wealth.ocd/Script.c @@ -21,12 +21,11 @@ public func Update() // Display wealth via text. CustomMessage(Format("@%d", wealth), this, plr, 0, 90); // Display wealth via graphics. - var num; - if (wealth < 180) num = 4; - if (wealth < 120) num = 3; - if (wealth < 70) num = 2; - if (wealth < 30) num = 1; - if (wealth < 10) num = 0; + var num = 0; + if (wealth >= 10) num = 1; + if (wealth >= 30) num = 2; + if (wealth >= 70) num = 3; + if (wealth >= 120) num = 4; SetGraphics(Format("%d", num)); return; } diff --git a/planet/Objects.ocd/HUD.ocd/GridMenu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/GridMenu.ocd/Script.c index 35bb45cfc..037a6b74c 100644 --- a/planet/Objects.ocd/HUD.ocd/GridMenu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/GridMenu.ocd/Script.c @@ -26,6 +26,9 @@ public func SetMenuSpacing(int distance) { menu_spacing = distance; } /** Sets the distance from the outer edges to the outer objects */ public func SetMenuBorder(int distance) { menu_border = distance; } +/** Sets the background color of the menu */ +public func SetBackgroundColor(int rgb) { SetClrModulation(rgb, 1); } + public func Construction() { rowitemcount = nil; @@ -52,7 +55,8 @@ public func UpdateMenu() if(ric == nil) { // we use the square root to get a square layout! trololo! - ric = Sqrt(itemcount); + // must not be 0 + ric = Max(1, Sqrt(itemcount)); rc = ric; if(itemcount > rc*rc) ric += 1; diff --git a/planet/Objects.ocd/HUD.ocd/Menu.ocd/MenuItem.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Menu.ocd/MenuItem.ocd/Script.c index 3fdc9b304..39e2eb880 100644 --- a/planet/Objects.ocd/HUD.ocd/Menu.ocd/MenuItem.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Menu.ocd/MenuItem.ocd/Script.c @@ -174,6 +174,10 @@ public func Update() // Update item amount. UpdateCount(); + + // Update tooltip + UpdateTooltip(); + return; } @@ -189,7 +193,7 @@ private func UpdateSymbol() { if (GetType(item_object) == C4V_C4Object) { - SetGraphics(nil, nil, 1, GFXOV_MODE_ObjectPicture, 0, 0, item_object); + SetGraphics(nil, nil, 1, GFXOV_MODE_ObjectPicture, nil, 0, item_object); if (item_object->~HasExtraSlot()) { SetGraphics(nil, GUI_ExtraSlot, 2, GFXOV_MODE_Base); @@ -197,7 +201,7 @@ private func UpdateSymbol() var content = item_object->Contents(0); if (content) { - SetGraphics(nil, nil, 3, GFXOV_MODE_ObjectPicture, 0, 0, content); + SetGraphics(nil, nil, 3, GFXOV_MODE_ObjectPicture, nil, 0, content); SetObjDrawTransform(1000/3, 0, 16000, 0, 1000/3, 16000, 3); } else @@ -262,3 +266,13 @@ private func UpdateCount() } return; } + +private func UpdateTooltip() +{ + if(!item_object) + this.Tooltip = nil; + else + { + this.Tooltip = item_object.Description; + } +} diff --git a/planet/Objects.ocd/HUD.ocd/Menu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Menu.ocd/Script.c index e569e63fc..35e6e67f6 100644 --- a/planet/Objects.ocd/HUD.ocd/Menu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Menu.ocd/Script.c @@ -34,8 +34,10 @@ protected func Construction() return; } +/** Returns whether drag and drop is enabled for this menu */ public func IsDragDropMenu() { return menu_isdragdrop; } +/** Sets whether drag and drop is enabled for this menu */ public func SetDragDropMenu(bool is_dragdrop) { menu_isdragdrop = is_dragdrop; @@ -44,27 +46,27 @@ public func SetDragDropMenu(bool is_dragdrop) return; } -// Sets the commander of this menu. +/** Sets the commander object of this menu. */ public func SetCommander(object commander) { menu_commander = commander; return; } -// Returns the commander of this menu. +/** Returns the commander object of this menu. */ public func GetCommander() { return menu_commander; } -// Sets the menu object for this menu. +/** Sets the object for which the menu is shown. */ public func SetMenuObject(object menuobject) { menu_object = menuobject; return; } -// Returns the menu object for this menu. +/** Returns the menu object for this menu. **/ public func GetMenuObject() { return menu_object; @@ -138,18 +140,41 @@ public func GetItems() */ public func RemoveItem(object item) { - for (var mitem in menu_items) + var length = GetLength(menu_items); + for(var i = 0; i < length; i++) { - if (mitem = item) - mitem->RemoveObject(); + if (menu_items[i] == item) + { + menu_items[i]->RemoveObject(); + break; + } } + // close gap + for(; i < length-1; i++) + menu_items[i] = menu_items[i+1]; + + SetLength(menu_items, length-1); + UpdateMenu(); return; } +/** Removes all items from the menu. */ +public func Clear() +{ + for (var mitem in menu_items) + { + mitem->RemoveObject(); + } + menu_items = []; + UpdateMenu(); + return; +} + + /* Callbacks from the menu items, to be forwarded to the commander. */ -// Called when an item has been selected (left mouse button). +/** Called when an item has been selected (left mouse button). **/ public func OnItemSelection(object item) { if (!menu_commander) @@ -158,7 +183,7 @@ public func OnItemSelection(object item) return menu_commander->~OnItemSelection(this, item); } -// Called when an item has been selected (right mouse button). +/** Called when an item has been selected (right mouse button). **/ public func OnItemSelectionAlt(object item) { if (!menu_commander) @@ -167,7 +192,7 @@ public func OnItemSelectionAlt(object item) return menu_commander->~OnItemSelectionAlt(this, item); } -// Called when an object is dragged onto the menu +/** Called when an object is dragged onto the menu **/ public func OnMouseDrop(int plr, obj) { // Check if the owners match. @@ -183,7 +208,7 @@ public func OnMouseDrop(int plr, obj) return menu_commander->~OnItemDropped(this, obj, nil); } -// Shows the menu. +/** Shows the menu. */ public func Show() { UpdateMenu(); @@ -196,6 +221,7 @@ public func Show() return; } +/** Hides the menu. */ public func Hide() { // Change visibility. @@ -208,6 +234,13 @@ public func Hide() return; } +public func Close() +{ + if(menu_object) + menu_object->~MenuClosed(this); + RemoveObject(); +} + // Engine callback: if the menu is destroyed, the items must follow. protected func Destruction() { diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..2aef1c30e --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_BarProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=8 +Height=8 +Offset=-4,-4 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/Graphics.4.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/Graphics.4.png new file mode 100644 index 000000000..aaafe3f6f Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/Script.c new file mode 100644 index 000000000..325a06df0 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/Script.c @@ -0,0 +1,223 @@ +/** + BarProgressBar + Shows progress. + Can also show a custom ID. + + additional data the bar takes through the "data" parameter: + bars: number of bars + color: color of filled bars + back_color: color of empty bars + graphics_name: graphics name of filled bars + back_graphics_name: graphics name of empty bars + size: size of the bar 1000 = 100% + image: id to use as bar graphics + fade_speed: after the time-out the bar starts to fade, this can specify the speed. standard: 5 +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +local maximum, current, timeout_time; +local bars; +local color, back_color, number_of_bars, size; +local graphics_name, back_graphics_name; +local image, fade_speed; + +local current_clr; +local active_overlay; + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; + + +func BarID() +{ + return GetID(); +} + +func Init(to, max, cur, timeout, offset, visibility, data) +{ + maximum = max; + current = cur; + timeout_time = timeout; + + bars = []; + + number_of_bars = data.bars ?? 10; + + graphics_name = data.graphics_name; + back_graphics_name = data.back_graphics_name; + color = data.color; + back_color = data.back_color; + + if(!color) + { + if(graphics_name) + color = RGB(255,255,255); + else + color = RGB(1, 255, 1); + } + if(!back_color) + { + if(back_graphics_name) + back_color = RGB(255,255,255); + else + back_color = RGBa(1, 1, 1, 150); + } + + size = data.size ?? 1000; + image = data.image ?? nil; + fade_speed = data.fade_speed ?? 5; + + if(timeout_time) + { + var e = AddEffect("TimeOut", this, 1, 5, this); + e.t = timeout_time; + } + + bars[0] = this; + + for(var i = 1; i < number_of_bars; ++i) + { + bars[i] = CreateObject(GetID(), 0, 0, GetOwner()); + } + + var cnt = 0; + for(var obj in bars) + { + if(image != nil) + { + obj->SetObjDrawTransform(1, 0, 0, 0, 1); // deactivate overlay 0 + obj->SetGraphics(nil, image, 1, GFXOV_MODE_IngamePicture, nil, nil); + obj.active_overlay = 1; + } + obj->Set(to, cnt, number_of_bars, size, offset, visibility); + ++cnt; + } + + AddEffect("LifeCheck", to, 1, 0, this); + Update(); +} + +func FxLifeCheckStop(target, effect, cause, temp) +{ + if(temp) return; + if(this) + this->RemoveObject(); +} + +func FxTimeOutTimer(target, effect, time) +{ + effect.t -= effect.Interval; + if(effect.t > 0) return 1; + var a = 255 - fade_speed * Abs(effect.t); + if(a <= 20) {Close(); return -1;} + else SetFade(a); + + return 1; +} + +func Update() +{ + var l = GetLength(bars); + var p = (current * 100) / maximum; + var last_colored = (l * p) / 100; + + + for(var i = 0; i < l; ++i) + { + var obj = bars[i]; + if(i >= last_colored) + { + obj.current_clr = back_color; + obj->SetClrModulation(back_color, active_overlay); + obj->SetGraphics(back_graphics_name, image, active_overlay, GFXOV_MODE_IngamePicture, nil, nil); + continue; + } + + obj.current_clr = color; + obj->SetClrModulation(color, active_overlay); + obj->SetGraphics(graphics_name, image, active_overlay, GFXOV_MODE_IngamePicture, nil, nil); + } +} + +func Close() +{ + RemoveObject(); +} + +func Destruction() +{ + if(GetType(bars) == C4V_Array) + for(var i = GetLength(bars) - 1; i > 0; --i) // off-by-one on purpose + { + var obj = bars[i]; + if(obj) + obj->RemoveObject(); + } +} + +func SetValue(int to) +{ + current = BoundBy(to, 0, maximum);; + var e = GetEffect("TimeOut", this); + if(e) + e.t = timeout_time; + Update(); +} + +func DoValue(int change) +{ + SetValue(current + change); +} + +func Initialize() +{ +} + +func AttachTargetLost() +{ + return RemoveObject(); +} + +func Set(to, number, max_num, size, offset, visibility) +{ + SetAction("Attach", to); + var x = 0 - offset.x; + var y = (6 * number * size) / 1000 - offset.y; + SetPosition(GetX() - x, GetY() - y + 8); // for good position in first frame + SetVertexXY(0, x + to->GetVertex(0, VTX_X), y + to->GetVertex(0, VTX_Y)); + + SetObjDrawTransform(size, 0, 0, 0, size, (6 * (1000 - size)), active_overlay); + this.Visibility = visibility; +} + +func SetFade(int a) +{ + for(var bar in bars) + { + var t_a = BoundBy(((bar.current_clr >> 24)) + a, 0, 255); + var clr = (bar.current_clr & 0xffffff) + (t_a << 24); + bar->SetClrModulation(clr, active_overlay); + } +} + +func SetPlane(int to) +{ + // called on a slave? + if(GetType(bars) != C4V_Array) return; + + for(var bar in bars) + bar.Plane = to; +} \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..ad40d14c3 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/BarProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Ring +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..a0680e33c --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_CustomImageProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=64 +Height=64 +Offset=-32,-32 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/Graphics.8.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/Graphics.8.png new file mode 100644 index 000000000..aec829f2d Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/Script.c new file mode 100644 index 000000000..0226c8b21 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/Script.c @@ -0,0 +1,178 @@ +/** + CustomImageProgressBar + Shows progress. + Takes an image-definition that is used as the source definition for SetGraphics. + The definition can have the callback "GetBarGraphicsName(int percent)" to return a string for a graphics file that is used for SetGraphics. + It can also have GetBarColor(int percent) to return a proplist with {r = ?, g = ?, b = ?} to get the color shown. + + additional data the bar takes through the "data" parameter: + image: definition to use as graphics + size: size of the progress bar 1000 = 100% +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +local current, maximum, timeout_time; +local image, size; +local lr, lg, lb, la, graphics_name; + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; + + +func Init(to, max, cur, timeout, offset, visibility, data) +{ + maximum = max; + current = cur; + timeout_time = timeout; + + la = 255; + + size = data.size ?? 1000; + image = data.image ?? Rock; + + if(timeout_time) + { + var e = AddEffect("TimeOut", this, 1, BoundBy(timeout_time/2, 5, 35), this); + e.t = timeout_time; + } + + AddEffect("LifeCheck", to, 1, 0, this); + + SetAction("Attach", to); + var x = -offset.x; + var y = -offset.y; + SetPosition(GetX() - x, GetY() - y + 32); // for good position in first frame + SetVertexXY(0, x + to->GetVertex(0, VTX_X), y + to->GetVertex(0, VTX_Y)); + + this.Visibility = visibility; + + Update(); +} + +func FxLifeCheckStop(target, effect, cause, temp) +{ + if(temp) return; + if(this) + this->RemoveObject(); +} + +func FxTimeOutTimer(target, effect, time) +{ + effect.t -= effect.Interval; + if(effect.t > 0) return 1; + if(!GetEffect("FadeOut", this)) + FadeOut(); + return 1; +} + +func FadeOut() +{ + AddEffect("FadeOut", this, 1, 3, this); +} + +func FxFadeOutTimer(target, effect, time) +{ + if(la <= 20) return Close(); + la -= 15; + SetClrModulation(RGBa(lr, lg, lb, la)); +} + +func Update() +{ + var p = (current * 100) / maximum; + var charge = (255 * p) / 100; + var clr; + if(clr = image->~GetBarColor(p)) + { + lr = clr.r; + lg = clr.g; + lb = clr.b; + } + else + { + lr = charge; + lg = 255 - charge; + lb = 255; + } + + SetGraphics(image->~GetBarGraphicsName(p), image, 0, GFXOV_MODE_IngamePicture, nil, GFX_BLIT_Custom); + SetClrModulation(RGB(lr, lg, lb)); + SetObjDrawTransform(size, 0, 0, 0, size); +} + +func Close() +{ + RemoveObject(); +} + +func Destruction() +{ + +} + +func SetValue(int to) +{ + current = BoundBy(to, 0, maximum);; + var e = GetEffect("TimeOut", this); + if(e) + e.t = timeout_time; + if(GetEffect("FadeOut", this)) + RemoveEffect("FadeOut", this); + Update(); +} + +func DoValue(int change) +{ + SetValue(current + change); +} + +func Initialize() +{ +} + +func SetParallax(f) +{ + if(f) + { + SetCategory(GetCategory() | C4D_Parallax); + this.Parallaxity = [0, 0]; + } + else + { + SetCategory(GetCategory() & ~C4D_Parallax); + this.Parallaxity = nil; + } + return true; +} + +func SetPlane(int to) +{ + if(to == nil) return; + this.Plane = to; + return true; +} + + +func MakeHUDElement() +{ + SetCategory(C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax); + SetParallax(); +} + +func AttachTargetLost() +{ + return RemoveObject(); +} diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..ad40d14c3 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomImageProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Ring +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..bec8c578e --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_CustomRingProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=8 +Height=8 +Offset=-4,-4 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/Graphics.8.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/Graphics.8.png new file mode 100644 index 000000000..aec829f2d Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/Script.c new file mode 100644 index 000000000..ce52b110b --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/Script.c @@ -0,0 +1,73 @@ +/** + CustomRingProgressBar + Shows progress. + + additional data the bar takes through the "data" parameter: + radius: radius of the bar in pixels, the amount of points is dynamically adjusted + image: definition to show when filled + back_image: definition to show when not filled, defaults to image + color: foreground color + back_color: background color +*/ + +#include GUI_RingProgressBar + +local Name = "$Name$"; +local Description = "$Description$"; + +local image, back_image; +local color, back_color; + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; + +func Init(to, max, cur, timeout, offset, visibility, data) +{ + data.image = data.image ?? GUI_RingProgressBar; + data.back_image = data.back_image ?? data.image; + data.color = data.color ?? RGBa(255, 255, 255,200); + data.back_color = data.back_color ?? RGBa(50, 50, 50, 50); + + image = data.image; + back_image = data.back_image; + color = data.color; + back_color = data.back_color; + + return inherited(to, max, cur, timeout, offset, visibility, data); +} + +func Update() +{ + var l = GetLength(ring); + var p = (current * 100) / maximum; + var last_colored = (l * p) / 100; + + + for(var i = 0; i < l; ++i) + { + var obj = ring[i]; + if(i >= last_colored) + { + obj->SetGraphics(nil, back_image, 0, GFXOV_MODE_ObjectPicture, nil, GFX_BLIT_Custom); + obj->SetClrModulation(back_color); + } + else + { + obj->SetGraphics(nil, image, 0, GFXOV_MODE_ObjectPicture, nil, GFX_BLIT_Custom); + obj->SetClrModulation(color); + } + obj->Rotate(obj.my_angle + 180, 0, 0); + } +} + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..ad40d14c3 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/CustomRingProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Ring +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..8c30e9f81 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=GUI_ProgressBar +Version=4,10,0,0 +Category=C4D_StaticBack + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/Graphics.png new file mode 100644 index 000000000..d1dd3b672 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..f8267ddf0 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_PieProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=8 +Height=8 +Offset=-4,-4 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/Graphics.8.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/Graphics.8.png new file mode 100644 index 000000000..bcf118560 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/Script.c new file mode 100644 index 000000000..3f593c232 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/Script.c @@ -0,0 +1,116 @@ +/** + PieProgressBar + Shows progress. + + additional data the bar takes through the "data" parameter: + size: size of the pie, 1000 = 100% + color: foreground color + back_color: background color +*/ + +#include GUI_RingProgressBar + +local Name = "$Name$"; +local Description = "$Description$"; + +local size; +local color, back_color; + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; + +func Init(to, max, cur, timeout, offset, visibility, data) +{ + data.color = data.color ?? RGBa(255, 255, 255,200); + data.back_color = data.back_color ?? RGBa(50, 50, 50, 50); + + size = data.size ?? 1000; + color = data.color; + back_color = data.back_color; + + maximum = max; + current = cur; + timeout_time = timeout; + + ring = []; + + if(timeout_time) + { + var e = AddEffect("TimeOut", this, 1, BoundBy(timeout_time/2, 5, 35), this); + e.t = timeout_time; + } + + var amount = 24; + + ring[0] = this; + + for(var i = 1; i < amount; ++i) + ring[i] = CreateObject(GetID(), 0, 0, GetOwner()); + + var cnt = 0; + for(var obj in ring) + { + obj->Set(to, 180 / amount + ((cnt * 360) / amount), offset, visibility, size); + ++cnt; + } + + AddEffect("LifeCheck", to, 1, 0, this); + Update(); +} + +func Update() +{ + var l = GetLength(ring); + var p = (current * 100) / maximum; + var last_colored = (l * p) / 100; + + + for(var i = 0; i < l; ++i) + { + var obj = ring[i]; + if(i >= last_colored) + { + obj->SetClrModulation(back_color); + } + else + { + obj->SetClrModulation(color); + } + } +} + +func Set(to, angle, offset, visibility, size) +{ + SetAction("Attach", to); + var distance = (10 * size) / 1000; + + var x = -Sin(angle, distance) - offset.x; + var y = +Cos(angle, distance) - offset.y; + SetPosition(GetX() - x, GetY() - y + 8); // for good position in first frame + SetVertexXY(0, x + to->GetVertex(0, VTX_X), y + to->GetVertex(0, VTX_Y)); + my_angle = -angle; + Rotate(my_angle, 0, 0, (2500 * size) / 1000); + + this.Visibility = visibility; +} + +func Rotate (int r, int xoff, int yoff, size) { + var fsin=Sin(r, 1000), fcos=Cos(r, 1000); + size = size ?? 1000; + // set matrix values + SetObjDrawTransform ( + (+fcos) * size / 1000, (+fsin) * size / 1000, ((1000-fcos)*xoff - fsin*yoff) * size / 1000, + (-fsin) * size / 1000, (+fcos) * size / 1000, ((1000-fcos)*yoff + fsin*xoff) * size / 1000 + ); +} \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..ad40d14c3 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/PieProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Ring +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..128b7c72d --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_RingProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=8 +Height=8 +Offset=-4,-4 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/Graphics.8.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/Graphics.8.png new file mode 100644 index 000000000..aec829f2d Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/Script.c new file mode 100644 index 000000000..add71c04a --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/Script.c @@ -0,0 +1,205 @@ +/** + RingProgressBar + Shows progress. + + additional data the bar takes through the "data" parameter: + radius: radius of the bar in pixels, the amount of points is dynamically adjusted + amount: number of segments in the ring, usually calculates form radius +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +local maximum, current, timeout_time; +local my_angle; +local ring; + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; + + +func Init(to, max, cur, timeout, offset, visibility, data) +{ + maximum = max; + current = cur; + timeout_time = timeout; + + ring = []; + + if(timeout_time) + { + var e = AddEffect("TimeOut", this, 1, BoundBy(timeout_time/2, 5, 35), this); + e.t = timeout_time; + } + + + var radius = data.radius ?? 20; + var amount = data.amount ?? BoundBy(radius, 8, 30); + + ring[0] = this; + + for(var i = 1; i < amount; ++i) + ring[i] = CreateObject(GetID(), 0, 0, GetOwner()); + + var cnt = 0; + for(var obj in ring) + { + obj->Set(to, radius, ((cnt * 360) / amount), offset, visibility); + ++cnt; + } + + AddEffect("LifeCheck", to, 1, 0, this); + Update(); +} + +func FxLifeCheckStop(target, effect, cause, temp) +{ + if(temp) return; + if(this) + this->RemoveObject(); +} + +func FxTimeOutTimer(target, effect, time) +{ + effect.t -= effect.Interval; + if(effect.t > 0) return 1; + Close(); + return -1; +} + +func Update() +{ + var l = GetLength(ring); + var p = (current * 100) / maximum; + var last_colored = (l * p) / 100; + + + for(var i = 0; i < l; ++i) + { + var obj = ring[i]; + if(i > last_colored) + { + obj->SetClrModulation(RGBa(10, 10, 10, 200)); + continue; + } + var p = (i * 100) / l; + var charge = (255 * p) / 100; + + var r = 255, g = 255; + if(p > 50) r = BoundBy(255 - charge * 2, 0, 255); + if(p < 50) g = BoundBy(charge * 2, 0, 255); + obj->SetClrModulation(RGBa(r, g, 1, 200)); + } +} + +func Close() +{ + RemoveObject(); +} + +func Destruction() +{ + if(GetType(ring) == C4V_Array) + for(var i = GetLength(ring) - 1; i > 0; --i) // off-by-one on purpose + { + var obj = ring[i]; + if(obj) + obj->RemoveObject(); + } +} + +func SetValue(int to) +{ + current = BoundBy(to, 0, maximum);; + var e = GetEffect("TimeOut", this); + if(e) + e.t = timeout_time; + Update(); +} + +func DoValue(int change) +{ + SetValue(current + change); +} + +func Initialize() +{ +} + +func SetParallax(f) +{ + f = f ?? true; + for(var obj in ring) + { + if(f) + { + obj->SetCategory(obj->GetCategory() | C4D_Parallax); + obj.Parallaxity = [0, 0]; + } + else + { + obj->SetCategory(obj->GetCategory() & ~C4D_Parallax); + obj.Parallaxity = nil; + } + } + return true; +} + +func SetPlane(int to) +{ + if(to == nil) return; + + for(var obj in ring) + { + obj.Plane = to; + } + return true; +} + + +func MakeHUDElement() +{ + for(var obj in ring) + { + obj->SetCategory(C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax); + } + SetParallax(); +} + +func AttachTargetLost() +{ + return RemoveObject(); +} + +func Rotate (int r, int xoff, int yoff) { + var fsin=Sin(r, 1000), fcos=Cos(r, 1000); + // set matrix values + SetObjDrawTransform ( + +fcos, +fsin, (1000-fcos)*xoff - fsin*yoff, + -fsin, +fcos, (1000-fcos)*yoff + fsin*xoff + ); +} + +func Set(to, distance, angle, offset, visibility) +{ + SetAction("Attach", to); + var x = -Sin(angle, distance) - offset.x; + var y = +Cos(angle, distance) - offset.y; + SetPosition(GetX() - x, GetY() - y + 8); // for good position in first frame + SetVertexXY(0, x + to->GetVertex(0, VTX_X), y + to->GetVertex(0, VTX_Y)); + my_angle = -angle; + Rotate(my_angle, 0, 0); + + this.Visibility = visibility; +} diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..ad40d14c3 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/RingProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Ring +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/Script.c new file mode 100644 index 000000000..a190c320b --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/Script.c @@ -0,0 +1,70 @@ +/** + GUI_ProgressBar + Provides the interface used by different progress bars. +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +// creates a progress bar of the given ID and returns it +global func CreateProgressBar( + ID /* ID of the progress bar */ + , int max /* maximum value of the progress bar */ + , int current /* starting value of the progress bar */ + , int time_out /* time in frames after which the progress bar closes itself when not receiving updates, might be nil */ + , int owner /* owner of the progress bar */ + , proplist offset /* proplist {x = ?, y = ?} that specifies the offset of the progress bar relative to the calling object */ + , int visibility /* visibility mask for the progress bar, f.e.: VIS_Owner | VIS_Allies */ + , proplist data /* proplist with extra data that is passed to the progress bar */ + ) +{ + if(!this) return; + owner = owner ?? NO_OWNER; + visibility = visibility ?? VIS_All; + offset = offset ?? {x = 0, y = 0}; + max = max ?? 100; + current = current ?? 0; + data = data ?? {}; + + if(!ID) + FatalError("CreateProgressBar called without valid ID"); + + var obj = CreateObject(ID, 0, 0, owner); + obj->Init(this, max, current, time_out, offset, visibility, data); + + return obj; +} + +// closes the progress bar and usually removes it +func Close(){return _inherited(...);} + +// sets the value of the progress bar, updates the progress bar +func SetValue(int to){return _inherited(to, ...);} + +// changes the value of the progress bar by the specified amount, usually calls SetValue +func DoValue(int change){return _inherited(change, ...);} + +// changes the offset {x = ?, y = ?} of the progress bar relative to the attached object (or global) +func SetOffset(proplist offset){return _inherited(offset, ...);} + +// makes the progress bar 100% parallax +func SetParallax(){return _inherited(...);} + +// sets the Plane property of the progress bar +func SetPlane(int to) {return _inherited(...);} + +// makes the object a HUD element by setting parallaxity and the category C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax +func MakeHUDElement() {return _inherited(...);} + +// called once on creation by CreateProgressBar on the new bar +func Init(object to /* object to attach the bar to */ + , int maximum /* maximum value of the progress bar (100%) */ + , int current /* starting value of the progress bar (0 <= current <= maximum*/ + , int timeout /* time in frames after which the progress bar should Close itself when not receiving updates, might be nil */ + , proplist offset /* proplist with properties "x" and "y" that specifies the offset of the bar relative to the target object, the progress bar might provide standard values */ + , proplist data /* proplist with additional data the progress bar can use */ + ) +{return _inherited(to, maximum, current, timeout, ...);} + +// updates the visuals of the progress bar +func Update(){return _inherited(...);} \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..83877c6e5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_ShadedSimpleProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=110 +Height=19 +Offset=-55,-10 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/Graphics.png new file mode 100644 index 000000000..fd6c95cce Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/GraphicsBar.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/GraphicsBar.png new file mode 100644 index 000000000..610110675 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/GraphicsBar.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/GraphicsEmpty.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/GraphicsEmpty.png new file mode 100644 index 000000000..af7036681 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/GraphicsEmpty.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/Script.c new file mode 100644 index 000000000..213c5c952 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/Script.c @@ -0,0 +1,114 @@ +/** + ShadedSimpleProgressBar + Shows progress. + + additional data the bar takes through the "data" parameter: + color: color of the inside + back_color: color of the background + width: length of the bar in pixels + height: height of the bar in pixels + + graphics_name: name of the filled graphics + back_graphics_name: name of the empty graphics + + image: id to get the graphics from +*/ + +#include GUI_SimpleProgressBar + + +local graphics_name, back_graphics_name, image; + +func Init(to, max, cur, timeout, offset, visibility, proplist data) +{ + inherited(to, max, cur, timeout, offset, visibility, data); + + image = data.image ?? GUI_ShadedSimpleProgressBar; + graphics_name = data.graphics_name ?? "Bar"; + back_graphics_name = data.back_graphics_name ?? "Empty"; + + SetGraphics(back_graphics_name, image, 0, GFXOV_MODE_Base, nil, GFX_BLIT_Custom); + SetGraphics(graphics_name, image, 1, GFXOV_MODE_Base, nil, GFX_BLIT_Custom); + SetBarColor(data.color, data.back_color); + Update(); +} + +func SetBarColor(c, b) +{ + color = c ?? RGB(255, 255, 255); + back_color = b ?? RGB(255, 255, 255); + + SetClrModulation(color, 1); + SetClrModulation(back_color, 0); +} + +func Update() +{ + var p = (current * 100) / maximum; + var w = (width * 1000) / 110; + var l = (width * p * 10) / 110; + SetObjDrawTransform((width * 1000) / 110, 0, 0, 0, (height * 1000) / 19, 0, 0); + SetObjDrawTransform(l, 0, -(w-l) * 55, 0, (height * 1000) / 19, 100, 1); +} + +/* + adds an energy bar above the object. + The energy bar uses either target.HitPoints & GetDamage() or target->GetMaxEnergy() & target->GetEnergy(). +*/ +global func AddEnergyBar() +{ + var e = AddEffect("ShowEnergyBar", this, 1, 0, nil, nil); + if (e) + return e.bar; +} + +global func FxShowEnergyBarStart(target, effect, temp) +{ + if (temp) return; + var attachpoint = { x = 0, y = target->GetDefOffset(1) - 5}; + var current, max; + if (target->GetCategory() & C4D_Living) + { + max = target->~GetMaxEnergy(); + current = target->GetEnergy(); + } + else + { + max = target.HitPoints; + current = max - target->GetDamage(); + } + + if (current == nil || max == nil) + return -1; + + effect.bar = target->CreateProgressBar(GUI_ShadedSimpleProgressBar, max, current, 0, target->GetOwner(), attachpoint, nil, { width = 28, height = 6, color = RGB(200, 1, 1) }); + effect.bar->SetPlane(750); + // update once + effect.Interval = 1; + + return 1; +} + +global func FxShowEnergyBarTimer(target, effect, time) +{ + var value; + if (target->GetCategory() & C4D_Living) value = target->GetEnergy(); + else value = target.HitPoints - target->GetDamage(); + + effect.bar->SetValue(value); + effect.Interval = 0; + return 1; +} + +global func FxShowEnergyBarDamage(target, effect, dmg, cause) +{ + effect.Interval = 1; + return dmg; +} + +global func FxShowEnergyBarStop(target, effect, reason, temp) +{ + if (temp) return; + if (effect.bar) + effect.bar->Close(); +} \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..6f3bf2f46 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/ShadedSimpleProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Bar +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/DefCore.txt new file mode 100644 index 000000000..62f955e15 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=GUI_SimpleProgressBar +Version=4,10,0,0 +Category=C4D_Vehicle +Width=16 +Height=16 +Offset=-8,-8 +Vertices=1 +VertexX=0 +VertexY=0 +VertexFriction=20 + diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/Graphics.png new file mode 100644 index 000000000..16064f92e Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/Script.c new file mode 100644 index 000000000..ce19e3cd8 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/Script.c @@ -0,0 +1,128 @@ +/** + SimpleProgressBar + Shows progress. + + additional data the bar takes through the "data" parameter: + color: color of the inside + back_color: color of the background + width: length of the bar in pixels + height: height of the bar in pixels +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +local maximum, current, timeout_time; + +local width, height, color, back_color; + +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; + + +func Init(to, max, cur, timeout, offset, visibility, proplist data) +{ + maximum = max; + current = cur; + timeout_time = timeout; + + width = data.width ?? 40; + height = data.height ?? 5; + + + if(timeout_time) + { + var e = AddEffect("TimeOut", this, 1, BoundBy(timeout_time/2, 5, 35), this); + e.t = timeout_time; + } + + this.Visibility = visibility; + + SetGraphics(nil, GetID(), 1, GFXOV_MODE_Base, nil, GFX_BLIT_Custom); + SetBarColor(data.color, data.back_color); + + SetAction("Attach", to); + SetVertexXY(0, -offset.x, -offset.y); + + AddEffect("LifeCheck", to, 1, 0, this); + Update(); +} + +func SetBarColor(c, b) +{ + color = c ?? RGB(200, 200, 10); + back_color = b ?? RGB(1, 1, 1); + + SetClrModulation(color, 1); + SetClrModulation(back_color, 0); +} + +func FxLifeCheckStop(target, effect, cause, temp) +{ + if(temp) return; + if(this) + this->RemoveObject(); +} + +func FxTimeOutTimer(target, effect, time) +{ + effect.t -= effect.Interval; + if(effect.t > 0) return 1; + Close(); + return -1; +} + +func Update() +{ + var p = (current * 100) / maximum; + var w = (width * 1000) / 16; + var l = (width * p * 10) / 16; + SetObjDrawTransform(w, 0, 0, 0, (height * 1000) / 16, 0, 0); + SetObjDrawTransform(l, 0, -(w-l) * 8, 0, (height * 800) / 16, 100, 1); +} + +func Close() +{ + RemoveObject(); +} + +func Destruction() +{ + +} + +func SetValue(int to) +{ + current = BoundBy(to, 0, maximum);; + var e = GetEffect("TimeOut", this); + if(e) + e.t = timeout_time; + Update(); +} + +func DoValue(int change) +{ + SetValue(current + change); +} + + +func AttachTargetLost() +{ + return RemoveObject(); +} + +func SetPlane(int to) +{ + this.Plane = to; +} diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..694a6aef5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Ladebalken +Description=Zeigt Fortschritt. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..6f3bf2f46 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/SimpleProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Progress Bar +Description=Shows progress. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/StringTblDE.txt new file mode 100644 index 000000000..3cc4664de --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=GUI_ProgressBar +Description=Stellt ein Interface für Fortschrittsleisten zur Verfügung. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/StringTblUS.txt new file mode 100644 index 000000000..736335b5e --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ProgressBar.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=GUI_ProgressBar +Description=Provides the interface used by different progress bars. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Menupoint.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Menupoint.ocd/Script.c index 055c3b8c8..3c2c054f0 100644 --- a/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Menupoint.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Menupoint.ocd/Script.c @@ -40,12 +40,8 @@ public func SetBG(bool newbg) { public func SetNothing() // No item, no image, no whatever, just a plain button { - SetAmount(0); + SetAmount(nil); SetSymbol(); - SetGraphics(nil,nil,9); - SetGraphics(nil,nil,10); - SetGraphics(nil,nil,11); - SetGraphics(nil,nil,12); } public func SetSize(int s) // in px *1000 @@ -80,7 +76,7 @@ public func SetSymbol(obj) { if (GetType(obj) == C4V_C4Object) { - SetGraphics(nil, nil, MI_ICON_LAYER, GFXOV_MODE_ObjectPicture, 0, 0, obj); + SetGraphics(nil, nil, MI_ICON_LAYER, GFXOV_MODE_ObjectPicture, nil, 0, obj); SetObjDrawTransform(size, 0, 0, 0, size, 0, MI_ICON_LAYER); if (obj->~HasExtraSlot()) { @@ -91,7 +87,7 @@ public func SetSymbol(obj) var content = obj->Contents(0); if (content) { - SetGraphics(nil, nil, MI_EXTRASLOT_LAYER, GFXOV_MODE_ObjectPicture, 0, 0, content); + SetGraphics(nil, nil, MI_EXTRASLOT_LAYER, GFXOV_MODE_ObjectPicture, nil, 0, content); SetObjDrawTransform(size/3, 0, 16*size, 0, size/3, 16*size, MI_EXTRASLOT_LAYER); } else @@ -122,9 +118,15 @@ public func SetExtraData(extradata) } public func SetAmount(Amount) { - - amnt=Amount; - if(Amount==1) return ; + amnt = Amount; + if (Amount == nil) + { + SetGraphics(nil,nil,MI_AMOUNTX_LAYER); + SetGraphics(nil,nil,MI_AMOUNT1_LAYER); + SetGraphics(nil,nil,MI_AMOUNT10_LAYER); + SetGraphics(nil,nil,MI_AMOUNT100_LAYER); + return; + } var one = Amount%10; var ten = (Amount/10)%10; var hun = (Amount/100)%10; diff --git a/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Script.c index 07f7d552e..e76e2edba 100644 --- a/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/Ringmenu.ocd/Script.c @@ -102,14 +102,7 @@ public func AddItem(new_item, int amount, extra) menu_icons[index] = CreateObject(GUI_RingMenu_Icon,0,0,menu_object->GetOwner()); menu_icons[index]->SetSymbol(new_item); menu_icons[index]->SetExtraData(extra); - if(amount == nil) - { - menu_icons[index]->SetAmount(1); - } - else - { - menu_icons[index]->SetAmount(amount); - } + menu_icons[index]->SetAmount(amount); menu_icons[index].Visibility = VIS_None; return index; } diff --git a/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/DefCore.txt new file mode 100644 index 000000000..bee3f8989 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Scoreboard +Version=4,10,0,0 +Category=C4D_StaticBack +Width=1 +Height=1 +Offset=-1,-1 diff --git a/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/Graphics.png new file mode 100644 index 000000000..9bb8607e9 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/Script.c new file mode 100644 index 000000000..985561c9b --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/Scoreboard.ocd/Script.c @@ -0,0 +1,325 @@ +/** + Scoreboard + Provides an additional abstraction layer on top of the scoreboard-functions + + Attention: Do not include this. Use the function as specified with f.e. Scoreboard->Init(...) +*/ + +// do not manipulate externally +static Scoreboard_keys; // [{key = ?, title = ?, ..}, ..] +static Scoreboard_data; // [{key = value, ..}, ..] +static Scoreboard_unique_ids; +static Scoreboard_title_set; + +static const Scoreboard_Y_title = SBRD_Caption; +static const Scoreboard_X_title = SBRD_Caption; + +// wrapper for Scoreboard->NewEntry, adds a new entry for a player with the tagged player name as the title +public func NewPlayerEntry(int plr) +{ + return Scoreboard->NewEntry(GetPlayerID(plr), GetTaggedPlayerName(plr)); +} + +public func RemovePlayerEntry(int plr) +{ + return Scoreboard->RemoveEntry(GetPlayerID(plr)); +} + +// adds a new entry (row) to the scoreboard, will return the ID of the added entry +// the parameter new_id might be nil in which case a unique new ID is chosen +public func NewEntry( + int new_id /* unique ID for the new entry, can be nil */ + , string new_title /* text for the first column */ + ) +{ + // not initialized yet? Then init empty. + if (!Scoreboard_keys) Init([]); + // check for duplicates + if(new_id) + { + var index = -1; + for(var i = 0; i < GetLength(Scoreboard_data); ++i) + { + if(Scoreboard_data[i].ID != new_id) continue; + index = i; + break; + } + + // duplicate? + if(index != -1) return nil; + } + else // no ID provided, get new one + { + new_id = ++Scoreboard_unique_ids; + } + + PushBack(Scoreboard_data, {ID = new_id, title = new_title}); + Scoreboard->Update(new_id); + return new_id; +} + +// removes an entry (row) from the scoreboard +public func RemoveEntry( + int remove_id /* unique ID for the new entry, can be nil */ + ) +{ + var i, len = GetLength(Scoreboard_data); + for(i = 0; i < len; ++i) if(Scoreboard_data[i].ID == remove_id) break; + if (i == len) return false; // not found + RemoveArrayIndex(Scoreboard_data, i); + // Clear all columns + for (var col in Scoreboard_keys) SetScoreboardData(remove_id, col.index); + SetScoreboardData(remove_id, Scoreboard_X_title); + return true; +} + +// sets a value for a specific key of a scoreboard entry for a player and updates it +// that entry must have been created earlier with ScoreboarNewPlayerEntry or manually with Scoreboard->NewEntry +public func SetPlayerData( + int plr /* player number for the player entry to manipulate */ + , string key /* name of the key assign value to */ + , to /* value to assign, might be ID, string, int or bool */ + , int sort_parameter /* parameter used for sorting. if nil, 'to' is used if possible*/ + ) +{ + var ID = GetPlayerID(plr); + return Scoreboard->SetData(ID, key, to, sort_parameter); +} + +// sets a value for a specific key of any entry in the scoreboard and updates it +// the entry must have been created with Scoreboard->NewEntry earlier +public func SetData( + int ID /* ID of the entry to manipulate */ + , string key /* name of the key to assign value to */ + , to /* new value of the key, might be int, string bool or id */ + , int sort_parameter /* parameter that is used for sorting of the entry. if nil, 'to' is used if possible*/ + ) +{ + var index = -1; + for(var i = 0; i < GetLength(Scoreboard_data); ++i) + { + if(Scoreboard_data[i].ID != ID) continue; + index = i; + break; + } + if(index == -1) return; + + Scoreboard_data[i][key] = to; + if(sort_parameter) + Scoreboard_data[i][Format("%s_", key)] = sort_parameter; + Scoreboard->Update(ID); +} + +// updates the display of the scoreboard +// there is usually no need to call it manually since Scoreboard->SetData calls Update +public func Update( + int ID /* ID of the entry to update */ + , int index /* optional, internal index. leave at nil.*/ + ) +{ + if(index == nil) + { + for(var i = 0; i < GetLength(Scoreboard_data); ++i) + { + if(Scoreboard_data[i].ID != ID) continue; + index = i; + break; + } + if(index == nil) return; + } + + var data = Scoreboard_data[index]; + + // title - playername f.e. + SetScoreboardData(data.ID, Scoreboard_X_title, data.title, -1); + + var len = GetLength(Scoreboard_keys); + for(var i = 0; i < len; ++i) + { + var col = Scoreboard_keys[i]; + if(!col.key) continue; + if(col.key == "title") continue; // already set + + // aquire value + var value = col.default; + if(data[col.key] != nil) value = data[col.key]; + + // get sorting parameter + var sort = data[Format("%s_", col.key)]; + if(sort == nil) + if(GetType(value) == C4V_Int) sort = value; + + // the column provides a conditional function + if(col.conditional) + { + value = col->conditional(value); + + // overwrite old sort? + if(GetType(value) == C4V_Int) sort = value; + } + + if(value == nil) value = ""; + else if(GetType(value) == C4V_Int) {value = Format("%d", value);} + else if(GetType(value) == C4V_Def) value = Format("{{%i}}", value); + else if(GetType(value) == C4V_Bool) {sort = value; if(value) value = "X"; else value = "";} + + SetScoreboardData(data.ID, col.index, value, sort); + } + UpdateSort(); + return true; +} + +public func UpdateSort() +{ + // do sorting for fields neccessary + var len = GetLength(Scoreboard_keys); + for(var i = len-1; i >= 0; --i) + { + var col = Scoreboard_keys[i]; + if(!col.key) continue; + if(!col.sorted) continue; + + SortScoreboard(col.index, col.desc); + } + return true; +} + +// updates the whole scoreboard +public func UpdateAll() +{ + // for every row, do update + var len = GetLength(Scoreboard_data); + for(var i = 0; i < len; ++i) + { + Scoreboard->Update(Scoreboard_data[i].ID, i); + } + return true; +} + +// remove a column from the scoreboard +public func RemoveColumn(string key) +{ + var col, data; + if (!key) FatalError("Scoreboard::RemoveColumn: Key required!"); + // find key + for (col in Scoreboard_keys) if (col.key == key) break; + if (!col || col.key != key) return false; // key not found. fail but not fatal. + // for every row, remove data for key + for (data in Scoreboard_data) + { + data[key] = data[Format("%s_", key)] = nil; + SetScoreboardData(data.ID, col.index); + } + // resort + SortScoreboard(col.index, col.desc); + return true; +} + +// initializes the scoreboard with certain columns and attributes +// can be called multiple times and scales +// values must be an array of proplists where each entry stands for one column +// the entries can have the following attributes: +// "key" is required and used later for Scoreboard->SetData +// {key (string), priority (int), sorted (bool), desc (bool), title (string), default (any)} +// one row with key = "title" is necessary and will be automatically added if left out and not existent +public func Init(array values /* see description */) +{ + // first call? + if(Scoreboard_unique_ids == nil) + { + Scoreboard_unique_ids = 0xffffff; + Scoreboard_keys = []; + Scoreboard_data = []; + + if(!Scoreboard_title_set) + Scoreboard->SetTitle("Scoreboard"); + } + + // merge arrays + for(var val in values) + { + if(val == nil) continue; + + var index = nil; + for(var i = GetLength(Scoreboard_keys)-1; i >= 0; --i) + { + if(Scoreboard_keys[i].key != val.key) continue; + index = i; + break; + } + if(index == nil) + PushBack(Scoreboard_keys, val); // new entry + else Scoreboard_keys[index] = val; // overwrite + } + + // title property set? + var found_title = false; + for(var col in Scoreboard_keys) + { + if(col.key != "title") continue; + found_title = true; + break; + } + + // if not, add + if(!found_title) + PushBack(Scoreboard_keys, {key = "title", title = ""}); + + + // sort, selection sort + var len = GetLength(Scoreboard_keys); + for(var x = 0; x < len - 1; ++x) + { + var max = -1, max_val = nil; + for(var i = x; i < len; ++i) + { + var data = Scoreboard_keys[i]; + if(max_val == nil || (data.priority > max_val)) + { + max = i; + max_val = data.priority; + } + } + if(max == -1) break; + + var t = Scoreboard_keys[x]; + Scoreboard_keys[x] = Scoreboard_keys[max]; + Scoreboard_keys[max] = t; + } + + // assign indices to scoreboard data, they are now sorted - also create scoreboard + var len = GetLength(Scoreboard_keys); + for(var i = 0; i < len; ++i) + { + Scoreboard_keys[i].index = i; + + if(Scoreboard_keys[i].key == "title") // title has special index and no headline + { + Scoreboard_keys[i].index = Scoreboard_X_title; + // don't set headline for title (first) column, because that would change the scoreboard title + continue; + } + + // check title + if(GetType(Scoreboard_keys[i].title) == C4V_Def) + Scoreboard_keys[i].title = Format("{{%i}}", Scoreboard_keys[i].title); + + var data = -0xffffff; + if(Scoreboard_keys[i].desc) data = 0xffffff; + SetScoreboardData(Scoreboard_Y_title, Scoreboard_keys[i].index, Scoreboard_keys[i].title, data); + } + + + // setup scoreboard + Scoreboard->UpdateAll(); + + // show scoreboard, only initially - after that it's the player's choice + DoScoreboardShow(1); +} + +// sets the title of the scoreboard, standard is "Scoreboard" +public func SetTitle(string title) +{ + SetScoreboardData(SBRD_Caption, SBRD_Caption, title); + Scoreboard_title_set = true; +} \ No newline at end of file diff --git a/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/DefCore.txt b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/DefCore.txt new file mode 100644 index 000000000..bf927097a --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Dummy +Version=5,3,0,0 +Category=C4D_StaticBack +Width=8 +Height=8 +Offset=-4,-4 diff --git a/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/Graphics.png b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/Graphics.png new file mode 100644 index 000000000..b15f128ed Binary files /dev/null and b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/Script.c new file mode 100644 index 000000000..2472d02d8 --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/Script.c @@ -0,0 +1,11 @@ +/** + Dummy + + A dummy object which may serve for various purposes +*/ + +// Stored objects will recreate their own dummies upon initialization +func SaveScenarioObject() { return false; } + +local Name = "$Name$"; +local Visibility = VIS_None; diff --git a/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/StringTblDE.txt b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/StringTblDE.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/StringTblUS.txt b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/StringTblUS.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/Dummy.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Appendto.ocd/ToolsWorkshop.ocd/DefCore.txt b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/DefCore.txt similarity index 58% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Appendto.ocd/ToolsWorkshop.ocd/DefCore.txt rename to planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/DefCore.txt index 3772e40bc..382d870a7 100644 --- a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Appendto.ocd/ToolsWorkshop.ocd/DefCore.txt +++ b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/DefCore.txt @@ -1,4 +1,6 @@ [DefCore] -id=Appendto_CableCar_ToolsWorkshop +id=DebugLine Version=5,2,0,1 Category=C4D_StaticBack +Vertices=2 +Line=1 diff --git a/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/Graphics.png b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/Graphics.png new file mode 100644 index 000000000..753695654 Binary files /dev/null and b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/Script.c new file mode 100644 index 000000000..38271db97 --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DebugLine.ocd/Script.c @@ -0,0 +1,31 @@ +/*-- Debug dusplay line --*/ + +// definition call: create line +func Create(int x1,int y1,int x2,int y2,int clr) +{ + var obj = CreateObject(DebugLine); + obj->Set(x1,y1,x2,y2,clr); + return obj; +} + +func Set(int x1,int y1,int x2,int y2,int clr) +{ + //SetAction("Connect"); + SetVertexXY(0, x1,y1); + SetVertexXY(1, x2,y2); + this.LineColors = [clr, clr]; + return; +} + +// Will be recreated when needed. +func SaveScenarioObject() { return false; } + +local ActMap = { + Connect = { + Prototype = Action, + Name = "Connect", + Procedure = DFA_CONNECT, + NextAction = "Connect" + } +}; + diff --git a/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DefCore.txt b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DefCore.txt new file mode 100644 index 000000000..c978b396a --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=S2AI +Version=5,2,0,1 +Category=C4D_Vehicle | C4D_MouseIgnore +Width=1 +Height=1 +Mass=1 + diff --git a/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/Graphics.png b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/Graphics.png new file mode 100644 index 000000000..2a11249d4 Binary files /dev/null and b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/Script.c new file mode 100644 index 000000000..b44707f83 --- /dev/null +++ b/planet/Objects.ocd/Helpers.ocd/EnemyAI.ocd/Script.c @@ -0,0 +1,677 @@ +static const S2AI_DefMaxAggroDistance = 200, // lose sight to target if it is this far away (unles we're ranged - then always guard the range rect) + S2AI_DefGuardRangeX = 300, // search targets this far away in either direction (searching in rectangle) + S2AI_DefGuardRangeY = 150, // search targets this far away in either direction (searching in rectangle) + S2AI_AlertTime = 800; // number of frames after alert after which AI no longer checks for projectiles + +/* Public interface */ + +// Add AI execution timer to target Clonk +func AddAI(object clonk) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx) fx = AddEffect("S2AI", clonk, 1, 3, nil, S2AI); + if (!fx || !clonk) return nil; + clonk.ExecuteS2AI = S2AI.Execute; + if (clonk->GetProcedure() == "PUSH") fx.vehicle = clonk->GetActionTarget(); + BindInventory(clonk); + SetHome(clonk); + SetGuardRange(clonk, fx.home_x-S2AI_DefGuardRangeX, fx.home_y-S2AI_DefGuardRangeY, S2AI_DefGuardRangeX*2, S2AI_DefGuardRangeY*2); + SetMaxAggroDistance(clonk, S2AI_DefMaxAggroDistance); + return fx; +} + +func GetAI(object clonk) { return GetEffect("S2AI", clonk); } + +// Set the current inventory to be removed when the clonk dies. Only works if clonk has an AI. +func BindInventory(object clonk) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx || !clonk) return false; + var cnt = clonk->ContentsCount(); + fx.bound_weapons = CreateArray(cnt); + for (var i=0; iContents(i); + clonk->Call(S2AI.UpdateDebugDisplay, fx); + return true; +} + +// Set the home position the Clonk returns to if he has no target +func SetHome(object clonk, int x, int y, int dir) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx || !clonk) return false; + // nil/nil defaults to current position + if (!GetType(x)) x=clonk->GetX(); + if (!GetType(y)) y=clonk->GetY(); + if (!GetType(dir)) dir=clonk->GetDir(); + fx.home_x = x; fx.home_y = y; + fx.home_dir = dir; + return true; +} + +// Set the guard range to the provided rectangle +func SetGuardRange(object clonk, int x, int y, int wdt, int hgt) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx || !clonk) return false; + fx.guard_range = {x=x, y=y, wdt=wdt, hgt=hgt}; + clonk->Call(S2AI.UpdateDebugDisplay, fx); + return true; +} + +// Set the maximum distance the enemy will follow an attacking Clonk +func SetMaxAggroDistance(object clonk, int max_dist) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx || !clonk) return false; + fx.max_aggro_distance = max_dist; + return true; +} + +// Set range in which, on first encounter, allied AI Clonks get the same aggro target set +func SetAllyAlertRange(object clonk, int new_range) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx || !clonk) return false; + fx.ally_alert_range = new_range; + clonk->Call(S2AI.UpdateDebugDisplay, fx); + return true; +} + +// Set callback function name to be called in game script when this AI is first encountered +// Callback function first parameter is (this) AI clonk, second parameter is player clonk. +// The callback should return true to be cleared and not called again. Otherwise, it will be called every time a new target is found. +func SetEncounterCB(object clonk, string cb_fn) +{ + var fx = GetEffect("S2AI", clonk); + if (!fx || !clonk) return false; + fx.encounter_cb = cb_fn; + clonk->Call(S2AI.UpdateDebugDisplay, fx); + return true; +} + +/* Scenario saving */ + +func FxS2AISaveScen(clonk, fx, props) +{ + if (!clonk) return false; + props->AddCall("S2AI", S2AI, "AddAI", clonk); + if (fx.home_x != clonk->GetX() || fx.home_y != clonk->GetY() || fx.home_dir != clonk->GetDir()) + props->AddCall("S2AI", S2AI, "SetHome", clonk, fx.home_x, fx.home_y, GetConstantNameByValueSafe(fx.home_dir, "DIR_")); + props->AddCall("S2AI", S2AI, "SetGuardRange", clonk, fx.guard_range.x, fx.guard_range.y, fx.guard_range.wdt, fx.guard_range.hgt); + if (fx.max_aggro_distance != S2AI_DefMaxAggroDistance) + props->AddCall("S2AI", S2AI, "SetMaxAggroDistance", clonk, fx.max_aggro_distance); + if (fx.ally_alert_range) + props->AddCall("S2AI", S2AI, "SetAllyAlertRange", clonk, fx.ally_alert_range); + if (fx.encounter_cb) + props->AddCall("S2AI", S2AI, "SetEncounterCB", clonk, Format("%v", fx.encounter_cb)); + return true; +} + + +/* AI effect callback functions */ + +protected func FxS2AITimer(clonk, fx, int time) { clonk->ExecuteS2AI(fx, time); return FX_OK; } + +protected func FxS2AIStop(clonk, fx, int reason) +{ + // remove debug display + if (fx.debug) clonk->Call(S2AI.EditCursorDeselection, fx); + // remove weapons on death + if (reason == FX_Call_RemoveDeath) + { + if (fx.bound_weapons) for (var obj in fx.bound_weapons) if (obj && obj->Contained()==clonk) obj->RemoveObject(); + } + return FX_OK; +} + +protected func FxS2AIDamage(clonk, fx, int dmg, int cause) +{ + // AI takes damage: Make sure we're alert so evasion and healing scripts are executed! + // It might also be feasible to execute encounter callbacks here (in case an AI is shot from a position it cannot see). + // However, the attacking Clonk is not known and the callback might be triggered e.g. by an unfortunate meteorite or lightning blast. + // So let's just keep it at alert state for now. + if (dmg<0) fx.alert=fx.time; + return dmg; +} + + +/* AI execution timer functions */ + +// called in context of the Clonk that is being controlled +private func Execute(proplist fx, int time) +{ + fx.time = time; + // Evasion, healing etc. if alert + if (fx.alert) if (ExecuteProtection(fx)) return true; + // Find something to fight with + if (!fx.weapon) { CancelAiming(fx); if (!ExecuteArm(fx)) return ExecuteIdle(fx); else if (!fx.weapon) return true; } + // Weapon out of ammo? + if (fx.ammo_check && !Call(fx.ammo_check, fx, fx.weapon)) { fx.weapon=nil; return false; } + // Find an enemy + if (fx.target) if (!fx.target->GetAlive() || (!fx.ranged && ObjectDistance(fx.target) >= fx.max_aggro_distance)) fx.target = nil; + if (!fx.target) + { + CancelAiming(fx); + if (!(fx.target = FindTarget(fx))) return ExecuteIdle(fx); + // first encounter callback. might display a message. + if (fx.encounter_cb) if (GameCall(fx.encounter_cb, this, fx.target)) fx.encounter_cb = nil; + // wake up nearby allies + if (fx.ally_alert_range) + { + var ally_fx; + for (var ally in FindObjects(Find_Distance(fx.ally_alert_range), Find_Exclude(this), Find_OCF(OCF_Alive), Find_Owner(GetOwner()))) + if (ally_fx = S2AI->GetAI(ally)) + if (!ally_fx.target) + { + ally_fx.target = fx.target; + ally_fx.alert = ally_fx.time; + if (ally_fx.encounter_cb) if (GameCall(ally_fx.encounter_cb, ally, fx.target)) ally_fx.encounter_cb = nil; + } + // waking up works only once. after that, AI might have moved and wake up Clonks it shouldn't + fx.ally_alert_range = nil; + } + } + // Attack it! + return Call(fx.strategy, fx); +} + +private func ExecuteProtection(fx) +{ + // Search for nearby projectiles. Ranged AI also searches for enemy clonks to evade. + var enemy_search; + if (fx.ranged) enemy_search = Find_And(Find_OCF(OCF_Alive), Find_Not(Find_Owner(GetOwner()))); + //Log("ExecProt"); + var projectiles = FindObjects(Find_InRect(-150,-50,300,80), Find_Or(Find_Category(C4D_Object), Find_Func("IsDangerous4AI"), Find_Func("IsArrow"), enemy_search), Find_OCF(OCF_HitSpeed2), Find_NoContainer(), Sort_Distance()); + for (var obj in projectiles) + { + var dx = obj->GetX()-GetX(), dy = obj->GetY()-GetY(); + var vx = obj->GetXDir(), vy = obj->GetYDir(); + if (Abs(dx)>40 && vx) dy += (Abs(10*dx/vx)**2)*GetGravity()/200; + var v2 = Max(vx*vx+vy*vy, 1); + var d2 = dx*dx+dy*dy; + if (d2/v2 > 4) + { + // won't hit within the next 20 frames + //obj->Message("ZZZ"); + continue; + } + //obj->Message("###%d", Sqrt(100*d2/v2)); + // Distance at which projectile will pass Clonk should be larger than Clonk size (erroneously assumes Clonk is a sphere) + var l = dx*vx+dy*vy; + //Log("%s l=%d d=%d r=%d gravcorr=%d", obj->GetName(), l, Sqrt(d2), Sqrt(d2-l*l/v2), (Abs(10*dx/vx)**2)*GetGravity()/200); + if (l<0 && Sqrt(d2-l*l/v2)<=GetCon()/8) + { + // Not if there's a wall between + if (!PathFree(GetX(),GetY(),obj->GetX(),obj->GetY())) continue; + // This might hit :o + fx.alert=fx.time; + // do we have a shield? + if (fx.shield) + { + // use it! + if (fx.aim_weapon == fx.shield) + { + // continue to hold shield + //Log("shield HOLD %d %d", dx,dy); + fx.shield->ControlUseHolding(this, dx,dy); + } + else + { + // start holding shield + if (fx.aim_weapon) CancelAiming(fx); + if (!CheckHandsAction(fx)) return true; + if (!fx.shield->ControlUseStart(this, dx,dy)) return false; // something's broken :( + //Log("shield START %d %d", dx,dy); + fx.shield->ControlUseHolding(this, dx,dy); + fx.aim_weapon = fx.shield; + } + return true; + } + // no shield. try to jump away + if (dx<0) SetComDir(COMD_Right); else SetComDir(COMD_Left); + if (ExecuteJump()) return true; + // Can only try to evade one projectile + break; + } + } + //Log("OK"); + // stay alert if there's a target. Otherwise alert state may wear off + if (fx.target) fx.alert=fx.time; else if (fx.time-fx.alert > S2AI_AlertTime) fx.alert=nil; + // nothing to do + return false; +} + +private func CheckTargetInGuardRange(fx) +{ + // if target is not in guard range, reset it and return false + if (!Inside(fx.target->GetX()-fx.guard_range.x, -10, fx.guard_range.wdt+9) + ||!Inside(fx.target->GetY()-fx.guard_range.y, -10, fx.guard_range.hgt+9)) + { fx.target=nil; return false; } + return true; +} + +private func ExecuteVehicle(fx) +{ + // only knows how to use catapult + if (!fx.vehicle || fx.vehicle->GetID() != Catapult) { fx.vehicle = nil; return false; } + // still pushing it? + if (GetProcedure() != "PUSH" || GetActionTarget() != fx.vehicle) + { + if (!GetCommand() || !Random(4)) SetCommand("Grab", fx.vehicle); + return true; + } + // Target still in guard range? + if (!CheckTargetInGuardRange(fx)) return false; + // turn in correct direction + var x=GetX(), y=GetY(), tx=fx.target->GetX(), ty=fx.target->GetY()-4; + if (tx>x && !fx.vehicle.dir) { fx.vehicle->ControlRight(this); return true; } + if (txControlLeft (this); return true; } + // make sure we're aiming + if (!fx.aim_weapon) + { + if (!fx.vehicle->~ControlUseStart(this)) return false; + fx.aim_weapon = fx.vehicle; + fx.aim_time = fx.time; + return true; + } + // update catapult animation + fx.vehicle->~ControlUseHolding(this, tx-x, ty-y); + // project target position + var d = Distance(x,y,tx,ty); + fx.projectile_speed = fx.vehicle->DefinePower(tx-x, ty-y); + var dt = d * 10 / fx.projectile_speed; // projected travel time of the object + tx += fx.target->GetXDir(dt); + ty += fx.target->GetYDir(dt); + if (!fx.target->GetContact(-1)) ty += GetGravity()*dt*dt/200; + // Can shoot now? + if (fx.time >= fx.aim_time + fx.aim_wait) if (PathFree(x,y,tx,ty)) + { + fx.aim_weapon->~ControlUseStop(this, tx-x,ty-y); + fx.aim_weapon = nil; + } + return true; +} + +private func CancelAiming(fx) +{ + if (fx.aim_weapon) + { + //if (fx.aim_weapon==fx.shield) Log("cancel shield"); + fx.aim_weapon->~ControlUseCancel(this); + fx.aim_weapon = nil; + } + return true; +} + +private func IsAimingOrLoading() { return !!GetEffect("IntAim*", this); } + +private func ExecuteRanged(fx) +{ + // Still carrying the bow? + if (fx.weapon->Contained() != this) { fx.weapon=nil; return false; } + // Target still in guard range? + if (!CheckTargetInGuardRange(fx)) return false; + // Look at target + ExecuteLookAtTarget(fx); + // Make sure we can shoot + if (!IsAimingOrLoading() || !fx.aim_weapon) + { + CancelAiming(fx); + if (!CheckHandsAction(fx)) return true; + // Start aiming + if (!fx.weapon->ControlUseStart(this, fx.target->GetX()-GetX(), fx.target->GetY()-GetY())) return false; // something's broken :( + fx.aim_weapon = fx.weapon; + fx.aim_time = fx.time; + // Enough for now + return; + } + // Stuck in aim procedure check? + if (GetEffect("IntAimCheckProcedure", this) && !this->ReadyToAction()) return ExecuteStand(fx); + // Calculate offset to target. Take movement into account + // Also aim for the head (y-4) so it's harder to evade by jumping + var x=GetX(), y=GetY(), tx=fx.target->GetX(), ty=fx.target->GetY()-4; + var d = Distance(x,y,tx,ty); + var dt = d * 10 / fx.projectile_speed; // projected travel time of the arrow + tx += fx.target->GetXDir(dt); + ty += fx.target->GetYDir(dt); + if (!fx.target->GetContact(-1)) ty += GetGravity()*dt*dt/200; + // Path to target free? + if (PathFree(x,y,tx,ty)) + { + // Get shooting angle + var shooting_angle = GetBallisticAngle(tx-x, ty-y, fx.projectile_speed, 160); + if (GetType(shooting_angle) != C4V_Nil) + { + // No ally on path? + var ally = FindObject(Find_OnLine(0,0,tx-x,ty-y), Find_Exclude(this), Find_OCF(OCF_Alive), Find_Owner(GetOwner())); + if (ally) + { + if (ExecuteJump()) return true; + // can't jump and ally is in the way. just wait. + } + else + { + //Message("Bow @ %d!!!", shooting_angle); + // Aim/Shoot there + x = Sin(shooting_angle,100); + y = -Cos(shooting_angle,100); + fx.aim_weapon->ControlUseHolding(this, x,y); + if (this->IsAiming() && fx.time >= fx.aim_time + fx.aim_wait) + { + //Log("Throw angle %v speed %v to reach %d %d", shooting_angle, fx.projectile_speed, tx-GetX(), ty-GetY()); + fx.aim_weapon->ControlUseStop(this, x,y); + fx.aim_weapon = nil; + } + return true; + } + } + } + // Path not free or out of range. Just wait for enemy to come... + //Message("Bow @ %s!!!", fx.target->GetName()); + fx.aim_weapon->ControlUseHolding(this,tx-x,ty-y); + // Might also change target if current is unreachable + var new_target; + if (!Random(3)) if (new_target = FindTarget(fx)) fx.target = new_target; + return true; +} + +private func ExecuteLookAtTarget(fx) +{ + // set direction to look at target. can assume this is instantanuous + var dir; + if (fx.target->GetX() > GetX()) dir = DIR_Right; else dir = DIR_Left; + SetDir(dir); + return true; +} + +private func ExecuteThrow(fx) +{ + // Still carrying the weapon to throw? + if (fx.weapon->Contained() != this) { fx.weapon=nil; return false; } + // Path to target free? + var x=GetX(), y=GetY(), tx=fx.target->GetX(), ty=fx.target->GetY(); + if (PathFree(x,y,tx,ty)) + { + var throw_speed = this.ThrowSpeed; + if (fx.weapon->GetID() == Javelin) throw_speed *= 2; + var rx = (throw_speed*throw_speed)/(100*GetGravity()); // horizontal range for 45 degree throw if enemy is on same height as we are + var ry = throw_speed*7/(GetGravity()*10); // vertical range of 45 degree throw + var dx = tx-x, dy = ty-y+15*GetCon()/100; // distance to target. Reduce vertical distance a bit because throwing exit point is not at center + // Check range + // Could calculate the optimal parabulum here, but that's actually not very reliable on moving targets + // It's usually better to throw straight at the target and only throw upwards a bit if the target stands on high ground or is far away + // Also ignoring speed added by own velocity, etc... + if (Abs(dx)*ry-Min(dy)*rx <= rx*ry) + { + // We're in range. Can throw? + if (!CheckHandsAction(fx)) return true; + // OK. Calc throwing direction + dy -= dx*dx/rx; // big math! + // And throw! + //Message("Throw!"); + SetCommand("None"); SetComDir(COMD_Stop); + return this->ControlThrow(fx.weapon, dx, dy); + } + } + // Can't reach target yet. Walk towards it. + if (!GetCommand() || !Random(3)) SetCommand("MoveTo", fx.target); + //Message("Throw %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName()); + return true; +} + +private func CheckHandsAction(fx) +{ + // can use hands? + if (this->~HasHandAction()) return true; + // Can't throw: Is it because e.g. we're scaling? + if (!this->HasActionProcedure()) { ExecuteStand(fx); return false; } + // Probably hands busy. Just wait. + //Message("HandsBusy"); + return false; +} + +private func ExecuteStand(fx) +{ + //Message("Stand"); + SetCommand("None"); + if (GetProcedure() == "SCALE") + { + if (GetDir()==DIR_Left) + ObjectControlMovement(GetOwner(), CON_Right, 100); + else + ObjectControlMovement(GetOwner(), CON_Left, 100); + } + else if (GetProcedure() == "HANGLE") + { + ObjectControlMovement(GetOwner(), CON_Down, 100); + } + else + { + // Hm. What could it be? Let's just hope it resolves itself somehow... + SetComDir(COMD_Stop); + //Message("???"); + } + return true; +} + +private func ExecuteMelee(fx) +{ + // Still carrying the melee weapon? + if (fx.weapon->Contained() != this) { fx.weapon=nil; return false; } + // Are we in range? + var x=GetX(), y=GetY(), tx=fx.target->GetX(), ty=fx.target->GetY(); + var dx = tx-x, dy = ty-y; + if (Abs(dx) <= 10 && PathFree(x,y,tx,ty)) + { + if (dy >= -15) + { + // target is under us - sword slash downwards! + if (!CheckHandsAction(fx)) return true; + // Stop here + SetCommand("None"); SetComDir(COMD_None); + // cooldown? + if (!fx.weapon->CanStrikeWithWeapon(this)) + { + //Message("MeleeWAIT %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName()); + // While waiting for the cooldown, we try to evade... + ExecuteEvade(fx,dx,dy); + return true; + } + // OK, slash! + //Message("MeleeSLASH %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName()); + return fx.weapon->ControlUse(this, tx,ty); + } + // Clonk is above us - jump there + //Message("MeleeJump %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName()); + this->ControlJump(); + if (dx<-5) SetComDir(COMD_Left); else if (dx>5) SetComDir(COMD_Right); else SetComDir(COMD_None); + } + // Not in range. Walk there. + if (!GetCommand() || !Random(3)) SetCommand("MoveTo", fx.target); + //Message("Melee %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName()); + return true; +} + +private func ExecuteEvade(fx,int threat_dx,int threat_dy) +{ + // Evade from threat at position delta threat_* + if (threat_dx < 0) SetComDir(COMD_Left); else SetComDir(COMD_Right); + if (threat_dy >= -5 && !Random(2)) if (ExecuteJump(fx)) return true; + // shield? todo + return true; +} + +private func ExecuteJump(fx) +{ + // Jump if standing on floor + if (GetProcedure() == "WALK") + //if (GetContact(-1, CNAT_Bottom)) - implied by walk + return this->ControlJump(); + return false; +} + +private func ExecuteArm(fx) +{ + // Find shield + if (fx.shield = FindContents(Shield)) this->SetHandItemPos(1, this->GetItemPos(fx.shield)); + // Find a weapon. For now, just search own inventory + if (FindInventoryWeapon(fx) && fx.weapon->Contained()==this) + { + this->SetHandItemPos(0, this->GetItemPos(fx.weapon)); + return true; + } + // no weapon :( + return false; +} + +private func FindInventoryWeapon(fx) +{ + fx.ammo_check = nil; fx.ranged = false; + // Find weapon in inventory, mark it as equipped and set according strategy, etc. + if (fx.weapon = fx.vehicle) + if (CheckVehicleAmmo(fx, fx.weapon)) + { fx.strategy = S2AI.ExecuteVehicle; fx.ranged=true; fx.aim_wait = 20; fx.ammo_check = S2AI.CheckVehicleAmmo; return true; } + else + fx.weapon = nil; + if (fx.weapon = FindContents(Bow)) + if (HasArrows(fx, fx.weapon)) + { fx.strategy = S2AI.ExecuteRanged; fx.projectile_speed = 100; fx.aim_wait = 0; fx.ammo_check = S2AI.HasArrows; fx.ranged=true; return true; } + else + fx.weapon = nil; + if (fx.weapon = FindContents(Javelin)) { fx.strategy = S2AI.ExecuteRanged; fx.projectile_speed = this.ThrowSpeed*21/100; fx.aim_wait = 16; fx.ranged=true; return true; } + if (fx.weapon = FindContents(Firestone)) { fx.strategy = S2AI.ExecuteThrow; return true; } + if (fx.weapon = FindContents(Rock)) { fx.strategy = S2AI.ExecuteThrow; return true; } + if (fx.weapon = FindContents(Sword)) { fx.strategy = S2AI.ExecuteMelee; return true; } + //if (fx.weapon = Contents(0)) { fx.strategy = S2AI.ExecuteThrow; return true; } - don't throw empty bow, etc. + // no weapon :( + return false; +} + +private func HasArrows(fx, object weapon) +{ + if (weapon->Contents(0)) return true; + if (FindObject(Find_Container(this), Find_Func("IsArrow"))) return true; + return false; +} + +private func CheckVehicleAmmo(fx, object catapult) +{ + if (catapult->ContentsCount()) return true; + // Vehicle out of ammo: Can't really be refilled. Stop using that weapon. + fx.vehicle = nil; + this->ObjectCommand("UnGrab"); + return false; +} + +private func ExecuteIdle(fx) +{ + if (!Inside(GetX()-fx.home_x, -5,5) || !Inside(GetY()-fx.home_y, -15,15)) + { + SetCommand("MoveTo", nil, fx.home_x, fx.home_y); + } + else + { + SetCommand("None"); SetComDir(COMD_Stop); SetDir(fx.home_dir); + } + //Message("zZz"); + return true; +} + +private func FindTarget(fx) +{ + // could search for hostile...for now, just search for all other players + for (var target in FindObjects(Find_AtRect(fx.guard_range.x-GetX(),fx.guard_range.y-GetY(),fx.guard_range.wdt,fx.guard_range.hgt), Find_OCF(OCF_Alive), Find_Not(Find_Owner(GetOwner())), Sort_Random())) + if (PathFree(GetX(),GetY(),target->GetX(),target->GetY())) + return target; + // nothing found + return nil; +} + +// Helper function: Convert target cordinates and bow out speed to desired shooting angle +// Because http://en.wikipedia.org/wiki/Trajectory_of_a_projectile says so +// No SimFlight checks to check upper angle (as that is really easy to evade anyway) +// just always shoot the lower angle if sight is free +private func GetBallisticAngle(int dx, int dy, int v, int max_angle) +{ + // v is in 1/10 pix/frame + // gravity is in 1/100 pix/frame^2 + var g = GetGravity(); + // correct vertical distance to account for integration error + // engine adds gravity after movement, so targets fly higher than they should + // thus, we aim lower. we don't know the travel time yet, so we assume some 90% of v is horizontal + // (it's ~2px correction for 200px shooting distance) + dy += Abs(dx)*g*10/(v*180); + //Log("Correction: Aiming %d lower!", Abs(dx)*q*10/(v*180)); + // q is in 1/10000 (pix/frame)^4 + var q = v**4 - g*(g*dx*dx-2*dy*v*v); // dy is negative up + if (q<0) return nil; // out of range + var a = (Angle(0,0,g*dx,Sqrt(q)-v*v)+180)%360-180; + // Check bounds + if(!Inside(a, -max_angle, max_angle)) return nil; + return a; +} + + +/* Editor display */ + +// called in clonk context +func UpdateDebugDisplay(fx) +{ + if (fx.debug) { EditCursorDeselection(fx); EditCursorSelection(fx); } + return true; +} + +// called in clonk context +func EditCursorSelection(fx) +{ + // clear previous + if (fx.debug) EditCursorDeselection(fx); + // encounter message + var msg = ""; + if (fx.encounter_cb) msg = Format("%s%v", msg, fx.encounter_cb); + // contents message + for (var i=0; iGetID()); + Message("@AI %s", msg); + // draw ally alert range. draw as square, although a circle would be more appropriate + fx.debug = {}; + var clr; + var x=GetX(), y=GetY(); + if (fx.ally_alert_range) + { + clr = 0xffffff00; + fx.debug.a1 = DebugLine->Create(x,y-fx.ally_alert_range,x+fx.ally_alert_range,y,clr); + fx.debug.a2 = DebugLine->Create(x+fx.ally_alert_range,y,x,y+fx.ally_alert_range,clr); + fx.debug.a3 = DebugLine->Create(x,y+fx.ally_alert_range,x-fx.ally_alert_range,y,clr); + fx.debug.a4 = DebugLine->Create(x-fx.ally_alert_range,y,x,y-fx.ally_alert_range,clr); + } + // draw guard range + if (fx.guard_range.wdt && fx.guard_range.hgt) + { + clr = 0xffff0000; + fx.debug.r1 = DebugLine->Create(fx.guard_range.x,fx.guard_range.y,fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y,clr); + fx.debug.r2 = DebugLine->Create(fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y,fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y+fx.guard_range.hgt,clr); + fx.debug.r3 = DebugLine->Create(fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y+fx.guard_range.hgt,fx.guard_range.x,fx.guard_range.y+fx.guard_range.hgt,clr); + fx.debug.r4 = DebugLine->Create(fx.guard_range.x,fx.guard_range.y+fx.guard_range.hgt,fx.guard_range.x,fx.guard_range.y,clr); + } + return true; +} + +// called in clonk context +func EditCursorDeselection(fx) +{ + if (fx.debug) + { + if (fx.debug.r1) fx.debug.r1->RemoveObject(); + if (fx.debug.r2) fx.debug.r2->RemoveObject(); + if (fx.debug.r3) fx.debug.r3->RemoveObject(); + if (fx.debug.r4) fx.debug.r4->RemoveObject(); + if (fx.debug.a1) fx.debug.a1->RemoveObject(); + if (fx.debug.a2) fx.debug.a2->RemoveObject(); + if (fx.debug.a3) fx.debug.a3->RemoveObject(); + if (fx.debug.a4) fx.debug.a4->RemoveObject(); + Message(""); + } + fx.debug = nil; + return true; +} diff --git a/planet/Objects.ocd/Helpers.ocd/FloatingMessage.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/FloatingMessage.ocd/Script.c index 535a6aac4..d7d2cce61 100644 --- a/planet/Objects.ocd/Helpers.ocd/FloatingMessage.ocd/Script.c +++ b/planet/Objects.ocd/Helpers.ocd/FloatingMessage.ocd/Script.c @@ -74,4 +74,6 @@ public func Initialize() g = 255; b = 255; return true; -} \ No newline at end of file +} + +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/Script.c index 4e657bbe9..7c53449fc 100644 --- a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/Script.c +++ b/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/Script.c @@ -25,6 +25,8 @@ local toSpawn; +static ItemSpark_particle; +static ItemSpark_particle_additive; global func StartItemSparks(int rate, bool mirror) { @@ -87,8 +89,36 @@ global func FxGlobalItemSparksTimer(_, effect, time) s.toSpawn=what; } +global func FxGlobalItemSparksSaveScen(_, effect, props) +{ + props->Add("Sparks", "StartItemSparks(%d, %v)", effect.rate, effect.mirror); + return true; +} + protected func Initialize() { + if (!ItemSpark_particle) + { + ItemSpark_particle = + { + Size = PV_Linear(15, 0), + Rotation = PV_Step(1, PV_Random(0, 90)), + Alpha = PV_Linear(0, 255), + R = PV_Random(0, 50), + G = PV_Random(0, 50), + B = PV_Random(200, 255), + Attach = ATTACH_Back, + CollisionVertex = 500, + OnCollision = PC_Die() + }; + + ItemSpark_particle_additive = + { + Prototype = ItemSpark_particle, + BlitMode = GFX_BLIT_Additive, + Attach = ATTACH_Front + }; + } AddEffect("Sparkle", this, 1, 2, this); AddEffect("CheckStuck", this, 1, 30); } @@ -102,12 +132,8 @@ func FxCheckStuckTimer(_, effect) func FxSparkleTimer(_, effect) { - //var x=RandomX(-4, 4); - //var p="ItemSpark"; - //if(Random(2)) p="ItemSparkA"; - //CreateParticle(p, x, (4-Abs(x))/2, -x/2, -3, 40, RGBa(50,50,150+Random(100), 200), nil); - CreateParticle("ItemSpark", 0, 0, 0, GetYDir(), 40, RGBa(50,50,150+Random(100), 255), this, true); - CreateParticle("ItemSparkA", 0, 0, 0, GetYDir(), 20, RGBa(50,50,200+Random(50), 255), this, false); + CreateParticle("ItemSpark", PV_Random(0, GetXDir()/10), PV_Random(0, GetYDir()/10), GetXDir(), GetYDir(), 36, ItemSpark_particle, 5); + CreateParticle("ItemSpark", PV_Random(0, GetXDir()/10), PV_Random(0, GetYDir()/10), GetXDir(), GetYDir(), 20, ItemSpark_particle_additive, 5); if(!Random(36)) for(var i=0;i<3;++i) @@ -140,8 +166,9 @@ func FxSparkleDeathTimer(_, effect, effect_time) effect.velX*=-1; effect.velY*=-1; } - CreateParticle("ItemSpark", AbsX(effect.x), AbsY(effect.y), 0, 0, effect.size, RGBa(50,50,150, 175), effect.from, true); - CreateParticle("ItemSparkA", AbsX(effect.x), AbsY(effect.y), 0, 0, effect.size/2, RGBa(50,50,255, 175), effect.from, false); + + effect.from->CreateParticle("ItemSpark", AbsX(effect.x), AbsY(effect.y), 0, 0, 18, ItemSpark_particle, 1); + effect.from->CreateParticle("ItemSpark", AbsX(effect.x), AbsY(effect.y), 0, 0, 10, ItemSpark_particle_additive, 1); effect.xT+=effect.velX; effect.yT+=effect.velY; @@ -157,9 +184,13 @@ func DoSpawn() { if(toSpawn == nil) toSpawn=GameCall("GetSparkItem", GetX(), GetY()); - var o=CreateObject(toSpawn, 0, 0, NO_OWNER); - o->SetYDir(-1); - GameCall("SetupSparkItem", o); + var item = CreateObject(toSpawn, 0, 0, NO_OWNER); + + if (item) + { + item->SetYDir(-1); + GameCall("SetupSparkItem", item); + } for(var cnt=0;cnt<5;++cnt) { @@ -187,4 +218,6 @@ func Hit() { if(GetEffect("Off", this)) return SetSpeed(); DoSpawn(); -} \ No newline at end of file +} + +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticle.ocd/Particle.txt b/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticle.ocd/Particle.txt deleted file mode 100644 index 991f0bfdb..000000000 --- a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticle.ocd/Particle.txt +++ /dev/null @@ -1,14 +0,0 @@ -[Particle] -Name=ItemSpark -MaxCount=1000 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Additive=0 -Attach=0 -RByV=3 -AlphaFade=8 -VertexCount=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticleAdditive.ocd/Graphics.png b/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticleAdditive.ocd/Graphics.png deleted file mode 100644 index d2ee451cd..000000000 Binary files a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticleAdditive.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticleAdditive.ocd/Particle.txt b/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticleAdditive.ocd/Particle.txt deleted file mode 100644 index b34e42c40..000000000 --- a/planet/Objects.ocd/Helpers.ocd/ItemSpark.ocd/SparkParticleAdditive.ocd/Particle.txt +++ /dev/null @@ -1,14 +0,0 @@ -[Particle] -Name=ItemSparkA -MaxCount=1000 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Additive=1 -Attach=0 -RByV=3 -AlphaFade=8 -VertexCount=1 \ No newline at end of file diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/DefCore.txt b/planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/DefCore.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/DefCore.txt rename to planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/DefCore.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/Graphics.png b/planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/Graphics.png similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/Graphics.png rename to planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/Graphics.png diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/Script.c similarity index 85% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/Script.c rename to planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/Script.c index dce4fe987..b7c98e2e7 100644 --- a/planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/Script.c +++ b/planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/Script.c @@ -9,8 +9,21 @@ /*-- Object Restoration --*/ +local particles; + protected func Initialize() { + particles = + { + Size = PV_Linear(10, 0), + Stretch = PV_Speed(1000, 1000), + Rotation = PV_Direction(), + Alpha = PV_KeyFrames(0, 0, 0, 100, 64, 1000, 64), + R = PV_Random(180, 200), + G = PV_Random(180, 200), + B = PV_Random(220, 255), + DampingX = 900, DampingY = 900 + }; return; } @@ -59,6 +72,7 @@ protected func FxRestoreTimer(object target, effect, int time) effect.to_restore->RemoveObject(); return -1; } + // Move to the object with a weighed sin-wave centered around the halfway point. var length = Distance(init_x, init_y, to_x, to_y); // Remove effect if animation is done. @@ -75,14 +89,8 @@ protected func FxRestoreTimer(object target, effect, int time) var x = init_x + Sin(angle, 2 * time); var y = init_y - Cos(angle, 2 * time); target->SetPosition(x, y); - // Draw Particles. - x = init_x + Sin(angle, 2 * time) + Cos(angle, Sin(20 * time, dev)) - target->GetX(); - y = init_y - Cos(angle, 2 * time) + Sin(angle, Sin(20 * time, dev)) - target->GetY(); - var color = RGB(128 + Cos(4 * time, 127), 128 + Cos(4 * time + 120, 127), 128 + Cos(4 * time + 240, 127)); - CreateParticle("PSpark", x, y, 0, 0, 32, color); - x = init_x + Sin(angle, 2 * time) - Cos(angle, Sin(20 * time, dev)) - target->GetX(); - y = init_y - Cos(angle, 2 * time) - Sin(angle, Sin(20 * time, dev)) - target->GetY(); - CreateParticle("PSpark", x, y, 0, 0, 32, color); + + CreateParticle("SphereSpark", 0, 0, 0, 0, 36, particles, 1); return 1; } @@ -128,8 +136,7 @@ protected func FxRestoreStop(object target, effect, int reason, bool temporary) to_x = to_container->GetX(); to_y = to_container->GetY(); } - var color = RGB(128 + Cos(18 * i, 127), 128 + Cos(18 * i + 120, 127), 128 + Cos(18 * i + 240, 127)); - CreateParticle("PSpark", to_x - GetX(), to_y - GetY(), RandomX(-10, 10), RandomX(-10, 10), 32, color); + CreateParticle("SphereSpark", to_x - GetX(), to_y - GetY(), PV_Random(-50, 50), PV_Random(-50, 50), PV_Random(2, 10), particles, 10); } // Sound. //TODO new sound. @@ -191,5 +198,16 @@ global func FxRestoreModeStop(object target, effect, int reason, bool temporary return 1; } +/* Scenario saving: Objects with restoration effect are stored. Restorations "on the way" are not. */ + +func SaveScenarioObject() { return false; } + +global func FxRestoreModeSaveScen(obj, effect, props) +{ + props->AddCall("Restore", obj, "AddRestoreMode", effect.to_container, effect.to_x, effect.to_y); + return true; +} + + local Name = "$Name$"; local Description = "$Description$"; diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/StringTblDE.txt b/planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/StringTblDE.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/StringTblDE.txt rename to planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/StringTblDE.txt diff --git a/planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/StringTblUS.txt b/planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/StringTblUS.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/Skylands.ocs/ObjectRestorer.ocd/StringTblUS.txt rename to planet/Objects.ocd/Helpers.ocd/ObjectRestorer.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Helpers.ocd/StatusSymbol.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/StatusSymbol.ocd/Script.c index 18d2e8942..4309c2dad 100644 --- a/planet/Objects.ocd/Helpers.ocd/StatusSymbol.ocd/Script.c +++ b/planet/Objects.ocd/Helpers.ocd/StatusSymbol.ocd/Script.c @@ -136,4 +136,5 @@ func FxBlinkingTimer(target, effect) this->Message(message); return 1; } - \ No newline at end of file + +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Icons.ocd/Cancel.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Cancel.ocd/DefCore.txt new file mode 100644 index 000000000..2a2d29724 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Cancel.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Cancel +Version=5,2,0,1 +Category=C4D_StaticBack +Picture=0,0,32,32 +Width=32 +Height=22 +Offset=-16,-16 diff --git a/planet/Objects.ocd/Icons.ocd/Cancel.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Cancel.ocd/Graphics.png new file mode 100644 index 000000000..28aa29857 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Cancel.ocd/Graphics.png differ diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Coins.ocd/DefCore.txt similarity index 58% rename from planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/DefCore.txt rename to planet/Objects.ocd/Icons.ocd/Coins.ocd/DefCore.txt index 84a6c44f1..c180406cc 100644 --- a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/DefCore.txt +++ b/planet/Objects.ocd/Icons.ocd/Coins.ocd/DefCore.txt @@ -1,9 +1,8 @@ [DefCore] -id=EnergyBar +id=Icon_Coins +Version=5,2,0,1 Category=C4D_StaticBack +Picture=0,0,32,32 Width=32 Height=32 Offset=-16,-16 -Vertices=1 -VertexX=0 -VertexY=8 diff --git a/planet/Objects.ocd/Icons.ocd/Coins.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Coins.ocd/Graphics.png new file mode 100644 index 000000000..841f09587 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Coins.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/DefCore.txt new file mode 100644 index 000000000..0f5d76c9b --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Lightbulb +Version=5,2,0,1 +Category=C4D_StaticBack +Picture=0,0,64,64 +Width=64 +Height=64 +Offset=-32,-32 diff --git a/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/Graphics.png new file mode 100644 index 000000000..ceba0dbed Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsGreen.png b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsGreen.png new file mode 100644 index 000000000..f71979770 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsGreen.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsRed.png b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsRed.png new file mode 100644 index 000000000..7337c899f Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsRed.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsYellow.png b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsYellow.png new file mode 100644 index 000000000..5e53c0344 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Lightbulb.ocd/GraphicsYellow.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Number.ocd/GraphicsInf.png b/planet/Objects.ocd/Icons.ocd/Number.ocd/GraphicsInf.png new file mode 100644 index 000000000..1e3edcf9e Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Number.ocd/GraphicsInf.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Ok.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Ok.ocd/DefCore.txt new file mode 100644 index 000000000..a3a9c7e41 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Ok.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Ok +Version=5,2,0,1 +Category=C4D_StaticBack +Picture=0,0,32,32 +Width=32 +Height=22 +Offset=-16,-16 diff --git a/planet/Objects.ocd/Icons.ocd/Ok.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Ok.ocd/Graphics.png new file mode 100644 index 000000000..ab6b87814 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Ok.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Ok.ocd/GraphicsMulti.png b/planet/Objects.ocd/Icons.ocd/Ok.ocd/GraphicsMulti.png new file mode 100644 index 000000000..2405ae385 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Ok.ocd/GraphicsMulti.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Ok.ocd/GraphicsRed.png b/planet/Objects.ocd/Icons.ocd/Ok.ocd/GraphicsRed.png new file mode 100644 index 000000000..18a7ded27 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Ok.ocd/GraphicsRed.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Play.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Play.ocd/DefCore.txt new file mode 100644 index 000000000..7f88a79ac --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Play.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Play +Version=5,2,0,1 +Category=C4D_StaticBack +Picture=0,0,32,32 +Width=32 +Height=22 +Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/Icons.ocd/Play.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Play.ocd/Graphics.png new file mode 100644 index 000000000..0fbb47eb1 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Play.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Stop.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Stop.ocd/DefCore.txt new file mode 100644 index 000000000..9e6bf7d53 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Stop.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Stop +Version=5,2,0,1 +Category=C4D_StaticBack +Picture=0,0,32,32 +Width=32 +Height=22 +Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/Icons.ocd/Stop.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Stop.ocd/Graphics.png new file mode 100644 index 000000000..4dcfac724 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Stop.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/Script.c index 85b15b71e..7351880cf 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/Script.c @@ -5,8 +5,6 @@ protected func Hit() Sound("GeneralHit?"); } -public func IsOvenProduct() { return true; } - /* Eating */ protected func ControlUse(object clonk, int iX, int iY) @@ -16,9 +14,12 @@ protected func ControlUse(object clonk, int iX, int iY) public func NutritionalValue() { return 50; } -public func NeedsWater() { return true; } +public func IsKitchenProduct() { return true; } +public func GetLiquidNeed() { return ["Water", 50]; } +public func GetFuelNeed() { return 50; } local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblDE.txt index 717d5dbce..3579e66ee 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Brot -Description=Schmackhafte Mahlzeit. \ No newline at end of file +Description=Diese schmackhafte Mahlzeit gibt dem Clonk viele Lebenspunkte zurück. +UsageHelp=Drücke [Benutzen] um das Brot zu essen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblUS.txt index 5a779e932..f805379a9 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Bread.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Bread -Description=Tasty meal. \ No newline at end of file +Description=This tasty meal restores the clonk's health a lot. +UsageHelp=Press [Use] to eat the bread. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/Script.c index fa857ef1a..b28518cf8 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/Script.c @@ -14,7 +14,11 @@ protected func ControlUse(object clonk, int iX, int iY) public func NutritionalValue() { return 15; } +public func IsKitchenProduct() { return true; } +public func GetFuelNeed() { return 50; } + local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = 1; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblDE.txt index 8505d3a2f..69bd89418 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ -Name=Gekochter Pilz -Description=Deliziöse Mahlzeit. \ No newline at end of file +Name=Gekochter Pilz +Description=Diese fantastische Mahlzeit gibt dem Clonk einige Lebenspunkte zurück. +UsageHelp=Drücke [Benutzen] um den Pilz zu essen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblUS.txt index 2ca43f2f6..6c62cd081 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/CookedMushroom.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Cooked Mushroom -Description=Delicious meal. \ No newline at end of file +Description=This fantastic meal restores some of the clonk's health. +UsageHelp=Press [Use] to eat the mushroom. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Flour.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Flour.ocd/StringTblUS.txt index fd6376702..fa272596b 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Flour.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Flour.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Flour -Description=Made from grain. Basic ingredient for bakery products. \ No newline at end of file +Description=Made from grain. Basic ingredient for baked goods. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/Script.c index fab101c64..6c84920d1 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/Script.c @@ -17,6 +17,7 @@ public func NutritionalValue() { return 10; } local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = false; diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblDE.txt index 4a68b5b23..c5d50aefa 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Sprossenbeere -Description=Süßlich. Keimt sehr schnell und ist schlecht zu lagern. \ No newline at end of file +Description=Süßlich. Keimt sehr schnell und ist schlecht zu lagern. +UsageHelp=Drücke [Benutzen] um die Beere zu essen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblUS.txt index dbabd8342..e27a14016 100644 --- a/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Foodstuff.ocd/Sproutberry.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Sprout Berry -Description=Sweet. Sprouts very fast and is difficult to store. \ No newline at end of file +Description=Sweet. Sprouts very fast and is difficult to store. +UsageHelp=Press [Use] to eat the berry. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/DefCore.txt new file mode 100644 index 000000000..c0ed8c8be --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Amethyst +Version=5,2,0,1 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=4 +VertexX=-4,0,4,0 +VertexY=0,-4,0,4 +VertexFriction=70,70,70,70 +Value=50 +Mass=10 +Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics.8.png new file mode 100644 index 000000000..1f9c51127 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics2.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics2.8.png new file mode 100644 index 000000000..4690beb42 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics2.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics3.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics3.8.png new file mode 100644 index 000000000..061b56f1e Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics3.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics4.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics4.8.png new file mode 100644 index 000000000..1c1cd2b55 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Graphics4.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Script.c new file mode 100644 index 000000000..6f154b1a4 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/Script.c @@ -0,0 +1,9 @@ +/*--- Amethyst ---*/ + +#include Ruby + +// returns the color of the gem (used for effects) +func GetGemColor() +{ + return RGB(255, 20, 255); +} diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/StringTblDE.txt new file mode 100644 index 000000000..5af20547d --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Amethyst +Description=Wertvoller Klunker \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/StringTblUS.txt new file mode 100644 index 000000000..51f30fe16 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Amethyst.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Amethyst +Description=Valuable clunker diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/DefCore.txt new file mode 100644 index 000000000..22d874a4c --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=Cloth +Version=5,2,0,1 +Category=C4D_Object +Width=8 +Height=4 +Offset=-4,-2 +Vertices=3 +VertexX=0,3,-3 +VertexY=0,1,1 +VertexFriction=50,100,100 +Value=10 +Mass=1 +Components=Cotton=1 +Picture=32,0,64,64 diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/Graphics.4.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/Graphics.4.png new file mode 100644 index 000000000..20dc61122 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/Script.c new file mode 100644 index 000000000..002d12ce9 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/Script.c @@ -0,0 +1,14 @@ +/*-- Cloth --*/ + +protected func Hit() +{ + Sound("GeneralHit?"); +} + +public func IsLoomProduct() { return true; } + +local Name = "$Name$"; +local Description = "$Description$"; +local Collectible = 1; +local Rebuy = true; +local Plane = 470; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/StringTblDE.txt new file mode 100644 index 000000000..385aecf62 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Stoff +Description=Baumaterial für alle stofflichen Dinge. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/StringTblUS.txt new file mode 100644 index 000000000..3a37da0bb --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cloth.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Cloth +Description=Basic material for fabric related objects. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/DefCore.txt index eae72f611..83a9114ca 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/DefCore.txt @@ -5,7 +5,7 @@ Category=C4D_Object Width=8 Height=8 Offset=-4,-4 -Picture=0,0,64,64 +Picture=64,0,64,64 Vertices=3 VertexX=0,2,-2 VertexY=1,-1,-1 @@ -14,5 +14,3 @@ Value=4 Mass=9 Components=Wood=2; Rotate=1 -ContactIncinerate=1 -BlastIncinerate=5 diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics.8.png index ea810d53b..40917ef52 100644 Binary files a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics.8.png and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics1.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics1.8.png index 05c7f7207..443097bf6 100644 Binary files a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics1.8.png and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics1.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics2.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics2.8.png index 8c51f6330..cb218ba4b 100644 Binary files a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics2.8.png and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics2.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics3.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics3.8.png index b675712f6..abb2de42f 100644 Binary files a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics3.8.png and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics3.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics4.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics4.8.png index f8ac72f31..cf6119570 100644 Binary files a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics4.8.png and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Graphics4.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Script.c index 9eae78f6f..2742ff257 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Coal.ocd/Script.c @@ -20,3 +20,6 @@ local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local BlastIncinerate = 5; +local ContactIncinerate = 1; +local Plane = 460; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/DefCore.txt new file mode 100644 index 000000000..03feefcb0 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/DefCore.txt @@ -0,0 +1,13 @@ +[DefCore] +id=Cotton +Version=5,2,0,1 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=2 +VertexX=0,0 +VertexY=1,-1 +VertexFriction=40,40,40 +Value=5 +Mass=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/Graphics.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/Graphics.8.png new file mode 100644 index 000000000..849e91f5a Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/Script.c new file mode 100644 index 000000000..9c8c6f807 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/Script.c @@ -0,0 +1,42 @@ +/* + Cotton + Author: Clonkonaut + + For planting cotton plants or to get cloth +*/ + +/*public func ControlUse(object clonk, int x, int y, bool box) +{ + if(clonk->GetAction() != "Walk") return true; + // Search for ground + x = 0; y = 0; + if (GBackSemiSolid(x,y)) return true; + var i = 0; + while (!GBackSolid(x,y) && i < 15) { ++y; ++i; } + if (!GBackSolid(x,y)) return true; + if (GetMaterialVal("Soil", "Material", GetMaterial(x,y)) == 1) + { + // Plant! + clonk->DoKneel(); + CreateObject(Wheat, x, y, clonk->GetOwner())->SetCon(1); + RemoveObject(); + } + else + clonk->Message("$NoSuitableGround$"); + + return true; +}*/ + +protected func Hit() +{ + Sound("GeneralHit?"); +} + +public func IsLoomIngredient() { return true; } + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Rebuy = true; +local Plane = 460; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/StringTblDE.txt new file mode 100644 index 000000000..9908865d9 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/StringTblDE.txt @@ -0,0 +1,4 @@ +Name=Baumwolle +Description=Baumwolle zum Anpflanzen oder Verarbeiten zu Stoff +UsageHelp=Drücke [Benutzen] um hier eine Baumwollpflanze anzupflanzen. +NoSuitableGround=Untergrund ist zum|Anbau nicht geeignet! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/StringTblUS.txt new file mode 100644 index 000000000..12a90de45 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Cotton.ocd/StringTblUS.txt @@ -0,0 +1,4 @@ +Name=Cotton +Description=Cotton for planting a cotton plant or producing cloth. +UsageHelp=Press [Use] to plant a cotton plant here. +NoSuitableGround=Ground not suitable|for planting! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/Script.c index 36edd5321..80d8c649d 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/Script.c @@ -18,4 +18,5 @@ protected func Hit() local Collectible = 1; local Name = "$Name$"; -local Description = "$Description$"; \ No newline at end of file +local Description = "$Description$"; +local Plane = 450; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/StringTblUS.txt index 5f4366f9e..ae4af05af 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Earth.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Chunk of earth -Description=Can be dug out, crumbles to earth on impact. +Description=Can be dug out of the ground. Will crumble to powder on impact. diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/DefCore.txt index a12c3569b..bfc4d8d9b 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/DefCore.txt @@ -11,8 +11,5 @@ VertexY=1,-1 VertexFriction=20 Value=5 Mass=10 -Components=Sulphur=1 Projectile=1 -Fragile=1 -Explosive=1 - +Fragile=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/Script.c index 103400589..5ca565718 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Firestone.ocd/Script.c @@ -9,12 +9,17 @@ protected func Construction() func Hit() { - Explode(20); + Sound("Fuse"); + CreateParticle("Fire", 0, 0, PV_Random(-5, 5), PV_Random(-15, 5), PV_Random(10, 40), Particles_Glimmer(), 5); } -public func IsToolProduct() { return true; } +func Hit2() +{ + Explode(18); +} local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; -local Rebuy = true; \ No newline at end of file +local Rebuy = true; +local Plane = 530; // cause it's explosive, players should see it in a pile of stuff \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/GoldBar.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/GoldBar.ocd/Script.c index 37842dace..68c981841 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/GoldBar.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/GoldBar.ocd/Script.c @@ -14,3 +14,4 @@ local Name = "$Name$"; local Description = "$Description$"; local Collectible = 1; local Rebuy = true; +local Plane = 480; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/DefCore.txt index 564cdae82..78ca253e5 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Ice Version=5,2,0,1 Category=C4D_Object -Timer=30 -TimerCall=Check Width=8 Height=8 Offset=-4,-4 diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/Script.c index 146c16778..232245fa3 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ice.ocd/Script.c @@ -8,33 +8,33 @@ protected func Hit() protected func Construction() { var graphic = Random(5); - if(graphic) - SetGraphics(Format("%d",graphic)); + if (graphic) + SetGraphics(Format("%d", graphic)); + AddTimer("Check", 30); } protected func Check() { - if(GetTemperature() > 0) Melt(); - if(GetTemperature() <= 0 && GetMaterial()==Material("Water") && GetCon()<100) Freeze(); + if (GetTemperature() <= 0 && GetMaterial() == Material("Water") && GetCon() < 100) + Freeze(); + // Don't do anything af + if (GetTemperature() > 0) + Melt(); } private func Melt() { - CastPXS("Water",2,0); + CastPXS("Water", 2, 0); DoCon(-1); } private func Freeze() { + ExtractMaterialAmount(0, 0, Material("Water"), 2); DoCon(1); - var i=2; - while(i>0) - { - ExtractLiquid(); - i=--i; - } } local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local Plane = 450; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/DefCore.txt index 14f9a6ebd..965b81f02 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/DefCore.txt @@ -12,5 +12,4 @@ VertexY=3,-3 VertexFriction=40,40 Value=5 Mass=10 -Components=Earth=2; -Rotate=1 +Rotate=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/Script.c index ff172d422..ba37f6be8 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/Script.c @@ -1,17 +1,11 @@ /* Loam */ -local last_x, last_y; // Last drawing position of bridge (global coordinates) -local last_frame; // Last frame during which a bridge chunk was drawn -local begin_frame; // Starting frame of briding process -local target_x, target_y; // local target coordinates during bridging -local loamused; // amound of loam already used - -static const LOAM_Bridge_Amount = 37; // bridge length in pixels +local loamused; // amount of loam already used protected func Construction() { var graphic = Random(5); - if(graphic) + if (graphic) SetGraphics(Format("%d",graphic)); } @@ -26,7 +20,7 @@ func ControlUseStart(object clonk, int x, int y) { // Clonk must stand on ground. Allow during SCALE; but Clonk won't keep animation if he's not actually near the ground var clnk_proc = clonk->GetProcedure(); - if(clnk_proc != "WALK" && clnk_proc != "SCALE") + if (clnk_proc != "WALK" && clnk_proc != "SCALE") { clonk->CancelUse(); return true; @@ -37,22 +31,34 @@ func ControlUseStart(object clonk, int x, int y) clonk->SetComDir(COMD_Stop); clonk->SetXDir(0); clonk->SetYDir(0); - last_x = BoundBy(x,-0,0)+GetX(); last_y = clonk->GetDefBottom()+3; - last_frame = begin_frame = FrameCounter(); - - target_x = x; target_y = y; - - AddEffect("IntBridge", clonk, 1, 1, this); + // Add bridge effect and pass target coordinates. + AddEffect("IntBridge", clonk, 1, 1, this, nil, x, y); return true; } func HoldingEnabled() { return true; } -func FxIntBridgeTimer(clonk, effect) +func FxIntBridgeStart(object clonk, proplist effect, int temp, int x, int y) +{ + if (temp) + return FX_OK; + // Drawing times. + effect.Begin = 0; + effect.Last = 0; + // Last bridge coordinates. + effect.LastX = GetX(); + effect.LastY = clonk->GetDefBottom() + 3; + // Target coordinates. + effect.TargetX = x; + effect.TargetY = y; + return FX_OK; +} + +func FxIntBridgeTimer(object clonk, proplist effect, int time) { // something happened - don't try to dig anymore - if(clonk->GetAction() != "Bridge") + if (clonk->GetAction() != "Bridge") { clonk->CancelUse(); return true; @@ -61,52 +67,66 @@ func FxIntBridgeTimer(clonk, effect) // clonk faces bridge direction var tdir = 0; // get global drawing coordinates - var x = target_x + GetX(), y = target_y + GetY(); + var x = effect.TargetX + GetX(); + var y = effect.TargetY + GetY(); if (x > 0) ++tdir; clonk->SetDir(tdir); // bridge speed: Build in smaller steps when briding upwards so Clonk moves up with bridge var min_dt = 3; - if (target_y < -20 && !Abs(target_x*5/target_y)) min_dt=2; + if (effect.TargetY < -20 && !Abs(effect.TargetX*5/effect.TargetY)) + min_dt = 2; // bridge speed by dig physical var speed = clonk.ActMap.Dig.Speed/6; // build bridge in chunks (for better angle precision) - var dt = FrameCounter() - last_frame; - if (dt < min_dt) return true; - last_frame += dt; + var dt = time - effect.Last; + if (dt < min_dt) return FX_OK; + effect.Last += dt; // draw loam (earth) line var line_wdt = 3; var line_len = speed * dt; - var dx = x-last_x, dy=y-last_y, d=Distance(dx, dy); + var last_x = effect.LastX; + var last_y = effect.LastY; + var dx = x-last_x, dy=y-last_y, d=Distance(dx, dy); + // Quantize angle as a multiple of 45 degrees. + var quant = 30; + var angle = Angle(0, 0, dx, dy); + angle = angle + quant/2 - Sign(angle-quant/2)*((angle-quant/2) % quant); + dx = Sin(angle, d); + dy = -Cos(angle, d); // Don't use up loam if the mouse position is reached... // wait for the mouse being moved and then continue bridging // into that direction - if(!d) return true; + if(!d) return FX_OK; var ox = dy * line_wdt / d, oy = -dx * line_wdt / d; dx = dx * line_len / (d*10); dy = dy * line_len / (d*10); DrawMaterialQuad("Earth-earth", last_x-ox,last_y-oy, last_x+dx-ox,last_y+dy-oy, last_x+dx+ox,last_y+dy+oy, last_x+ox,last_y+oy, DMQ_Bridge); - last_x += dx; - last_y += dy; + effect.LastX += dx; + effect.LastY += dy; // bridge time is up? loamused += Max(line_len/10,1); - if(loamused >= LOAM_Bridge_Amount) + if (loamused >= BridgeLength) { clonk->CancelUse(); } + return FX_OK; } func ControlUseHolding(object clonk, int new_x, int new_y) { - target_x = new_x; - target_y = new_y; - + var effect = GetEffect("IntBridge", clonk); + if (!effect) + return true; + // Update target coordinates in bridge effect. + effect.TargetX = new_x; + effect.TargetY = new_y; return true; } @@ -125,24 +145,29 @@ public func ControlUseCancel(object clonk, int x, int y) private func LoamDone(object clonk) { // Get out of animation - if(clonk->GetAction() == "Bridge") + if (clonk->GetAction() == "Bridge") { clonk->SetAction("Walk"); clonk->SetComDir(COMD_Stop); } - // Remove loam object if most of it has been consumed - if(loamused > LOAM_Bridge_Amount - 10) - { - RemoveObject(); - } // Remove Effect RemoveEffect("IntBridge", clonk); + // Remove loam object if most of it has been consumed + if (loamused > BridgeLength - 10) + RemoveObject(); + return; } public func IsFoundryProduct() { return true; } -public func GetLiquidNeed() { return ["Water", 150]; } +public func GetLiquidNeed() { return ["Water", 60]; } +public func GetMaterialNeed() { return ["Earth", 25]; } + +public func GetMaterialIcon(string mat) { return Earth; } local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; +local BridgeLength = 37; // bridge length in pixels +local Plane = 470; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblDE.txt index 9f76a17f6..bf144f02d 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Lehm -Description=Drücke [Benutzen] um eine Lehmbrücke zu bauen. \ No newline at end of file +Description=Mit Lehm können kleine Lehmbrücken gebaut werden.|Benötigt ein Fass mit Wasser und einen Eimer Erde zur Produktion. +UsageHelp=Halte [Benutzen] gedrückt um eine Lehmbrücke in die gezeigte Richtung zu bauen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblUS.txt index 86d7c4332..91975efdf 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Loam.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Loam -Description=Press [Use] to build a loam bridge into the specified direction. +Description=With loam one can build small loam bridges.|Needs a barrel of water and a bucket of water to produce. +UsageHelp=Hold down the [Use] key to build a bridge, move the mouse to control where it is created. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Metal.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Metal.ocd/Script.c index a38241319..6c2890471 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Metal.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Metal.ocd/Script.c @@ -8,7 +8,7 @@ protected func Construction() protected func Hit() { - Sound("MetalHit?"); + Sound("GeneralHit?"); return 1; } @@ -19,3 +19,4 @@ local Name = "$Name$"; local Description = "$Description$"; local Collectible = 1; local Rebuy = true; +local Plane = 470; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/DefCore.txt index e19d74e00..39e6c0fc0 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/DefCore.txt @@ -12,8 +12,5 @@ VertexFriction=75,75,75 Value=1 Mass=1 Components=Moss=1 -ContactIncinerate=1 -BlastIncinerate=1 Rotate=1 -Float=1 -Placement=3 \ No newline at end of file +Float=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/Script.c index fcb45f90f..1eb8846e8 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/Script.c @@ -117,4 +117,9 @@ public func GetFuelAmount() { return 100; } local Collectible = 1; local Name = "$Name$"; -local Description = "$Description$"; \ No newline at end of file +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Placement = 3; +local BlastIncinerate = 1; +local ContactIncinerate = 1; +local Plane = 470; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblDE.txt index 7eb74c357..6bca1db45 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblDE.txt @@ -1,3 +1,4 @@ Name=Moos -Description=Moos wächst unterirdisch nahe des Wassers. [Benutzen] zum Einpflanzen. Zum Trocknen Kontakt mit Wasser vermeiden. +Description=Nützlicher Brennstoff. Kann in der Nähe von Wasser gezüchtet werden. +UsageHelp=[Benutzen] zum Einpflanzen in der Nähe von Wasser. Zum Trocknen Kontakt mit Wasser vermeiden. NoSuitableGround=Untergrund ist zum|Anbau nicht geeignet! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblUS.txt index fec8904e4..d1a39800c 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Moss.ocd/StringTblUS.txt @@ -1,3 +1,4 @@ Name=Moss -Description=Moss grows close to subterraen ponds. Press [Use] to plant. Keep away from water to dry. +Description=Useful fuel. Can be grown near water. +UsageHelp=Press [Use] to plant near water. Keep away from water to dry. NoSuitableGround=Ground not suitable|for planting! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Nugget.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Nugget.ocd/Script.c index c68ba9b39..3022aba26 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Nugget.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Nugget.ocd/Script.c @@ -19,4 +19,8 @@ func Definition(def) { } local Name = "$Name$"; local Description = "$Description$"; -local Touchable = 2; \ No newline at end of file +<<<<<<< HEAD +local Touchable = 2; +======= +local Plane = 470; +>>>>>>> master diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ore.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ore.ocd/Script.c index 492ce8ccc..bfb8326c3 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ore.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ore.ocd/Script.c @@ -19,3 +19,4 @@ local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local Plane = 460; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/Script.c index c055e0d68..2226d25a4 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/Script.c @@ -17,3 +17,4 @@ local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local Plane = 450; diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblDE.txt index b8402e6ef..074242e62 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblDE.txt @@ -1,2 +1,2 @@ Name=Stein -Description=Wichtiges Baumaterial. \ No newline at end of file +Description=Wichtiges Baumaterial und Waffe. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblUS.txt index 680b508d9..55fd1401c 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Rock.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Rock -Description=Basic construction material. \ No newline at end of file +Description=Basic construction material and weapon. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/DefCore.txt new file mode 100644 index 000000000..dd7def241 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Ruby +Version=5,2,0,1 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=4 +VertexX=-4,0,4,0 +VertexY=0,-4,0,4 +VertexFriction=70,70,70,70 +Value=50 +Mass=10 +Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics.8.png new file mode 100644 index 000000000..35c5bc4af Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics2.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics2.8.png new file mode 100644 index 000000000..bffc427b4 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics2.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics3.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics3.8.png new file mode 100644 index 000000000..feb07da39 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics3.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics4.8.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics4.8.png new file mode 100644 index 000000000..b6684b5b1 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Graphics4.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Script.c new file mode 100644 index 000000000..318f630fb --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/Script.c @@ -0,0 +1,56 @@ +/*--- Ruby ---*/ + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local Plane = 480; + +// returns the color of the gem (used for effects) +func GetGemColor() +{ + return RGB(255, 20, 20); +} + +func Initialize() +{ + AddEffect("Sparkle", this, 1, 30 + RandomX(-3, 3), this); + var gfx = Random(4); + if (gfx) SetGraphics(Format("%d", gfx+1)); + return true; +} + +func FxSparkleStart(target, effect, temp) +{ + if (temp) return; + var color = this->~GetGemColor() ?? RGB(255, 20, 20); + effect.particles = + { + Prototype = Particles_MagicRing(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + }; +} + +func FxSparkleTimer(target, effect, effect_time) +{ + if(this()->Contained() || !Random(2)) return FX_OK; + CreateParticle("MagicRing", 0, 0, 0, 0, effect.Interval, effect.particles, 1); + return FX_OK; +} + +func IsValuable() { return true; } + +func QueryOnSell() +{ + // Inform goal of gem sale + var goal = FindObject(Find_ID(Goal_SellGems)); + if (goal) goal->OnGemSold(); + return false; // do perform selling +} + +func Hit() +{ + Sound("GlassHit*"); + return true; +} \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/StringTblDE.txt new file mode 100644 index 000000000..8c56ad3aa --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Rubin +Description=Wertvoller Klunker \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/StringTblUS.txt new file mode 100644 index 000000000..745485521 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Ruby.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Ruby +Description=Valuable clunker diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/DefCore.txt index 6ee3a13bd..1e4e4036c 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/DefCore.txt @@ -10,5 +10,4 @@ VertexX=0,0 VertexY=1,-1 VertexFriction=40,40,40 Value=5 -Mass=2 -Components=Rock=1 \ No newline at end of file +Mass=2 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/Script.c index bae77febb..239f99102 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/Script.c @@ -37,4 +37,5 @@ public func IsMillIngredient() { return true; } local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblDE.txt index ebc15332f..c451945ce 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblDE.txt @@ -1,3 +1,4 @@ Name=Samen -Description=Zum Anpflanzen von Weizen. +Description=Samen zum Anpflanzen von Weizen. +UsageHelp=Drücke [Benutzen] um hier Weizen anzupflanzen. NoSuitableGround=Untergrund ist zum|Anbau nicht geeignet! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblUS.txt index 532a617e1..9fec5ad29 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Seeds.ocd/StringTblUS.txt @@ -1,3 +1,4 @@ Name=Seeds -Description=To plant wheat. +Description=Seeds for planting wheat. +UsageHelp=Press [Use] to plant wheat here. NoSuitableGround=Ground not suitable|for planting! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/DefCore.txt index 74bfa32bb..c56125af9 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Snow Version=5,2,0,1 Category=C4D_Object -Timer=30 -TimerCall=Check Width=8 Height=8 Offset=-4,-4 diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/Script.c index 338a603d7..8959b2187 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/Script.c @@ -5,6 +5,7 @@ protected func Construction() var graphic = Random(5); if(graphic) SetGraphics(Format("%d",graphic)); + AddTimer("Check", 30); } protected func Check() @@ -27,3 +28,4 @@ private func Hit() local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local Plane = 450; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblDE.txt index a89d31dea..0a370b716 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblDE.txt @@ -1,2 +1,2 @@ Name=Schneeball -Description=Gefrorenes Wasser. \ No newline at end of file +Description=Schneeballschlacht! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblUS.txt index 329bcd81b..52b314ac7 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Snow.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Snowball -Description=Frozen water. \ No newline at end of file +Description=Snowball fight! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/Script.c index a106a65e4..391463e5d 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/Script.c @@ -16,3 +16,4 @@ local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local Plane = 460; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/StringTblUS.txt index 0615994fd..507906074 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Sulphur.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Sulphur -Description=Material for various explosives. +Description= Raw material for various explosives. diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/DefCore.txt index 348f04a3a..3845c90fd 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/DefCore.txt @@ -3,18 +3,17 @@ id=Wood Version=5,2,0,1 Category=C4D_Object Width=12 -Height=12 -Offset=-7,-6 +Height=5 +Offset=-6,-3 Vertices=3 -VertexX=4,-5 -VertexY=-1,2 +VertexX=5,-4 +VertexY=0,0 VertexCNAT=1,2 VertexFriction=50,50 Value=2 Mass=6 Components=Wood=1 -ContactIncinerate=1 -BlastIncinerate=5 +Picture=0,24,60,60 Rotate=1 Float=1 StretchGrowth=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Graphics.5.png b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Graphics.5.png index b5135d30c..63823e5c0 100644 Binary files a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Graphics.5.png and b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Graphics.5.png differ diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Script.c index d49238b14..90d4883c0 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/Script.c @@ -19,3 +19,6 @@ local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local BlastIncinerate = 5; +local ContactIncinerate = 1; +local Plane = 470; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/StringTblUS.txt index a72d5db47..3768fd152 100644 --- a/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Resources.ocd/Wood.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Log -Description=Needed for construction or as firing material. +Description=Needed for construction or as fuel. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Axe.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Axe.jpg new file mode 100644 index 000000000..64ffefb15 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Axe.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Axe.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Axe.png deleted file mode 100644 index 344fec360..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Axe.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/DefCore.txt index 1808cfb86..616a87a0e 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/DefCore.txt @@ -6,7 +6,7 @@ Width=6 Height=10 Offset=-3,-5 Vertices=3 -VertexX=0,2,0 +VertexX=2,2,0 VertexY=0,3,-3 VertexFriction=50,50,50 Value=15 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Scene.material index 3ec1a06ca..ef8cb46b7 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Scene.material @@ -11,7 +11,7 @@ material Axe emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Axe.png + texture Axe.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Script.c index b46252707..570b0c7e6 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/Script.c @@ -9,7 +9,6 @@ #include Library_MeleeWeapon -local tree; local swing_anim; local using; local carry_bone; @@ -51,21 +50,20 @@ public func ControlUseStart(object clonk, int iX, int iY) if (!clonk->IsWalking() && !clonk->IsJumping()) return true; - tree = FindObject(Find_AtPoint(0,0), Find_Func("IsTree"), Sort_Distance(), Find_NoContainer()); - + // find tree that is closest to the clonk's axe when swung + var x_offs = 10; + if(clonk->GetDir() == DIR_Left) { + x_offs = -x_offs; + } + // Chopping - if(tree && clonk->IsWalking()) + if (clonk->IsWalking()) for (var tree in FindObjects(Find_AtPoint(x_offs,0), Find_Func("IsTree"), Sort_Distance(x_offs, 0), Find_NoContainer())) { //treedist - the x-distance the clonk is from the centre of a tree-trunk - var treedist = Abs(clonk->GetX() - tree->GetX()); - if(tree->IsStanding() && treedist < 15 && treedist > 6) + var treedist = Abs(clonk->GetX() + x_offs - tree->GetX()); + if(tree->IsStanding() && treedist <= 6) { using = 1; - //Set the clonk's dir to face the tree if he isn't - if(clonk->GetX() < tree->GetX() && clonk->GetDir() == 0) - clonk->SetDir(1); - else if(clonk->GetX() > tree->GetX() && clonk->GetDir() == 1) - clonk->SetDir(0); //The clonk cannot hold other items in hand while swinging an axe clonk->SetHandAction(1); @@ -76,8 +74,8 @@ public func ControlUseStart(object clonk, int iX, int iY) //Make sure the clonk is holding the axe in the correct position var hand = "Chop.R"; - if(clonk->GetDir() == 0) hand = "Chop.L"; - swing_anim = clonk->PlayAnimation(hand, 10, Anim_Linear(0, 0, clonk->GetAnimationLength("Chop.R"), axe_swing_time, ANIM_Loop), Anim_Const(1000)); + if((clonk->GetDir() == 0) != (clonk.Plane < tree.Plane)) hand = "Chop.L"; + swing_anim = clonk->PlayAnimation(hand, 10, Anim_Linear(0, 0, clonk->GetAnimationLength(hand), axe_swing_time, ANIM_Loop), Anim_Const(1000)); //The timed effect for when the axe actually hits the tree AddEffect("IntAxe", clonk, 1, 1, this, 0, tree); @@ -126,6 +124,12 @@ public func ControlUseStart(object clonk, int iX, int iY) if(!GetEffect("AxeStrikeStop", clonk, 0)) AddEffect("AxeStrikeStop", clonk, 2, 50, this); } + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1) + { + arm = "L"; + carry_bone = "pos_hand1"; + animation = Format("SwordSlash%d.%s", rand, arm); + } if(clonk->IsJumping()) { rand = 1; @@ -133,12 +137,6 @@ public func ControlUseStart(object clonk, int iX, int iY) animation = Format("SwordJump%d.%s",rand,arm); } - if(clonk->GetItemPos(this) == 1) - { - arm = "L"; - carry_bone = "pos_hand1"; - } - PlayWeaponAnimation(clonk, animation, 10, Anim_Linear(0, 0, clonk->GetAnimationLength(animation), length, ANIM_Remove), Anim_Const(1000)); clonk->UpdateAttach(); @@ -191,17 +189,14 @@ func FxIntAxeTimer(object clonk, effect, int time) var x = 10; if(clonk->GetDirection() == COMD_Left) x = x * -1; - //Create the woodchip particle - var i; - while(i != 4) - { - //random speed & angle - i++; - CreateParticle("Axe_WoodChip", x, 4, 5 - Random(11), RandomX(6,13) * -1, 20, RGB(255,255,255), tree); - } - + //Create the woodchip particles + var particles = Particles_WoodChip(); + // need to be behind the Clonk? + if (clonk.Plane > effect.tree.Plane) + particles = {Prototype = Particles_WoodChip(), Attach = ATTACH_Back}; + clonk->CreateParticle("WoodChip", x, 4, PV_Random(-12, 12), PV_Random(-13, -6), PV_Random(36 * 3, 36 * 10), particles, 10); // Damage tree - tree->DoDamage(this.ChopStrength, 3, clonk->GetOwner()); // 3 = FX_Call_DmgChop + effect.tree->DoDamage(this.ChopStrength, 3, clonk->GetOwner()); // 3 = FX_Call_DmgChop } //Make sure the clonk does not move clonk->SetComDir(COMD_Stop); @@ -242,13 +237,7 @@ func FxIntSplitTimer(object clonk, effect, int time) if(clonk->GetDirection() == COMD_Left) x = x * -1; //Create the woodchip particle - var i; - while(i != 4) - { - //random speed & angle - i++; - CreateParticle("Axe_WoodChip", x, 4, 5 - Random(11), RandomX(6,13) * -1, 20, RGB(255,255,255), tree); - } + clonk->CreateParticle("WoodChip", x, 4, PV_Random(-12, 12), PV_Random(-13, -6), PV_Random(36 * 3, 36 * 10), Particles_WoodChip(), 10); } // Tree split! if ((axe_swing_time * 12) / time == 1) @@ -288,7 +277,6 @@ public func Reset(clonk) clonk->SetTurnForced(-1); clonk->StopAnimation(swing_anim); swing_anim = nil; - tree = nil; RemoveEffect("IntAxe", clonk); RemoveEffect("IntSplit", clonk); } @@ -320,7 +308,7 @@ func CheckStrike(iTime) // don't hit objects twice if(!GetEffect(effect_name, obj)) { - AddEffect(effect_name, obj, 1, 60 /* arbitrary */, 0, 0); + AddEffect(effect_name, obj, 1, 60 /* arbitrary */, nil, 0); if(GetEffect(axe_name, obj)) { @@ -328,7 +316,7 @@ func CheckStrike(iTime) } else { - AddEffect(axe_name, obj, 1, 40, 0, 0); + AddEffect(axe_name, obj, 1, 40, nil, 0); } // Reduce damage by shield @@ -387,5 +375,6 @@ public func IsToolProduct() { return true; } local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; local ChopStrength = 10; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblDE.txt index 425df3b2d..152deef8b 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Axt -Description=Drücke [Benutzen], um damit einen Baum zu fällen. Drücke [Benutzen] noch mal, um einen bereits gefällten Baum zu Holz zu zerkleinern (verlustreich). \ No newline at end of file +Description=Werkzeug eines jeden Holzfällers. +UsageHelp=Benutze die Axt um einen Baum zu fällen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblUS.txt index bb5bf4e34..85100dfeb 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Axe -Description=Press [Use] to chop down a tree. Press [Use] again to split a chopped tree into wood (but gain less wood than from a sawmill). \ No newline at end of file +Description=A woodcutter's tool. +UsageHelp=Use to chop down a tree. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/WoodChip.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/WoodChip.ocd/Particle.txt deleted file mode 100644 index 5560ab2ec..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Axe.ocd/WoodChip.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Axe_WoodChip -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Stop -DrawFn=Std -Face=0,0,16,16,-8,-8 -FadeOutDelay=40 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=4 -AlphaFade=12 -Additive=0 -RByV=3 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/DefCore.txt index 6c72b2364..6ffa50202 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/DefCore.txt @@ -12,4 +12,4 @@ VertexFriction=50,50,50,50,50,50,50,50 VertexCNAT=16,4,1,2,8,9,10,24 ContactCalls=1 Mass=3 -BorderBound=5 +BorderBound=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Magic_Balloon.mesh.xml b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Magic_Balloon.mesh.xml deleted file mode 100644 index 0e51e2d56..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Magic_Balloon.mesh.xml +++ /dev/null @@ -1,941 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Magic_Balloon.skeleton.xml b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Magic_Balloon.skeleton.xml deleted file mode 100644 index 727359cd7..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Magic_Balloon.skeleton.xml +++ /dev/null @@ -1,1173 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Script.c index 1909273af..15d45d160 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/BalloonDeployed.ocd/Script.c @@ -2,23 +2,17 @@ local rider; local parent; -local idir,dir; +local idir; protected func Initialize() { idir = 0; - dir = 0; SetAction("Inflate"); SetComDir(COMD_None); AddEffect("Float",this,1,1,this); //Special Effects - var i = 0; - while(i <= 7) - { - CreateParticle("Air", 0,16,-3 + Random(7),Random(2),RandomX(70,150),RGB(255,255,255), this); - ++i; - } + CreateParticle("Air", PV_Random(-1, 1), PV_Random(15, 17), PV_Random(-3, 3), PV_Random(0, 2), 18, Particles_Air(), 20); } private func Deflate() @@ -33,16 +27,17 @@ private func Deflate() private func DeflateEffect() { - CreateParticle("Air",0,16,0,0,GetActTime()*3,RGB(255,255,255)); + var act_time = GetActTime(); + CreateParticle("Air", PV_Random(-1, 1), PV_Random(-1, 5), PV_Random(-act_time, act_time), PV_Random(-act_time, act_time), 18, Particles_Air(), act_time); } private func Pack() { RemoveEffect("NoDrop",parent); - RemoveObject(); rider->SetAction("Jump"); rider->SetSpeed(GetXDir(),GetYDir()); rider->SetComDir(COMD_Down); + RemoveObject(); } func ControlLeft() @@ -77,10 +72,13 @@ public func IsProjectileTarget(target,shooter) public func OnProjectileHit() { //Pop! - CastParticles("Air",20,5,0,-10,170,190,RGB(255,255,255),RGB(255,255,255)); + CreateParticle("Air", 0, -10, PV_Random(-10, 10), PV_Random(-10, 10), 10, Particles_Air(), 30); Sound("BalloonPop"); - if(rider!=nil) rider->SetAction("Tumble"); - rider->SetSpeed(GetXDir(),GetYDir()); + if (rider) + { + rider->SetAction("Tumble"); + rider->SetSpeed(GetXDir(),GetYDir()); + } parent->RemoveObject(); RemoveObject(); } @@ -109,6 +107,11 @@ private func FxFloatTimer(object target, effect, int time) } } +// Could store and restore the deployed balloon, but all the +// dependencies to be set when recreating this mid-animation +// will probably cause more upwards incompatibilities than benefit +func SaveScenarioObject() { return false; } + local ActMap = { Float = { diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/DefCore.txt index 45b208df5..1ed6e8208 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/DefCore.txt @@ -1,7 +1,7 @@ [DefCore] id=Balloon Version=5,2,0,1 -Category=C4D_Vehicle +Category=C4D_Object Width=8 Height=8 Offset=-4,-4 @@ -10,7 +10,7 @@ VertexX=-3,3,-3,3 VertexY=3,-3,-3,3 VertexFriction=50,50,50,50 Value=10 -Mass=15 -Components=Cloth=1 +Mass=1 +Components=Cloth=2 Float=1 Rotate=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/Script.c index 91e4f48ae..fc2dd38d3 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/Script.c @@ -5,7 +5,7 @@ local user; func ControlUseStart(object clonk, int ix, int iy) { if(GBackSolid(0,15) || GBackLiquid(0,15) || clonk->GetActionTarget() != nil) return 1; - var balloon = CreateObject(BalloonDeployed,0,-5); + var balloon = CreateObject(BalloonDeployed,0,5); balloon->SetSpeed(clonk->GetXDir(),clonk->GetYDir()); //sound @@ -40,7 +40,10 @@ func Hit() Sound("GeneralHit?"); } +func IsInventorProduct() { return true; } + local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblDE.txt index cf7879fe6..fe09f46fa 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Ballon -Description=Benutze den Ballon um deinen Fall abzubremsen. \ No newline at end of file +Description=Kann den Fall eines Clonks wie ein Fallschirm abbremsen. +UsageHelp=Benutze den Ballon um deinen Fall abzubremsen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblUS.txt index 78808e515..90a6f9429 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Balloon.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Balloon -Description=Use the balloon to slow down your fall. \ No newline at end of file +Description=Acts like a parachute to slow the fall of your clonk. +UsageHelp=Press the use key while falling. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/Graphics.png deleted file mode 100644 index 979ecbfe5..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_acid.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_acid.png deleted file mode 100644 index 41584b1c8..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_acid.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_lava.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_lava.png deleted file mode 100644 index a46c9bb0a..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_lava.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_water.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_water.png deleted file mode 100644 index 9b1d53185..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/MB_water.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/Scene.material deleted file mode 100644 index be1a3c8aa..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/Scene.material +++ /dev/null @@ -1,83 +0,0 @@ -material Barrel_Water -{ - receive_shadows on - technique - { - pass - { - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 1.000000 1.000000 1.000000 1.000000 - specular 0.000000 0.000000 0.000000 1.000000 12.500000 - emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit - { - texture barrel_water.png - tex_address_mode wrap - filtering trilinear - } - } - } -} - -material MB_Water -{ - receive_shadows on - technique - { - pass - { - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 1.000000 1.000000 1.000000 1.000000 - specular 0.000000 0.000000 0.000000 1.000000 12.500000 - emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit - { - texture MB_water.png - tex_address_mode wrap - filtering trilinear - } - } - } -} - -material MB_Acid -{ - receive_shadows on - technique - { - pass - { - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 1.000000 1.000000 1.000000 1.000000 - specular 0.000000 0.000000 0.000000 1.000000 12.500000 - emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit - { - texture MB_acid.png - tex_address_mode wrap - filtering trilinear - } - } - } -} - -material MB_Lava -{ - receive_shadows on - technique - { - pass - { - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 1.000000 1.000000 1.000000 1.000000 - specular 0.000000 0.000000 0.000000 1.000000 12.500000 - emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit - { - texture MB_lava.png - tex_address_mode wrap - filtering trilinear - } - } - } -} \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/barrel_water.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/barrel_water.png deleted file mode 100644 index d73121ef6..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/barrel_water.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/DefCore.txt index c9c484d35..201aa92e8 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/DefCore.txt @@ -2,7 +2,6 @@ id=Barrel Version=5,2,0,1 Category=C4D_Object -TimerCall=Check Width=16 Height=16 Offset=-8,-8 @@ -13,6 +12,5 @@ VertexFriction=60,60,60,60,60,60 Value=12 Mass=20 Components=Wood=2;Metal=1; -ContactIncinerate=2 Rotate=1 Float=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/DefCore.txt index 382b26280..9c8340b7e 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/DefCore.txt @@ -2,7 +2,6 @@ id=MetalBarrel Version=5,2,0,1 Category=C4D_Object -TimerCall=Check Width=16 Height=16 Offset=-8,-8 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Overlay.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Overlay.png new file mode 100644 index 000000000..5d4b7e44e Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Overlay.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Scene.material index c822acf70..493a94948 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Scene.material @@ -9,11 +9,26 @@ material MetalBarrel diffuse 1.000000 1.000000 1.000000 1.000000 specular 0.000000 0.000000 0.000000 1.000000 12.500000 emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit + texture_unit Overlay { - texture metalbarrel.png + texture Overlay.png tex_address_mode wrap filtering trilinear + colour_op_ex modulate src_texture src_player_colour + } + texture_unit Barrel + { + texture metalbarrel.jpg + tex_address_mode wrap + filtering trilinear + colour_op_ex blend_current_alpha src_current src_texture + } + texture_unit Light + { + // apply lighting -- note this texture unit does not need an + // actual texture image: no hardware TIU will be used. + colour_op_ex modulate src_current src_diffuse + alpha_op_ex modulate src_current src_diffuse } } } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Script.c index 8f5623b85..07a82e789 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/Script.c @@ -7,18 +7,6 @@ #include Barrel -local szLiquid; -local iVolume; - -local debug; - - -protected func Initialize() -{ - iVolume = 0; - debug = 0; -} - private func Hit() { Sound("DullMetalHit?"); @@ -31,61 +19,17 @@ private func Hit() } } -private func FillWithLiquid() +private func AcceptMaterial(int material) { - var mat = GetMaterial(); - - if (mat == Material("Water")) - { - FillBarrel(MaterialName(mat)); - SetMeshMaterial("MB_Water"); - return 1; - } - - if (mat == Material("Acid")) - { - FillBarrel(MaterialName(mat)); - SetMeshMaterial("MB_Acid"); - return 1; - } - - if (mat == Material("Lava") || mat == Material("DuroLava")) - { - FillBarrel(MaterialName(mat)); - SetMeshMaterial("MB_Lava"); - return 1; - } - - if (mat == Material("Oil")) - { - FillBarrel(MaterialName(mat)); - SetMeshMaterial("MB_Oil"); - return 1; - } -} - -private func OriginalTex() -{ - SetMeshMaterial("MetalBarrel"); + // Accepts all fluids + return true; } public func IsBarrelForMaterial(string sznMaterial) { - if ((iVolume > 0) && (WildcardMatch(szLiquid,sznMaterial))) - return true; - if (WildcardMatch("Water", sznMaterial)) - return true; - if (WildcardMatch("Acid", sznMaterial)) - return true; - if (WildcardMatch("Lava", sznMaterial)) - return true; - if (WildcardMatch("DuroLava", sznMaterial)) - return true; - if (WildcardMatch("Oil", sznMaterial)) - return true; - //if (GetMaterialVal("Density","Material",Material(szMaterial))) - // return true; - return false; + // anything liquid + var density = GetMaterialVal("Density","Material",Material(sznMaterial)); + return density < 50 && density >= 25; } local Collectible = false; @@ -93,3 +37,4 @@ local Touchable = 2; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local ContactIncinerate = 0; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblDE.txt index 4839f81df..a2ed581de 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblDE.txt @@ -1,2 +1,7 @@ Name=Metallfass -Description=In einem Metallfass können gefährliche Flüssigkeiten transportiert werden. \ No newline at end of file +Description=Stabiler Behälter zum Transport gefährlicher Flüssigkeiten wie Säure. +MaterialLava=Lava +MaterialDuroLava=Lava +MaterialWater=Wasser +MaterialFirefluid=Feuerdings +MaterialAcid=Säure \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblUS.txt index 431859965..028ce4d79 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/StringTblUS.txt @@ -1,2 +1,7 @@ Name=Metal Barrel -Description=You can transport hazardous liquids in a metal barrel. \ No newline at end of file +Description=Solid container for transporting hazardous liquids like acid. +MaterialLava=lava +MaterialDuroLava=lava +MaterialWater=water +MaterialFirefluid=fire stuff +MaterialAcid=acid \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/metalbarrel.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/metalbarrel.jpg new file mode 100644 index 000000000..0930107c9 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/metalbarrel.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/metalbarrel.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/metalbarrel.png deleted file mode 100644 index f53f27778..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/MetalBarrel.ocd/metalbarrel.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Overlay.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Overlay.png new file mode 100644 index 000000000..98bf2856d Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Overlay.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Scene.material index f3d899452..50003d44c 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Scene.material @@ -9,11 +9,26 @@ material Barrel diffuse 1.000000 1.000000 1.000000 1.000000 specular 0.000000 0.000000 0.000000 1.000000 12.500000 emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit + texture_unit Overlay { - texture barrel.png + texture Overlay.png tex_address_mode wrap filtering trilinear + colour_op_ex modulate src_texture src_player_colour + } + texture_unit Barrel + { + texture barrel.jpg + tex_address_mode wrap + filtering trilinear + colour_op_ex blend_current_alpha src_current src_texture + } + texture_unit Light + { + // apply lighting -- note this texture unit does not need an + // actual texture image: no hardware TIU will be used. + colour_op_ex modulate src_current src_diffuse + alpha_op_ex modulate src_current src_diffuse } } } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c index cdf3c6d49..8d27ab2a0 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/Script.c @@ -10,8 +10,6 @@ local szLiquid; local iVolume; -local debug; - public func GetCarryTransform(clonk) { if(GetCarrySpecial(clonk)) @@ -27,7 +25,7 @@ public func GetCarryPhase() protected func Initialize() { iVolume = 0; - debug = 0; + AddTimer("Check", 5); } private func Hit() @@ -50,36 +48,38 @@ private func Check() if (GBackLiquid(0, iSource)) { FillWithLiquid(); + this.Name = this.Prototype.Name; } if (iVolume == 0) { - SetGraphics(); + SetColor(RGB(0,0,0)); szLiquid = nil; } //Value. Base value is 10. if (iVolume == 0) SetProperty("Value", 10); - //if(szLiquid == Oil) SetProperty("Value", 10 + (iVolume / 15)); //No oil in current build - //Debug/Testing Purposes - if (debug == 1) - Message("Volume:|%d|Liquid:|%s", iVolume, szLiquid); + //Message("Volume:|%d|Liquid:|%s", iVolume, szLiquid); } -//over-ridden with metal barrel private func FillWithLiquid() { var mat = GetMaterial(); - - if (mat == Material("Water")) + if (AcceptMaterial(mat)) { FillBarrel(MaterialName(mat)); - SetMeshMaterial("Barrel_Water"); + UpdateBarrel(); } } +private func AcceptMaterial(int material) +{ + // Accepts only water. + return material == Material("Water"); +} + private func FillBarrel(string szMat) { var iCapacity = BarrelMaxFillLevel(); @@ -95,21 +95,40 @@ private func FillBarrel(string szMat) szLiquid = szMat; } -private func EmptyBarrel(int iAngle, int iStrength) +private func EmptyBarrel(int angle, int strength, object clonk) { - if (!iAngle) - iAngle = 0; - if (!iStrength) - iStrength = 30; - CastPXS(szLiquid, iVolume, iStrength, 0, 0, iAngle, 30); + if (!angle) + angle = 0; + if (!strength) + strength = 30; + CastPXS(szLiquid, iVolume, strength, 0, 0, angle, 30); + var spray = {}; + spray.Liquid = szLiquid; + spray.Volume = iVolume; + spray.Strength = strength; + spray.Angle = angle; + spray.Clonk = clonk; + AddEffect("ExtinguishingSpray", clonk, 100, 1, this, nil, spray); iVolume = 0; - OriginalTex(); + UpdateBarrel(); } -//over-ridden with metal barrel -private func OriginalTex() +private func UpdateBarrel() { - SetMeshMaterial("Barrel"); + if (iVolume == 0) + { + SetColor(RGB(0,0,0)); + this.Name = this.Prototype.Name; + } + else + { + var tex = GetMaterialVal("TextureOverlay","Material",Material(szLiquid)); + var color = GetAverageTextureColor(tex); + SetColor(color); + var materialTranslation = Translate(Format("Material%s",szLiquid)); + this.Name = Format("%s $NameWith$ %s", this.Prototype.Name, materialTranslation); + } + return; } public func ControlUse(object clonk, int iX, int iY) @@ -117,7 +136,7 @@ public func ControlUse(object clonk, int iX, int iY) var AimAngle = Angle(0, 0, iX, iY); if (iVolume >= 1) { - EmptyBarrel(AimAngle, 50); + EmptyBarrel(AimAngle, 50, clonk); if (iX > 1) Contained()->SetDir(1); if (iX < -1) @@ -126,14 +145,42 @@ public func ControlUse(object clonk, int iX, int iY) return 1; } -public func IsToolProduct() { return true; } - -public func Definition(proplist def) +protected func FxExtinguishingSprayStart(object target, proplist effect, int temp, proplist spray) { - SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0, 1000, 0), Trans_Rotate(-40, 1, 0, 0), Trans_Rotate(20, 0, 0, 1)), def); + if (temp) + return FX_OK; + // Only for extinguishing materials. + if (!GetMaterialVal("Extinguisher", "Material", Material(spray.Liquid))) + return FX_Start_Deny; + // If used by an object also extinguish that. + if (spray.Clonk) + spray.Clonk->Extinguish(Min(100, spray.Volume/3)); + // Store spray parameters. + effect.Volume = spray.Volume; + effect.Strength = spray.Strength; + effect.Angle = spray.Angle; + return FX_OK; } +protected func FxExtinguishingSprayTimer(object target, proplist effect, int time) +{ + // Move three lines from the barrel outwards along the defined angle. + // And extinguish all objects on these lines. + if (time > 20) + return FX_Execute_Kill; + var d = effect.Strength * time / 25; + for (var dev = -10; dev <= 10; dev+= 10) + { + var x = Sin(effect.Angle + dev, d); + var y = -Cos(effect.Angle + dev, d); + if (PathFree(GetX(), GetY(), GetX() + x, GetY() + y)) + for (var obj in FindObjects(Find_AtPoint(x, y), Find_OCF(OCF_OnFire))) + obj->Extinguish(Max(0, effect.Volume/3 - 2 * d)); + } + return FX_OK; +} +public func IsToolProduct() { return true; } public func BarrelMaxFillLevel() { @@ -175,6 +222,41 @@ public func IsBarrelForMaterial(string sznMaterial) public func IsLiquidContainer() { return true; } +public func SetFilled(material, volume) +{ + szLiquid = material; + iVolume = volume; +} + +public func CalcValue(object in_base, int for_player) +{ + var val = GetDefValue(); + if (iVolume > 0) + { + val += GetValueOf(szLiquid) * iVolume / 300; + } + return val; +} + +private func GetValueOf(string szMaterial) // 300 px of... +{ + // just some provisional values, feel free to change them + // for gameplay reasons + if (szMaterial == "Water") return -6; + if (szMaterial == "Lava") return -10; + if (szMaterial == "DuroLava") return -10; + if (szMaterial == "Acid") return -8; + if (szMaterial == "Firefluid") return 10; + return 0; +} + +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (szLiquid) props->AddCall("Fill", this, "SetFilled", Format("%v", szLiquid), iVolume); + return true; +} + /** Extract liquid from barrel @param sznMaterial: Material to extract; Wildcardsupport @@ -191,6 +273,7 @@ public func GetLiquid(string sznMaterial, int inMaxAmount, object pnTarget) inMaxAmount = 0; inMaxAmount = Min(inMaxAmount, iVolume); iVolume -= inMaxAmount; + UpdateBarrel(); return [szLiquid, inMaxAmount]; } @@ -205,17 +288,24 @@ public func PutLiquid(string sznMaterial, int inMaxAmount, object pnSource) { //Wrong material? if (sznMaterial != szLiquid) - if (iVolume>0) + if (iVolume > 0) return 0; else if (IsBarrelForMaterial(sznMaterial)) - szLiquid=sznMaterial; + szLiquid = sznMaterial; inMaxAmount = BoundBy(BarrelMaxFillLevel() - iVolume, 0, inMaxAmount); iVolume += inMaxAmount; + UpdateBarrel(); return inMaxAmount; } +public func Definition(proplist def) +{ + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0, 1000, 0), Trans_Rotate(-40, 1, 0, 0), Trans_Rotate(20, 0, 0, 1)), def); +} + local Collectible = false; local Touchable = 2; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local ContactIncinerate = 2; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblDE.txt index bda5bc747..697b6820a 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblDE.txt @@ -1,2 +1,4 @@ Name=Holzfass -Description=In einem Holzfass können Flüssigkeiten transportiert werden. \ No newline at end of file +Description=Behälter zum Transport von Flüssigkeiten. +NameWith=mit +MaterialWater=Wasser \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblUS.txt index 5bb09afb1..b9e4eb792 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/StringTblUS.txt @@ -1,2 +1,4 @@ Name=Wooden Barrel -Description=You can transport liquids in a wooden barrel. \ No newline at end of file +Description=Container for transporting liquids. +NameWith=with +MaterialWater=water \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/barrel.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/barrel.jpg new file mode 100644 index 000000000..caafc2118 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/barrel.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/barrel.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/barrel.png deleted file mode 100644 index a31e7e460..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/barrel.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BlastFirework.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BlastFirework.ogg new file mode 100644 index 000000000..80b7bcb1e Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BlastFirework.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BoompackFly.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BoompackFly.ogg new file mode 100644 index 000000000..7e10a3cca Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BoompackFly.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BoompackLaunch.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BoompackLaunch.ogg new file mode 100644 index 000000000..fabc83ec3 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/BoompackLaunch.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Cracker.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Cracker.ogg new file mode 100644 index 000000000..469069c2b Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Cracker.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/DefCore.txt index 6913389cb..ec65b2b6e 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/DefCore.txt @@ -11,6 +11,6 @@ VertexY=3,-6,10,10 VertexFriction=80,60,60 Value=12 Mass=20 -Components=Blackpowder=3;Wood=1;Metal=1; +Components=PowderKeg=1;Firestone=1;Wood=1; Rotate=1 ColorByOwner=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Scene.material index 963e810ed..93de531ef 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Scene.material @@ -5,13 +5,13 @@ material Boompack { pass { - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 0.640000 0.640000 0.640000 1.000000 + ambient 1 1 1 1.000000 + diffuse 1 1 1 1.000000 specular 0.000000 0.000000 0.000000 1.000000 12.500000 emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture boompack.png + texture boompack.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Script.c index 501312df6..563b8c147 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Script.c @@ -23,6 +23,14 @@ local controllable; public func GetCarryMode(clonk) { return CARRY_BothHands; } public func GetCarryPhase() { return 700; } +public func GetCarryTransform(clonk) +{ + if(GetCarrySpecial(clonk)) + return Trans_Translate(0, 0, -6500); + + return Trans_Translate(-1500, 0, 0); +} + protected func Construction() { //flight length @@ -31,6 +39,16 @@ protected func Construction() controllable = true; } +func Fuse() +{ + Launch(GetR()); +} + +func Incineration() +{ + Fuse(); +} + protected func Destruction() { if(rider) JumpOff(rider); @@ -93,9 +111,12 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime) JumpOff(rider,30); } + if(!Random(105)) Sound("Cracker"); + if(fuel<=0) { DoFireworks(); + return; } var ignition = iEffectTime % 9; @@ -108,13 +129,12 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime) SetR(angle); } - var sizemod = ignition*ignition/3; - - var x = -Sin(GetR(),22); - var y = +Cos(GetR(),22); - - CreateParticle("ExploSmoke",x,y,RandomX(-1,1),RandomX(-1,2),RandomX(120,280),RGBa(130,130,130,75)); - CreateParticle("Thrust",x,y,GetXDir()/2,GetYDir()/2,RandomX(80,120)+sizemod,RGBa(255,200,200,160)); + var x = -Sin(GetR(), 10); + var y = +Cos(GetR(), 10); + + var xdir = GetXDir() / 2; + var ydir = GetYDir() / 2; + CreateParticle("FireDense", x, y, PV_Random(xdir - 4, xdir + 4), PV_Random(ydir - 4, ydir + 4), PV_Random(16, 38), Particles_Thrust(), 5); fuel--; } @@ -145,8 +165,8 @@ protected func Hit() JumpOff(rider); } //Message("I have hit something",this); - if(GetEffect("Flight",this)) DoFireworks(); Sound("GeneralHit?"); + if(GetEffect("Flight",this)) DoFireworks(); } public func OnMount(clonk) @@ -155,6 +175,12 @@ public func OnMount(clonk) if(clonk->GetDir() == 1) iDir = -1; clonk->PlayAnimation("PosRocket", 10, Anim_Const(0), Anim_Const(1000)); riderattach = AttachMesh(clonk, "main", "pos_tool1", Trans_Mul(Trans_Translate(2000, -1000, -2000*iDir), Trans_Rotate(90*iDir,0,1,0))); + + //Modify picture transform to fit icon on clonk mount + //clean pic transform rotations + SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(0,1,0,0), Trans_Rotate(0,0,0,1), Trans_Rotate(0,0,1,0))); + //apply the new one + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(5000 * clonk->GetDir(),0,0), Trans_Rotate(-20,1,0,0), Trans_Rotate(0,0,0,1), Trans_Rotate(0,0,1,0), Trans_Scale(700))); return true; } @@ -162,6 +188,7 @@ public func OnUnmount(clonk) { clonk->StopAnimation(clonk->GetRootAnimation(10)); DetachMesh(riderattach); + DefaultPicTransform(); return true; } @@ -171,7 +198,9 @@ func Launch(int angle, object clonk) SetCategory(C4D_Vehicle); Exit(); - AddEffect("Flight",this,150,1,this,this); + Sound("BoompackLaunch"); + AddEffect("Flight",this,150,1,this); + Sound("BoompackFly", false, 60, nil, 1); //AddEffect("HitCheck", this, 1,1, nil,nil, clonk, true); //Ride the rocket! @@ -202,6 +231,7 @@ func DoFireworks() { RemoveEffect("Flight",this); Fireworks(); + Sound("BlastFirework", false, 200); Explode(30); } @@ -225,11 +255,29 @@ func GetFuel() return fuel; } -func Definition(def) { - SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(30,0,0,1),Trans_Rotate(-30,1,0,0),Trans_Scale(1300)),def); +public func IsProjectileTarget() +{ + return 1; } + +func OnProjectileHit() +{ + Incinerate(); +} + +func IsInventorProduct() { return true; } + +private func DefaultPicTransform() { return SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(30,0,0,1),Trans_Rotate(-30,1,0,0),Trans_Scale(1300))); } + +func Definition(def) { + DefaultPicTransform(); +} + local Collectible = false; local Touchable = 2; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; +local BlastIncinerate = 1; +local ContactIncinerate = 1; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblDE.txt index 440067993..f44d8aa09 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Boompack -Description=Ziele und drücke [Benutzen], um die Rakete zu zünden und auf ihr in eine beliebige Richtung katapultiert zu werden. \ No newline at end of file +UsageHelp=Ziele und zünde die Rakete um in diese Richtung zu fliegen. Springe rechtzeitig ab bevor sie explodiert! +Description=Einweg-Transportmittel für besonders wagemütige Clonks. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblUS.txt index c39c99248..9deeb8317 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Boompack -Description=Aim and press [Use] to ignite the rocket and catapult yourself in any direction. \ No newline at end of file +UsageHelp=Aim and ignite the rocket to fly with it in that direction. Jump off before the rocket explodes! +Description=Single-use transport for daring clonks. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Thrust.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Thrust.ocd/Particle.txt deleted file mode 100644 index 348b16cdc..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/Thrust.ocd/Particle.txt +++ /dev/null @@ -1,12 +0,0 @@ -[Particle] -Name=Thrust -MaxCount=300 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,16,16,-8,-8 -Delay=0 -Repeats=1 -Reverse=1 -Additive=1 -AlphaFade=40 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/authors.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/authors.txt new file mode 100644 index 000000000..328bd0132 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/authors.txt @@ -0,0 +1,11 @@ +"BoompackFly.ogg" includes a rocket sound by "primeval_polypod": + http://www.freesound.org/people/primeval_polypod/sounds/158894/ + +"BlastFirework" includes the sound + http://www.freesound.org/people/soundscalpel.com/sounds/110391/ +by freesound.org user "soundscalpel.com" +and + http://www.freesound.org/people/sarge4267/sounds/102720/?page=2#comment +by "sarge4267" + +License: CC Attribution 3.0 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/boompack.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/boompack.jpg new file mode 100644 index 000000000..4a7b224a0 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/boompack.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/boompack.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/boompack.png deleted file mode 100644 index 9a0e07391..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Boompack.ocd/boompack.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Graphics.mesh b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Graphics.mesh index b1d140e1e..5728c8457 100644 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Graphics.mesh and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Script.c index 2673966d5..92450713d 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/Script.c @@ -6,9 +6,6 @@ @author Clonkonaut */ -local Name = "$Name$"; -local Description = "$Description$"; - // Maximum distance at which material is collected / spilled local maxreach = 15; // Variable to store extracted material @@ -21,70 +18,99 @@ public func GetCarryTransform() return Trans_Mul(Trans_Rotate(-90, 0, 0, 1), Trans_Translate(-4000,3500)); } -public func ControlUseStart(object clonk, int iX, int iY) +public func ControlUse(object clonk, int iX, int iY) { - // Can clonk use the bucket? - if (!clonk->IsWalking() && !clonk->IsJumping()) - return true; - - // if the clonk doesn't have an action where he can use it's hands do nothing - if (!clonk->HasHandAction()) - return true; - - var arm = "R"; - var carry_bone = "pos_hand2"; - if(clonk->GetItemPos(this) == 1) - { - arm = "L"; - carry_bone = "pos_hand1"; - } - var animation = Format("SwordSlash2.%s", arm); - - // figure out the kind of animation to use - var length=15; - if(clonk->IsJumping()) - animation = Format("SwordJump2.%s",arm); - - clonk->PlayAnimation(animation, 10, Anim_Linear(0, 0, clonk->GetAnimationLength(animation), length, ANIM_Remove), Anim_Const(1000)); - clonk->UpdateAttach(); - - //Creates an imaginary line which runs for 'maxreach' distance (units in pixels) - //or until it hits a solid wall. var angle = Angle(0,0,iX,iY); + var distance = GetBucketReachDistance(angle); + var x2 = Sin(180-angle,distance); + var y2 = Cos(180-angle,distance); + + // spill bucket + if (IsBucketFilled()) + { + Spill(x2, y2, distance >= maxreach); + EmptyBucket(); + PlayAnimation(clonk); + return true; + } + + // otherwise try to fill bucket + if(GBackSolid(x2,y2)) + { + if (clonk->HasHandAction()) + { + var mat = GetMaterial(x2,y2); + + if(GetMaterialVal("DigFree","Material",mat)) + { + Sound("SoftTouch2"); + var amount = DigFree(GetX()+x2,GetY()+y2,5, true); + FillBucket(mat, amount); + PlayAnimation(clonk); + } + } + } + return true; +} + +public func EmptyBucket() +{ + in_bucket_amount = 0; + in_bucket_mat = nil; + this.PictureTransformation = Trans_Mul(Trans_Translate(500,400,0), Trans_Rotate(-10,1,0,0), Trans_Rotate(30,0,1,0), Trans_Rotate(+25,0,0,1), Trans_Scale(1350)); +} + +public func FillBucket(int mat, int amount) +{ + in_bucket_amount = amount; + in_bucket_mat = mat; + this.PictureTransformation = Trans_Mul(Trans_Translate(500,400,0), Trans_Rotate(-20,1,0,0), Trans_Rotate(20,0,1,0), Trans_Rotate(-15,0,0,1), Trans_Scale(1350)); +} + +public func IsBucketFilled() +{ + return in_bucket_mat != nil; +} + +/** Creates an imaginary line which runs for 'maxreach' distance (units in pixels) or until it hits a solid wall */ +private func GetBucketReachDistance(int angle) +{ var distance = 0; while(!GBackSolid(Sin(180-angle,distance),Cos(180-angle,distance)) && distance < maxreach) { ++distance; } + return distance; +} - var x2 = Sin(180-angle,distance); - var y2 = Cos(180-angle,distance); +private func PlayAnimation(object clonk) +{ + // animation only available for jumping and walking + if(!clonk->IsJumping() && !clonk->IsWalking()) + return; - if (this.spill) + var arm, carry_bone; + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1) { - Spill(x2, y2, distance >= maxreach); - this.spill = false; - in_bucket_amount = 0; - in_bucket_mat = 0; - clonk->CancelUse(); - return true; + arm = "L"; + carry_bone = "pos_hand1"; } - - if(GBackSolid(x2,y2)) + else { - var mat = GetMaterial(x2,y2); - - if(GetMaterialVal("DigFree","Material",mat)) - { - var amount = DigFree(GetX()+x2,GetY()+y2,5, true); - in_bucket_amount = amount; - in_bucket_mat = mat; - this.spill = true; - Sound("SoftTouch2"); - } + arm = "R"; + carry_bone = "pos_hand2"; } - clonk->CancelUse(); - return true; + + // figure out the kind of animation to use + var length=15; + var animation; + if(clonk->IsJumping()) + animation = Format("SwordJump2.%s",arm); + else + animation = Format("SwordSlash2.%s", arm); + + clonk->PlayAnimation(animation, 10, Anim_Linear(0, 0, clonk->GetAnimationLength(animation), length, ANIM_Remove), Anim_Const(1000)); + clonk->UpdateAttach(); } private func Spill(int x, int y, bool soft_spill) @@ -176,17 +202,52 @@ private func DrawPixel(int x, int y) in_bucket_amount--; } -private func Hit() +protected func Hit() { Sound("DullWoodHit?"); } +// Production stuff (for loam) +public func IsMaterialContainer() { return true; } +public func GetContainedMaterial() { return MaterialName(in_bucket_mat); } +public func RemoveContainedMaterial(string material, int amount) +{ + if (material != MaterialName(in_bucket_mat)) return 0; + if (amount > in_bucket_amount) + { + var ret = in_bucket_amount; + in_bucket_amount = 0; + in_bucket_mat = nil; + return ret; + } + in_bucket_amount -= amount; + return amount; +} +public func GetFillLevel() { return in_bucket_amount; } + public func IsTool() { return true; } public func IsToolProduct() { return true; } -protected func Definition(def) +public func SetFilled(string mat, int amount) { - SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(15,1,0,0), Trans_Rotate(5,0,1,0), Trans_Rotate(-5,0,0,1), Trans_Translate(500,-400,0), Trans_Scale(1350)),def); + in_bucket_mat = mat; + in_bucket_amount = amount; + return true; } +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (in_bucket_mat) props->AddCall("Fill", this, "SetFilled", Format("%v", in_bucket_mat), in_bucket_amount); + return true; +} + +protected func Definition(def) +{ + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(500,400,0), Trans_Rotate(-10,1,0,0), Trans_Rotate(30,0,1,0), Trans_Rotate(+25,0,0,1), Trans_Scale(1350)),def); +} + +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = true; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblDE.txt index cd29c9e82..b197abeb0 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Eimer -Description=Mit dem Eimer kann Erde aufgenommen und andernorts eingesetzt werden, um Brücken zu bauen und Wege zu ebnen. Drücke [Benutzen] um Erde einzufüllen oder auszuschütten. \ No newline at end of file +Description=Mit dem Eimer kann Erde aufgenommen und andernorts eingesetzt werden, um Brücken zu bauen und Wege zu ebnen. +UsageHelp=Drücke [Benutzen] um Erde einzufüllen oder auszuschütten. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblUS.txt index 1baf50171..affe9fdd3 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Bucket -Description=You can gather earth with the bucket to use it as a material for bridge or similar tasks. Press [Use] to collect or dump earth. \ No newline at end of file +Description=You can gather earth with the bucket to use it as a material for bridges or other similar tasks. +UsageHelp=Press [Use] to collect or dump earth. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/bucket_clr_mix.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/bucket_clr_mix.png index 60256e12b..6593d0e7b 100644 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/bucket_clr_mix.png and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Bucket.ocd/bucket_clr_mix.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Scene.material index 870fbccfc..48065cc1d 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Scene.material @@ -12,7 +12,7 @@ material Crate emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture crate.png + texture crate.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Script.c index cff504597..a9f4dad57 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/Script.c @@ -12,6 +12,14 @@ local crateanim; public func GetCarryMode(clonk) { return CARRY_BothHands; } public func GetCarryPhase() { return 800; } +public func GetCarryTransform(clonk) +{ + if(GetCarrySpecial(clonk)) + return Trans_Translate(0, 3500, -6500); + + return Trans_Translate(-1500, 0, 0); +} + protected func Construction() { crateanim = PlayAnimation("Open", 1, Anim_Linear(0, 0, 1, 20, ANIM_Hold), Anim_Const(1000)); diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/crate.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/crate.jpg new file mode 100644 index 000000000..9f99a4507 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/crate.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/crate.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/crate.png deleted file mode 100644 index b7c6480f2..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Crate.ocd/crate.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/DefCore.txt index 080091f6d..2b7a14fb7 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/DefCore.txt @@ -13,6 +13,4 @@ VertexFriction=90,90,90 Value=3 Mass=8 Rotate=1 -Components=Coal=1;Sulphur=1 -ContactIncinerate=1 -BlastIncinerate=1 +Components=Coal=1;Firestone=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Script.c index 7a8ef30bc..b8477eacd 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Script.c @@ -5,7 +5,9 @@ A volatile tool that can be pressed into walls for accurate mining, burning a short fuse before exploding. */ - + +// time in frames until explosion +func FuseTime() { return 140; } public func ControlUse(object clonk, int x, int y, bool box) { @@ -120,21 +122,20 @@ public func Reset() private func Fusing() { - var sin=Sin(180-GetR(),5); - var cos=Cos(180-GetR(),5); + var x = Sin(GetR(), 5); + var y = -Cos(GetR(), 5); if(Contained()!=nil) { //If the dynamite is held, sparks come from clonk's center. - sin=0; - cos=0; + x = y = 0; } // Effekt - if(GetActTime() < 120) - CastParticles("Spark",1,20,sin,cos,15,25,RGB(255,200,0),RGB(255,255,150)); + if(GetActTime() < FuseTime() - 20) + CreateParticle("Fire", x, y, PV_Random(x - 5, x + 5), PV_Random(y - 15, y + 5), PV_Random(10, 40), Particles_Glimmer(), 3); // Explosion - else if(GetActTime() > 140) + else if(GetActTime() > FuseTime()) DoExplode(); } @@ -148,12 +149,11 @@ public func DoExplode() // Activate all fuses for(var obj in FindObjects(Find_Category(C4D_StaticBack), Find_Func("IsFuse"), Find_ActionTargets(this))) obj->~StartFusing(this); - Explode(18); + Explode(26); } -public func IsToolProduct() { return true; } -public func IsAlchemyProduct() { return true; } -public func HasFuse() { return true; } +public func IsChemicalProduct() { return true; } +public func IsGrenadeLauncherAmmo() { return true; } local ActMap = { Fuse = { @@ -179,5 +179,8 @@ local ActMap = { }; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; +local BlastIncinerate = 1; +local ContactIncinerate = 1; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Spark.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Spark.ocd/Graphics.png deleted file mode 100644 index 9032951cd..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Spark.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Spark.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Spark.ocd/Particle.txt deleted file mode 100644 index 0bca154e7..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/Spark.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Spark -MaxCount=1000 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=50 -AlphaFade=8 -Additive=1 -RByV=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblDE.txt index 2424e20ba..cfb89fb61 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Dynamitstange -Description=Drücke [Benutzen], um sie anzuzünden. Ziele danach in die Richtung in die Du sie platzieren willst und drücke nochmals [Benutzen]. +Description=Einfacher Sprengstoff, geeignet zum Abbau von Ressourcen. +UsageHelp=Drücke [Benutzen], um sie anzuzünden. Ziele und drücke danach in eine Richtung um sie zu platzieren. diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblUS.txt index 29ba7e199..793107f52 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Dynamite.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Dynamite stick -Description=Press [Use] to ignite. After it has been ignited, aim into the direction you want to place it and press [Use] again. \ No newline at end of file +Description=Basic explosive for mining. +UsageHelp=Press [Use] to ignite. After it has been ignited, aim with the mouse and press [Use] again to place it in the desired direction. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/DefCore.txt index fae48bdf1..b8fb29923 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/DefCore.txt @@ -12,5 +12,5 @@ VertexFriction=50,50,50,50 Picture=0,0,64,64 Value=16 Mass=30 -Components=Wood=1;Metal=1;Coal=2;Sulphur=3 +Components=Wood=1;Coal=2;Firestone=2 Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Fuse.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Fuse.ocd/Script.c index ca54c8034..93badb591 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Fuse.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Fuse.ocd/Script.c @@ -77,7 +77,7 @@ func FxIntFusingTimer() if( (fuse_vertex == 0 && fuse_dir == -1) || (fuse_vertex == GetVertexNum()-1 && fuse_dir == +1)) { fuse_call->~OnFuseFinished(this); - RemoveObject(this); + if (fuse_call) RemoveObject(); return -1; } fuse_x = GetVertex(fuse_vertex, 0)*10; @@ -90,8 +90,7 @@ func FxIntFusingTimer() fuse_x += Sin(iAngle, speed); fuse_y +=-Cos(iAngle, speed); - CastParticles("Spark",1,20,fuse_x/10-GetX(), fuse_y/10-GetY(),15,25,RGB(255,200,0),RGB(255,255,150)); - + CreateParticle("Fire", fuse_x/10-GetX(), fuse_y/10-GetY(), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(10, 40), Particles_Glimmer(), 3); SetVertexXY(fuse_vertex, fuse_x/10, fuse_y/10); } @@ -100,6 +99,9 @@ func FxIntFusingStop() Sound("FuseLoop",false,75,nil,-1); } +// Only the main dynamite pack is stored. +public func SaveScenarioObject() { return false;} + public func IsFuse() { return true; } local ActMap = { diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Scene.material index e0ba0f864..3bb42d0b1 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Scene.material @@ -11,7 +11,7 @@ material Dynamite_Igniter emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture igniter.png + texture igniter.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Script.c index dc442d9e2..b0ce9c240 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/Script.c @@ -73,6 +73,9 @@ public func ResetClonk(clonk) RemoveObject(); } +// Only the main dynamite box is stored. +public func SaveScenarioObject() { return false; } + public func IsTool() { return true; } public func IsToolProduct() { return false; } public func IsAlchemyProduct() { return false; } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/igniter.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/igniter.jpg new file mode 100644 index 000000000..106430179 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/igniter.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/igniter.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/igniter.png deleted file mode 100644 index 09e50a16d..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Igniter.ocd/igniter.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Scene.material index b8bd30d9f..32528ad12 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Scene.material @@ -11,7 +11,7 @@ material Dynamite_Box emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture box.png + texture box.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Script.c index 73a6045a0..5340a80f8 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Script.c @@ -10,8 +10,8 @@ public func Initialize() aWires = CreateArray(iCount); for(var i = 0; i < iCount; i++) { - aDynamites[i] = 0; - aWires[i] = 0; + aDynamites[i] = nil; + aWires[i] = nil; } this.PictureTransformation = Trans_Scale(); // Hide it TODO: Remove if the mesh isn't shown if there is a picture set @@ -156,13 +156,14 @@ func FxIntLengthStop(pTarget, effect, iReason, fTmp) } public func IsTool() { return true; } -public func IsToolProduct() { return true; } -public func IsAlchemyProduct() { return true; } +public func IsChemicalProduct() { return true; } func Definition(def) { SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(150, 1, 0, 0), Trans_Rotate(140, 0, 1, 0)), def); } + local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblDE.txt index c6bcbfe37..754742a5c 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Dynamitkiste -Description=Die Kiste enthält fünf Dynamitstangen, die eine nach der anderen mit [Benutzen] platziert werden. Ziele in die Richtung, in der Du sie platzieren willst. \ No newline at end of file +Description=Eine Kiste mit fünf Dynamitstangen welche zusammen platziert und angezündet werden. +UsageHelp=Die Kiste enthält fünf Dynamitstangen, die eine nach der anderen mit [Benutzen] platziert werden. Ziele in die Richtung, in der Du sie platzieren willst. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblUS.txt index 46e07064a..8f6538630 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Dynamite box -Description=The box contains five sticks of dynamite. Place them one after another with [Use], aiming into the direction you want to place them. \ No newline at end of file +Description=A box with five sticks of dynamite which are placed and ignited together. +UsageHelp=The box contains five sticks of dynamite. Place them one after another with [Use], aiming in the direction you want to place them. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/box.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/box.jpg new file mode 100644 index 000000000..a13cc41d8 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/box.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/box.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/box.png deleted file mode 100644 index 6d05ea9f0..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/box.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/DefCore.txt index afa74863a..b7cef8452 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/DefCore.txt @@ -13,7 +13,4 @@ Value=12 Mass=10 Components=Wood=2;Metal=1;Rope=1; Rotate=1 -ContactIncinerate=5 -BlastIncinerate=30 -BurnTo=NONE Float=2 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c index 3fba86440..d2a5aea69 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c @@ -152,7 +152,7 @@ public func Entrance(object container) public func OnRopeBreak() { - RemoveEffect(0, clonk, fx_hook); + RemoveEffect(nil, clonk, fx_hook); RemoveObject(); return; } @@ -366,4 +366,7 @@ public func FxIntGrappleControlStop(object target, fxnum, int reason, int tmp) } } -public func NoWindjarForce() { return true; } +public func NoWindbagForce() { return true; } + +// Only the grappler is stored. +public func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Rope.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Rope.ocd/Script.c index 1d98b93e2..b6b5e6073 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Rope.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Rope.ocd/Script.c @@ -34,7 +34,7 @@ public func BreakRope() return; } -/* --------------------- Callbacks form the rope ---------------------- */ +/* --------------------- Callbacks from the rope ---------------------- */ /* To be overloaded for special segment behaviour */ private func CreateSegment(int index, object previous) @@ -251,6 +251,54 @@ func SetLineTransform(obj, int r, int xoff, int yoff, int length, int layer, int ); } +/* --------------------- Overloaded from the rope library --------------------- */ + +func ForcesOnObjects() +{ + if(!length) return; + + var redo = LengthAutoTryCount(); + while(length_auto && redo) + { + var speed = Vec_Length(Vec_Sub(particles[-1][0], particles[-1][1])); + if(length == GetMaxLength()) + { + if(ObjContact(objects[1][0])) + speed = 40; + else speed = 100; + } + if(speed > 150) DoLength(1); + else if(speed < 50) DoLength(-1); // TODO not just obj 1 + else redo = 0; + if(redo) redo --; + } + var j = 0; + if(PullObjects() ) + for(var i = 0; i < 2; i++) + { + if(i == 1) j = ParticleCount-1; + var obj = objects[i][0]; + + if(obj == nil || objects[i][1] == 0) continue; + + if(obj->Contained()) obj = obj->Contained(); + + if( (obj->GetAction() == "Walk" || obj->GetAction() == "Scale" || obj->GetAction() == "Hangle")) + obj->SetAction("Jump"); + if( obj->GetAction() == "Climb") + obj->SetAction("Jump"); + + var xdir = BoundBy(particles[j][0][0]-particles[j][1][0], -300, 300); + var ydir = BoundBy(particles[j][0][1]-particles[j][1][1], -300, 300); + + obj->SetXDir( xdir, Rope_Precision); + obj->SetYDir( ydir, Rope_Precision); + } +} + +// Only the grappler is stored. +public func SaveScenarioObject() { return false; } + func Definition(def) { def.LineColors = [RGB(66,33,00), RGB(66,33,00)]; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Script.c index 6b658e971..e25abf1a3 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Script.c @@ -15,11 +15,9 @@ local fAiming; local hook; local hook_attach; -public func GetCarryMode() { if(hook->Contained() == nil) return CARRY_Back; return CARRY_HandBack; } - public func GetCarrySpecial(clonk) { if(fAiming) return "pos_hand2"; } public func GetCarryBone2(clonk) { return "main2"; } -public func GetCarryMode(clonk) { if(hook->Contained() == nil) return CARRY_Back; if(fAiming >= 0) return CARRY_Grappler; } +public func GetCarryMode(clonk) { if(hook && hook->Contained() == nil) return CARRY_Back; if(fAiming >= 0) return CARRY_Grappler; } /* +++++++++++ Controls ++++++++++++++ */ @@ -48,13 +46,19 @@ public func SetHook(object new_hook) hook = new_hook; } +private func EnsureHook() +{ + // Create hook if it went missing + if(!hook) hook = CreateObject(GrappleHook, 0, 0, NO_OWNER); + return hook; +} + public func OnRopeBreak() { if(hook_attach) DetachMesh(hook_attach); - if(!hook) - hook = CreateObject(GrappleHook, 0, 0, NO_OWNER); + EnsureHook(); hook->Enter(this); hook_attach = AttachMesh(hook, "bolt", "main"); PlayAnimation("Load", 5, Anim_Const(GetAnimationLength("Load")), Anim_Const(1000)); @@ -62,30 +66,42 @@ public func OnRopeBreak() public func DrawRopeIn() { - var rope = hook->GetRope(); - if (rope) - rope->DrawIn(); + if (hook) + { + var rope = hook->GetRope(); + if (rope) + rope->DrawIn(); + } } protected func Destruction() { - var rope = hook->GetRope(); - if (rope) - rope->BreakRope(); + if (hook) + { + var rope = hook->GetRope(); + if (rope) + rope->BreakRope(); + } } protected func Departure() { - var rope = hook->GetRope(); - if (rope) - rope->DrawIn(); + if (hook) + { + var rope = hook->GetRope(); + if (rope) + rope->DrawIn(); + } } public func GetAnimationSet() { return animation_set; } public func ControlUseStart(object clonk, int x, int y) { + // Burned? + if (GetCon()<100) return false; // Cut rope, or otherwise remove helper object. + EnsureHook(); if (hook->Contained() != this) { var rope = hook->GetRope(); @@ -93,8 +109,12 @@ public func ControlUseStart(object clonk, int x, int y) { rope->DrawIn(); // rope->BreakRope(); + return true; + } + else + { + hook->Enter(this); } - return true; } // if the clonk doesn't have an action where he can use it's hands do nothing @@ -145,6 +165,8 @@ public func ControlUseStop(object clonk, int x, int y) // Callback from the clonk, when he actually has stopped aiming public func FinishedAiming(object clonk, int angle) { + if (GetCon()<100) return false; + EnsureHook(); DetachMesh(hook_attach); hook_attach = nil; @@ -177,6 +199,32 @@ public func OnRestartAim(object clonk) return false; } +/* Destroyed by fire? Make it visible. */ + +func Incineration() +{ + // GrappleBow becomes unusable on incineration. + if (hook) + { + var rope = hook->GetRope(); + if (rope) rope->BreakRope(); + if (hook) hook->RemoveObject(); + } + SetClrModulation(0xff606060); + return _inherited(...); +} + +func Extinguishing() +{ + // If extinguished on the same frame it got incinerated, make it usable again + if (GetCon()>=100) + { + EnsureHook(); + SetClrModulation(); + } + return _inherited(...); +} + /* ++++++++ Animation functions ++++++++ */ public func Reset(clonk) @@ -187,10 +235,15 @@ public func Reset(clonk) StopAnimation(GetRootAnimation(6)); } +func IsInventorProduct() { return true; } + func Definition(def) { SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(-700,400),Trans_Scale(1150),Trans_Rotate(180,0,1,0),Trans_Rotate(-30,-1,0,-1)),def); } local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; +local BlastIncinerate = 30; +local ContactIncinerate = 0; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblDE.txt index a785184a3..8aebd9cb3 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Enterhaken -Description=Schieße den Enterhaken an eine Decke, um Dich daran zu sichern. \ No newline at end of file +Description=Sehr nützliches Werkzeug zum Erklimmen von schwierigem Terrain. +UsageHelp=Schieße den Enterhaken an eine Decke, um Dich daran zu sichern. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblUS.txt index e791c4603..d7e690b6d 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Grappling hook -Description=Shoot the grappling hook at a ceiling to attach yourself to it. \ No newline at end of file +Description=Very useful tool for scaling difficult terrain. +UsageHelp=Shoot the grappling hook at a ceiling to attach yourself to it. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Scene.material index 3862ae90a..570261c5f 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Scene.material @@ -11,7 +11,7 @@ material Hammer emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture hammer.png + texture hammer.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Script.c index ed1e8bd7c..68d24a55f 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/Script.c @@ -21,4 +21,5 @@ func Definition(def) { local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblDE.txt index ce668f091..a5f99cefa 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblDE.txt @@ -1,5 +1,6 @@ -TxtNoconstructionplansa=Keine Baupläne verfügbar +TxtNoconstructionplansa=Keine Baupläne verfügbar TxtConstructions=Konstruktion: %s TxtCantConstruct=%s kann nicht bauen. Name=Hammer -Description=Drücke [Benutzen], um ein Gebäude zu errichten. \ No newline at end of file +Description=Mit dem Hammer können neue Gebäude errichtet werden. +UsageHelp=Drücke [Benutzen], um ein Gebäude zu errichten. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblUS.txt index 07e19df85..564efef67 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/StringTblUS.txt @@ -2,4 +2,5 @@ TxtNoconstructionplansa=No construction plans available TxtConstructions=Construction: %s TxtCantConstruct=%s can't build. Name=Hammer -Description=Press [Use] to construct a building. \ No newline at end of file +Description=Basic tool for constructing new buildings. +UsageHelp=Press [Use] to construct a building. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/hammer.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/hammer.jpg new file mode 100644 index 000000000..1f3391e74 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/hammer.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/hammer.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/hammer.png deleted file mode 100644 index 975db0585..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Hammer.ocd/hammer.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air.ocd/Graphics.png deleted file mode 100644 index 21fcdb673..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air.ocd/Particle.txt deleted file mode 100644 index 3a886a782..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air.ocd/Particle.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Particle] -Name=Air -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Bounce -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=-15 -VertexCount=1 -VertexY=50 -AlphaFade=8 -Additive=1 -RByV=1 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air1.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air1.ocd/Graphics.png deleted file mode 100644 index 841ef8809..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air1.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air1.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air1.ocd/Particle.txt deleted file mode 100644 index 535c1d141..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Air1.ocd/Particle.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Particle] -Name=AirIntake -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,128,128,-64,-64 -Delay=0 -Repeats=1 -GravityAcc=-15 -VertexCount=1 -VertexY=50 -AlphaFade=8 -Additive=1 -RByV=1 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/DefCore.txt deleted file mode 100644 index 78c6724cd..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/DefCore.txt +++ /dev/null @@ -1,16 +0,0 @@ -[DefCore] -id=JarOfWinds -Version=5,2,0,1 -Category=C4D_Object -Width=9 -Height=9 -Offset=-5,-5 -Vertices=4 -VertexX=-1,3,-1,-5 -VertexY=-4,0,4,0 -VertexFriction=50,50,50,50 -Picture=0,0,64,64 -Value=14 -Mass=15 -Components=Rock=6;Metal=1; -Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Graphics.7.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Graphics.7.png deleted file mode 100644 index f0a9f05ad..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Graphics.7.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Graphics.mesh b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Graphics.mesh deleted file mode 100644 index 22ecf21f6..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Graphics.mesh and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/StringTblDE.txt deleted file mode 100644 index 0c36e626d..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Windkrug -Description=Drücke [Benutzen], um zu zielen und einen Windstoß in diese Richtung zu abzugeben, der Dich in die andere Richtung drückt. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/StringTblUS.txt deleted file mode 100644 index 140de3802..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Jar of Winds -Description=Press [Use] to aim and release a gust of wind into one direction, pushing you into the other. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindCharge.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindCharge.ogg deleted file mode 100644 index 702cdd07e..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindCharge.ogg and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindChargeStop.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindChargeStop.ogg deleted file mode 100644 index d345e6a73..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindChargeStop.ogg and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindGust.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindGust.ogg deleted file mode 100644 index 3a366b2f3..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindGust.ogg and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindJar.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindJar.png deleted file mode 100644 index 25f50ba09..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/WindJar.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/jar.skeleton b/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/jar.skeleton deleted file mode 100644 index 5af94ec94..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/jar.skeleton and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/DefCore.txt index 602c60811..771b94744 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/DefCore.txt @@ -7,7 +7,7 @@ Height=10 Offset=-5,-5 Vertices=4 VertexX=0,-4,4,0 -VertexY=-4,-3,-3,4 +VertexY=-6,-5,-5,4 VertexFriction=50,100,100,40 Value=10 Mass=20 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Scene.material index 6be12a96b..fab22b771 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Scene.material @@ -11,7 +11,7 @@ material Pickaxe emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture pickaxe.png + texture pickaxe.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Script.c index 2420e3194..4e1e77387 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/Script.c @@ -45,8 +45,9 @@ func ControlUseStart(object clonk, int ix, int iy) return true; using = 1; // Create an offset, so that the hit matches with the animation - swingtime = Pickaxe_SwingTime*4/38; + swingtime = Pickaxe_SwingTime*1/38; clonk->SetTurnType(1); + clonk->SetHandAction(1); clonk->UpdateAttach(); clonk->PlayAnimation("StrikePickaxe", 10, Anim_Linear(0, 0, clonk->GetAnimationLength("StrikePickaxe"), Pickaxe_SwingTime, ANIM_Loop), Anim_Const(1000)); @@ -88,33 +89,52 @@ protected func DoSwing(object clonk, int ix, int iy) { ++iDist; } - + + //Point of contact, where the pick strikes the landscape var x2 = Sin(180-angle,iDist); var y2 = Cos(180-angle,iDist); - - if(GBackSolid(x2,y2)) - { -// Message("Hit %s", MaterialName(GetMaterial(x2,y2))); //for debug - + var is_solid = GBackSolid(x2,y2); + + // alternatively hit certain objects + var target_obj = FindObject(Find_AtPoint(x2, y2), Find_Func("CanBeHitByPickaxe")); + + // notify the object that it has been hit + if(target_obj) + target_obj->~OnHitByPickaxe(this, clonk); + + // special effects only ifhit something + if(is_solid || target_obj) + { var mat = GetMaterial(x2,y2); var tex = GetTexture(x2,y2); - - // special effects - if(GetMaterialVal("DigFree","Material",mat)) + + //Is the material struck made of a diggable material? + if(is_solid && GetMaterialVal("DigFree","Material",mat)) { var clr = GetAverageTextureColor(tex); - var a = 80; - CreateParticle("Dust",x2,y2,RandomX(-3,3),RandomX(-3,3),RandomX(10,250),DoRGBaValue(clr,-255+a,0)); + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + Size = PV_KeyFrames(0, 0, 0, 200, PV_Random(2, 50), 1000, 0), + }; + CreateParticle("Dust", x2, y2, PV_Random(-3, 3), PV_Random(-3, -3), PV_Random(18, 1 * 36), particles, 3); + Sound("Dig?"); } + //It's solid, but not diggable. So it is a hard mineral. else { - CastParticles("Spark",RandomX(3,9),35,x2*9/10,y2*9/10,10,30,RGB(255,255,150),RGB(255,255,200)); + CreateParticle("Spark", x2*9/10,y2*9/10, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(10, 20), Particles_Glimmer(), 10); Sound("Clang?"); } - - // dig out resources too! Don't just remove landscape pixels - BlastFree(GetX()+x2,GetY()+y2,5,GetController()); + + //Do blastfree after landscape checks are made. Otherwise, mat always returns as "tunnel" + // Call in clonk context to ensure DigOutObject callback is done in Clonk + clonk->BlastFree(GetX()+x2,GetY()+y2,5,GetController(),MaxPickDensity); } + } func FxIntPickaxeTimer(clonk, effect, time) @@ -141,7 +161,7 @@ func FxIntPickaxeTimer(clonk, effect, time) protected func ControlUseCancel(object clonk, int ix, int iy) { - Reset(clonk); + Reset(clonk); return true; } @@ -149,6 +169,7 @@ public func Reset(clonk) { using = 0; clonk->SetTurnType(0); + clonk->SetHandAction(false); clonk->UpdateAttach(); clonk->StopAnimation(clonk->GetRootAnimation(10)); swingtime=0; @@ -161,4 +182,6 @@ public func IsToolProduct() { return true; } local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; +local MaxPickDensity = 70; // can't pick granite diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblDE.txt index f12cb63b1..5a2295f00 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Spitzhacke -Description=Halte [Benutzen] gedrückt, um langsam in Gesteinsformationen vorzudringen. \ No newline at end of file +Description=Mit der Spitzhacke kann man auch ohne Sprengstoff Gestein durchdringen. +UsageHelp=Halte [Benutzen] gedrückt, um langsam in Gesteinsformationen vorzudringen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblUS.txt index 0bc391857..ebbccbcfb 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Pickaxe -Description=Hold the [Use]-key to slowly mine into rock formations. \ No newline at end of file +Description=Basic mining tool for mining through rock when no explosives are available. +UsageHelp=Hold [Use] to slowly mine into rock formations. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/pickaxe.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/pickaxe.jpg new file mode 100644 index 000000000..15911645f Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/pickaxe.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/pickaxe.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/pickaxe.png deleted file mode 100644 index d61878645..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pickaxe.ocd/pickaxe.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/DefCore.txt index d27335e0f..68bce26ec 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/DefCore.txt @@ -3,12 +3,13 @@ id=Pipe Version=5,2,0,1 Category=C4D_Object Width=8 -Height=6 -Offset=-4,-3 +Height=8 +Offset=-4,-4 Vertices=1 -VertexY=1 +VertexX=0 +VertexY=3 VertexFriction=50 Value=10 Mass=15 Components=Metal=1 -Picture=0,6,64,64 +Picture=64,0,64,64 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Graphics.8.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Graphics.8.png new file mode 100644 index 000000000..53eeacbc5 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/Script.c index b85676a32..25a5e79b3 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/Script.c @@ -1,6 +1,18 @@ -/*-- Pipe line --*/ +/*-- Pipe line -//Author: ST-DDT + Author: ST-DDT +--*/ + +local Name = "$Name$"; + +local ActMap = { + Connect = { + Prototype = Action, + Name = "Connect", + Procedure = DFA_CONNECT, + NextAction = "Connect" + } +}; protected func Initialize() { @@ -11,19 +23,19 @@ protected func Initialize() return; } -// Returns true if this object is a functioning pipe. +/** Returns true if this object is a functioning pipe. */ public func IsPipeLine() { return GetAction() == "Connect"; } -// Returns whether this pipe is connected to an object. +/** Returns whether this pipe is connected to an object. */ public func IsConnectedTo(object obj) { return GetActionTarget(0) == obj || GetActionTarget(1) == obj; } -// Returns the object which is connected to obj through this pipe. +/** Returns the object which is connected to obj through this pipe. */ public func GetConnectedObject(object obj) { if (GetActionTarget(0) == obj) @@ -51,61 +63,9 @@ private func BreakMessage() return; } -local ActMap = { - Connect = { - Prototype = Action, - Name = "Connect", - Procedure = DFA_CONNECT, - NextAction = "Connect" - } -}; - -/** -Extract liquid from barrel -@param sznMaterial: Material to extract; Wildcardsupport -@param inMaxAmount: Max Amount of Material being extracted -@param pnTarget: Object which extracts the liquid -@return [irMaterial,irAmount] - -irMaterial: Material being extracted - -irAmount: Amount being extracted -*/ -public func GetLiquid(string sznMaterial, int inMaxAmount, object pnTarget, bool bWildcard) +func SaveScenarioObject(props) { - var pConnected = GetConnectedObject(pnTarget); - if (!pConnected) - return ["", 0]; - var aMat = pConnected->~LiquidOutput(sznMaterial, inMaxAmount, pnTarget, this, bWildcard); - //Bad script? Not needed. - if (GetType(aMat) != C4V_Array) - return [-1, 0]; - //Verify data - if ((aMat[0] == "") || (GetLength(aMat) == 1)) - aMat[1] = 0; - //Nothing is nothing - if (aMat[1] <= 0) - { - aMat[0] = ""; - aMat[1] = 0; - } //Bad script end - return aMat; + if (!inherited(props, ...)) return false; + SaveScenarioObjectAction(props); + return true; } - -/** -Insert liquid to barrel - @param sznMaterial: Material to insert - @param inMaxAmount: Max Amount of Material being inserted - @param pnSource: Object which inserts the liquid - @return inAmount: The inserted amount -*/ -public func PutLiquid(string sznMaterial, int inMaxAmount, object pnSource) -{ - var pConnected = GetConnectedObject(pnSource); - if (!pConnected) - return 0; - if (sznMaterial == "") - return 0; - return BoundBy(pConnected->~LiquidInput(sznMaterial, inMaxAmount, pnSource, this), 0, inMaxAmount); -} - -local Name = "$Name$"; - diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/StringTblDE.txt index 5b573fcba..f291225c2 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/PipeLine.ocd/StringTblDE.txt @@ -1,2 +1,2 @@ TxtPipeBroke=Rohr gerissen -Name=Rohr leiting +Name=Rohrleitung diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Script.c index 533d371c9..0735e06f4 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/Script.c @@ -1,6 +1,13 @@ -/*-- Pipe --*/ +/*-- Pipe -//Author: ST-DDT + Author: ST-DDT +--*/ + +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Collectible = 1; +local Rebuy = true; protected func Hit() { @@ -11,17 +18,13 @@ public func IsToolProduct() { return true; } /*-- Line connection --*/ -// Called with double dig: will connect power line to building at the clonk's position. +/** Will connect power line to building at the clonk's position. */ protected func ControlUse(object clonk, int x, int y) { // Is this already connected to a liquid pump? - if (FindObject(Find_PipeLine())) + if (FindObject(Find_Func("IsConnectedTo",this))) return false; - // Only use if clonk is walking. - if (!clonk->IsWalking()) - return true; - // Clonk should stand still. - clonk->SetComDir(COMD_Stop); + // Is there an object which accepts power lines? var liquid_pump = FindObject(Find_AtPoint(), Find_Func("IsLiquidPump")); // No liquid pump, display message. @@ -30,95 +33,33 @@ protected func ControlUse(object clonk, int x, int y) clonk->Message("$MsgNoNewPipe$"); return true; } + + // already two pipes connected + if(liquid_pump->GetSource() && liquid_pump->GetDrain()) + { + clonk->Message("$MsgHasPipes$"); + return true; + } + // Create and connect pipe. - var pipe; + var pipe = CreateObject(PipeLine, 0, 0, NO_OWNER); + pipe->SetActionTargets(this, liquid_pump); + Sound("Connect"); + // If liquid pump has no source yet, create one. if (!liquid_pump->GetSource()) { - pipe = CreateObject(PipeLine, 0, 0, NO_OWNER); - pipe->SetActionTargets(this, liquid_pump); liquid_pump->SetSource(pipe); - Sound("Connect"); clonk->Message("$MsgCreatedSource$"); - return true; } // Otherwise if liquid pump has no drain, create one. - if (!liquid_pump->GetDrain()) + else { - pipe = CreateObject(PipeLine, 0, 0, NO_OWNER); - pipe->SetActionTargets(this, liquid_pump); liquid_pump->SetDrain(pipe); - Sound("Connect"); clonk->Message("$MsgCreatedDrain$"); - return true; } - // Otherwise do nothing and notify player. - clonk->Message("MsgHasPipes"); return true; } -// Finds all pipe lines connected to obj (can be nil in local calls). -private func Find_PipeLine(object obj) -{ - if (!obj) - obj = this; - return [C4FO_Func, "IsConnectedTo", obj]; -} -/** -Extract liquid from this -@param sznMaterial: Material to extract. 0 or "*" for any material. -@param inMaxAmount: Max Amount of Material being extracted -@param pnPump: Object which extracts the liquid -@param pnPipe: Pipe which extracts the liquid (connected to pnPump) -@param bnWildcard: Usefull to extract random liquids; use '*' for sznMaterial for all Materials -@return [irMaterial,irAmount] - -irMaterial: Material being extracted - -irAmount: Amount being extracted -*/ -public func LiquidOutput(string sznMaterial, int inMaxAmount, object pnPump, object pnPipe, bool bnWildcard) -{ - var itMaterial; - //Search liquid to pump - if (bnWildcard) - { - itMaterial = GetMaterial(); - //nothing? - if (itMaterial == -1) - return ["", 0]; - //no liquid? - if (GetMaterialVal("Density", "Material", itMaterial) != 25) - return ["", 0]; - //wrong liquid? - if (sznMaterial) - if (!WildcardMatch(MaterialName(itMaterial),sznMaterial)) - return ["", 0]; - sznMaterial = MaterialName(itMaterial); - } - else - itMaterial = Material(sznMaterial); - if (GetMaterial() != itMaterial) - return ["", 0]; - var itFound = ExtractMaterialAmount(0, 0, itMaterial, 5); - return [sznMaterial, itFound]; -} -/** -Insert liquid to this - @param sznMaterial: Material to insert - @param inMaxAmount: Max Amount of Material being inserted - @param pnPump: Object which inserts the liquid - @param pnPipe: Pipe which inserts the liquid (connected to pnPump) - @return irAmount: The inserted amount -*/ -public func LiquidInput(string sznMaterial, int inMaxAmount, object pnPump, object pnPipe) -{ - var i=Max(0,inMaxAmount),itMaterial=Material(sznMaterial); - while (i--) InsertMaterial(itMaterial); - return inMaxAmount; -} - -local Name = "$Name$"; -local Description = "$Description$"; -local Collectible = 1; -local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblDE.txt index d64faa3d2..93d0c6924 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblDE.txt @@ -1,7 +1,8 @@ Name=Rohr -Description=Press [Use] in front of a liquid pump to create a source or drain pipe. +UsageHelp=Drücke [Benutzen] vor einer Pumpe um von dort ein Zu- oder Abflussrohr zu legen. +Description=Rohre können in Verbindung mit Pumpen zum Transport von Flüssigkeiten verwendet werden. -MsgNoNewPipe=Cannot create a new pipe here. -MsgCreatedSource=Connected source pipe. -MsgCreatedDrain=Connected drain pipe. -MsgHasPipes=No new connection available. \ No newline at end of file +MsgNoNewPipe=Hier ist keine Pumpe. +MsgCreatedSource=Zuflussrohr angeschlossen. +MsgCreatedDrain=Abflussrohr angeschlossen. +MsgHasPipes=Die Pumpe hat schon ein Zu- und Abflussrohr. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblUS.txt index d081e6366..dfe92f7e2 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Pipe.ocd/StringTblUS.txt @@ -1,7 +1,8 @@ Name=Pipe -Description=Press [Use] in front of a liquid pump to create a source or drain pipe. +UsageHelp=Press [Use] in front of a pump to create a source or drain pipe. +Description=In conjunction with pumps, pipes can be used to transport liquids. -MsgNoNewPipe=Cannot create a new pipe here. +MsgNoNewPipe=There is no pump here. MsgCreatedSource=Connected source pipe. MsgCreatedDrain=Connected drain pipe. -MsgHasPipes=No new connection available. \ No newline at end of file +MsgHasPipes=Pump already has a source and a drain pipe. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/DefCore.txt index 6cada3559..2229c064d 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/DefCore.txt @@ -11,9 +11,6 @@ VertexY=-6,-6,6,6,0,0 VertexFriction=60,60,60,60,60,60 Value=20 Mass=20 -Components=Barrel=1;Sulphur=1;Coal=1; -ContactIncinerate=2 -BlastIncinerate=1 -NoBurnDecay=1 +Components=Barrel=1;Coal=1; NoComponentMass=1 Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/PowderKeg.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/PowderKeg.jpg new file mode 100644 index 000000000..836442607 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/PowderKeg.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/PowderKeg.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/PowderKeg.png deleted file mode 100644 index 69af5e1d9..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/PowderKeg.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Scene.material index 109069038..1163fb1b8 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Scene.material @@ -11,7 +11,7 @@ material PowderKeg emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture PowderKeg.png + texture PowderKeg.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Script.c index 75d241ef7..66fe52224 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/PowderKeg.ocd/Script.c @@ -86,7 +86,7 @@ public func Incineration() public func FxFuseTimer(object target, effect, int timer) { - CastParticles("Spark",1,10,0,0,20,30,RGB(255,255,0),RGB(255,255,0)); + CreateParticle("Fire", 0, 0, PV_Random(-10, 10), PV_Random(-20, 10), PV_Random(10, 40), Particles_Glimmer(), 6); if(timer > 90) { //17-32 explosion radius @@ -100,7 +100,7 @@ public func IsProjectileTarget(target,shooter) return 1; } -public func Damage(int change, int byplayer) +public func Damage() { Incinerate(); } @@ -115,7 +115,15 @@ func Hit() Sound("DullWoodHit?"); } -func IsAlchemyProduct() { return true; } +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + var v = PowderCount(); + if (v != 12) props->AddCall("Powder", this, "SetPowderCount", v); + return true; +} + +func IsChemicalProduct() { return true; } func AlchemyProcessTime() { return 100; } local Collectible = false; @@ -123,3 +131,6 @@ local Touchable = 2; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = true; +local BlastIncinerate = 1; +local NoBurnDecay = 1; +local ContactIncinerate = 2; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/DefCore.txt index 4e725dc81..692563f1c 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/DefCore.txt @@ -13,8 +13,6 @@ VertexFriction=30,30 Value=0 Mass=6 Components=Wood=1 -ContactIncinerate=1 -BlastIncinerate=5 Rotate=1 Float=1 StretchGrowth=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/Script.c index 49cd3e1e4..4d5027555 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeLoosePlank.ocd/Script.c @@ -14,7 +14,12 @@ func Incineration() public func IsFuel() { return true; } public func GetFuelAmount() { return 30; } +// Main bridge object is saved +func SaveScenarioObject() { return false; } + local Collectible = 0; local Name = "$Name$"; local Description = "$Description$"; local Rebuy = false; +local BlastIncinerate = 5; +local ContactIncinerate = 1; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/DefCore.txt index dba34fee8..35dcccf0f 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/DefCore.txt @@ -9,7 +9,5 @@ Vertices=2 VertexX=0,0 VertexY=-5,5 Picture=0,0,36,32 -#RotatedSolidmasks=1 -SolidMask=50,0,2,8 Rotate=1 Mass=0 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/Script.c index c1a40f0a9..8bd307af4 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/Script.c @@ -1,10 +1,5 @@ /*-- Ropelbridge_Segment --*/ -public func Initialize() -{ - SetSolidMask(50,0,2,8); -} - local master; local Plank; local fragile; @@ -65,6 +60,9 @@ func CreateDouble() } } +// Main bridge object is saved +func SaveScenarioObject() { return false; } + local ActMap = { Attach = { Prototype = Action, diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/SolidMask.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/SolidMask.png new file mode 100644 index 000000000..dd4be3348 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/BridgeSegment.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/Script.c index d41b2d089..064500cb7 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/Script.c @@ -85,6 +85,21 @@ func SetFragile() segments[i].fragile = 1; } +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + props->Remove("Category"); + // Save bridge creation on scenario save + if (objects && objects[0] && objects[1]) + { + var o1 = objects[0][0], o2 = objects[1][0]; + if (o1 && o2) props->AddCall("Bridge", this, "MakeBridge", o1, o2); + } + return true; +} + + + /* --------------------- Callbacks form the rope ---------------------- */ /* To be overloaded for special segment behaviour */ @@ -260,6 +275,5 @@ Hanging = { }, }; local Name = "$Name$"; -local Description = "$Description$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblDE.txt index f17d6d0e1..216b990a8 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblDE.txt @@ -1,2 +1 @@ -Name=Hängebrücke -Description=Drücke an einem Abgrund [Benutzen], um die Strickleiter auszurollen. Du kannst sie auch beim Klettern oder Hangeln benutzen. \ No newline at end of file +Name=Hängebrücke \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblUS.txt index 00437abb4..bfa6ab749 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropebridge.ocd/StringTblUS.txt @@ -1,2 +1 @@ -Name=Ropeladder -Description=Press [Use] at a cliff to unroll it. You can also use it while climbing or hangling. \ No newline at end of file +Name=Suspension bridge \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/DefCore.txt index eaff22e31..1fdd10f9d 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/DefCore.txt @@ -11,6 +11,6 @@ VertexY=4,-3,-3 VertexFriction=100,100,100 Value=8 Mass=10 -Components=Wood=2;Rope=2; +Components=Wood=2;Rope=1; Rotate=1 NoStabilize=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/Script.c index f74eb3608..7af14cf80 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/Script.c @@ -1,5 +1,6 @@ /*-- Ropeladder_Grabber --*/ +func SaveScenarioObject() { return false; } public func Interact(object clonk) { @@ -28,5 +29,4 @@ local ActMap = { }, }; local Name = "$Name$"; -local Description = "$Description$"; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblDE.txt index 9311b1f24..4c8d3b597 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblDE.txt @@ -1,3 +1,2 @@ Name=Strickleiter -Description=Drücke [Benutzen], um die Strickleiter wieder reinzuziehen. GrabLadder=Leiter reinziehen \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblUS.txt index 1fe6980b8..259c69977 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderGrabber.ocd/StringTblUS.txt @@ -1,3 +1,2 @@ Name=Ropeladder -Description=Press [Use] to pull the ladder in again. GrabLadder=Pull in ladder \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderSegment.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderSegment.ocd/Script.c index 631411a78..54cbad003 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderSegment.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/LadderSegment.ocd/Script.c @@ -50,3 +50,6 @@ public func OnLadderClimb(clonk) if(master != nil) master->OnLadderClimb(clonk, index); } + +// Main ladder object is saved +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/Script.c index 4e1da7d96..64047e492 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/Script.c @@ -438,7 +438,7 @@ public func GetLadderData(index) var angle = Angle(particles[2][0][0], particles[2][0][1], particles[0][0][0], particles[0][0][1]); return [startx, starty, startx, starty-5000, angle]; } - if(index == ParticleCount-1 || segments[index+1]->CanNotBeClimbed()) + if(index == ParticleCount-1 || segments[index+1]->~CanNotBeClimbed()) { angle = Angle(particles[index][0][0], particles[index][0][1], particles[index-2][0][0], particles[index-2][0][1]); } @@ -454,6 +454,17 @@ func Hit() Sound("WoodHit?"); } +// Save unrolled ladders in scenario +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (UnrollDir) props->AddCall("Unroll", this, "Unroll", UnrollDir); + return true; +} + +public func IsTool() { return true; } +public func IsToolProduct() { return true; } + local ActMap = { Hanging = { Prototype = Action, @@ -461,6 +472,7 @@ Hanging = { }, }; local Name = "$Name$"; +local UsageHelp = "$UsageHelp$"; local Description = "$Description$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblDE.txt index d9e3e540c..7caa2cc18 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Strickleiter -Description=Drücke an einem Abgrund [Benutzen], um die Strickleiter auszurollen. Du kannst sie auch beim Klettern oder Hangeln benutzen. \ No newline at end of file +Description=Erleichtert den Auf- und Abstieg an Klippen. +UsageHelp=Drücke an einem Abgrund [Benutzen], um die Strickleiter auszurollen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblUS.txt index 00437abb4..ba57b89b9 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Ropeladder.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Ropeladder -Description=Press [Use] at a cliff to unroll it. You can also use it while climbing or hangling. \ No newline at end of file +Description=Makes descending and ascending cliffs easier. +UsageHelp=Press [Use] at a cliff to unroll. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Dust.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Dust.ocd/Graphics.png deleted file mode 100644 index 5ff59bec4..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Dust.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Dust.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Dust.ocd/Particle.txt deleted file mode 100644 index bf1f84a29..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Dust.ocd/Particle.txt +++ /dev/null @@ -1,13 +0,0 @@ -[Particle] -Name=Dust -MaxCount=300 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -GravityAcc=0 -AlphaFade=2 -Attach=1 -RByV=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Graphics.mesh b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Graphics.mesh index 5d9476a2a..20b16b727 100644 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Graphics.mesh and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Scene.material index e7864ce0e..f510de786 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Scene.material @@ -11,7 +11,7 @@ material shovel emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture shovel.png + texture shovel.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Script.c index 211c7cbb5..5d3510a49 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/Script.c @@ -20,6 +20,12 @@ public func ControlUseStart(object clonk, int x, int y) { AddEffect("ShovelDig",clonk,1,1,this); // ControlUseHolding(clonk, x, y); + + //temporary workaround to allow clonks to dig free when they are stuck in dirt + if(clonk->Stuck()){ + DigFree(clonk->GetX(), clonk->GetY(), 10); + } + return true; } @@ -42,7 +48,7 @@ public func ControlUseCancel(object clonk, int x, int y) public func ControlUseStop(object clonk, int x, int y) { fDigging = 0; - RemoveEffect("ShovelDig",clonk,0); + RemoveEffect("ShovelDig",clonk); if(clonk->GetAction() != "Dig") return true; // EffectCall(clonk, GetEffect("IntDig", clonk), "StopDig"); @@ -58,10 +64,12 @@ public func FxShovelDigTimer(object clonk, effect, int time) { var xdir_boost = 0, ydir_boost = 0; // Currently not digging? - if(clonk->GetAction() != "Dig") + if(clonk->GetAction() != "Dig" || clonk->GBackLiquid(0,-4)) { var is_scaling = (clonk->GetProcedure() == "SCALE"); var can_dig = (clonk->GetAction() == "Walk" || is_scaling || clonk->GetProcedure() == "HANGLE"); + // Prevent clonk from starting to dig if in deep liquid + if (clonk->GBackLiquid(0,-4)) can_dig = false; if (can_dig) { clonk->SetAction("Dig"); @@ -86,7 +94,7 @@ public func FxShovelDigTimer(object clonk, effect, int time) if (fDigging) { fDigging = false; - RemoveEffect("ShovelDust",clonk,0); + RemoveEffect("ShovelDust",clonk); } return true; } @@ -112,7 +120,8 @@ public func FxShovelDigTimer(object clonk, effect, int time) clonk->SetYDir(Cos(DigAngle,-speed)+ydir_boost,100); // Dust - Dust(clonk); + if (!Random(10)) + Dust(clonk); } } @@ -135,8 +144,15 @@ public func Dust(object target) if(GetMaterialVal("DigFree","Material",mat)) { var clr = GetAverageTextureColor(tex); - var a = 80; - CreateParticle("Dust",groundx,groundy,RandomX(-3,3),RandomX(-3,3),RandomX(10,250),DoRGBaValue(clr,-255+a,0)); + var particles = + { + Prototype = Particles_Dust(), + R = (clr >> 16) & 0xff, + G = (clr >> 8) & 0xff, + B = clr & 0xff, + Size = PV_KeyFrames(0, 0, 0, 300, 40, 1000, 15), + }; + CreateParticle("Dust", groundx, groundy, PV_Random(-3, 3), PV_Random(-3, 3), PV_Random(18, 1 * 36), particles, 3); } } @@ -150,4 +166,5 @@ func Definition(def) { local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblDE.txt index 83766c97a..19004ace2 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Schaufel -Description=Halte [Benutzen] gedrückt, um durch die Erde zu graben. \ No newline at end of file +UsageHelp=Halte [Benutzen] gedrückt, um durch die Erde zu graben. +Description=Ohne Schaufeln können selbst Clonks nicht durch die Erde graben. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblUS.txt index 3c3b963f8..e6433e7a4 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Shovel -Description=Hold down the [Use] key to dig through the earth. \ No newline at end of file +UsageHelp=Hold down the [Use] key to dig through the earth. +Description=Even a clonk can't dig without a shovel. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/shovel.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/shovel.jpg new file mode 100644 index 000000000..3766af531 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/shovel.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/shovel.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/shovel.png deleted file mode 100644 index 79b43143f..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/Shovel.ocd/shovel.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/DefCore.txt new file mode 100644 index 000000000..8a55b9630 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=Sickle +Version=5,2,0,1 +Category=C4D_Object +Width=10 +Height=7 +Offset=-5,-4 +Vertices=3 +VertexX=0,-4,5 +VertexY=0,0,0 +VertexFriction=50,50,100 +Value=10 +Mass=10 +Components=Wood=1;Metal=1; +Rotate=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Graphics.mesh b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Graphics.mesh new file mode 100644 index 000000000..b5b9c56aa Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Scene.material new file mode 100644 index 000000000..ff6ec4250 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Scene.material @@ -0,0 +1,30 @@ +// sickle genrated by blender2ogre 0.5.8 + +material sickle +{ + receive_shadows on + + technique + { + pass sickle + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0 + specular 0.5 0.5 0.5 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + + alpha_to_coverage off + cull_hardware clockwise + depth_write on + scene_blend one zero + + texture_unit + { + texture sickle.jpg + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } + } + } +} diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Script.c new file mode 100644 index 000000000..b16bd1f11 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Script.c @@ -0,0 +1,64 @@ +/** + Sickle + Used for harvesting (wheat, cotton, ...) + + @author Clonkonaut +*/ + +private func Hit() +{ + Sound("WoodHit?"); +} + +public func GetCarryMode() { return CARRY_HandBack; } +public func GetCarryBone() { return "main"; } +public func GetCarryTransform() { return Trans_Rotate(270,0,1,0); } + +public func ControlUseStart(object clonk, int x, int y) +{ + // Can clonk use the sickle? + if (!clonk->IsWalking() && !clonk->IsJumping()) + return true; + + // If the clonk doesn't have an action where he can use it's hands do nothing + if (!clonk->HasHandAction()) + return true; + + var arm = "R"; + var carry_bone = "pos_hand2"; + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1) + { + arm = "L"; + carry_bone = "pos_hand1"; + } + var animation = Format("SwordSlash2.%s", arm); + + // Figure out the kind of animation to use + var length=15; + if(clonk->IsJumping()) + animation = Format("SwordJump2.%s",arm); + + clonk->PlayAnimation(animation, 10, Anim_Linear(0, 0, clonk->GetAnimationLength(animation), length, ANIM_Remove), Anim_Const(1000)); + clonk->UpdateAttach(); + + // Search for harvestable plants + var crop = FindObject(Find_InRect(AbsX(clonk->GetX()-8), AbsY(clonk->GetY()-10), 16,20), Find_Func("IsHarvestable"), Find_Func("SickleHarvesting")); + if (crop) + crop->Harvest(); + + clonk->CancelUse(); + return true; +} + +public func IsTool() { return true; } +public func IsToolProduct() { return true; } + +func Definition(def) { + SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(15, 0, 1, 0), Trans_Rotate(320, 0,0,1)),def); +} + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Rebuy = true; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Sickle.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Sickle.jpg new file mode 100644 index 000000000..0a109f922 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Sickle.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Sickle.skeleton b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Sickle.skeleton new file mode 100644 index 000000000..5bedd1bcc Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/Sickle.skeleton differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/StringTblDE.txt new file mode 100644 index 000000000..631168e9a --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Sichel +UsageHelp=Halte [Benutzen] gedrückt, um Pflanzen zu ernten. +Description=Die Sichel wird zum Ernten hartnäckiger Pflanzen (wie Weizen und Baumwolle) benötigt. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/StringTblUS.txt new file mode 100644 index 000000000..20310b874 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/Sickle.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Sickle +UsageHelp=Hold down the [Use] key to harvest plants. +Description=Clonks require sickles to harvest particularly stubborn plants, such as wheat or cotton. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Scene.material index b005f3171..4482336a5 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Scene.material @@ -12,7 +12,7 @@ material TeleGlove scene_blend alpha_blend texture_unit { - texture TeleGlove.png + texture TeleGlove.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Script.c index 1a04e91ec..7ba6be484 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Script.c @@ -22,7 +22,7 @@ protected func Initialize() { reach = 150; radius = 60; - radiusparticle = 60; + radiusparticle = radius / 4; } public func GetCarryMode() { return CARRY_HandBack; } @@ -55,12 +55,12 @@ private func StartUsage(object clonk) { var hand; // which animation to use? (which hand) - if(clonk->GetItemPos(this) == 0) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0) { carry_bone = "pos_hand2"; hand = "AimArmsGeneric.R"; } - if(clonk->GetItemPos(this) == 1) + else { carry_bone = "pos_hand1"; hand = "AimArmsGeneric.L"; @@ -125,30 +125,30 @@ public func ControlUseHolding(object clonk, ix, iy) var ys = -Cos(Random(359),radiusparticle/2); var anglep = Angle(0,0,ix,iy); var distp = Distance(0,0,ix,iy); - + + var particles; + if (Random(2)) particles = Particles_ElectroSpark1(); + else particles = Particles_ElectroSpark2(); + if(distp < reach) { //Particles moving towards object - for(var i; i < 2; i++) - { - CreateParticle("Spark1", ix + xs, iy + ys, -xs/3, -ys/3, RandomX(30,90), RGB(185,250,250)); - CreateParticle("Spark2", ix + xs, iy + ys, -xs/3, -ys/3, RandomX(30,90), RGB(185,250,250)); - } + CreateParticle("ElectroSpark", ix + xs, iy + ys, PV_Random(-xs/2, -xs/4), PV_Random(-ys/2, -ys/4), PV_Random(5, 10), particles, 5); //Particles emitting from clonk var wp = 1; if(Random(2)) wp = -1; - var xp = anglep - 90 + (Angle(0,0,distp,radiusparticle/2 * wp)); - var yp = anglep - 90 + (Angle(0,0,distp,radiusparticle/2 * wp)); - - CreateParticle("Spark1", Sin(xp, Random(distp)), -Cos(yp, Random(distp)), Sin(xp, 10), -Cos(yp, 10), RandomX(30,90), RGB(185,250,250)); + var xp = anglep + RandomX(-3, 3); + var yp = anglep + RandomX(-3, 3); + var xdir = Sin(xp, 10); + var ydir = -Cos(yp, 10); + var distance = Random(distp); + CreateParticle("ElectroSpark", Sin(xp, distance), -Cos(yp, distance), PV_Random(xdir - 5, xdir + 5), PV_Random(ydir - 2, ydir + 2), PV_Random(5, 10), particles, 5); } var target; if(target_object) { - radiusparticle = 30; - if(Distance(target_object->GetX(), target_object->GetY(), clonk->GetX() + ix, clonk->GetY() + iy) > radius || Distance(target_object->GetX(), target_object->GetY(), clonk->GetX(), clonk->GetY()) > reach) { @@ -159,8 +159,6 @@ public func ControlUseHolding(object clonk, ix, iy) if(!target_object) { - radiusparticle = 60; - target = FindObject(Find_Exclude(this), Find_NoContainer(), Find_Category(C4D_Object), @@ -190,7 +188,7 @@ public func ControlUseHolding(object clonk, ix, iy) target_object->SetSpeed(Sin(angle, speed), -Cos(angle, speed)); //Particles emitting from object - target_object->CreateParticle("Spark1", 0, 0, xs/10, ys/10, RandomX(20,40), RGB(185,250,250)); + target_object->CreateParticle("ElectroSpark", 0, 0, PV_Random(xs/8, xs/10), PV_Random(ys/8, ys/10), PV_Random(5, 10), particles, 5); } else LostTargetObject(target_object); @@ -252,7 +250,6 @@ protected func CancelUse(object clonk) aiming = 0; if(target_object) LostTargetObject(target_object); target_object = nil; - radiusparticle = 60; return 1; } @@ -261,10 +258,14 @@ func Hit() Sound("GeneralHit?"); } +func IsInventorProduct() { return true; } + func Definition(def) { SetProperty("PictureTransformation",Trans_Rotate(-60,1,0,1),def); } + local Name = "$Name$"; +local UsageHelp = "$UsageHelp$"; local Description = "$Description$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark1.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark1.ocd/Graphics.png deleted file mode 100644 index 8b8b41c25..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark1.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark1.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark1.ocd/Particle.txt deleted file mode 100644 index ae952483c..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark1.ocd/Particle.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Particle] -Name=Spark1 -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=2 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=64 -AlphaFade=0 -Additive=1 -RByV=1 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark2.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark2.ocd/Graphics.png deleted file mode 100644 index e81773fa8..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark2.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark2.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark2.ocd/Particle.txt deleted file mode 100644 index 71c8a46a2..000000000 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/Spark2.ocd/Particle.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Particle] -Name=Spark2 -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=2 -Repeats=1 -GravityAcc=0 -VertexCount=1 -VertexY=64 -AlphaFade=0 -Additive=1 -RByV=1 -Attach=0 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblDE.txt index fcdeb5a40..bc16883e3 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ -Name=Telekinetischer Gyrohandschuh -Description=Du kannst ein frei herumliegendes Objekt durch die Landschaft ziehen, indem Du darauf zeigst und dabei die Maustaste gedrückt hälst. \ No newline at end of file +Name=Telehandschuh +Description=Dieser experimentelle Handschuh ermöglicht es, kleine Objekte telekinetisch durch die Luft zu bewegen und sogar zu verschleudern. +UsageHelp=Ziele auf ein kleines Objekt in deiner Nähe und halte [Benutzen] gedrückt um es durch die Luft zu bewegen. diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblUS.txt index 3ee87a560..0cb7ed196 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ -Name=Telekinetic Gyroglove -Description=You can drag a small object lying about through the landscape by pointing on it while holding the mouse button. \ No newline at end of file +Name=Tele Glove +Description=With this experimental glove it is possible to telekinetically move objects through the air and and even fling them away. +UsageHelp=Aim for a small object in your vicinity and press and hold [Use] to move it around. diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/TeleGlove.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/TeleGlove.jpg new file mode 100644 index 000000000..31cc42fdb Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/TeleGlove.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/TeleGlove.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/TeleGlove.png deleted file mode 100644 index 99eaa9b48..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Tools.ocd/TeleGlove.ocd/TeleGlove.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/DefCore.txt new file mode 100644 index 000000000..6cb1cecd5 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/DefCore.txt @@ -0,0 +1,17 @@ +[DefCore] +id=WallKit +Version=5,2,0,1 +Category=C4D_Object +Width=12 +Height=4 +Offset=-6,-2 +Vertices=3 +VertexX=-5,5,0 +VertexY=0,0,0 +VertexCNAT=1,2,16 +VertexFriction=30,30,30 +Value=8 +Mass=12 +Components=Metal=2 +Rotate=1 +Picture=0,20,64,64 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Graphics.5.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Graphics.5.png new file mode 100644 index 000000000..465f84e8d Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Graphics.5.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/DefCore.txt new file mode 100644 index 000000000..bcbaf6356 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/DefCore.txt @@ -0,0 +1,6 @@ +[DefCore] +id=WallKit_Preview +Version=5,2,0,1 +Category=C4D_StaticBack +Vertices=2 +Line=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/Graphics.png new file mode 100644 index 000000000..753695654 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/Script.c new file mode 100644 index 000000000..2b60878c2 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Preview.ocd/Script.c @@ -0,0 +1,17 @@ +/*-- WallKit preview --*/ + +// definition call: create line +func Create(int x1,int y1,int x2,int y2,int clr) +{ + var obj = CreateObject(WallKit_Preview); + obj->Set(x1,y1,x2,y2,clr); + return obj; +} + +func Set(int x1,int y1,int x2,int y2,int clr) +{ + SetVertexXY(0, x1,y1); + SetVertexXY(1, x2,y2); + this.LineColors = [clr, clr]; + return; +} diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Script.c new file mode 100644 index 000000000..3ef71da7b --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/Script.c @@ -0,0 +1,118 @@ +/* Wall kit */ + +#include Library_Stackable + +func MaxStackCount() { return 4; } + +/* Item usage */ + +func ControlUseStart(object clonk, int x, int y) +{ + clonk->Sound("WallKitClick"); + SetPreview(clonk,x,y); + return true; +} + +func HoldingEnabled() { return true; } + +func ControlUseHolding(object clonk, int new_x, int new_y) +{ + SetPreview(clonk, new_x, new_y); + return true; +} + +public func ControlUseStop(object clonk, int x, int y) +{ + StopPreview(clonk); + var item = TakeObject(); + if (!item) return true; // zero stack count? + item->CreateBridge(clonk, x, y); + if (item) item->RemoveObject(); + return true; +} + +public func ControlUseCancel(object clonk, int x, int y) +{ + StopPreview(clonk); + return true; +} + + +/* Bridge building */ + +private func CreateBridge(object clonk, int x, int y) +{ + var c = Offset2BridgeCoords(clonk, x, y); + x=clonk->GetX(); y=clonk->GetY(); + DrawMaterialQuad("Granite-granite", x+c.x1-c.dx,y+c.y1-c.dy, x+c.x1+c.dx,y+c.y1+c.dy, x+c.x2+c.dx,y+c.y2+c.dy, x+c.x2-c.dx,y+c.y2-c.dy, DMQ_Bridge); + clonk->Sound("WallKitLock"); + return true; +} + + +/* Bridge position calculation */ + +private func Offset2BridgeCoords(object clonk, int x, int y) +{ + // Returns starting and end point offset of bridge to be built as player points to offset x/y + var dx=clonk->GetDefWidth(), dy=clonk->GetDefHeight(), ox,oy,rx,ry,l=BridgeLength; + ox=x*2/Abs(y+!y); oy=y*2/Abs(x+!x); + ry=ox/=Abs(ox)+!ox; + rx=oy/=Abs(oy)+!oy; + ox*=dx/2+2*!oy; + oy*=dy/2+2*!ox; + l-=l*3*Abs(rx*ry)/10; + return { dx=ry*BridgeThickness, dy=rx*BridgeThickness, x1=ox+(rx*=l), y1=oy-(ry*=l), x2=ox-rx, y2=oy+ry }; +} + + + +/* Preview */ + +local preview; + +func SetPreview(object clonk, int x, int y) +{ + var c = Offset2BridgeCoords(clonk, x, y), clr = 0xffa0a0a0; + x=clonk->GetX(); y=clonk->GetY(); + if (!preview) + { + preview = WallKit_Preview->Create(x+c.x1,y+c.y1,x+c.x2,y+c.y2,clr); + preview->SetOwner(clonk->GetOwner()); + preview.Visibility = VIS_Owner; + } + else + { + preview->Set(x+c.x1,y+c.y1,x+c.x2,y+c.y2,clr); + } + return true; +} + +func StopPreview(object clonk) +{ + if (preview) preview->RemoveObject(); + return true; +} + + +/* Impact sound */ + +func Hit() +{ + Sound("GeneralHit?"); + return true; +} + + +/* Status */ + +public func IsTool() { return true; } +public func IsToolProduct() { return true; } + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Rebuy = true; +local BridgeLength = 20; +local BridgeThickness = 1; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/StringTblDE.txt new file mode 100644 index 000000000..a7b07dbcd --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Wandbausatz +Description=Mit dem Wandbausatz koennen stabile Waende errichtet werden. +UsageHelp=Halte [Benutzen] gedrückt, um eine Vorschau für die Brücke zu erhalten. Lasse los, um die Brücke am gewünschten Ort zu errichten. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/StringTblUS.txt new file mode 100644 index 000000000..4b36fde2a --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Wall kit +Description=You can create solid walls with the wall kit. +UsageHelp=Hold down the [Use] key to see a preview in the direction you are pointing. Let go to build there. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/WallKitClick.wav b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/WallKitClick.wav new file mode 100644 index 000000000..e3517ed48 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/WallKitClick.wav differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/WallKitLock.wav b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/WallKitLock.wav new file mode 100644 index 000000000..79d39e08e Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WallKit.ocd/WallKitLock.wav differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/DefCore.txt new file mode 100644 index 000000000..45af9b1c3 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=WindBag +Category=C4D_Object +Width=18 +Height=10 +Offset=-9,-5 +Vertices=4 +VertexX=-8,6,0 +VertexY=-1,-3,4 +VertexFriction=50,50,50 +Value=14 +Mass=12 +Components=Cloth=1;Metal=1; +Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Graphics.mesh b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Graphics.mesh new file mode 100644 index 000000000..4cd138060 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c similarity index 76% rename from planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Script.c rename to planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c index b4b92fb37..6a963af24 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c @@ -1,9 +1,8 @@ /*-- - Jar of Winds + Windbag (aka Jar of Winds) Author: MimmoO Collect air until you're full, then release it with a blast. - --*/ local Amount; @@ -12,10 +11,14 @@ local sound; func Hit() { - Sound("GlassHit?"); + Sound("GeneralHit?"); } -public func GetCarryMode(clonk) { return CARRY_BothHands; } +public func GetCarryMode(clonk) { return CARRY_Musket; } +public func GetCarryTransform() +{ + return Trans_Mul(Trans_Rotate(220,0,0,1),Trans_Rotate(-30,1,0,0),Trans_Rotate(26,0,1,0)); +} public func GetCarryPhase() { return 600; } public func FxJarReloadTimer(object target, effect, int time) @@ -31,7 +34,7 @@ public func DoFullLoad() protected func Initialize() { - MaxCap = 60; //Changes duration and power of the Jar + MaxCap = 60; //Changes duration and power SetR(-45); AddEffect("JarReload",this,100,2,this); sound=false; @@ -81,13 +84,7 @@ protected func Load() sound=true; } Amount += 2; //Air is sucked in. - CreateParticle("AirIntake", - SX,SY, - Sin(A + R,-D / 2), - Cos(A + R,-D / 2), - RandomX(35,80), - RGBa(255,255,255,128) - ); + CreateParticle("Air", SX, SY, Sin(A + R,-D / 2), Cos(A + R,-D / 2), 18, {Prototype = Particles_Air(), Size = PV_KeyFrames(0, 0, 0, 250, 3, 1000, 0)}); } else if(GBackSolid(0,0) || GBackLiquid(0,0)) { @@ -127,12 +124,7 @@ private func FireWeapon(object pClonk,iX,iY) if(!GBackSolid(SX,SY)) { - CreateParticle("Air", - SX,SY, - Sin(180 - iAngle + (R),(Amount / 2) + 25), - Cos(180 - iAngle + (R),(Amount / 2) + 25), - Max(i + 30, 90) + 75, - ); + CreateParticle("Air", SX, SY, Sin(180 - iAngle + (R),(Amount / 2) + 25), Cos(180 - iAngle + (R),(Amount / 2) + 25), 36, Particles_Air()); } } @@ -154,7 +146,8 @@ private func FireWeapon(object pClonk,iX,iY) Find_Distance(25,Sin(180 - iAngle,70),Cos(180 - iAngle,70)) ), Find_Not(Find_Category(C4D_Structure)), - Find_Not(Find_Func("NoWindjarForce")), + Find_Not(Find_Func("IsEnvironment")), + Find_Not(Find_Func("NoWindbagForce")), Find_Layer(GetObjectLayer()), Find_NoContainer() ) ) @@ -170,7 +163,14 @@ private func FireWeapon(object pClonk,iX,iY) } } +func IsInventorProduct() { return true; } + +func Definition(def) { + SetProperty("PictureTransformation",Trans_Mul(Trans_Scale(1500),Trans_Rotate(150,0,0,1),Trans_Rotate(-170,1,0,0),Trans_Rotate(10,0,1,0)),def); +} + local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt new file mode 100644 index 000000000..c3b9f5900 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Windbeutel +Description=Enthält komprimierten Wind der in einem Stoß entfesselt werden kann. +UsageHelp=Ziele und drücke [Benutzen], um einen Windstoß in diese Richtung zu entfesseln. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt new file mode 100644 index 000000000..52d7d7563 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Wind bag +Description=Contains compressed wind that can be released in one gust. +UsageHelp=Aim and press [Use] to release a gust of wind in the direction specified. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindCharge.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindCharge.ogg new file mode 100644 index 000000000..52f467b52 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindCharge.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindChargeStop.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindChargeStop.ogg new file mode 100644 index 000000000..8a5e26dc5 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindChargeStop.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindGust.ogg b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindGust.ogg new file mode 100644 index 000000000..c48cbc2fa Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/WindGust.ogg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/authors.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/authors.txt similarity index 100% rename from planet/Objects.ocd/Items.ocd/Tools.ocd/JarOfWinds.ocd/authors.txt rename to planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/authors.txt diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/bagpipe.jpg b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/bagpipe.jpg new file mode 100644 index 000000000..9445d7297 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/bagpipe.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/windbag.skeleton b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/windbag.skeleton new file mode 100644 index 000000000..dfe9e5a71 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/windbag.skeleton differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/windbag_material.material b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/windbag_material.material new file mode 100644 index 000000000..4aed91afd --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/windbag_material.material @@ -0,0 +1,31 @@ +// windbag_material genrated by blender2ogre 0.6.0 + +material windbag_material +{ + receive_shadows on + + technique + { + pass windbag_material + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + specular 0.009999999776482582 0.009999999776482582 0.009999999776482582 1.0 3.75 + emissive 0.0 0.0 0.0 1.0 + + alpha_to_coverage off + cull_hardware clockwise + depth_check on + depth_write on + scene_blend one zero + + texture_unit + { + texture bagpipe.jpg + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } + } + } +} diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Arrow.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Arrow.ocd/Script.c index b9e788e87..a33d3a0fc 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Arrow.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Arrow.ocd/Script.c @@ -24,10 +24,11 @@ protected func Construction() public func Launch(int angle, int str, object shooter) { //SetGraphics(0, HelpArrow); - SetShape(-2,-2,4,11); - SetVertex(0, 1, 4, 1); - SetVertex(1, 1, 8, 1); - SetVertex(2, 1, 0, 1); + SetShape(-2, -2, 4, 11); + SetVertex(0, VTX_Y, 3, 1); + SetVertex(1, VTX_Y, 4, 1); + SetVertex(2, VTX_Y, -2, 1); + SetPosition(GetX(), GetY() - 2); var xdir = Sin(angle,str); var ydir = Cos(angle,-str); SetXDir(xdir); @@ -61,7 +62,7 @@ private func Stick() //if(GetMaterialVal("DigFree","Material",mat)) //{ // stick in landscape - SetVertex(2,VTX_Y,-12,1); + SetVertex(2,VTX_Y,-10,1); //} } } @@ -75,7 +76,7 @@ public func HitObject(object obj) var dmg = ArrowStrength()*speed/100; ProjectileHit(obj,dmg,ProjectileHit_tumble); // Stick does something unwanted to controller. - Stick(); + if (this) Stick(); } // called by successful hit of object after from ProjectileHit(...) diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/DefCore.txt index fff46b988..8b360e064 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/DefCore.txt @@ -13,7 +13,4 @@ Value=8 Mass=10 Components=Wood=3; Rotate=1 -ContactIncinerate=5 -BlastIncinerate=30 -BurnTo=NONE Float=2 diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c index 24bd178c9..d0cbaa070 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/Script.c @@ -238,5 +238,8 @@ func Definition(def) { local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; +local BlastIncinerate = 30; +local ContactIncinerate = 5; \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblDE.txt index beec3d0e4..358e1ac83 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Bogen -Description=Ziele und schieße mit [Benutzen]. Der Bogen benötigt Pfeile als Munition. \ No newline at end of file +Description=Klassische Fernkampfwaffe. Der Bogen benötigt Pfeile als Munition. +UsageHelp=Ziele und schieße mit [Benutzen]. Der Bogen benötigt Pfeile als Munition. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblUS.txt index c3d12c88e..8bb2ecf0d 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Bow.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Bow -Description=Aim and shoot with [Use]. The bow needs arrows as ammunition. \ No newline at end of file +Description=Classic ranged weapon. The bow needs arrows for ammunition. +UsageHelp=Aim and shoot with [Use]. The bow needs arrows as ammunition. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Club.jpg b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Club.jpg new file mode 100644 index 000000000..00624a5e5 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Club.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Club.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Club.png deleted file mode 100644 index 1e26afdfc..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Club.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Scene.material index bc93cdee2..305a75986 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Scene.material @@ -11,7 +11,7 @@ material Club emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Club.png + texture Club.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Script.c index baa6f21e4..b942e7828 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/Script.c @@ -13,7 +13,7 @@ public func GetCarrySpecial(clonk) { if(fAiming) { - if(clonk->GetItemPos(this) == 1) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1) return "pos_hand1"; else return "pos_hand2"; @@ -67,9 +67,9 @@ local fAiming; public func ControlUseStart(object clonk, int x, int y) { - if(clonk->GetItemPos(this) == 0) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0) ClubChangeHandAnims("R"); - else if(clonk->GetItemPos(this) == 1) + else ClubChangeHandAnims("L"); // cooldown? @@ -85,8 +85,6 @@ public func ControlUseStart(object clonk, int x, int y) return 1; } -public func HoldingEnabled() { return true; } - func ControlUseHolding(object clonk, ix, iy) { var angle = Angle(0,0,ix,iy); @@ -177,21 +175,29 @@ func FxAfterClubShootControlQueryCatchBlow(object target, effect, object obj) func DoStrike(clonk, angle) { - var x=Sin(angle, 7); - var y=-Cos(angle, 7); - var found=false; - for(var obj in FindObjects(Find_Distance(7, x, y), Find_Or(Find_OCF(OCF_Alive), Find_Category(C4D_Object), Find_Category(C4D_Vehicle)), Find_Exclude(clonk), Find_NoContainer(), Find_Layer(GetObjectLayer()))) + // hit all objects in the direction of the Clonk - the angle is only important for the direction of the flinging + var x = Sin(angle, 7); + var y = -Cos(angle, 7); + var found = false; + for (var obj in FindObjects(Find_Distance(15, 0, 0), Find_Or(Find_OCF(OCF_Alive), Find_Category(C4D_Object), Find_Category(C4D_Vehicle)), Find_Exclude(clonk), Find_NoContainer(), Find_Layer(GetObjectLayer()), Sort_Distance())) { - if(obj->Stuck()) continue; + if (obj->Stuck()) continue; + + // don't hit objects behind the Clonk + if (x < 0) + { + if (obj->GetX() > GetX()) continue; + } + else if (obj->GetX() < GetX()) continue; // vehicles are only hit if they are pseudo vehicles. Bad system - has to be changed in the future - if(obj->GetCategory() & C4D_Vehicle) - if(!GetEffect("HitCheck", obj)) continue; + if (obj->GetCategory() & C4D_Vehicle) + if (!GetEffect("HitCheck", obj)) continue; - var en=Format("CannotBeHitTwiceBy%d", this->ObjectNumber()); - if(GetEffect(en, obj)) continue; + var en = Format("CannotBeHitTwiceBy%d", this->ObjectNumber()); + if (GetEffect(en, obj)) continue; - if(obj->GetOCF() & OCF_Alive) + if (obj->GetOCF() & OCF_Alive) { var damage=5*1000; ApplyWeaponBash(obj, 400, angle); @@ -202,19 +208,22 @@ func DoStrike(clonk, angle) var div=100; if(obj->GetContact(-1)) div*=10; + // the better you hit, the more power you have + var precision = BoundBy(Distance(obj->GetX(), obj->GetY(), GetX() + x, GetY() + y), 1, 15); + // mass/size factor - var fac1=10000/Max(2, obj->GetMass()); - var fac2=BoundBy(10-Abs(obj->GetDefCoreVal("Width", "DefCore")-obj->GetDefCoreVal("Height", "DefCore")), 1, 10); - var speed=(3000 * fac1 * fac2) / 10 / 1000; + var fac1 = 10000/Max(2, obj->GetMass()); + var fac2 = BoundBy(10-Abs(obj->GetDefCoreVal("Width", "DefCore")-obj->GetDefCoreVal("Height", "DefCore")), 1, 10); + var speed = (3000 * fac1 * fac2) / 2 / 1000 / precision; obj->SetXDir((obj->GetXDir(100) + Sin(angle, speed)) / 2, div); obj->SetYDir((obj->GetYDir(100) - Cos(angle, speed)) / 2, div); } - AddEffect(en, obj, 1, 15, 0); + AddEffect(en, obj, 1, 15, nil); found=true; break; } - if(found) + if (found) RemoveEffect("DuringClubShoot", clonk); } @@ -228,4 +237,5 @@ func Definition(def) { local Collectible = 1; local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblDE.txt index 85bd8a89a..af5ee8b5c 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Keule -Description=Mit der Keule lassen sich heranfliegende Dinge und Clonks wegschlagen. Zielen und Schlagen mit [Benutzen]. \ No newline at end of file +Description=Großer Bruder des Baseballschlägers. +UsageHelp=Zielen und Schlagen mit [Benutzen]. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblUS.txt index 673e03e92..c38ccdbd6 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Club.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Club -Description=With the club, you can bat away stuff, including clonks. Aim and bat with [Use]. \ No newline at end of file +Description=Big brother of the baseball bat. +UsageHelp=Aim and bat with [Use]. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/DefCore.txt new file mode 100644 index 000000000..6a85912da --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=GrenadeLauncher +Version=5,2,0,1 +Category=C4D_Object +Width=16 +Height=6 +Offset=-8,-3 +Vertices=4 +VertexX=-7,3,5,0 +VertexY=0,0,2,0 +VertexFriction=50,50,70 +Value=25 +Mass=15 +Components=Metal=3;Wood=1; +Rotate=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Graphics.mesh b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Graphics.mesh new file mode 100644 index 000000000..1fdb37144 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/GrenadeLauncher.skeleton b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/GrenadeLauncher.skeleton new file mode 100644 index 000000000..178e1f79f Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/GrenadeLauncher.skeleton differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Scene.material new file mode 100644 index 000000000..5b72754c5 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Scene.material @@ -0,0 +1,31 @@ +// grenade_launcher genrated by blender2ogre 0.6.0 + +material grenade_launcher +{ + receive_shadows on + + technique + { + pass grenade_launcher + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0 + specular 0.02459016442298889 0.02459016442298889 0.02459016442298889 1.0 2.5 + emissive 0.0 0.0 0.0 1.0 + + alpha_to_coverage off + cull_hardware clockwise + depth_check on + depth_write on + scene_blend one zero + + texture_unit + { + texture grenadelauncher.jpg + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } + } + } +} diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c new file mode 100644 index 000000000..43fb517c0 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c @@ -0,0 +1,200 @@ +/*-- + Grenade Launcher + Author: Clonkonaut + + A single shot grenade launcher which fires dangerous iron bombs. + +--*/ + +//Uses the extra slot library +#include Library_HasExtraSlot + +func Hit() +{ + Sound("GeneralHit?"); +} + +local fAiming; + +public func GetCarryMode(clonk) { if(fAiming >= 0) return CARRY_Musket; } +public func GetCarrySpecial(clonk) { if(fAiming > 0) return "pos_hand2"; } +public func GetCarryBone() { return "main"; } +public func GetCarryTransform() +{ + return Trans_Mul(Trans_Rotate(-90,0,1,0), Trans_Rotate(10,1,0,0)); +} + +local animation_set; + +func Initialize() +{ + //Tweaking options + MuzzleUp = 12; + MuzzleFront = 13; + MuzzleDown = 16; + MuzzleOffset = -8; + + animation_set = { + AimMode = AIM_Position, // The aiming animation is done by adjusting the animation position to fit the angle + AnimationAim = "MusketAimArms", + AnimationLoad = "MusketLoadArms", + LoadTime = 80, + AnimationShoot = nil, + ShootTime = 20, + WalkSpeed = 84, + WalkBack = 56, + }; +} + +public func GetAnimationSet() { return animation_set; } + +local loaded; +local reload; + +local yOffset; +local iBarrel; + +local holding; + +local MuzzleUp; local MuzzleFront; local MuzzleDown; local MuzzleOffset; + +protected func HoldingEnabled() { return true; } + +func ControlUseStart(object clonk, int x, int y) +{ + // if the clonk doesn't have an action where he can use it's hands do nothing + if(!clonk->HasHandAction()) + { + holding = true; + return true; + } + + // nothing in extraslot? + if(!Contents(0)) + { + // put something inside + var obj; + if(obj = FindObject(Find_Container(clonk), Find_Func("IsGrenadeLauncherAmmo"))) + { + obj->Enter(this); + } + } + + // something in extraslot + if(!Contents(0)) + { + clonk->CancelUse(); + return true; + } + + fAiming = 1; + + holding = true; + + // reload weapon if not loaded yet + if(!loaded) + clonk->StartLoad(this); + else + clonk->StartAim(this); + + ControlUseHolding(clonk, x, y); + + return true; +} + +// Callback from the clonk when loading is finished +public func FinishedLoading(object clonk) +{ + SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(500,1000,-000),Trans_Rotate(130,0,1,0),Trans_Rotate(20,0,0,1))); + loaded = true; + if(holding) clonk->StartAim(this); + return holding; // false means stop here and reset the clonk +} + +func ControlUseHolding(object clonk, ix, iy) +{ + var angle = Angle(0,0,ix,iy-MuzzleOffset); + angle = Normalize(angle,-180); + + clonk->SetAimPosition(angle); + + return true; +} + +protected func ControlUseStop(object clonk, ix, iy) +{ + holding = false; + clonk->StopAim(); + return -1; +} + +// Callback from the clonk, when he actually has stopped aiming +public func FinishedAiming(object clonk, int angle) +{ + if(!loaded) return; + + // Fire + if(Contents(0) && Contents(0)->IsGrenadeLauncherAmmo()) + FireWeapon(clonk, angle); + clonk->StartShoot(this); + return true; +} + +protected func ControlUseCancel(object clonk, int x, int y) +{ + clonk->CancelAiming(this); + return true; +} + +public func Reset(clonk) +{ + fAiming = 0; +} + +private func FireWeapon(object clonk, int angle) +{ + var shot = Contents(0)->~TakeObject() ?? Contents(0); + + var IX=Sin(180-angle,MuzzleFront); + var IY=Cos(180-angle,MuzzleUp)+MuzzleOffset; + + shot->LaunchProjectile(angle, 0, 75, IX, IY); + shot->~Fuse(true); + + loaded = false; + SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1500,0,-1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1))); + + Sound("GunShoot?"); + + // Muzzle Flash & gun smoke + if(Abs(Normalize(angle,-180)) > 90) + IY=Cos(180-angle,MuzzleDown)+MuzzleOffset; + + var x = Sin(angle, 20); + var y = -Cos(angle, 20); + CreateParticle("Smoke", IX, IY, PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), PV_Random(40, 60), Particles_Smoke(), 20); + + clonk->CreateMuzzleFlash(IX, IY, angle, 40); + CreateParticle("Flash", 0, 0, 0, 0, 8, Particles_Flash()); +} + +func RejectCollect(id shotid, object shot) +{ + // Only collect grenade launcher ammo + if(!(shot->~IsGrenadeLauncherAmmo())) return true; +} + +public func IsWeapon() { return true; } +public func IsArmoryProduct() { return true; } + + + +func Definition(def) { + SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1500,0,-1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1)),def); +} + +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Collectible = 1; +local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/StringTblDE.txt new file mode 100644 index 000000000..d02bc5e71 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Granatwerfer +Description=Feuerwaffe. Der Granatwerfer benötigt Eisenbomben als Munition. +UsageHelp=Ziele und schieße mit [Benutzen]. Der Granatwerfer benötigt Eisenbomben als Munition. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/StringTblUS.txt new file mode 100644 index 000000000..5f7449ae5 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Grenade Launcher +Description=Firearm. The grenade launcher needs iron bombs for ammunition. +UsageHelp=Aim and shoot with [Use]. The grenade launcher needs iron bombs for ammunition. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/grenadelauncher.jpg b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/grenadelauncher.jpg new file mode 100644 index 000000000..6e6b93b12 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/grenadelauncher.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/DefCore.txt index e0f3b27bf..232dcc5ab 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/DefCore.txt @@ -12,7 +12,5 @@ VertexY=-2,2,2 VertexFriction=20,20,20 Value=3 Mass=10 -Components=IronBomb=1; +Components=Metal=1;Firestone=1; Rotate=1 -ContactIncinerate=1 -BlastIncinerate=1 diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Script.c index 38dad9994..8e13c541d 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Script.c @@ -1,10 +1,11 @@ /* IronBomb - Author: Ringwaul + Author: Ringwaul, Clonkonaut - Explodes after a short fuse. + Explodes after a short fuse. Explodes on contact if shot by the grenade launcher */ - + +local armed; // If true, explodes on contact public func ControlUse(object clonk, int x, int y, bool box) { @@ -20,8 +21,9 @@ public func ControlUse(object clonk, int x, int y, bool box) } } -func Fuse() +func Fuse(bool explode_on_hit) { + armed = explode_on_hit; AddEffect("FuseBurn", this, 1,1, this); } @@ -30,7 +32,7 @@ func FxFuseBurnTimer(object bomb, int num, int timer) var i = 3; var x = +Sin(GetR(), i); var y = -Cos(GetR(), i); - CreateParticle("EngineSmoke", x, y, x, y, RandomX(20,50), RGB(100,100,100)); + CreateParticle("Smoke", x, y, x, y, PV_Random(18, 36), Particles_Smoke(), 2); if(timer == 1) Sound("FuseLoop",nil,nil,nil,+1); if(timer >= 90) @@ -49,6 +51,7 @@ func DoExplode() var shrapnel = CreateObject(Shrapnel); shrapnel->SetVelocity(Random(359), RandomX(100,140)); shrapnel->SetRDir(-30+ Random(61)); + shrapnel->Launch(GetController()); CreateObject(BulletTrail)->Set(2,30,shrapnel); i--; } @@ -56,14 +59,14 @@ func DoExplode() Sound("BlastLiquid2"); else Sound("BlastMetal"); - CreateParticle("ExploSmoke", 0,0,0,0,390,RGBa(255,255,255,165)); - Explode(14); + CreateParticle("Smoke", PV_Random(-30, 30), PV_Random(-30, 30), 0, 0, PV_Random(40, 60), Particles_Smoke(), 60); + Explode(30); } protected func Hit(x, y) { + if (armed) return DoExplode(); StonyObjectHit(x,y); - return true; } protected func Incineration() { Extinguish(); Fuse(); } @@ -75,9 +78,12 @@ protected func RejectEntrance() public func IsWeapon() { return true; } public func IsArmoryProduct() { return true; } -public func HasFuse() { return true; } +public func IsGrenadeLauncherAmmo() { return true; } local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; +local BlastIncinerate = 1; +local ContactIncinerate = 1; diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Shrapnel.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Shrapnel.ocd/Script.c index a512f4e17..5045c39fb 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Shrapnel.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/Shrapnel.ocd/Script.c @@ -1,6 +1,6 @@ /* shrapnel */ -public func ProjectileDamage() { return 1; } +public func ProjectileDamage() { return 3; } public func FlightTime() { return 4; } protected func Initialize() @@ -9,20 +9,24 @@ protected func Initialize() AddEffect("Fade", this, 1, 1, this); } +public func Launch(int shooter) +{ + SetController(shooter); + AddEffect("HitCheck", this, 1,1, nil, nil); +} + protected func FxFadeTimer(object target, int num, int timer) { -/* SetObjAlpha(255 - ((timer * 1275)/ 100)); - if(timer >= 20) - { - RemoveObject(); - }*/ - if(timer > FlightTime()) RemoveObject(); } protected func Hit() { ShakeFree(6); + RemoveEffect("HitCheck",this); + Sound("BulletHitGround?"); + CreateParticle("Spark", 0, 0, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(10, 20), Particles_Glimmer(), 3); + RemoveObject(); } diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblDE.txt index 66cf06e27..e0ff6e9aa 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Eisenbombe -Description=Nach dem Anzünden, drücke [Benutzen], um zu werfen. \ No newline at end of file +Description=Bumm! +UsageHelp=Drücke [Benutzen] um sie anzuzünden, danach schnell wegwerfen! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblUS.txt index 4a1d9f745..8a0e176b0 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/IronBomb.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Iron Bomb -Description=Press [Use] to ignite. After it has been ignited, throw it with [Use]. \ No newline at end of file +Description=Boom! +UsageHelp=Press [Use] to ignite. After that, throw it away quickly! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/Scene.material index ea3e36f5b..04b76ab4e 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/Scene.material @@ -11,7 +11,7 @@ material Javelin emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture javelin.png + texture javelin.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblDE.txt index ad72860d6..7b73505b3 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Wurfspeer -Description=Ziele und werfe einen der Wurfspeere mit [Benutzen]. Mit Anlauf kannst Du den Wurfspeer wesentlich weiter werfen. \ No newline at end of file +Description=Wurfwaffe, kann nach dem Wurf wieder aufgesammelt werden. +UsageHelp=Ziele und werfe einen der Wurfspeere mit [Benutzen]. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblUS.txt index 0f6e90883..ba10d51a8 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Javelin -Description=Press [Use] to aim and throw one of the javelins. If you take a run up, you'll be able to throw it farther. \ No newline at end of file +Description=Throwing weapon. Can be recollected after it is thrown. +UsageHelp=Press [Use] to aim and throw one of the javelins. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/javelin.jpg b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/javelin.jpg new file mode 100644 index 000000000..f7d36913b Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/javelin.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/javelin.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/javelin.png deleted file mode 100644 index ca45baaf7..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Javelin.ocd/javelin.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Ammo.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Ammo.ocd/Script.c index 95c705075..aa1f3900f 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Ammo.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Ammo.ocd/Script.c @@ -17,18 +17,18 @@ protected func Hit() Sound("BulletHitGround?"); - CastParticles("Spark",1,20,0,0,15,25,RGB(255,200,0),RGB(255,255,150)); + CreateParticle("Spark", 0, 0, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(10, 20), Particles_Glimmer(), 3); RemoveObject(); } } -public func Launch(object shooter, int angle, int dist, int speed) +public func Launch(object shooter, int angle, int dist, int speed, int offset_x, int offset_y) { SetController(shooter->GetController()); AddEffect("HitCheck", this, 1,1, nil,nil, shooter); - LaunchProjectile(angle, dist, speed); + LaunchProjectile(angle, dist, speed, offset_x, offset_y); // remove after some time SetAction("Travel"); diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/BulletTrail.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/BulletTrail.ocd/Script.c index a5e51dc0c..8d1f44721 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/BulletTrail.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/BulletTrail.ocd/Script.c @@ -113,6 +113,8 @@ public func DrawTransform() { ); } +public func SaveScenarioObject() { return false; } + local ActMap = { Travel = { diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/MuzzleFlash.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/MuzzleFlash.ocd/Particle.txt deleted file mode 100644 index d61b971ab..000000000 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/MuzzleFlash.ocd/Particle.txt +++ /dev/null @@ -1,13 +0,0 @@ -[Particle] -Name=MuzzleFlash -MaxCount=130 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=1 -Repeats=1 -GravityAcc=0 -Additive=1 -RByV=2 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Script.c index 4fe1ca47c..657c9dea3 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/Script.c @@ -153,8 +153,14 @@ public func Reset(clonk) private func FireWeapon(object clonk, int angle) { + // calculate offset for shot and effects + var IX=Sin(180-angle,MuskFront); + var IY=Cos(180-angle,MuskUp)+MuskOffset; + if(Abs(Normalize(angle,-180)) > 90) + IY=Cos(180-angle,MuskDown)+MuskOffset; + var shot = Contents(0)->TakeObject(); - shot->Launch(clonk,angle,iBarrel,200); + shot->Launch(clonk, angle, iBarrel, 200, IX, IY); loaded = false; SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1500,0,-1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1))); @@ -162,19 +168,12 @@ private func FireWeapon(object clonk, int angle) Sound("GunShoot?"); // Muzzle Flash & gun smoke - var IX=Sin(180-angle,MuskFront); - var IY=Cos(180-angle,MuskUp)+MuskOffset; - if(Abs(Normalize(angle,-180)) > 90) - IY=Cos(180-angle,MuskDown)+MuskOffset; + var x = Sin(angle, 20); + var y = -Cos(angle, 20); + CreateParticle("Smoke", IX, IY, PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), PV_Random(40, 60), Particles_Smoke(), 20); + clonk->CreateMuzzleFlash(IX, IY, angle, 20); - for(var i=0; i<10; ++i) - { - var speed = RandomX(0,10); - var r = angle; - CreateParticle("ExploSmoke",IX,IY,+Sin(r,speed)+RandomX(-2,2),-Cos(r,speed)+RandomX(-2,2),RandomX(100,400),RGBa(255,255,255,50)); - } - CreateParticle("MuzzleFlash",IX,IY,+Sin(angle,500),-Cos(angle,500),450,RGB(255,255,255),clonk); - CreateParticle("Flash",0,0,0,0,800,RGBa(255,255,64,150)); + CreateParticle("Flash", 0, 0, 0, 0, 8, Particles_Flash()); } func RejectCollect(id shotid, object shot) @@ -192,5 +191,6 @@ func Definition(def) { local Name = "$Name$"; local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblDE.txt index 9d514218a..7fa05223f 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Muskete -Description=Ziele und schieße mit [Benutzen]. Die Muskete benötigt Bleikugeln als Munition. \ No newline at end of file +Description=Feuerwaffe. Die Muskete benötigt Bleikugeln als Munition. +UsageHelp=Ziele und schieße mit [Benutzen]. Die Muskete benötigt Bleikugeln als Munition. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblUS.txt index 1d1a4e2fa..cfe9591ad 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Musket.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Musket -Description=Aim and shoot with [Use]. The musket needs lead shot as ammunition. \ No newline at end of file +Description=Firearm. The musket needs lead shot for ammunition. +UsageHelp=Aim and shoot with [Use]. The musket needs lead shot for ammunition. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Scene.material index ac65483e6..aee0699f0 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Scene.material @@ -20,7 +20,7 @@ material Shield } texture_unit { - texture shield.png + texture shield.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Script.c index 2c76a2554..1ba5dad91 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/Script.c @@ -49,12 +49,12 @@ private func StartUsage(object clonk) { var hand; // which animation to use? (which hand) - if(clonk->GetItemPos(this) == 0) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0) { carry_bone = "pos_hand2"; hand = "ShieldArms.R"; } - if(clonk->GetItemPos(this) == 1) + else { carry_bone = "pos_hand1"; hand = "ShieldArms.L"; @@ -63,9 +63,9 @@ private func StartUsage(object clonk) aim_anim = clonk->PlayAnimation(hand, 10, Anim_Const(clonk->GetAnimationLength(hand)/2), Anim_Const(1000)); var handLR; - if(clonk->GetItemPos(this) == 0) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0) handLR = "R"; - if(clonk->GetItemPos(this) == 1) + else handLR = "L"; clonk->UpdateAttach(); @@ -77,6 +77,8 @@ private func StartUsage(object clonk) if(!GetEffect("ShieldStopControl", clonk)) AddEffect("ShieldStopControl", clonk, 2, 5, this); + + clonk->SetTurnType(1, 1); } private func EndUsage(object clonk) @@ -94,7 +96,10 @@ private func EndUsage(object clonk) AdjustSolidMaskHelper(); if(GetEffect("ShieldStopControl", clonk)) RemoveEffect("ShieldStopControl", clonk); - + + clonk->SetTurnForced(-1); + clonk->SetTurnType(0, -1); + StopWeaponHitCheckEffect(clonk); } @@ -104,24 +109,15 @@ private func UpdateShieldAngle(object clonk, int x, int y) var angle=Normalize(Angle(0,0, x,y),-180); angle=BoundBy(angle,-150,150); - if(clonk->GetDir() == DIR_Left) - { - if(angle > 0) return; - } - else - { - if(angle < 0) return; - } - - iAngle=angle; - + iAngle = angle; + var weight = 0; - if( Abs(iAngle) > 90) weight = 1000*( Abs(iAngle)-60 )/90; + if( Abs(angle) > 90) weight = 1000*( Abs(angle)-60 )/90; var handLR; - if(clonk->GetItemPos(this) == 0) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0) handLR = "R"; - if(clonk->GetItemPos(this) == 1) + else handLR = "L"; clonk->ReplaceAction("Stand", [Format("ShieldStandUp.%s",handLR), Format("ShieldStandDown.%s",handLR), weight]); @@ -130,7 +126,10 @@ private func UpdateShieldAngle(object clonk, int x, int y) if(!GetEffect("IntShieldSuspend", clonk)) { - clonk->SetAnimationPosition(aim_anim, Anim_Const(Abs(iAngle) * 11111/1000)); + if(angle > 0) clonk->SetTurnForced(DIR_Right); + else clonk->SetTurnForced(DIR_Left); + + clonk->SetAnimationPosition(aim_anim, Anim_Const(Abs(angle) * 11111/1000)); AdjustSolidMaskHelper(); } } @@ -282,15 +281,16 @@ public func GetCarrySpecial(clonk) { return carry_bone; } public func GetCarryTransform(clonk, sec, back) { if(aim_anim && !sec) return Trans_Mul(Trans_Rotate(180,0,0,1),Trans_Rotate(90,0,0,1)); - if(aim_anim && sec) return Trans_Rotate(180,1,0,0); + if(aim_anim && sec) return Trans_Mul(Trans_Rotate(180,1,0,0), Trans_Rotate(90,0,0,1)); if(mTrans != nil) return mTrans; if(!sec) { - if(back) return Trans_Mul(Trans_Rotate(-90, 0, 0, 1),Trans_Translate(0,0,-400)); + if(back) return Trans_Mul(Trans_Rotate(-90, 0, 0, 1),Trans_Translate(0,0,400)); return nil; } - if(back) return Trans_Mul(Trans_Mul(Trans_Rotate(90, 0, 0, 1),Trans_Rotate(180, 0, 1)),Trans_Translate(0,0,-400)); + + if(back) return Trans_Mul(Trans_Mul(Trans_Rotate(90, 0, 0, 1),Trans_Rotate(180, 0, 1)),Trans_Translate(0,0,400)); return Trans_Rotate(180,1,0,0); } @@ -300,11 +300,11 @@ public func IsArmoryProduct() { return true; } /* Definition */ func Definition(def) { - def.Name = "$Name$"; - def.Description = "$Description$"; - def.Collectible = 1; - SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1000,-500),Trans_Rotate(20,1,1,-1),Trans_Scale(1200)),def); } + +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/DefCore.txt index 30ee789e7..bf70c386b 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/DefCore.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/DefCore.txt @@ -5,7 +5,7 @@ Category=C4D_Vehicle Width=8 Height=11 Offset=-4,-5 -SolidMask=8, 0, 8, 11 +SolidMask=0, 0, 8, 11 Vertices=1 VertexFriction=100 Rotate=1 diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/Graphics.png index ab7cdf5de..18cf98be7 100644 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/Graphics.png and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/SolidMask.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/SolidMask.png new file mode 100644 index 000000000..2a70c333d Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/ShieldSolidMask.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblDE.txt index d143e12a4..ec548a82b 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Schild -Description=Benutze das Schild, um dich vor heranfliegenden Dingen zu schützen. \ No newline at end of file +Description=Bietet dem Clonk einigen Schutz. +UsageHelp=Halte [Benutzen] gedrückt um dich vor heranfliegenden Dingen aus einer Richtung zu schützen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblUS.txt index d731093dd..86943f442 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Shield -Description=Use the shield to block stuff that is flying at you. \ No newline at end of file +Description=Provides the clonk with some protection. +UsageHelp=Press and hold [Use] to block stuff that is flying towards you from the direction you aim towards. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/shield.jpg b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/shield.jpg new file mode 100644 index 000000000..e1e7ca000 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/shield.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/shield.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/shield.png deleted file mode 100644 index 8d12d49d5..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Shield.ocd/shield.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/DefCore.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/DefCore.txt new file mode 100644 index 000000000..1c34502ee --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Sword_JumpEffect +Version=4,10,0,0 +Category=C4D_StaticBack +Width=10 +Height=10 +Offset=-5,-5 diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/Graphics.4.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/Graphics.4.png new file mode 100644 index 000000000..833fe0bdc Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/Script.c new file mode 100644 index 000000000..815597bd1 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/Script.c @@ -0,0 +1,50 @@ +/** + JumpEffect + Visual. +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + +local last_from; + +func Initialize() +{ + this.Plane = 200; + SetClrModulation(RGBa(255, 255, 255, 100)); +} + +func Point(from, to) +{ + if(from == nil) from = last_from; + else last_from = from; + + var my_size = 10; + var dis = Distance(from.x, from.y, to.x, to.y); + var angle = Angle(from.x, from.y, to.x, to.y); + var midpoint_x = (from.x + to.x)/2; + var midpoint_y = (from.y + to.y)/2; + var s = (dis * 100) / my_size; + var stretch = (1100 * s) / 100; + + SetObjDrawTransform(500, 0, 0, 0, stretch, 0, 0); + SetR(angle); + SetPosition(midpoint_x, midpoint_y); +} + +func FadeOut() +{ + AddEffect("QuickFade", this, 1, 1, this); +} + +func FxQuickFadeTimer(target, effect, time) +{ + var fade = time * 6; + if(fade > 90) + { + RemoveObject(); + return -1; + } + + SetClrModulation(RGBa(255, 255, 255, 100 - fade)); +} \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/StringTblDE.txt new file mode 100644 index 000000000..29550175e --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=JumpEffect +Description=Visual. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/StringTblUS.txt new file mode 100644 index 000000000..29550175e --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/JumpEffect.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=JumpEffect +Description=Visual. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Scene.material b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Scene.material index 59e4b86e8..57a7445b1 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Scene.material +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Scene.material @@ -11,7 +11,7 @@ material Sword2 emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Sword2.png + texture Sword2.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Script.c index bc4ac4761..e9fe2c80a 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Script.c @@ -2,6 +2,8 @@ #include Library_MeleeWeapon +static const Sword_Standard_StrikingLength = 15; // in frames + func Hit() { Sound("LightMetalHit?"); @@ -16,12 +18,9 @@ public func Initialize() public func GetCarryMode() { return CARRY_HandBack; } public func GetCarryBone() { return "main"; } public func GetCarrySpecial(clonk) { return carry_bone; } -public func GetCarryTransform() +public func GetCarryTransform(clonk, sec, back) { - var act = Contained()->GetAction(); - if(act != "Walk" && act != "Jump") - return Trans_Mul(Trans_Translate(0,4500,0), Trans_Rotate(90,0,1,0), Trans_Rotate(180,0,0,1) ); - + if(back) return Trans_Mul(Trans_Rotate(180,0,0,1), Trans_Rotate(90,0,1,0), Trans_Translate(0,-7000,0)); return Trans_Rotate(90, 0, 1, 0); } @@ -40,7 +39,7 @@ public func ControlUse(object clonk, int x, int y) var arm = "R"; carry_bone = "pos_hand2"; - if(clonk->GetItemPos(this) == 1) + if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1) { arm = "L"; carry_bone = "pos_hand1"; @@ -51,14 +50,11 @@ public func ControlUse(object clonk, int x, int y) var downwards_stab = false; // figure out the kind of attack to use - var length=15; + var length = Sword_Standard_StrikingLength; if(clonk->IsWalking()) { - //length=20; - /*if(!GetEffect("SwordStrikeSpeedUp", clonk) && !slow) - AddEffect("SwordStrikeSpeedUp", clonk, 1, 5, this);*/ - if(!GetEffect("SwordStrikeStop", clonk, 0)) - AddEffect("SwordStrikeStop", clonk, 2, 50, this); + if(!GetEffect("SwordStrikeStop", clonk)) + AddEffect("SwordStrikeStop", clonk, 2, length, this); } else if(clonk->IsJumping()) { @@ -68,11 +64,14 @@ public func ControlUse(object clonk, int x, int y) if(!slow && !GetEffect("DelayTranslateVelocity", clonk)) { - //TranslateVelocity(clonk, Angle(0, 0, x,y), 0, 300, 1); + // check whether the player aims below the Clonk var a=Angle(0, 0, x,y); - if(Inside(a, 35+90, 35+180)) + var x_dir = Sin(a, 60); + + if(Inside(a, 35+90, 35+180)) // the player aims downwards + if((BoundBy(x_dir, -1, 1) == BoundBy(clonk->GetXDir(), -1, 1)) || (clonk->GetXDir() == 0)) // the player aims into the direction the Clonk is already jumping { - clonk->SetXDir(Sin(a, 60)); + clonk->SetXDir(x_dir); clonk->SetYDir(-Cos(a, 60)); AddEffect("DelayTranslateVelocity", clonk, 2, 3, nil, Library_MeleeWeapon); @@ -80,7 +79,11 @@ public func ControlUse(object clonk, int x, int y) length = 50; animation = Format("SwordSlash1.%s", arm); downwards_stab = true; + if(GetEffect("Fall", clonk)) RemoveEffect("Fall", clonk); + + // visual effect + AddEffect("VisualJumpStrike", clonk, 1, 2, nil, Sword); } } } @@ -99,35 +102,71 @@ public func ControlUse(object clonk, int x, int y) } clonk->UpdateAttach(); - magic_number=((magic_number+1)%10) + (ObjectNumber()*10); + // this means that the sword can only hit an object every X frames + // change it to something that changes every strike if you want the sword to be able to hit the same enemy with different + // strikes regardless of the time in between + magic_number = ObjectNumber(); StartWeaponHitCheckEffect(clonk, length, 1); - this->Sound("WeaponSwing?", false, nil, nil, nil); + this->Sound("WeaponSwing?"); return true; } +func FxVisualJumpStrikeStart(target, effect, temp) +{ + if(temp) return; + effect.x_add = 20; + if(target->GetXDir() < 0) effect.x_add *= -1; + effect.visual = CreateObject(Sword_JumpEffect, 0, 0, nil); + effect.visual->Point({x = target->GetX() + effect.x_add, y = target->GetY() + 10}, {x = target->GetX() + effect.x_add, y = target->GetY() + 10}); +} + +func FxVisualJumpStrikeTimer(target, effect, time) +{ + if(!target->~IsJumping()) + { + effect.visual->FadeOut(); + effect.visual = nil; + return -1; + } + effect.visual->Point(nil, {x = target->GetX() + effect.x_add, y = target->GetY() + 10}); +} + +func FxVisualJumpStrikeStop(target, effect, reason, temp) +{ + if(temp) return; + if(!effect.visual) return; + effect.visual->FadeOut(); +} + func OnWeaponHitCheckStop(clonk) { carry_bone = nil; clonk->UpdateAttach(); if(GetEffect("SwordStrikeSpeedUp", clonk)) RemoveEffect("SwordStrikeSpeedUp", clonk); - //if(GetEffect("DelayTranslateVelocity", clonk)) - // RemoveEffect("DelayTranslateVelocity", clonk); + if(clonk->IsJumping()) { if(!GetEffect("Fall", clonk)) AddEffect("Fall",clonk,1,1,clonk); } + + if(GetEffect("SwordStrikeStop", clonk)) + RemoveEffect("SwordStrikeStop", clonk); + return; } +// called when the strike expired before end of length (aborted) func WeaponStrikeExpired() { - //if(Contained()) - // this->ScheduleCall(this, "ControlUseStart", 1, 0, Contained(), 0, 0); - if(GetEffect("SwordStrikeStop", Contained())) - RemoveEffect("SwordStrikeStop", Contained()); + +} + +func SwordDamage(int shield) +{ + return ((100-shield)*9*1000 / 100); } func CheckStrike(iTime) @@ -167,7 +206,7 @@ func CheckStrike(iTime) // don't hit objects twice if(!GetEffect(effect_name, obj)) { - AddEffect(effect_name, obj, 1, 60 /* arbitrary */, 0, 0); + AddEffect(effect_name, obj, 1, Sword_Standard_StrikingLength, nil, 0); if(GetEffect(sword_name, obj)) { @@ -177,7 +216,7 @@ func CheckStrike(iTime) else { //Log("first hit overall"); - AddEffect(sword_name, obj, 1, 40, 0, 0); + AddEffect(sword_name, obj, 1, 40, nil, 0); } @@ -187,7 +226,7 @@ func CheckStrike(iTime) continue; // fixed damage (9) - var damage=((100-shield)*9*1000 / 100); + var damage = SwordDamage(shield); ProjectileHit(obj, damage, ProjectileHit_no_query_catch_blow_callback | ProjectileHit_exact_damage | ProjectileHit_no_on_projectile_hit_callback, FX_Call_EngGetPunched); // object has not been deleted? @@ -203,14 +242,19 @@ func CheckStrike(iTime) DoWeaponSlow(obj, 300); // Particle effect - var x=-1; - var p="Slice2"; - if(Contained()->GetDir() == DIR_Right) + var particle = { - x=1; - p="Slice1"; + Size = 20, + BlitMode = GFX_BLIT_Additive, + Attach = ATTACH_Front | ATTACH_MoveRelative, + Phase = PV_Linear(0, 3) + }; + + if(Contained()->GetDir() == DIR_Left) + { + particle.Phase = PV_Linear(4, 7); } -// CreateParticle(p, AbsX(obj->GetX())+RandomX(-1,1), AbsY(obj->GetY())+RandomX(-1,1), 0, 0, 100, RGB(255,255,255), obj); + obj->CreateParticle("SwordSlice", RandomX(-1,1), RandomX(-1,1), 0, 0, 6, particle); } // sound and done. We can only hit one target @@ -224,19 +268,19 @@ func CheckStrike(iTime) func FxSwordStrikeStopStart(pTarget, effect, iTemp) { - pTarget->PushActionSpeed("Walk", (pTarget.ActMap.Walk.Speed)/100); if(iTemp) return; + pTarget->PushActionSpeed("Walk", (pTarget.ActMap.Walk.Speed)/100); } func FxSwordStrikeStopStop(pTarget, effect, iCause, iTemp) { - pTarget->PopActionSpeed("Walk"); if(iTemp) return; + pTarget->PopActionSpeed("Walk"); } func FxSwordStrikeStopTimer(pTarget, effect) { - return 1; + return -1; } func FxSwordStrikeSpeedUpStart(pTarget, effect, iTemp) @@ -258,7 +302,7 @@ func FxSwordStrikeSpeedUpStop(pTarget, effect, iCause, iTemp) if(iTemp) return; if(!pTarget->GetAlive()) return; - AddEffect("SwordStrikeSlow", pTarget, 1, 5, 0, Sword, effect.Time); + AddEffect("SwordStrikeSlow", pTarget, 1, 5, nil, Sword, effect.Time); } func FxSwordStrikeSlowStart(pTarget, effect, iTemp, iTime) @@ -282,10 +326,11 @@ public func IsWeapon() { return true; } public func IsArmoryProduct() { return true; } func Definition(def) { - SetProperty("Collectible", 1, def); - SetProperty("Name", "$Name$", def); - SetProperty("Description", "$Description$", def); SetProperty("PictureTransformation",Trans_Rotate(20, 0, 0, 1),def); } + +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle1.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle1.ocd/Graphics.png deleted file mode 100644 index 38e5c6f91..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle1.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle1.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle1.ocd/Particle.txt deleted file mode 100644 index 6576a77c0..000000000 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle1.ocd/Particle.txt +++ /dev/null @@ -1,15 +0,0 @@ -[Particle] -Name=Slice1 -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,50,50,-25,-25 -Delay=2 -Repeats=1 -VertexCount=1 -VertexY=50 -AlphaFade=1 -Additive=1 -RByV=0 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle2.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle2.ocd/Graphics.png deleted file mode 100644 index 7c28fc020..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle2.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle2.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle2.ocd/Particle.txt deleted file mode 100644 index 988bbf795..000000000 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SliceParticle2.ocd/Particle.txt +++ /dev/null @@ -1,15 +0,0 @@ -[Particle] -Name=Slice2 -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,50,50,-25,-25 -Delay=2 -Repeats=1 -VertexCount=1 -VertexY=50 -AlphaFade=1 -Additive=1 -RByV=0 -Attach=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblDE.txt index 12ac7481e..ed87dc470 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblDE.txt @@ -1,2 +1,3 @@ Name=Schwert -Description=Drücke [Benutzen], um zuzuschlagen. \ No newline at end of file +Description=Nahkampfwaffe. +UsageHelp=Drücke [Benutzen], um zuzuschlagen. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblUS.txt index 46e831a5f..3aa114a26 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/StringTblUS.txt @@ -1,2 +1,3 @@ Name=Sword -Description=Press [Use] to strike. \ No newline at end of file +Description=Close combat weapon. +UsageHelp=Press [Use] to strike. \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Sword2.jpg b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Sword2.jpg new file mode 100644 index 000000000..fac7cf6f0 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Sword2.jpg differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Sword2.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Sword2.png deleted file mode 100644 index 79fbf959f..000000000 Binary files a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/Sword2.png and /dev/null differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SwordSliceParticle.ocd/Graphics.png b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SwordSliceParticle.ocd/Graphics.png new file mode 100644 index 000000000..1d9169333 Binary files /dev/null and b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SwordSliceParticle.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SwordSliceParticle.ocd/Particle.txt b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SwordSliceParticle.ocd/Particle.txt new file mode 100644 index 000000000..b8a96ea87 --- /dev/null +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/Sword.ocd/SwordSliceParticle.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=SwordSlice +Face=0,0,50,50,-25,-25 diff --git a/planet/Objects.ocd/Libraries.ocd/AimManager.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/AimManager.ocd/Script.c index d106f1ea5..7df9b55ca 100644 --- a/planet/Objects.ocd/Libraries.ocd/AimManager.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/AimManager.ocd/Script.c @@ -81,6 +81,8 @@ func SetTurnType () { return _inherited(...); } func SetTurnForced() { return _inherited(...); } func SetBackwardsSpeed() { return _inherited(...); } +func IsAiming() { return !!GetEffect("IntAim", this); } + func FxIntAimCheckProcedureStart(target, effect, tmp) { if(tmp) return; @@ -161,7 +163,10 @@ func PauseAim() { if(!aim_weapon) return CancelAiming(); ResetHands(1); - aim_weapon->~OnPauseAim(this); + + // might be invalid if the weapon does anything weird on Reset() + if(aim_weapon) + aim_weapon->~OnPauseAim(this); } func RestartAim() @@ -204,6 +209,29 @@ public func StartLoad(object weapon) aim_schedule_timer2 = aim_set["LoadTime2"]; aim_schedule_call2 = "DuringLoad"; } + + var e = GetEffect("IntLoadingBar", this); + if(e) + { + RemoveEffect(nil, this, e); + } + + e = AddEffect("IntLoadingBar", this, 1, BoundBy(aim_schedule_timer / 20, 3, 20), this); + e.max = aim_schedule_timer; + e.current = 0; + // handled by HUDAdapter to add a progress bar + this->~SetProgressBarLinkForObject(weapon, e); +} + +func FxIntLoadingBarTimer(target, effect, time) +{ + effect.current = time; + + if(time > effect.max + 40) // the progress bar int he HUD should have updated by then + { + return -1; + } + return 1; } public func DuringLoad() { aim_weapon->~DuringLoad(this); } @@ -255,7 +283,7 @@ public func StartAim(object weapon, int angle) func FxIntAimTimer(target, effect, time) { var angle, delta_angle, length; - var speed = aim_set["AimSpeed"];; + var speed = aim_set["AimSpeed"]; if(speed == nil) speed = 50; else speed *= 10; if(aim_angle < 0) SetTurnForced(DIR_Left); @@ -400,6 +428,9 @@ public func ApplySet(set) public func ResetHands(bool pause) { + if(!GetEffect("IntAimCheckProcedure", this)) + return; + if(aim_weapon != nil) { aim_weapon->~Reset(this); @@ -418,6 +449,7 @@ public func ResetHands(bool pause) SetBackwardsSpeed(nil); RemoveEffect("IntAim", this); + RemoveEffect("IntLoadingBar", this); SetTurnForced(-1); @@ -428,7 +460,12 @@ public func ResetHands(bool pause) { aim_weapon = nil; aim_set = nil; - + + aim_schedule_call = nil; + aim_schedule_timer = nil; + aim_schedule_call2 = nil; + aim_schedule_timer2 = nil; + RemoveEffect("IntAimCheckProcedure", this); } } diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/DefCore.txt new file mode 100644 index 000000000..db7dca5a3 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Library_AlignVehicleRotation +Version=5,2,0,1 +Category=C4D_StaticBack diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/DefCore.txt new file mode 100644 index 000000000..a4c0215bc --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/DefCore.txt @@ -0,0 +1,14 @@ +[DefCore] +id=Vehicle_FloorHelper +Version=5,2,0,1 +Category=C4D_Vehicle +Width=6 +Height=4 +Offset=-3,-2 +Vertices=1 +VertexX=1 +VertexY=1 +VertexFriction=0 +VertexCNAT=6 +SolidMask=0,0,6,4,0,0 +BorderBound=7 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/Graphics.png new file mode 100644 index 000000000..796a75a4e Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/Script.c new file mode 100644 index 000000000..7cc1830ea --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/Script.c @@ -0,0 +1,18 @@ +protected func Initialize() +{ + SetAction("Floor"); +} + +local ActMap = { + Floor = { + Prototype = Action, + Name = "Floor", + Procedure = DFA_FLOAT, + Directions = 1, + X = 0, + Y = 0, + Wdt = 0, + Hgt = 0, + NextAction = "Floor", + }, +}; \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/SolidMask.png b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/SolidMask.png new file mode 100644 index 000000000..796a75a4e Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/FloorHelper.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/Graphics.png new file mode 100644 index 000000000..2a11249d4 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/Script.c new file mode 100644 index 000000000..3ae20584f --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/AlignVehicleRotation.ocd/Script.c @@ -0,0 +1,176 @@ +//Makes objects follow the solid mask of a vehicle if they are touching it (within a specified rectangle) +//Works for both livings and vehicles. + +//To enable in a vehicle, you need two things: +//1. A parent object which will rotate 'children' to match it's rotation on the Z axis (screen-vertical) +// which either AlignObjectsToRotation or AlignToRotation will be called from, and +//2. A 'turnTarget' which will be queried for the Z-angle, in the form of 'turnTarget->GetTurnAngle()'. +// This function should return a value from 0-180, where 0 is turned completely left, and 180 right. + +// The turnTarget can be the same object as the parent object. The reason they are separated is due +// to the separation of the 3D graphic and solidmask object of any solidmask enabled 3D vehicle. +// In this way, the 3D graphic module of a vehicle can query its own animation position. + +///Function must be called from vehicle context +///param x,y,w,h = target rectangle to look for objects in to follow the vehicle's rotation +func AlignObjectsToRotation(object turnTarget, int x, int y, int w, int h) +{ + if(!this) FatalError("Function AlignToRotation must be called from object (vehicle) context"); + if(!turnTarget) FatalError("Function requires a valid turnTarget to get rotation value from"); + + if(x == nil) x = this->GetDefCoreVal("Offset", "DefCore", 0); + if(y == nil) y = this->GetDefCoreVal("Offset", "DefCore", 1); + if(w == nil) w = this->GetDefCoreVal("Width", "DefCore"); + if(h == nil) h = this->GetDefCoreVal("Height", "DefCore"); + + //make objects follow ship rotation + for(var targetObj in FindObjects(Find_Not(Find_ID(this)), Find_NoContainer(), Find_Or(Find_Category(C4D_Living), Find_Category(C4D_Object), Find_Func("IsVehicle")), Find_InRect(x,y,w,h))){ + AlignToRotation(targetObj, turnTarget); + } +} + +//Used to parent a single object to the vehicle's rotation +/// param 'target' is the child object. Function is called from the vehicle context. +/// turnTarget is the object which must have a function returning the angle from +/// 0-180 (left to right), from the function GetTurnAngle() +func AlignToRotation(object target, object turnTarget) +{ + if(target){ + //only objects with lower indexes can ride + if(target.Plane <= this.Plane) return false; + + //Must have a turnTarget to check the rotation + if(turnTarget == nil){ + FatalError("No defined turnTarget object to get rotation from"); + } + + //turnTarget must have a function returning what angle the vehicle is at + else { + if(turnTarget->~GetTurnAngle() == nil){ + FatalError(Format("turnTarget %s has no GetTurnAngleFunction", turnTarget->GetName())); + } + } + +// if(target->GetContact(-1) > 0){ + if(target->GetY() > -1 || target->GetY() < 1){ + var oldNewX = nil; + var oldNewR = nil; + + var oldEffect = GetEffect("AlignRotation", target); + //Get originalX from previous effect if it existed + if(oldEffect){ + oldNewX = oldEffect.originalX * -1; + if(oldEffect.originalR != nil) oldNewR = oldEffect.originalR * -1; + RemoveEffect(nil,target,oldEffect); + } + + //Create the turn effect + var effect = AddEffect("AlignRotation", target, 1, 1, this); + //set effect vars + effect.turnTarget = turnTarget; + + //If the turn was already in progress, reuse the last one + if(oldNewX) effect.originalX = oldNewX; + if(oldNewR) effect.originalR = oldNewR; + } + } +} + +private func FxAlignRotationStart(object target, proplist effect) +{ + /// param 'target' is the object which follows 'this' + /// 'this' refers to the vehicle the effect is created in the object context of. + + DebugLog(Format("Added AlignRotation effect to %s, child of %s", target->GetName(), GetName())); + + effect.originalX = target->GetX(100) - this->GetX(100); + effect.originalY = target->GetY(100) - this->GetY(100); + effect.originalR = nil; + if(target->GetDefCoreVal("Rotate", "DefCore") >= 1){ + effect.originalR = Normalize(target->GetR(),-180); + if(target->GetDefCoreVal("Rotate", "DefCore") == 1){ + effect.noRSmooth = true; + } + } + + //Temporary no collection effect + effect.oldCollect = target.Collectible; + if(effect.oldCollect == 1) target.Collectible = 0; + + effect.floorYOff = (effect.originalY + ((target->GetDefCoreVal("Height", "DefCore") / 2 + 2) * 100)); + + //Create floor helper. Makes certain clonks don't fall while boat is turning + //(due to the solid mask flipping and such); so they keep a solid footing. + if(target->GetCategory() & C4D_Living){ +// if(target->GetY() == 0){ + effect.floorHelper = this->CreateObject(Vehicle_FloorHelper, effect.originalX / 100, (effect.originalY / 100) + (effect.floorYOff / 100) + 1); + + //adjust floor helper size + var width = BoundBy(target->GetDefCoreVal("Width", "DefCore"),6,64); + effect.floorHelper->SetSolidMask(0,0,width,2, (width * -1) / 2 + 1,0); + } + + return 1; +} + +//Basically what this does is move the target object in a sinal path to emulate +//rotating with the boat. +private func FxAlignRotationTimer(object target, proplist effect, int timer) +{ + //Z-Rotation value of the vehicle + var ang = effect.turnTarget->GetTurnAngle() - 90; + + //sinal movement and rotation + var newX = Sin(ang, Abs(effect.originalX)); + var newR = Sin(ang, Abs(effect.originalR)) * -1; + + //Is the target on the left side of the vehicle, and the vehicle is turning left? + //Is the target on the right side of the vehicle, and the vehicle is turning right? + if((effect.originalX < 0 && this->GetDir() == 0) || (effect.originalX > 0 && this->GetDir() == 1)){ + newX = Sin(ang, Abs(effect.originalX)) * -1; + newR = Sin(ang, Abs(effect.originalR)); + } + + //Debug + //target->Message(Format("%d,%d; %d", effect.originalX, newX, effect.floorYOff)); + + if(newX != effect.originalX * -1){ + target->SetPosition(newX + this->GetX(100), target->GetY(100), true, 100); + + //change rotation + if(effect.originalR != nil){ + //debug +// target->Message(Format("R=%d", newR)); + +// target->SetR(newR); + if(target->GetCategory() & C4D_Object) target->SetR(); + } + + //Make sure vehicles aren't affected by gravity when rotating + if((target->GetCategory() & C4D_Living) == 0){ + if(target->GetProcedure() == "FLOAT") target->SetYDir(0); + else target->SetYDir(-2); + } + + //update floor-helper position for clonks/livings + if(effect.floorHelper != nil){ + effect.floorHelper->SetPosition(this->GetX(100) + newX, this->GetY(100) + effect.floorYOff, true, 100); + } + } + else{ + return -1; + } +} + +private func FxAlignRotationStop(object target, proplist effect) +{ + //re-enable collection + target.Collectible = effect.oldCollect; + + var newX = effect.originalX * -1; + //push vehicle up out of solidmask if it got stuck in it + while(target->Stuck()) target->SetPosition(newX + this->GetX(100), target->GetY(100) - 50, true, 100); + + //Get rid of the floor helper object + if(effect.floorHelper) effect.floorHelper->RemoveObject(); +} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c index 013492721..f5930ba78 100644 --- a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Animal.ocd/Script.c @@ -85,5 +85,3 @@ protected func RejectEntrance(object pContainer) // All other cases depend on the global settings (game rule) return 1;// !Library_Animal_IsCollectible(pContainer); TODO create this rule :-) } - -local Name = "$Name$"; diff --git a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Animal.ocd/StringTblDE.txt deleted file mode 100644 index 458876592..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Tiervermehrung diff --git a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Animal.ocd/StringTblUS.txt deleted file mode 100644 index 15822905e..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Animal.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Animal reproduction diff --git a/planet/Objects.ocd/Libraries.ocd/Bars.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Bars.ocd/Script.c index 1713e855b..f84481ed2 100644 --- a/planet/Objects.ocd/Libraries.ocd/Bars.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Bars.ocd/Script.c @@ -70,3 +70,6 @@ public func SetBarProgress(int promille, int num) return true; } + +// UI not saved. +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/DefCore.txt index 8d96e2497..28b75d76e 100644 --- a/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/DefCore.txt +++ b/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/DefCore.txt @@ -3,5 +3,3 @@ id=BaseMaterial Version=5,2,0,1 Category=C4D_StaticBack Picture=0,0,64,64 -TimerCall=ExecHomeBaseProduction -Timer=2100 diff --git a/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/Script.c index 17a5ccea6..fafe6e37c 100644 --- a/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Base.ocd/BaseMaterial.ocd/Script.c @@ -31,6 +31,7 @@ func Initialize() aHomabaseProduction[GetLength(aHomabaseProduction)] = [idID, iCount]; iIndex++; } + AddTimer("ExecHomeBaseProduction", 2100); } static const BaseMaterial_MaxHomeBaseProduction = 25; @@ -175,4 +176,8 @@ public func DoDoHomebaseProduction (id idID, int iChange) return false; } +// Internal management object not saved. +// Use Scenario.txt to adjust homebase material +func SaveScenarioObject() { return false; } + local Name = "$Name$"; diff --git a/planet/Objects.ocd/Libraries.ocd/Base.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Base.ocd/Script.c index c684e1792..2a19711d7 100644 --- a/planet/Objects.ocd/Libraries.ocd/Base.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Base.ocd/Script.c @@ -24,7 +24,7 @@ public func ExecAutoSell() { // Search all objects for objects that want to be sold automatically for(pObj in FindObjects(Find_Container(this), Find_Func("AutoSell"))) - Sell(pObj); + Sell(pObj->GetOwner(), pObj, this); } // Does the base block enemies? @@ -42,7 +42,7 @@ func GetBuyObject(int iIndex) var idDef = GetHomebaseMaterial(GetOwner(), nil, iIndex, C4D_All); aBuy[0] = idDef; aBuy[1] = GetHomebaseMaterial(GetOwner(), idDef, 0); - if(!idDef) return 0; + if(!idDef) return nil; // The default implementation returns the Homebasemaerial of the playeer return aBuy; } diff --git a/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/Script.c index d105da11a..9caa300d2 100644 --- a/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/Script.c @@ -18,6 +18,8 @@ public func GetCarrySpecial(clonk) return "skeleton_body"; } +public func GetDropDescription() { return Format("$TxtPutDown$", GetName()); } + public func Grabbed(object clonk, bool grab) { if(grab) @@ -43,23 +45,30 @@ public func Grabbed(object clonk, bool grab) } -private func DoLift() +private func DoLift(bool forceEnter) { if(!liftheavy_carrier) return; if(!IsCarryingHeavy(liftheavy_carrier)) - AddEffect("IntLiftHeavy", liftheavy_carrier, 1, 1, this); + AddEffect("IntLiftHeavy", liftheavy_carrier, 1, 1, this, nil, forceEnter); } // ------------------ // Lifting the object // ------------------ static const lift_heavy_time = 60; -func FxIntLiftHeavyStart(object clonk, proplist effect, bool tmp) +func FxIntLiftHeavyStart(object clonk, proplist effect, bool tmp, bool forceEnter) { if(tmp) return; if(!clonk) return -1; if(Contained() != clonk) return -1; + + // if the clonk is inside, we can skip the animation + if(clonk->Contained()) + { + AddEffect("IntCarryHeavy", clonk, 1, 1, this); + return -1; + } //Stop the clonk from moving, and tell the clonk's control library //it now has a hand action @@ -74,7 +83,7 @@ func FxIntLiftHeavyStart(object clonk, proplist effect, bool tmp) //Play the animation of the clonk picking up the object effect.anim = clonk->PlayAnimation("CarryArmsPickup", 10, Anim_Linear(0,0,clonk->GetAnimationLength("CarryArmsPickup"), lift_heavy_time, ANIM_Remove), Anim_Const(1000)); - effect.noExit = true; + effect.doExit = !forceEnter; // default: true } func FxIntLiftHeavyTimer(object clonk, proplist effect, int timer) @@ -87,7 +96,6 @@ func FxIntLiftHeavyTimer(object clonk, proplist effect, int timer) { if(clonk->GetAction() != "Stand" || clonk->IsJumping() || Abs(clonk->GetXDir()) > 0) { - Exit(); return -1; } } @@ -98,7 +106,6 @@ func FxIntLiftHeavyTimer(object clonk, proplist effect, int timer) if(clonk->GetAction() != "Stand") { //If the clonk moved when he was disabled from doing so (or jumped), cancel lifting - Exit(); return -1; } } @@ -108,14 +115,24 @@ func FxIntLiftHeavyTimer(object clonk, proplist effect, int timer) if(timer >= lift_heavy_time) { AddEffect("IntCarryHeavy", clonk, 1, 1, this); + // don't exit the object + effect.doExit = false; return -1; } + + // we got moved out during lifting + if(Contained() != clonk) + return -1; } func FxIntLiftHeavyStop(object clonk, proplist effect, int reason, bool tmp) { if(tmp) return; + // drop the object + if(effect.doExit && Contained()==clonk) // only if still in the clonk + Exit(); + clonk->DetachMesh(effect.mesh); clonk->StopAnimation(effect.anim); @@ -163,9 +180,16 @@ func FxIntDropHeavyStart(object clonk, proplist effect, bool tmp) if(clonk->GetEffect("IntCarryHeavy")) clonk->RemoveEffect("IntCarryHeavy"); + // if the clonk is inside, we don't play the animation + if(clonk->Contained()) + return -1; + clonk->SetTurnForced(clonk->GetDir()); clonk->SetHandAction(1); clonk->SetAction("Stand"); + + //Stop the clonk if he is moving + if(clonk->GetXDir() != 0) clonk->SetXDir(); //Attach the mesh of the object. It is not displayed normally because the //hands are told they have an action in the next few lines @@ -187,6 +211,10 @@ func FxIntDropHeavyTimer(object clonk, proplist effect, int timer) // animation finished? if(timer >= lift_heavy_time) return -1; + + // we got moved out during lifting + if(Contained() != clonk) + return -1; } func FxIntDropHeavyStop(object clonk, proplist effect, int reason, bool tmp) @@ -204,7 +232,7 @@ func FxIntDropHeavyStop(object clonk, proplist effect, int reason, bool tmp) if(clonk->GetDir() == DIR_Left) dir = -1; // Set down at barrel position - Exit(7*dir, 12); + Exit(6*dir, 9); } UndoLift(clonk); @@ -244,7 +272,10 @@ protected func Entrance(object obj) if(obj->~GetCarryHeavy() == this) { liftheavy_carrier = obj; - DoLift(); + if(obj->GetAction() == "Walk" && !obj->Contained()) + DoLift(true); + else + AddEffect("IntCarryHeavy",obj, 1, 1, this); } } diff --git a/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblDE.txt index 4c61190d6..58c016579 100644 --- a/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblDE.txt @@ -1 +1,2 @@ -TxtHandsFull=Hände sind voll; Kein Platz im Rucksack! \ No newline at end of file +TxtHandsFull=Hände sind voll! +TxtPutDown=%s abstellen \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblUS.txt index 9f071be15..8d924ce94 100644 --- a/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Libraries.ocd/CarryHeavy.ocd/StringTblUS.txt @@ -1 +1,2 @@ -TxtHandsFull=Hands are full; no room in backpack! \ No newline at end of file +TxtHandsFull=Hands are full! +TxtPutDown=Put %s down \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Backpack.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Backpack.ocd/DefCore.txt deleted file mode 100644 index 40bf71ba5..000000000 --- a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Backpack.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=Icon_Backpack -Version=5,2,0,1 -Category=C4D_StaticBack -Picture=0,0,128,128 -Width=128 -Height=128 -Offset=-64,-64 diff --git a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Backpack.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Backpack.ocd/Graphics.png deleted file mode 100644 index f72987e75..000000000 Binary files a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Backpack.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c index 27c6815eb..989db1a1e 100644 --- a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c @@ -35,27 +35,36 @@ array 'inventory'. They are accessed via GetItem(i) and GetItemPos(obj). Other functions are MaxContentsCount() (defines the maximum number of contents) + + Furthermore the clonk has a defined amount of "hands", defined by HandObjects(). + The array 'use_objects' is a mapping of "hands" onto the inventory-slots. + The functions GetHandItem(i) returns the object in the "i"th hand. + + Carryheavy is also handled here. When a clonk picks up a carryheavy object + it's saved in 'carryheavy' */ /* ++++++++++++++++++++++++ Clonk Inventory Control ++++++++++++++++++++++++ */ -local disableautosort; -local force_collection; -local inventory; // items in the inventory, array -local carryheavy; // object beeing carried with carryheavy -local use_objects; // hand-slots (mapping onto inventory) +local inventory; // items in the inventory, array +local carryheavy; // object beeing carried with carryheavy +local use_objects; // hand-slots (mapping onto inventory) -local handslot_choice_pending; -local hotkeypressed; -local forced_ejection; +local handslot_choice_pending; // used to determine if a slot-hotkey (1-9) has already been handled by a mouseclick +local hotkeypressed; // used to determine if an interaction has already been handled by a hotkey (space + 1-9) + +local disableautosort; // used to get default-Collection-behaviour (see Collection2) +local force_collection; // used to pick stuff up, even though the hand-slots are all full (see RejectCollect + Collect with CON_Collect) +local forced_ejection; // used to recognize if an object was thrown out with or without the force-key (Shift). If not, next hand slot will be selected. /* Item limit */ -private func HandObjects() { return 2; } -public func MaxContentsCount() { return 7; } -public func NoStackedContentMenu() { return true; } +private func HandObjects() { return 2; } // How many "Hands" the clonk has +public func MaxContentsCount() { return 7; } // Size of the clonks inventory +public func NoStackedContentMenu() { return true; } // Contents-Menu shall display each object in a seperate slot -/* Get the ith item in the inventory */ + +/** Get the 'i'th item in the inventory */ public func GetItem(int i) { if (i >= GetLength(inventory)) @@ -65,7 +74,7 @@ public func GetItem(int i) return inventory[i]; } -/* returns all items in the inventory */ +/** Returns all items in the inventory */ public func GetItems() { var inv = inventory[:]; @@ -73,29 +82,55 @@ public func GetItems() return inv; } -/* Get the ith item in hands. - These are the items that will be used with use-commands. (Left mouse click, etc...) */ +/** Returns how many items are in the clonks inventory + Does not have to be the same as ContentCounts() because of objects with special handling, like CarryHeavy */ +public func GetItemCount() +{ + var count = 0; + for(var i=0; i < GetLength(inventory); i++) + if(inventory[i]) + count++; + + return count; +} + +/** Get the 'i'th item in hands. + These are the items that will be used with use-commands. (Left mouse click, etc...) */ public func GetHandItem(int i) { - // carrying a carry heavy item always returns said item - if (carryheavy) - return carryheavy; + // i is valid range if (i >= GetLength(use_objects)) return nil; if (i < 0) return nil; + + // carrying a carry heavy item always returns said item. (he holds it in both hands, after all!) + if (IsCarryingHeavy()) + return GetCarryHeavy(); return GetItem(use_objects[i]); } -/* Set the "hand"th use-item to the "inv"th slot */ +/** Set the 'hand'th use-item to the 'inv'th slot */ public func SetHandItemPos(int hand, int inv) { - if(carryheavy) - return nil; - if(hand >= HandObjects() || inv >= MaxContentsCount()) + // indices are in range? + if(hand >= HandObjects() || inv >= this->MaxContentsCount()) return nil; if(hand < 0 || inv < 0) return nil; + // can't use anything except carryheavy if carrying heavy object. + if(IsCarryingHeavy()) + return nil; + + // changing slots cancels using, if the slot with the used object is contained + if(using) + { + var used_slot = GetItemPos(using); + if(used_slot != nil) + if(used_slot == GetHandItemPos(hand) || used_slot == inv) + CancelUseControl(0,0); + } + // If the item is already selected, we can't hold it in another one too. var hand2 = GetHandPosByItemPos(inv); if(hand2 != nil) @@ -105,10 +140,13 @@ public func SetHandItemPos(int hand, int inv) use_objects[hand] = inv; // additional callbacks - if(GetHandItem(hand2)) + var hand_item; + if(hand_item = GetHandItem(hand2)) { this->~OnSlotFull(hand2); - GetItem(inv)->~Selection(this, hand2); + // OnSlotFull might have done something to the item + if(GetHandItem(hand2) == hand_item) + hand_item->~Selection(this, hand2); } else this->~OnSlotEmpty(hand2); @@ -117,10 +155,13 @@ public func SetHandItemPos(int hand, int inv) use_objects[hand] = inv; // call callbacks - if(GetItem(inv)) + var item; + if(item = GetItem(inv)) { this->~OnSlotFull(hand); - GetItem(inv)->~Selection(this, hand); + // OnSlotFull might have done something to the item + if(GetItem(inv) == item) + GetItem(inv)->~Selection(this, hand); } else { @@ -130,7 +171,7 @@ public func SetHandItemPos(int hand, int inv) handslot_choice_pending = false; } -/* Returns the position in the inventory of the ith use item */ +/** Returns the position in the inventory of the 'i'th use item */ public func GetHandItemPos(int i) { if (i >= GetLength(use_objects)) @@ -140,7 +181,7 @@ public func GetHandItemPos(int i) return use_objects[i]; } -/* Returns in which hand-slot the oth inventory-slot is */ +/** Returns in which hand-slot the inventory-slot is */ private func GetHandPosByItemPos(int o) // sorry for the horribly long name --boni { for(var i=0; i < GetLength(use_objects); i++) @@ -150,6 +191,7 @@ private func GetHandPosByItemPos(int o) // sorry for the horribly long name --bo return nil; } +/** Drops the item in the inventory slot, if any */ public func DropInventoryItem(int slot) { var obj = GetItem(slot); @@ -158,12 +200,8 @@ public func DropInventoryItem(int slot) this->SetCommand("Drop",obj); } - -// For the HUD: this object shows its items in the HUD (i.e. has the GetItem function) -public func HUDShowItems() { return true; } - -/* Search the index of an item */ +/** Search for the index of an item */ public func GetItemPos(object item) { if (item) @@ -179,13 +217,13 @@ public func GetItemPos(object item) return nil; } -/* Switch two items in the clonk's inventory */ +/** Switch two items in the clonk's inventory */ public func Switch2Items(int one, int two) { // no valid inventory index: cancel - if (!Inside(one,0,MaxContentsCount()-1)) return; - if (!Inside(two,0,MaxContentsCount()-1)) return; + if (!Inside(one,0,this->MaxContentsCount()-1)) return; + if (!Inside(two,0,this->MaxContentsCount()-1)) return; // switch them around var temp = inventory[one]; @@ -230,20 +268,21 @@ public func Switch2Items(int one, int two) this->~OnInventoryChange(one, two); } -/* Overload of Collect function */ - +/* Overload of Collect function + Allows inventory/hands-Handling with forced-collection +*/ public func Collect(object item, bool ignoreOCF, int pos, bool force) { force_collection = force; var success = false; - if (pos == nil) + if (pos == nil || item->~IsCarryHeavy()) { success = _inherited(item,ignoreOCF); force_collection = false; return success; } // fail if the specified slot is full - if (GetItem(pos) == nil && pos >= 0 && pos < MaxContentsCount()) + if (GetItem(pos) == nil && pos >= 0 && pos < this->MaxContentsCount()) { if (item) { @@ -300,7 +339,7 @@ protected func Collection2(object obj) // carryheavy object gets special treatment if(obj->~IsCarryHeavy()) // we can assume that we don't have a carryheavy object yet. If we do, Scripters are to blame. { - if(obj != carryheavy) + if(obj != GetCarryHeavy()) CarryHeavy(obj); return true; @@ -327,7 +366,7 @@ protected func Collection2(object obj) // otherwise, first empty slot if(!success) { - for(var i = 0; i < MaxContentsCount(); ++i) + for(var i = 0; i < this->MaxContentsCount(); ++i) { if (!GetItem(i)) { @@ -347,7 +386,9 @@ protected func Collection2(object obj) if(handpos != nil) { this->~OnSlotFull(handpos); - obj->~Selection(this, handpos); + // OnSlotFull might have done something to obj + if(GetHandItem(handpos) == obj) + obj->~Selection(this, handpos); } } @@ -358,7 +399,7 @@ protected func Collection2(object obj) protected func Ejection(object obj) { // carry heavy special treatment - if(obj == carryheavy) + if(obj == GetCarryHeavy()) { StopCarryHeavy(); return true; @@ -399,7 +440,7 @@ protected func Ejection(object obj) { // look for following non-selected non-free slots var found_slot = false; - for(var j=i; j < MaxContentsCount(); j++) + for(var j=i; j < this->MaxContentsCount(); j++) if(GetItem(j) && !GetHandPosByItemPos(j)) { found_slot = true; @@ -431,6 +472,8 @@ protected func Ejection(object obj) for(var c = 0; c < ContentsCount(); ++c) { var o = Contents(c); + if(o->~IsCarryHeavy()) + continue; if (GetItemPos(o) == nil) { // found it! Collect it properly @@ -441,7 +484,9 @@ protected func Ejection(object obj) if(handpos != nil) { this->~OnSlotFull(handpos); - o->~Selection(this, handpos); + // OnSlotFull might have done something to o + if(GetHandItem(handpos) == o) + o->~Selection(this, handpos); } break; @@ -458,7 +503,7 @@ protected func ContentsDestruction(object obj) this->~OnInventoryChange(); // check if it was carryheavy - if(obj == carryheavy) + if(obj == GetCarryHeavy()) { StopCarryHeavy(); } @@ -471,7 +516,7 @@ protected func RejectCollect(id objid, object obj) // collection of that object magically disabled? if(GetEffect("NoCollection", obj)) return true; - // Carry heavy only gets picked up if non held already + // Carry heavy only gets picked up if none held already if(obj->~IsCarryHeavy()) { if(IsCarryingHeavy()) @@ -502,7 +547,7 @@ protected func RejectCollect(id objid, object obj) // check max contents - if (ContentsCount() >= MaxContentsCount()) return true; + if (ContentsCount() >= this->MaxContentsCount()) return true; // check if the two first slots are full. If the overloaded // Collect() is called, this check will be skipped @@ -517,7 +562,11 @@ protected func RejectCollect(id objid, object obj) public func AllowTransfer(object obj) { // Only check max contents. - if (ContentsCount() >= MaxContentsCount()) + if (GetItemCount() >= this->MaxContentsCount()) + return false; + + // don't allow picking up multiple carryheavy-objects + if(IsCarryingHeavy() && obj->~IsCarryHeavy()) return false; return true; @@ -529,14 +578,18 @@ public func GetUsedObject() { return using; } /* Carry heavy stuff */ -// picks up the object +/** Tells the clonk that he is carrying the given carry heavy object */ public func CarryHeavy(object target) { if(!target) return; + // actually.. is it a carry heavy object? + if(!target->~IsCarryHeavy()) + return; + // only if not carrying a heavy objcet already if(IsCarryingHeavy()) return; - + carryheavy = target; if(target->Contained() != this) @@ -546,19 +599,33 @@ public func CarryHeavy(object target) this->~OnCarryHeavyChange(carryheavy); // Update attach stuff - //this->~UpdateAttach(); + this->~OnSlotFull(); return true; } +/** Drops the carried heavy object, if any */ +public func DropCarryHeavy() +{ + // only if actually possible + if(!IsCarryingHeavy()) + return; + + GetCarryHeavy()->Drop(); + StopCarryHeavy(); + + return true; +} + +// Internal function to clear carryheavy-status private func StopCarryHeavy() { - if(!carryheavy) + if(!IsCarryingHeavy()) return; carryheavy = nil; this->~OnCarryHeavyChange(nil); - this->~UpdateAttach(); + this->~OnSlotEmpty(); } public func GetCarryHeavy() { return carryheavy; } @@ -627,6 +694,37 @@ protected func OnActionChanged(string oldaction) return _inherited(oldaction,...); } +/** Returns additional interactions the clonk possesses as an array of function pointers. + Returned Proplist contains: + Fn = Name of the function to call + Object = object to call the function in. Will also be displayed on the interaction-button + Description = a description of what the interaction does + IconID = ID of the definition that contains the icon (like GetInteractionMetaInfo) + IconName = Namo of the graphic for teh icon (like GetInteractionMetaInfo) + [Priority] = Where to sort in in the interaction-list. 0=front, 1=after script, 2=after vehicles, >=3=at the end, nil equals 3 +*/ +public func GetExtraInteractions() +{ + var functions = CreateArray(); + + // flipping construction-preview + var effect; + if(effect = GetEffect("ControlConstructionPreview", this)) + { + if(effect.flipable) + PushBack(functions, {Fn = "Flip", Description=ConstructionPreviewer->GetFlipDescription(), Object=effect.preview, IconID=ConstructionPreviewer_IconFlip, Priority=0}); + } + + // dropping carry heavy + if(IsCarryingHeavy() && GetAction() == "Walk") + { + var ch = GetCarryHeavy(); + PushBack(functions, {Fn = "Drop", Description=ch->GetDropDescription(), Object=ch, IconName="LetGo", IconID=GUI_ObjectSelector, Priority=1}); + } + + return functions; +} + /* +++++++++++++++++++++++++++ Clonk Control +++++++++++++++++++++++++++ */ local using, using_type; @@ -644,7 +742,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re //Log(Format("%d, %d, %s, strength: %d, repeat: %v, release: %v", x,y,GetPlayerControlName(ctrl), strength, repeat, release),this); // some controls should only do something on release (everything that has to do with interaction) - if(ctrl == CON_Interact || ctrl == CON_PushEnter || ctrl == CON_Ungrab || ctrl == CON_Grab || ctrl == CON_Enter || ctrl == CON_Exit) + if(ctrl == CON_Interact || ctrl == CON_PushEnter || ctrl == CON_Ungrab || ctrl == CON_GrabNext || ctrl == CON_Grab || ctrl == CON_Enter || ctrl == CON_Exit) { if(!release) { @@ -655,6 +753,16 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re // if the interaction-command has already been handled by a hotkey (else it'd double-interact) else if(hotkeypressed) return false; + // check if we can handle it by simply accessing the first actionbar item (for consistency) + else + { + if(GetMenu()) + if(!GetMenu()->~Uncloseable()) + return CancelMenu(); + + if(this->~ControlHotkey(0)) + return true; + } } // Contents menu @@ -667,8 +775,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re if (GetMenu()->~Uncloseable()) return true; var is_content = GetMenu()->~IsContentMenu(); - GetMenu()->RemoveObject(); - SetMenu(nil); + CancelMenu(); // If contents menu, don't open new one and return. if (is_content) return true; @@ -678,7 +785,8 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re CreateContentsMenus(); // CreateContentsMenus calls SetMenu(this) in the clonk // so after this call menu = the created menu - GetMenu()->Show(); + if(GetMenu()) + GetMenu()->Show(); return true; } @@ -794,7 +902,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re if (ctrl == CON_Hotkey8SelectAlt) {hot = 8; hand=1; } if (ctrl == CON_Hotkey9SelectAlt) {hot = 9; hand=1; } - if(hot > 0 && hot <= MaxContentsCount()) + if(hot > 0 && hot <= this->MaxContentsCount()) { SetHandItemPos(hand, hot-1); this->~OnInventoryHotkeyRelease(hot-1); @@ -816,7 +924,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re // only the last-pressed key is taken into consideration. // if 2 hotkeys are held, the earlier one is beeing treated as released - if (hot > 0 && hot <= MaxContentsCount()) + if (hot > 0 && hot <= this->MaxContentsCount()) { // if released, we chose, if not chosen already if(release) @@ -855,9 +963,9 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re { if(ObjectControlInteract(plr,ctrl)) return true; - else if(IsCarryingHeavy()) + else if(IsCarryingHeavy() && GetAction() == "Walk") { - GetCarryHeavy()->Drop(); + DropCarryHeavy(); return true; } @@ -945,8 +1053,11 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re // Collecting if (ctrl == CON_Collect) { + // only if not inside something + if(Contained()) return false; // not handled + var dx = -GetDefWidth()/2, dy = -GetDefHeight()/2; - var wdt = GetDefWidth(), hgt = GetDefHeight(); + var wdt = GetDefWidth(), hgt = GetDefHeight()+2; var obj = FindObject(Find_InRect(dx,dy,wdt,hgt), Find_OCF(OCF_Collectible), Find_NoContainer()); if(obj) { @@ -954,6 +1065,9 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re // collected into the hands Collect(obj,nil,nil,true); } + + // return not handled to still receive other controls - collection should not block anything else + return false; } // Throwing and dropping @@ -975,7 +1089,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re { CancelUse(); - if (proc == "SCALE" || proc == "HANGLE") + if (proc == "SCALE" || proc == "HANGLE" || proc == "SWIM") return ObjectCommand("Drop", contents); else return ObjectCommand("Throw", contents, x, y); @@ -1703,7 +1817,14 @@ func GetMenu() func CancelMenu() { - if (menu) menu->Close(); + if (menu) + { + menu->Close(); + SetMenu(nil); + return true; + } + + return false; } func ReinitializeControls() @@ -1744,8 +1865,8 @@ private func DoThrow(object obj, int angle) { // parameters... var iX, iY, iR, iXDir, iYDir, iRDir; - iX = 8; if (!GetDir()) iX = -iX; - iY = Cos(angle,-8); + iX = 4; if (!GetDir()) iX = -iX; + iY = Cos(angle,-4); iR = Random(360); iRDir = RandomX(-10,10); diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionMenu.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionMenu.ocd/Script.c index 421a72548..745790d78 100644 --- a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionMenu.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionMenu.ocd/Script.c @@ -14,7 +14,7 @@ local constructinfo_shown; @param producer the producer for which to create the production menu. @return a pointer to the created menu, or \c nil if failed. */ -global func CreateConstructionMenu(object constructor) +global func CreateConstructionMenu(object constructor, bool create_at_mouse_pos) { // Safety checks. if (!this) return; @@ -27,6 +27,13 @@ global func CreateConstructionMenu(object constructor) this->SetMenu(controller); controller->SetCommander(constructor); + if(create_at_mouse_pos) + { + var xy = GetPlayerCursorPos(constructor->GetOwner()); + if(xy) + controller->SetPosition(xy[0],xy[1],true); + } + // Add all possible structures to the menu. controller->AddMenuStructures(constructor, this); @@ -103,13 +110,6 @@ public func HideConstructionInfo() public func IsConstructionMenu() { return true; } -public func Close() -{ - if(menu_object) - menu_object->~MenuClosed(this); - RemoveObject(); -} - public func HasCommander(object producer) { if (menu_commander == producer) @@ -177,3 +177,6 @@ public func OnMouseOutItem(object out_item, object dragged_item) return _inherited(out_item, dragged_item, ...); } + +// UI not saved. +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconCombine.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconCombine.ocd/DefCore.txt new file mode 100644 index 000000000..ac55c10e7 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconCombine.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=ConstructionPreviewer_IconCombine +Version=4,10,0,0 +Category=C4D_StaticBack | C4D_IgnoreFoW +Width=23 +Height=15 +Offset=-11,-7 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconCombine.ocd/Graphics.3.png b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconCombine.ocd/Graphics.3.png new file mode 100644 index 000000000..496e72b66 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconCombine.ocd/Graphics.3.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/DefCore.txt new file mode 100644 index 000000000..9e08f3253 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=ConstructionPreviewer_IconFlip +Version=4,10,0,0 +Category=C4D_StaticBack | C4D_IgnoreFoW +Width=24 +Height=13 +Offset=-12,-6 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/Graphics.8.png b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/Graphics.8.png new file mode 100644 index 000000000..7070ce7c2 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/Script.c new file mode 100644 index 000000000..386f128f4 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/Script.c @@ -0,0 +1,24 @@ +/** + ConstructionPreviewer_IconFlip + + + @author Clonkonaut +*/ + +local previewer; + +func Construction(object mom) +{ + SetProperty("Visibility", VIS_Owner); + previewer = mom; + SetPosition(previewer->GetX(), previewer->GetY() - (previewer.dimension_y / 2) - 8); + this->Message("@$Space$"); + AddTimer("KeepPosition", 1); +} + +func KeepPosition() +{ + if (!previewer) return RemoveObject(); + + SetPosition(previewer->GetX(), previewer->GetY() - (previewer.dimension_y / 2) - 8); +} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/StringTblDE.txt new file mode 100644 index 000000000..4500afbe4 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Space=[Leertaste] \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/StringTblUS.txt new file mode 100644 index 000000000..a4bfd88dc --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/IconFlip.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Space=[Space] \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/Script.c index d802cb0b7..4175932e0 100644 --- a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/Script.c @@ -5,7 +5,11 @@ @author Clonkonaut */ -local dimension_x, dimension_y, clonk, structure; +local dimension_x, dimension_y, clonk, structure, direction, stick_to; +local GFX_StructureOverlay = 1; +local GFX_CombineIconOverlay = 2; + +public func GetFlipDescription() { return "$TxtFlipDesc$"; } func Initialize() { @@ -14,40 +18,68 @@ func Initialize() func Set(id to_construct, object constructing_clonk) { - SetGraphics(nil, to_construct, GFX_Overlay, GFXOV_MODE_Base); + SetGraphics(nil, to_construct, GFX_StructureOverlay, GFXOV_MODE_Base); + SetGraphics(nil, to_construct, 3, GFXOV_MODE_Picture, nil, GFX_BLIT_Wireframe); dimension_x = to_construct->GetDefWidth(); dimension_y = to_construct->GetDefHeight(); + clonk = constructing_clonk; structure = to_construct; - AdjustPreview(); + direction = DIR_Left; + this->AdjustPreview(); } -// Positions the preview according to the landscape, coloring it green or red +// Positions the preview according to the landscape, coloring it green, yellow or red func AdjustPreview(bool look_up, bool no_call) { - // Place on material - var search_dir = 1; - if (look_up) search_dir = -1; - var x = 0, y = 0, fail = false; var half_y = dimension_y / 2; - while(!(!GBackSolid(x,y + half_y) && GBackSolid(x,y + half_y + 1))) + // Do only if not sticking to another object + if (!stick_to) { - y += search_dir; - if (Abs(y) > dimension_y/2) + // Place on material + var search_dir = 1; + if (look_up) search_dir = -1; + var x = 0, y = 0, fail = false; + while(!(!GBackSolid(x,y + half_y) && GBackSolid(x,y + half_y + 1))) { - fail = true; - break; + y += search_dir; + if (Abs(y) > dimension_y/2) + { + fail = true; + break; + } } + if (fail && !no_call) + return this->AdjustPreview(!look_up, true); + if (fail) + return SetClrModulation(RGBa(255,50,50, 100), GFX_StructureOverlay); + SetPosition(GetX(), GetY() + y); } - if (fail && !no_call) - return AdjustPreview(!look_up, true); - if (fail) - return SetClrModulation(RGBa(255,50,50, 100), GFX_Overlay); - SetPosition(GetX(), GetY() + y); - if (CheckConstructionSite(structure, 0, half_y)) - SetClrModulation(RGBa(50,255,50, 100), GFX_Overlay); + if (!CheckConstructionSite(structure, 0, half_y)) + fail = true; else - SetClrModulation(RGBa(255,50,50, 100), GFX_Overlay); + // intersection-check with all other construction sites... bah + for(var other_site in FindObjects(Find_ID(ConstructionSite))) + { + if(!(other_site->GetLeftEdge() > GetX()+dimension_x/2 || + other_site->GetRightEdge() < GetX()-dimension_x/2 || + other_site->GetTopEdge() > GetY()+half_y || + other_site->GetBottomEdge() < GetY()-half_y)) + { + fail = true; + } + } + + + if(!fail) + { + if (!stick_to) + SetClrModulation(RGBa(50,255,50, 100), GFX_StructureOverlay); + else + SetClrModulation(RGBa(255,255,50, 200), GFX_StructureOverlay); + } + else + SetClrModulation(RGBa(255,50,50, 100), GFX_StructureOverlay); } // Positions the preview according to the mouse cursor, calls AdjustPreview afterwards @@ -56,6 +88,62 @@ func Reposition(int x, int y) { x = BoundBy(x, -dimension_x/2, dimension_x/2); y = BoundBy(y, -dimension_y/2, dimension_y/2); - SetPosition(clonk->GetX() + x, clonk->GetY() + y); - AdjustPreview(); -} \ No newline at end of file + var found = false; + if (structure->~ConstructionCombineWith()) + { + var other = FindObject(Find_Func(structure->ConstructionCombineWith(), this), + Find_InRect(AbsX(clonk->GetX() + x - dimension_x/2 - 10), AbsY(clonk->GetY() + y - dimension_y/2 - 10), dimension_x + 20, dimension_y + 20), + Find_OCF(OCF_Fullcon), + Find_Layer(clonk->GetObjectLayer()), + Find_Allied(clonk->GetOwner()), + Find_NoContainer()); + if (other) + { + if (other->GetX() < GetX()) + x = other->GetX() + other->GetObjWidth()/2 + dimension_x / 2; + else + x = other->GetX() - other->GetObjWidth()/2 - dimension_x / 2; + y = other->GetY(); + stick_to = other; + found = true; + } + } + if (!found) + { + x = clonk->GetX() + x; + y = clonk->GetY() + y; + } + + if (!found && stick_to) + { + stick_to = nil; + SetGraphics(nil, nil, GFX_CombineIconOverlay); + } else if (stick_to) { + SetGraphics(nil, ConstructionPreviewer_IconCombine, GFX_CombineIconOverlay, GFXOV_MODE_Base); + var dir = 1; + if (stick_to->GetX() < GetX()) dir = -1; + SetObjDrawTransform(1000, 0, dimension_x/2 * 1000 * dir, 0, 1000, 0, GFX_CombineIconOverlay); + } + + SetPosition(x, y); + this->AdjustPreview(); +} + +// Flips the preview horizontally +func Flip() +{ + // Flip not allowed? + if (structure->~NoConstructionFlip()) return; + + if (direction == DIR_Left) + { + direction = DIR_Right; + SetObjDrawTransform(-1000,0,0, 0,1000,0, GFX_StructureOverlay); + } else { + direction = DIR_Left; + SetObjDrawTransform(1000,0,0, 0,1000,0, GFX_StructureOverlay); + } +} + +// UI not saved. +func SaveScenarioObject() { return false; } \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/StringTblDE.txt new file mode 100644 index 000000000..fb616880a --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/StringTblDE.txt @@ -0,0 +1 @@ +TxtFlipDesc=Baustelle umdrehen \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/StringTblUS.txt new file mode 100644 index 000000000..34fcec7fc --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionPreviewer.ocd/StringTblUS.txt @@ -0,0 +1 @@ +TxtFlipDesc=Flip construction site \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/ConsSignTex.png b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/ConsSignTex.png new file mode 100644 index 000000000..ac63db6dd Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/ConsSignTex.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/ConsSiteSign.skeleton b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/ConsSiteSign.skeleton new file mode 100644 index 000000000..8603b10d0 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/ConsSiteSign.skeleton differ diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/DefCore.txt new file mode 100644 index 000000000..9b9295b90 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=ConstructionSite +Version=5,3,3 +Category=C4D_StaticBack +Width=16 +Height=16 +Offset=-8,-14 +ClosedContainer=2 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Graphics.mesh b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Graphics.mesh new file mode 100644 index 000000000..4f4d62504 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Overlay.png b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Overlay.png new file mode 100644 index 000000000..ad1fa232e Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Overlay.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Script.c new file mode 100644 index 000000000..0c2bb41d4 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/Script.c @@ -0,0 +1,238 @@ +/** + ConstructionSite + Needs material put into it, then constructs the set building. + + @author boni +*/ + +local definition; +local direction; +local stick_to; +local full_material; // true when all needed material is in the site + +public func IsContainer() { return !full_material; } +// disallow taking stuff out +public func RefuseTransfer(object toMove) { return true; } + +// we have 2 interaction modes +public func IsInteractable(object obj) { return definition != nil && !full_material; } +public func GetInteractionCount() { return 2; } +public func GetInteractionMetaInfo(object obj, int num) +{ + if(num == 0) + return {IconName=nil, IconID=Hammer, Description="$TxtTransfer$"}; + if(num == 1) + return {IconName=nil, IconID=Icon_Cancel, Description="$TxtAbort$"}; +} + +public func Construction() +{ + this.visibility = VIS_None; + definition = nil; + full_material = false; + + return true; +} + +public func Set(id def, int dir, object stick) +{ + definition = def; + direction = dir; + stick_to = stick; + + var xw = (1-dir*2)*1000; + + var w,h; + w = def->GetDefWidth(); + h = def->GetDefHeight(); + + SetGraphics(nil, def, 1, GFXOV_MODE_Base); + SetClrModulation(RGBa(255,255,255,50), 1); + SetObjDrawTransform(xw,0,0,0,1000, -h*500,1); + SetGraphics(nil, def, 2, GFXOV_MODE_Base, nil, GFX_BLIT_Wireframe); + SetObjDrawTransform(xw,0,0,0,1000, -h*500,2); + SetShape(-w/2, -h, w, h); + + SetName(Translate(Format("TxtConstruction",def->GetName()))); + + this.visibility = VIS_Owner | VIS_Allies; + + ShowMissingComponents(); +} + +// Scenario saving +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + props->Remove("Name"); + if (definition) props->AddCall("Definition", this, "Set", definition, direction, stick_to); + return true; +} + +// only allow collection if needed +public func RejectCollect(id def, object obj) +{ + var max = GetComponent(def, nil, nil, definition); + + // not a component? + if(max == 0) + return true; + if(ContentsCount(def) < max) + return false; + + return true; +} + +// check if full +public func Collection2(object obj) +{ + // update message + ShowMissingComponents(); + + // check if we're done? + if(full_material) + StartConstructing(); +} + +// Interacting removes the Construction site +public func Interact(object clonk, int num) +{ + // Open Contents-Menu + if(num == 0) + { + clonk->CreateContentsMenus(); + } + // Remove Site + if(num == 1) + { + // test + for(var obj in FindObjects(Find_Container(this))) + obj->Exit(); + + RemoveObject(); + } +} + +private func ShowMissingComponents() +{ + if(definition == nil) + { + Message(""); + return; + } + + var stuff = GetMissingComponents(); + //var msg = "Construction Needs:"; + var msg = "@"; + for(var s in stuff) + if(s.count > 0) + msg = Format("%s %dx{{%i}}", msg, s.count, s.id); + + //Message("@%s",msg); + CustomMessage(msg, this, NO_OWNER, 0, 23); +} + +private func GetMissingComponents() +{ + if(definition == nil) + return; + + if(full_material == true) + return nil; + + // set false again as soon as we find a missing component + full_material = true; + + // check for material + var comp, index = 0; + var missing_material = CreateArray(); + while (comp = GetComponent(nil, index, nil, definition)) + { + // find material + var max_amount = GetComponent(comp, nil, nil, definition); + var c = ContentsCount(comp); + var dif = max_amount-c; + + if(dif > 0) + { + PushBack(missing_material, {id=comp, count=dif}); + full_material = false; + } + + index++; + } + + return missing_material; +} + +private func StartConstructing() +{ + if(!definition) + return; + if(!full_material) + return; + + // find all objects on the bottom of the area that are not stuck + var wdt = GetObjWidth(); + var hgt = GetObjHeight(); + var lying_around = FindObjects(Find_Or(Find_Category(C4D_Vehicle), Find_Category(C4D_Object), Find_Category(C4D_Living)),Find_InRect(-wdt/2 - 2, -hgt, wdt + 2, hgt + 12), Find_OCF(OCF_InFree)); + + // create the construction + var site; + if(!(site = CreateConstruction(definition, 0, 0, GetOwner(), 1, 1, 1))) + { + Interact(nil, 1); + return; + } + + if(direction) + site->SetDir(direction); + // Inform about sticky building + if (stick_to) + site->CombineWith(stick_to); + + // Autoconstruct 2.0! + Schedule(site, "DoCon(2)",1,50); + Schedule(this,"RemoveObject()",1); + + // clean up stuck objects + for(var o in lying_around) + { + var x, y; + var dif = 0; + + x = o->GetX(); + y = o->GetY(); + + // move living creatures upwards till they stand on top. + if(o->GetOCF() & OCF_Alive) + { + while(o->GetContact(-1, CNAT_Bottom)) + { + // only up to 20 pixel + if(dif > 20) + { + o->SetPosition(x,y); + break; + } + + dif++; + o->SetPosition(x, y-dif); + } + } + else { + while(o->Stuck()) + { + // only up to 20 pixel + if(dif > 20) + { + o->SetPosition(x,y); + break; + } + + dif++; + o->SetPosition(x, y-dif); + } + } + } +} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/StringTblDE.txt new file mode 100644 index 000000000..aacf4b59c --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +TxtTransfer=Baumaterial transferieren +TxtAbort=Konstruktion abbrechen +TxtConstruction=Baustelle: %s \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/StringTblUS.txt new file mode 100644 index 000000000..151c547ee --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +TxtTransfer=Transfer Material +TxtAbort=Abort Construction +TxtConstruction=Construction Site: %s \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/scene.material b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/scene.material new file mode 100644 index 000000000..d950aa480 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/ConstructionSite.ocd/scene.material @@ -0,0 +1,42 @@ +material ConsSiteSign +{ + receive_shadows on + + technique + { + pass + { + cull_hardware none + //scene_blend alpha_blend + diffuse 1 1 1 1.0 + + texture_unit Overlay + { + texture Overlay.png + tex_address_mode wrap + filtering trilinear + //colour_op_ex modulate src_texture src_player_colour + // take alpha from texture only, ignore player alpha + alpha_op_ex source1 src_texture src_player_colour + } + + texture_unit Sign + { + texture ConsSignTex.png + tex_address_mode wrap + filtering trilinear + colour_op_ex blend_current_alpha src_current src_texture + // Don't blend alpha, to make sure we have full intensity at the base/overlay border region + alpha_op_ex add src_current src_texture + } + texture_unit Light + { + // apply lighting + colour_op_ex modulate src_current src_diffuse + alpha_op_ex modulate src_current src_diffuse + } + } + } +} + + diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/Script.c index 308b4f60b..c26b3ee2e 100644 --- a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/Script.c @@ -18,14 +18,10 @@ public func ControlUseStart(object clonk, int x, int y) return true; } // Is the clonk at an construction site? + // TODO: check for multiple objects var structure = FindObject(Find_Category(C4D_Structure), Find_Or(Find_Distance(20), Find_AtPoint()), Find_Layer(GetObjectLayer())); if (structure) { - if (structure->GetCon() < 100) - { - Construct(clonk, structure); - return true; - } if (structure->GetDamage() > 0) { Repair(clonk, structure); @@ -34,7 +30,7 @@ public func ControlUseStart(object clonk, int x, int y) } // Otherwise create a menu with possible structures to build. - clonk->CreateConstructionMenu(this); + clonk->CreateConstructionMenu(this, true); clonk->CancelUse(); return true; } @@ -53,11 +49,6 @@ public func ControlUseHolding(object clonk, int x, int y) var structure = FindObject(Find_Category(C4D_Structure), Find_Or(Find_Distance(20), Find_AtPoint()), Find_Layer(GetObjectLayer())); if (structure) { - if (structure->GetCon() < 100) - { - Construct(clonk, structure); - return true; - } if (structure->GetDamage() > 0) { Repair(clonk, structure); @@ -68,50 +59,9 @@ public func ControlUseHolding(object clonk, int x, int y) return true; } -private func Construct(object clonk, object structure) -{ - // Look for missing components. - var structure_id = structure->GetID(); - var con = structure->GetCon(); - var comp, index = 0; - var can_construct = true; - while (comp = structure->GetComponent(nil, index)) - { - var max_amount = GetComponent(comp, nil, nil, structure_id); - // Try to transfer components from constructing clonk to the structure. - for (var i = 0; i < max_amount - structure->GetComponent(comp); i++) - { - var content = FindObject(Find_Container(clonk), Find_ID(comp)); - if (content) - { - clonk->Message("Used {{%i}}", comp); - content->RemoveObject(); - structure->SetComponent(comp, structure->GetComponent(comp) + 1); - } - } - // Check if there now is enough material for current con, if so the construction can continue. - if (100 * structure->GetComponent(comp) / max_amount < con) - can_construct = false; - index++; - } - // Continue construction if possible. - if (can_construct) - { - structure->DoCon(1); - clonk->Message("Constructing %d%", structure->GetCon()); - } - // Otherwise show missing construction materials. - else - { - ShowConstructionMaterial(clonk, structure); - clonk->CancelUse(); - } - return; -} - private func ShowConstructionMaterial(object clonk, object structure) { - var mat_msg = "Construction needs "; + var mat_msg = "$TxtNeeds$"; var structure_id = structure->GetID(); var comp, index = 0; while (comp = structure->GetComponent(nil, index)) @@ -137,7 +87,7 @@ public func GetConstructionPlans(int plr) { var construction_plans = []; var construct_id, index = 0; - while (construct_id = GetPlrKnowledge(plr, 0, index++, C4D_Structure)) + while (construct_id = GetPlrKnowledge(plr, nil, index++, C4D_Structure)) construction_plans[index-1] = construct_id; return construction_plans; } @@ -156,7 +106,9 @@ func FxControlConstructionPreviewStart(object clonk, effect, int temp, id struct if (temp) return; effect.structure = structure_id; - effect.preview = CreateObject(ConstructionPreviewer, AbsX(clonk->GetX()), AbsY(clonk->GetY()), clonk->GetOwner()); + effect.flipable = !structure_id->~NoConstructionFlip(); + effect.preview = structure_id->~CreateConstructionPreview(clonk); + if (!effect.preview) effect.preview = CreateObject(ConstructionPreviewer, AbsX(clonk->GetX()), AbsY(clonk->GetY()), clonk->GetOwner()); effect.preview->Set(structure_id, clonk); } @@ -167,11 +119,20 @@ func FxControlConstructionPreviewControl(object clonk, effect, int ctrl, int x, { // CON_Use is accept if (ctrl == CON_Use) - CreateConstructionSite(clonk, effect.structure, AbsX(effect.preview->GetX()), AbsY(effect.preview->GetY() + effect.preview.dimension_y/2)); + CreateConstructionSite(clonk, effect.structure, AbsX(effect.preview->GetX()), AbsY(effect.preview->GetY() + effect.preview.dimension_y/2), effect.preview.direction, effect.preview.stick_to); // movement is allowed - else if(ctrl == CON_Left || ctrl == CON_Right || ctrl == CON_Up || ctrl == CON_Down || ctrl == CON_Jump) + else if (IsMovementControl(ctrl)) return false; - + // Flipping + // this is actually realized twice. Once as an Extra-Interaction in the clonk, and here. We don't want the Clonk to get any non-movement controls though, so we handle it here too. + // (yes, this means that actionbar-hotkeys wont work for it. However clicking the button will.) + else if (IsInteractionControl(ctrl)) + { + if (release) + effect.preview->Flip(); + return true; + } + // everything else declines RemoveEffect("ControlConstructionPreview", clonk, effect); return true; @@ -181,33 +142,95 @@ func FxControlConstructionPreviewControl(object clonk, effect, int ctrl, int x, return true; } -func FxControlConstructionPreviewStop(object target, effect, int reason, bool temp) +func FxControlConstructionPreviewStop(object clonk, effect, int reason, bool temp) { if (temp) return; effect.preview->RemoveObject(); + SetPlayerControlEnabled(clonk->GetOwner(), CON_Aim, false); } /* Construction */ -func CreateConstructionSite(object clonk, id structure_id, int x, int y) +func CreateConstructionSite(object clonk, id structure_id, int x, int y, int dir, object stick_to) { // Only when the clonk is standing and outdoors if (clonk->GetAction() != "Walk") return false; - if (clonk->Contained()) + if (clonk->Contained()) return false; // Check if the building can be build here if (structure_id->~RejectConstruction(x, y, clonk)) return false; + if (!CheckConstructionSite(structure_id, x, y)) + { + CustomMessage("$TxtNoSiteHere$", this, clonk->GetOwner(), nil,nil, RGB(255,0,0)); // todo: stringtable + return false; + } + // intersection-check with all other construction sites... bah + for(var other_site in FindObjects(Find_ID(ConstructionSite))) + { + if(!(other_site->GetLeftEdge() > GetX()+x+structure_id->GetDefWidth()/2 || + other_site->GetRightEdge() < GetX()+x-structure_id->GetDefWidth()/2 || + other_site->GetTopEdge() > GetY()+y+structure_id->GetDefHeight()/2 || + other_site->GetBottomEdge() < GetY()+y-structure_id->GetDefHeight()/2 )) + { + CustomMessage(Format("$TxtBlocked$",other_site->GetName()), this, clonk->GetOwner(), nil,nil, RGB(255,0,0)); // todo: stringtable + return false; + } + } + // Set owner for CreateConstruction SetOwner(clonk->GetOwner()); // Create construction site var site; - if (!(site = CreateConstruction(structure_id, x, y, Contained()->GetOwner(), 1, 1, 1))) - return false; - // Message - clonk->Message("$TxtConstructions$", site->GetName()); - return true; -} + site = CreateObject(ConstructionSite, x, y, Contained()->GetOwner()); + + // Randomize sign rotation + site -> SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(RandomX(-30, 30), 0, 1, 0), Trans_Rotate(RandomX(-10, 10), 1, 0, 0))); + site -> PlayAnimation("LeftToRight", 1, Anim_Const(RandomX(0, GetAnimationLength("LeftToRight"))), Anim_Const(500)); + + site -> Set(structure_id, dir, stick_to); + //if(!(site = CreateConstruction(structure_id, x, y, Contained()->GetOwner(), 1, 1, 1))) + //return false; + + // check for material + var comp, index = 0; + var mat; + var w = structure_id->GetDefWidth()+10; + var h = structure_id->GetDefHeight()+10; + while (comp = GetComponent(nil, index, nil, structure_id)) + { + // find material + var count_needed = GetComponent(comp, nil, nil, structure_id); + index++; + + mat = CreateArray(); + // 1. look for stuff in the clonk + mat[0] = FindObjects(Find_ID(comp), Find_Container(clonk)); + // 2. look for stuff lying around + mat[1] = clonk->FindObjects(Find_ID(comp), Find_NoContainer(), Find_InRect(-w/2, -h/2, w,h)); + // 3. look for stuff in nearby lorries/containers + var i = 2; + for(var cont in clonk->FindObjects(Find_Or(Find_Func("IsLorry"), Find_Func("IsContainer")), Find_InRect(-w/2, -h/2, w,h))) + mat[i] = FindObjects(Find_ID(comp), Find_Container(cont)); + // move it + for(var mat2 in mat) + { + for(var o in mat2) + { + if(count_needed <= 0) + break; + o->Exit(); + o->Enter(site); + count_needed--; + } + } + } + + + // Message + clonk->Message("$TxtConstructions$", structure_id->GetName()); + return true; +} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblDE.txt index ce668f091..fd1742566 100644 --- a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblDE.txt @@ -1,5 +1,6 @@ -TxtNoconstructionplansa=Keine Baupläne verfügbar TxtConstructions=Konstruktion: %s -TxtCantConstruct=%s kann nicht bauen. +TxtBlocked=%s blockiert die Baustelle +TxtNoSiteHere=Kann hier keine Baustelle errichten! +TxtNeeds=Baustelle braucht noch Name=Hammer Description=Drücke [Benutzen], um ein Gebäude zu errichten. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblUS.txt index 07e19df85..4d3038430 100644 --- a/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Libraries.ocd/Constructor.ocd/StringTblUS.txt @@ -1,5 +1,6 @@ -TxtNoconstructionplansa=No construction plans available TxtConstructions=Construction: %s -TxtCantConstruct=%s can't build. +TxtBlocked=Construction blocked by %s +TxtNoSiteHere=Can't create the construction site here! +TxtNeeds=Construction needs Name=Hammer Description=Press [Use] to construct a building. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/Script.c index a1983fe6d..07cb2611d 100644 --- a/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/Script.c @@ -61,4 +61,3 @@ func Collection2(obj) return _inherited (obj); } -local Name = "$Name$"; diff --git a/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblDE.txt index a3b977f2c..5eddb1d56 100644 --- a/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblDE.txt @@ -1,2 +1 @@ -Name=Eingangssteuerung TxtNoEntryEnemy=%s verfeindet.|Eingang versperrt! \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblUS.txt index 791348349..18cd1c648 100644 --- a/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Libraries.ocd/DoorControl.ocd/StringTblUS.txt @@ -1,2 +1 @@ -Name=Door control TxtNoEntryEnemy=%s hostile.|No entrance! \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/Script.c index c2451c8aa..37b9206a2 100644 --- a/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/Script.c @@ -56,8 +56,9 @@ public func FxElevatorControlStart(object vehicle, proplist effect, int temp, ob public func FxElevatorControlTimer(object vehicle, proplist effect) { - if (ObjectDistance(effect.case, vehicle) > 12) - return -1; + if(!effect.case) return -1; + if(effect.case->OutOfRange(vehicle)) return -1; + if (effect.controlled && !FindObject(Find_Action("Push"), Find_ActionTarget(vehicle))) { effect.case->ControlStop(vehicle, effect.controlled); diff --git a/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/StringTblDE.txt deleted file mode 100644 index d001b4e60..000000000 --- a/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Fahrstuhlsteuerung \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/StringTblUS.txt deleted file mode 100644 index 60d40dd8d..000000000 --- a/planet/Objects.ocd/Libraries.ocd/ElevatorControl.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Elevator control \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/DefCore.txt new file mode 100644 index 000000000..01e5ad5c5 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/DefCore.txt @@ -0,0 +1,11 @@ +[DefCore] +id=Library_Flag_ConstructionPreviewer_Arrow +Version=5,2,0,1 +Category=C4D_StaticBack +Width=16 +Height=36 +Offset=-8,-18 +Vertices=1 +VertexX=0 +VertexY=15 +Rotate=1 diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/Graphics.8.png b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/Graphics.8.png new file mode 100644 index 000000000..c32c24775 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/Script.c new file mode 100644 index 000000000..b4f02976a --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/Script.c @@ -0,0 +1,28 @@ +/*-- Flag construction preview helper arrow --*/ + +protected func Initialize() +{ + this["Visibility"] = VIS_Owner; + return; +} + +// UI not saved. +func SaveScenarioObject() { return false; } + +/*-- Proplist --*/ + +local ActMap = { + Show = { + Prototype = Action, + Name = "Show", + Procedure = DFA_ATTACH, + Length = 1, + Delay = 0, + X = 0, + Y = 0, + Wdt = 40, + Hgt = 20, + NextAction = "Show", + }, +}; +local Name = "$Name$"; diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/StringTblDE.txt new file mode 100644 index 000000000..c34449a60 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Benachbarte Flagge im Radius \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/StringTblUS.txt new file mode 100644 index 000000000..411cb8ae6 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Arrow.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Neighboured flag in radius \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/DefCore.txt new file mode 100644 index 000000000..2bd6324b9 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Library_Flag_ConstructionPreviewer +Version=4,10,0,0 +Category=C4D_StaticBack | C4D_IgnoreFoW +Width=1 +Height=1 +Offset=-1,-1 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Graphics.png new file mode 100644 index 000000000..0ae92115f Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Script.c new file mode 100644 index 000000000..ff941eb5b --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/ConstructionPreviewer.ocd/Script.c @@ -0,0 +1,58 @@ +/** + LibraryFlag_ConstructionPreviewer + Construction preview object for objects implementing flagpole + Shows helper arrows around the preview to tell the player which neighbouring flags will be connected + + @author Sven2 +*/ + +#include ConstructionPreviewer + +local neighbour_flag_arrows; + +func Initialize() +{ + var r = _inherited(...); + neighbour_flag_arrows = []; + return r; +} + +// Preview update: Called on initial creation and when position is updated +func AdjustPreview(bool look_up, bool no_call) +{ + // Regular preview behaviour (check site, color object, etc.) + inherited(look_up, no_call, ...); + if (no_call) return true; + // Update arrows pointing to neighboured flags + var neighboured_flags = Library_Flag->FindFlagsInRadius(this, structure->GetFlagRadius(), clonk->GetOwner()); + var i; + for (var flag in neighboured_flags) + { + var arrow = neighbour_flag_arrows[i]; + if (!arrow) + { + neighbour_flag_arrows[i] = arrow = CreateObject(Library_Flag_ConstructionPreviewer_Arrow, 0,0, GetOwner()); + if (!arrow) { ++i; continue; } + arrow->SetAction("Show", this); + } + arrow->SetR(Angle(GetX(), GetY(), flag->GetX(), flag->GetY())); + ++i; + } + // Kill any leftover arrows + for (var j=i; jRemoveObject(); + } + SetLength(neighbour_flag_arrows, i); + return true; +} + +func Destruction() +{ + // Preview gone. Remove arrows. + for (var arrow in neighbour_flag_arrows) if (arrow) arrow->RemoveObject(); + return _inherited(...); +} + +// UI not saved. +func SaveScenarioObject() { return false; } diff --git a/planet/System.ocg/Flag.c b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Helpers.ocd/System.ocg/FlagHelpers.c similarity index 54% rename from planet/System.ocg/Flag.c rename to planet/Objects.ocd/Libraries.ocd/Flag.ocd/Helpers.ocd/System.ocg/FlagHelpers.c index 50bafaeba..ebf6011ba 100644 --- a/planet/System.ocg/Flag.c +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Helpers.ocd/System.ocg/FlagHelpers.c @@ -4,7 +4,10 @@ Authors: Zapper --*/ -global func GetFlagpoleForPosition(int x, int y) +// returns the flagpole that is currently holding ownership of a specific point in the landscape +global func GetFlagpoleForPosition( + int x /* x position in local coordinates */ + , int y /* y position in local coordinates */) { if(GetType(LibraryFlag_flag_list) != C4V_Array) return nil; @@ -12,6 +15,7 @@ global func GetFlagpoleForPosition(int x, int y) for(var flag in LibraryFlag_flag_list) { + if (!flag) continue; // safety in case this gets called during destruction of a flag var d = Distance(GetX() + x, GetY() + y, flag->GetX(), flag->GetY()); if(d > flag->GetFlagRadius()) continue; @@ -24,15 +28,19 @@ global func GetFlagpoleForPosition(int x, int y) return oldest; } -global func GetOwnerOfPosition(int x, int y) +// returns the current owner that controls a certain point with a flagpole or NO_OWNER +global func GetOwnerOfPosition( + int x /* x position in local coordinates */ + , int y /* y position in local coordinates */) { var flag = GetFlagpoleForPosition(x, y); if(!flag) return NO_OWNER; return flag->GetOwner(); } +// redraws all flag radiuses global func RedrawAllFlagRadiuses() { for(var f in LibraryFlag_flag_list) - f->RedrawFlagRadius(); -} \ No newline at end of file + if (f) f->RedrawFlagRadius(); +} diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/DefCore.txt index 5b9765862..4ad6bac76 100644 --- a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/DefCore.txt +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/DefCore.txt @@ -6,7 +6,6 @@ Width=8 Height=8 Offset=-4,-4 Rotate=1 -ColorByOwner=1 [Physical] Float=1000 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/Script.c index 2aae34bad..ae1724dc5 100644 --- a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Marker.ocd/Script.c @@ -16,17 +16,24 @@ Fly = { } }; +func IsEnvironment() { return true; } // shouldn't be affected by wind, etc. + public func Initialize() { this.Plane=1545; fade = 0; - color = GetPlayerColor(GetOwner()); - SetClrModulation(color|RGBa(0,0,0,fade)); SetAction("Fly"); SetComDir(COMD_None); + ResetColor(); return true; } +func ResetColor() +{ + color = GetPlayerColor(GetOwner()); + SetClrModulation(color|RGBa(0,0,0,fade)); +} + func MoveTo(int x, int y, int r) { if(GetEffect("MoveTo", this)) RemoveEffect("MoveTo", this); @@ -103,12 +110,17 @@ func FxFadeInTimer(target, effect, time) { if(fade == 255) return -1; fade = BoundBy(fade+3, 0, 255); - SetClrModulation(color|RGBa(0,0,0,fade)); + //SetClrModulation(color|RGBa(0,0,0,fade)); + SetObjAlpha(fade); } func FxFadeOutTimer(target, effect, time) { if(fade == 0) return -1; fade = BoundBy(fade-3, 0, 255); - SetClrModulation(color|RGBa(0,0,0,fade)); -} \ No newline at end of file + //SetClrModulation(color|RGBa(0,0,0,fade)); + SetObjAlpha(fade); +} + +// UI not saved. +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Script.c index 79d2c9550..83662fc87 100644 --- a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/Script.c @@ -2,26 +2,24 @@ The flagpoles mark the area a player owns. It also serves as an energy transmitter. */ -local Name = "$Name$"; -local Description = "$Description$"; -static const LibraryFlag_standard_radius = 200; static LibraryFlag_flag_list; +local DefaultFlagRadius = 200; // Radius of new flag of this type, unless overwritten by SetFlagRadius(). local lflag; public func IsFlagpole(){return true;} func RefreshAllFlagLinks() { - for(var f in LibraryFlag_flag_list) + for(var f in LibraryFlag_flag_list) if (f) { f->ScheduleRefreshLinkedFlags(); } // update power balance for power helpers after refreshing the linked flags Schedule(nil, "Library_Flag->RefreshAllPowerHelpers()", 2, 0); - AddEffect("ScheduleRefreshAllPowerHelpers", 0, 1, 2, nil, Library_Flag); + AddEffect("ScheduleRefreshAllPowerHelpers", nil, 1, 2, nil, Library_Flag); } func FxScheduleRefreshAllPowerHelpersTimer() @@ -40,7 +38,7 @@ func RefreshAllPowerHelpers() var neutral = nil; for(var obj in Library_Power_power_compounds) { - if(!obj.neutral) continue; + if(!obj || !obj.neutral) continue; neutral = obj; break; } @@ -54,6 +52,7 @@ func RefreshAllPowerHelpers() for(var i = GetLength(Library_Power_power_compounds); --i >= 0;) { var obj = Library_Power_power_compounds[i]; + if (!obj) continue; if(GetLength(obj.power_links) == 0 && GetLength(obj.sleeping_links) == 0) { obj->RemoveObject(); @@ -73,7 +72,7 @@ func RedrawFlagRadius() //var flags = FindObjects(Find_ID(FlagPole),Find_Exclude(target), Find_Not(Find_Owner(GetOwner())), /*Find_Distance(FLAG_DISTANCE*2 + 10,0,0)*/Sort_Func("GetLifeTime")); var other_flags = []; var i = 0; - for(var f in LibraryFlag_flag_list) + for(var f in LibraryFlag_flag_list) if (f) { //if(f->GetOwner() == GetOwner()) continue; if(f == this) continue; @@ -91,7 +90,7 @@ func RedrawFlagRadius() var y=-Cos(i, lflag.radius); //var inEnemy = false; - for(var f in other_flags) + for(var f in other_flags) if (f) { if(Distance(GetX()+x,GetY()+y,f->GetX(),f->GetY()) <= f->GetFlagRadius()) { @@ -129,6 +128,18 @@ func RedrawFlagRadius() lflag.range_markers[marker_index] = marker; } + // there were unnecessary markers? + if(marker_index < GetLength(lflag.range_markers) - 1) + { + var old = marker_index; + while(++marker_index < GetLength(lflag.range_markers)) + { + var marker = lflag.range_markers[marker_index]; + marker->RemoveObject(); + lflag.range_markers[marker_index] = nil; + } + SetLength(lflag.range_markers, old + 1); + } } func RefreshOwnershipOfSurrounding() @@ -139,11 +150,13 @@ func RefreshOwnershipOfSurrounding() if(obj->GetOwner() == o) continue; var old = obj->GetOwner(); obj->SetOwner(o); - obj->~OnOwnerChange(old); } } public func Initialize() { + // no falling down anymore + SetCategory(C4D_StaticBack); + if(GetIndexOf(LibraryFlag_flag_list, this) == -1) LibraryFlag_flag_list[GetLength(LibraryFlag_flag_list)] = this; @@ -155,6 +168,8 @@ public func Initialize() // linked flags - optimization for power system RefreshAllFlagLinks(); + + return _inherited(...); } public func Construction() @@ -165,7 +180,7 @@ public func Construction() lflag = { construction_time = FrameCounter(), - radius = LibraryFlag_standard_radius, + radius = GetID()->GetFlagRadius(), range_markers = [], linked_flags = [], power_helper = nil @@ -217,6 +232,20 @@ func FxRefreshLinkedFlagsTimer() return -1; } +// Returns all flags allied to owner of which the radius intersects the given circle +func FindFlagsInRadius(object center_object, int radius, int owner) +{ + var flag_list = []; + if (LibraryFlag_flag_list) for(var flag in LibraryFlag_flag_list) + { + if(!IsAllied(flag->GetOwner(), owner)) continue; + if(flag == center_object) continue; + if(ObjectDistance(center_object, flag) > radius + flag->GetFlagRadius()) continue; + flag_list[GetLength(flag_list)] = flag; + } + return flag_list; +} + func RefreshLinkedFlags() { // failsafe - the array should exist @@ -238,6 +267,7 @@ func RefreshLinkedFlags() { if(!IsAllied(flag->GetOwner(), owner)) continue; if(GetIndexOf(current, flag) != -1) continue; + if(GetIndexOf(new, flag) != -1) continue; if(flag == this) continue; if(ObjectDistance(oldflag, flag) > oldflag->GetFlagRadius() + flag->GetFlagRadius()) continue; @@ -288,6 +318,7 @@ func RefreshPowerHelper(h) if(o == nil) continue; // possible var actual = Library_Power->GetPowerHelperForObject(o.obj); + if (!actual) continue; if(actual == h) continue; // right one already // remove from old and add to new h->RemovePowerLink(o.obj, true); @@ -324,7 +355,7 @@ public func GetLinkedFlags(){return lflag.linked_flags;} private func ClearFlagMarkers() { for(var obj in lflag.range_markers) - obj->RemoveObject(); + if (obj) obj->RemoveObject(); lflag.range_markers = []; } @@ -341,6 +372,30 @@ public func SetFlagRadius(int to) return true; } -public func GetFlagRadius(){return lflag.radius;} +// reassign owner of flag markers for correct color +func OnOwnerChanged(int new_owner, int old_owner) +{ + for(var marker in lflag.range_markers) + { + if(!marker) continue; + marker->SetOwner(new_owner); + marker->ResetColor(); + } +} + +// callback from construction library: Create a special preview that gives extra info about affected buildings / flags +func CreateConstructionPreview(object constructing_clonk) +{ + return CreateObject(Library_Flag_ConstructionPreviewer, constructing_clonk->GetX()-GetX(), constructing_clonk->GetY()-GetY(), constructing_clonk->GetOwner()); +} + +public func GetFlagRadius(){if (lflag) return lflag.radius; else return DefaultFlagRadius;} public func GetFlagConstructionTime() {return lflag.construction_time;} public func GetFlagMarkerID(){return LibraryFlag_Marker;} + +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (lflag && lflag.radius != DefaultFlagRadius) props->AddCall("Radius", this, "SetFlagRadius", lflag.radius); + return true; +} diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/StringTblDE.txt deleted file mode 100644 index e57d3cc4e..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Flag.ocd -Description=Cares for the ownership of areas. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Flag.ocd/StringTblUS.txt deleted file mode 100644 index e57d3cc4e..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Flag.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Flag.ocd -Description=Cares for the ownership of areas. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Goal.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Goal.ocd/Script.c index 690dd991b..31ee10815 100644 --- a/planet/Objects.ocd/Libraries.ocd/Goal.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Goal.ocd/Script.c @@ -25,7 +25,7 @@ func Initialize() return _inherited(...); } -func UpdateTransferZone() +func OnSynchronized() { // Create timer if it doesn't exist yet RecheckGoalTimer(); @@ -35,7 +35,7 @@ func UpdateTransferZone() func RecheckGoalTimer() { // Create timer if it doesn't exist yet - if (!GetEffect("IntGoalCheck", 0)) + if (!GetEffect("IntGoalCheck", nil)) { var timer_interval = 35; if (GetLeague()) @@ -130,3 +130,11 @@ protected func Activate(plr) return(MessageWindow("$MsgGoalFulfilled$", plr)); return MessageWindow(GetProperty("Description"), plr); } + +// Scenario sacing +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (mission_password) props->AddCall("MissionAccess", this, "SetMissionAccess", Format("%v", mission_password)); + return true; +} diff --git a/planet/Objects.ocd/Libraries.ocd/GoldSeller.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/GoldSeller.ocd/Script.c index 51b057078..2cf7e91f7 100644 --- a/planet/Objects.ocd/Libraries.ocd/GoldSeller.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/GoldSeller.ocd/Script.c @@ -7,12 +7,12 @@ func AutoSellValuablesRadius(){return 50;} static const LIBRARY_GOLDSELLER_MinTimer = 10; -static const LIBRARY_GOLDSELLER_MaxTimer = 60; +static const LIBRARY_GOLDSELLER_MaxTimer = 30; static const LIBRARY_GOLDSELLER_TimerStep = 10; func Initialize() { - AddEffect("AutoSellValuables", this, 1, 20, this); + AddEffect("AutoSellValuables", this, 1, LIBRARY_GOLDSELLER_MaxTimer, this); return _inherited(...); } @@ -28,7 +28,7 @@ func FxAutoSellValuablesTimer(_, effect, time) if(!GetPlayerName(owner)) { - effect.TimerIntervall = LIBRARY_GOLDSELLER_MaxTimer; + effect.Interval = LIBRARY_GOLDSELLER_MaxTimer; return 1; } @@ -43,7 +43,7 @@ func FxAutoSellValuablesTimer(_, effect, time) if(!GetLength(objs)) { - effect.TimerIntervall = LIBRARY_GOLDSELLER_MaxTimer; + effect.Interval = LIBRARY_GOLDSELLER_MaxTimer; return 1; } @@ -60,10 +60,20 @@ func FxAutoSellValuablesTimer(_, effect, time) // assert: at least one object in to_remove var value = 0; var fm = CreateObject(FloatingMessage, comp->GetX() - GetX(), comp->GetY() - GetY(), NO_OWNER); - fm->SetColor(50, 100, 50); + fm->SetColor(250, 200, 50); fm->FadeOut(2, 10); fm->SetSpeed(0, -5); + var dust_particles = + { + Prototype = Particles_Dust(), + Size = PV_KeyFrames(0, 0, 0, 100, 10, 1000, 0), + Alpha = PV_KeyFrames(0, 0, 255, 750, 255, 1000, 0), + R = 200, + G = 125, + B = 125, + }; + for(var valuable in to_remove) { if(valuable->~QueryOnSell(valuable->GetController())) continue; @@ -72,14 +82,14 @@ func FxAutoSellValuablesTimer(_, effect, time) value += valuable->GetValue(); - CreateParticle("Flash", valuable->GetX() - GetX(), valuable->GetY() - GetY(), 0, 0, 10 * Max(5, Max(valuable->GetDefWidth(), valuable->GetDefHeight())), RGB(255,255,50)); - CastParticles("Dust2", 4, 10, valuable->GetX() - GetX(), valuable->GetY() - GetY(), 50, 70, RGB(100, 100, 100), RGB(200,125,125)); + CreateParticle("Flash", valuable->GetX() - GetX(), valuable->GetY() - GetY(), 0, 0, 8, { Prototype = Particles_Flash(), Size = 2 * Max(5, Max(valuable->GetDefWidth(), valuable->GetDefHeight())) }); + CreateParticle("Dust", valuable->GetX() - GetX(), valuable->GetY() - GetY(), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(18, 36), dust_particles, 10); valuable->RemoveObject(); } - fm->SetMessage(Format("%d$", value)); + fm->SetMessage(Format("%d{{Icon_Coins}}", value)); Sound("Cash"); - effect.TimerIntervall = BoundBy(effect.TimerIntervall - Random(LIBRARY_GOLDSELLER_TimerStep), LIBRARY_GOLDSELLER_MaxTimer, LIBRARY_GOLDSELLER_MaxTimer); + effect.Interval = BoundBy(effect.Interval - Random(LIBRARY_GOLDSELLER_TimerStep), LIBRARY_GOLDSELLER_MinTimer, LIBRARY_GOLDSELLER_MaxTimer); return 1; } diff --git a/planet/Objects.ocd/Libraries.ocd/HUDAdapter.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/HUDAdapter.ocd/Script.c index 467df8fb3..10ce8eb9b 100644 --- a/planet/Objects.ocd/Libraries.ocd/HUDAdapter.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/HUDAdapter.ocd/Script.c @@ -40,12 +40,33 @@ protected func Recruitment(int plr) if (!HUDcontroller) HUDcontroller = CreateObject(GUI_Controller, 10, 10, plr); - HUDcontroller->ScheduleUpdateBackpack(); - HUDcontroller->UpdateHealthTube(); + HUDcontroller->OnCrewRecruitment(this, plr, ...); + HUDcontroller->ScheduleUpdateInventory(); return _inherited(plr, ...); } +protected func DeRecruitment(int plr) +{ + if (HUDcontroller) HUDcontroller->OnCrewDeRecruitment(this, plr, ...); + + return _inherited(plr, ...); +} + +protected func Death(int killed_by) +{ + if (HUDcontroller) HUDcontroller->OnCrewDeath(this, killed_by, ...); + + return _inherited(killed_by,...); +} + +protected func Destruction() +{ + if (HUDcontroller) HUDcontroller->OnCrewDestruction(this, ...); + + return _inherited(...); +} + public func OnDisplayInfoMessage() { if (HUDcontroller) @@ -62,24 +83,18 @@ protected func OnPromotion() protected func OnEnergyChange() { - if (HUDcontroller) - HUDcontroller->UpdateHealthTube(); if (HUDselector) HUDselector->UpdateHealthBar(); return _inherited(...); } protected func OnBreathChange() { - if (HUDcontroller) - HUDcontroller->UpdateBreathTube(); if (HUDselector) HUDselector->UpdateBreathBar(); return _inherited(...); } protected func OnMagicEnergyChange() { - if (HUDselector) - HUDselector->UpdateMagicBar(); return _inherited(...); } @@ -150,6 +165,14 @@ protected func OnSlotEmpty(int slot) return _inherited(slot, ...); } +// used to add a progress bar to an inventory slot +// "effect" refers to an effect with the properties "max" and "current" that is used to keep the progress bar state up-to-date +func SetProgressBarLinkForObject(object what, proplist effect) +{ + if(HUDcontroller) + HUDcontroller->SetProgressBarLinkForObject(what, effect); + return _inherited(what, effect, ...); +} protected func OnHandSelectionChange(int old, int new, int handslot) { @@ -176,15 +199,16 @@ protected func OnInventoryHotkeyRelease(int slot) protected func OnInventoryChange() { if (HUDcontroller) - HUDcontroller->ScheduleUpdateBackpack(); + HUDcontroller->ScheduleUpdateInventory(); return _inherited(...); } // when a carryheavy object is picked up/dropped -func OnCarryHeavyChange(object carried) +protected func OnCarryHeavyChange(object carried) { if(HUDcontroller) - HUDcontroller->OnCarryHeavyChange(carried); + if(GetCursor(GetOwner()) == this) + HUDcontroller->OnCarryHeavyChange(carried); return _inherited(carried, ...); } @@ -192,20 +216,20 @@ func OnCarryHeavyChange(object carried) func Collection2() { if (HUDcontroller) - HUDcontroller->ScheduleUpdateBackpack(); + HUDcontroller->ScheduleUpdateInventory(); return _inherited(...); } func Ejection() { if (HUDcontroller) - HUDcontroller->ScheduleUpdateBackpack(); + HUDcontroller->ScheduleUpdateInventory(); return _inherited(...); } func ControlContents() { if (HUDcontroller) - HUDcontroller->ScheduleUpdateBackpack(); + HUDcontroller->ScheduleUpdateInventory(); return _inherited(...); } diff --git a/planet/Objects.ocd/Libraries.ocd/LadderClimb.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/LadderClimb.ocd/Script.c index cb54fd789..2aad3eac3 100644 --- a/planet/Objects.ocd/Libraries.ocd/LadderClimb.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/LadderClimb.ocd/Script.c @@ -165,7 +165,7 @@ func LadderStep(target, effect, fUp) func FxIntClimbControlTimer(target, effect, time) { if (GetAction() != "Climb" || Contained()) return -1; - if(effect.ladder && effect.ladder->CanNotBeClimbed(1)) effect.ladder = nil; + if(effect.ladder && effect.ladder->~CanNotBeClimbed(1)) effect.ladder = nil; if(!effect.ladder) { no_ladder_counter = 5; diff --git a/planet/Objects.ocd/Libraries.ocd/Map.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Map.ocd/DefCore.txt new file mode 100644 index 000000000..41c30e340 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Map.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Library_Map +Version=5,2,0,1 +Category=C4D_StaticBack diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Map.ocd/Graphics.png similarity index 100% rename from planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/Graphics.png rename to planet/Objects.ocd/Libraries.ocd/Map.ocd/Graphics.png diff --git a/planet/Objects.ocd/Libraries.ocd/Map.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Map.ocd/Script.c new file mode 100644 index 000000000..5f0b944f2 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Map.ocd/Script.c @@ -0,0 +1,237 @@ +/*-- + Library_Map + Authors: Sven2 + + Utility functions for map drawing in InitializeMap(). +--*/ + +// Returns p if p is an int. If p is an array of two ints, returns a +// random value between both (assuming p[1]>p[0]) +func EvalIntPar(p) { if (GetType(p) == C4V_Array) return p[0]+Random(p[1]-p[0]); return p; } + +// Returns p if p is an int. If p is an array of two ints, returns the +// medium value of both +func EvalIntParM(p) { if (GetType(p) == C4V_Array) return (p[0]+p[1])/2; return p; } + +func DrawVaried(string mat, proplist algo, array rect, vary_mats) +{ + // Draw material and put rndchecker variations of other materials on it + if (GetType(vary_mats) != C4V_Array || (GetLength(vary_mats)==3 && GetType(vary_mats[1])==C4V_Int)) vary_mats = [vary_mats]; + var ratio = 100/(GetLength(vary_mats)+1); + var main_shape = this->CreateLayer(); + main_shape->Draw(mat, algo, rect); + this->Blit(main_shape, rect); + for (var vary_def in vary_mats) + { + var sx=3,sy=3; + if (GetType(vary_def) == C4V_Array) + { + sx=vary_def[1]; sy = vary_def[2]; + vary_def = vary_def[0]; + } + var rand_algo = {Algo=MAPALGO_RndChecker, Ratio=ratio, Wdt=sx, Hgt=sy}; + var turb_algo = {Algo=MAPALGO_Turbulence, Amplitude=12, Scale=8, Op=rand_algo}; + this->Draw(vary_def, {Algo=MAPALGO_And, Op=[main_shape, turb_algo]}); + } + return main_shape; +} + +func DrawSpots(string mat, int num, sizex, sizey, array rect, inmat, vary_mats) +{ + // Default parameters + if (!inmat) inmat="Earth"; + if (!sizex) sizex = [5, 20]; + if (!sizey) sizey = [5, 7]; + if (!num) num=Max(this->GetPixelCount(inmat, rect) / (EvalIntParM(sizex)*EvalIntParM(sizey)*10), 1); + // Draw num spots + var spot = {Algo=MAPALGO_Ellipsis}; + while (num--) + { + if (!this->FindPosition(spot, inmat, rect)) break; + var mask = this->Duplicate(inmat); + spot.Wdt = EvalIntPar(sizex)/2; + spot.Hgt = EvalIntPar(sizey)/2; + var algo = {Algo=MAPALGO_And, Op=[mask, {Algo=MAPALGO_Turbulence, Amplitude=Max(spot.Wdt, spot.Hgt), Scale=Max(spot.Wdt, spot.Hgt), Op=spot}]}; + if (vary_mats) + DrawVaried(mat, algo, rect, vary_mats); + else + this->Draw(mat, algo, rect); + } + return true; +} + +func DrawCoal(int num, array rect) { return DrawSpots("Coal", num, [20,60], [4,8], rect, nil); } +func DrawFirestone(int num, array rect) { return DrawSpots("Firestone", num, [20,60], [8,12], rect, nil); } +func DrawOre(int num, array rect) { return DrawSpots("Ore", num, [8,12], [14,20], rect, nil); } +func DrawGold(int num, array rect) { return DrawSpots("Gold", num, [10,14], [10,14], rect, nil); } +func DrawRock(int num, array rect) { return DrawSpots("Rock-rock", num, [20,80], [6,8], rect, nil, [["Rock-rock_cracked", 3,10], ["Granite", 6,2]]); } + +func DrawWaterVeins(int num, array rect) +{ + while (num--) DrawLiquidVein("Water", 3, 5, rect); + return true; +} + +func DrawLiquidVein(string mat, int wdt, int spread, array rect, inmat) +{ + if (!rect) rect = [0,0,this.Wdt, this.Hgt]; + if (!inmat) inmat="Earth"; + var mask = this->Duplicate(inmat); + var x1 = rect[0]-rect[2]+Random(rect[2]*3); + var y1 = rect[1]-rect[3]+Random(rect[3]*3); + var x2 = rect[0]+Random(rect[2]); + var y2 = rect[1]+Random(rect[3]); + var water = {Algo=MAPALGO_Polygon, X=[x1,x2], Y=[y1,y2], Wdt=wdt}; + var water_rand = {Algo=MAPALGO_Turbulence, Amplitude=30, Scale=30, Op=water}; + var water_rand2 = {Algo=MAPALGO_Turbulence, Amplitude=spread*2, Scale=2, Op=water_rand}; + this->Draw(mat, {Algo=MAPALGO_And, Op=[mask, water_rand2]}); + return true; +} + +func DrawRegularGround(array rect, yoff, turbulence) +{ + // Draw regular (boring) ground level + if (!rect) rect = [0,0,this.Wdt, this.Hgt]; + if (GetType(yoff) == C4V_Nil) yoff = rect[3]/4; + if (GetType(turbulence) == C4V_Nil) turbulence = 30; + var ground_rect = {Algo=MAPALGO_Rect, X=-100, Y=rect[1]+yoff, Wdt=rect[0]+rect[2]+200, Hgt=rect[3]+100}; + var ground_algo = {Algo=MAPALGO_Turbulence, Amplitude=turbulence, Scale=30, Op=ground_rect}; + var earth_shape = DrawVaried("Earth-earth", ground_algo, rect, [["Earth-earth_dry", 3,10], ["Earth-earth_rough", 6,2]]); + var top1 = {Algo=MAPALGO_Border, Top=[-10, 3], Op=earth_shape}; + var top2 = {Algo=MAPALGO_Border, Top=[-10, 1], Op=earth_shape}; + this->Draw("Earth-earth_midSoil", {Algo=MAPALGO_And, Op=[earth_shape, {Algo=MAPALGO_Turbulence, Amplitude=4, Scale=10, Op=top1}]}); + this->Draw("Earth-earth_topSoil", {Algo=MAPALGO_And, Op=[earth_shape, {Algo=MAPALGO_Turbulence, Amplitude=4, Scale=10, Op=top2}]}); + return true; +} + +func FixLiquidBorders(border_material, lava_border_material) +{ + // Makes sure liquids bordering other liquids as well as liquids + // bordering background materials are surrounded by fix_material + // Default border materials + if (!border_material) border_material = "Earth-earth_topSoil"; + if (!lava_border_material) lava_border_material = "Rock"; + // Find liquid-to-background borders + var liquids = this->Duplicate("Liquid"); + var liquid_borders = {Algo=MAPALGO_Border, Op=liquids, Wdt=-1, Top=0 }; + var background = this->Duplicate("Background"); + background->Draw("Sky", {Algo=MAPALGO_Not, Op=this}); + this->Draw(border_material, {Algo=MAPALGO_And, Op=[liquid_borders, background]}); + // Put lava on top of other liquids + var lava_borders = {Algo=MAPALGO_Border, Op=this->Duplicate(["Lava", "DuroLava"])}; + this->Draw(lava_border_material, {Algo=MAPALGO_And, Op=[lava_borders, liquids]}); + // Put acid on top of water + var acid_borders = {Algo=MAPALGO_Border, Op=this->Duplicate("Acid")}; + this->Draw(border_material, {Algo=MAPALGO_And, Op=[acid_borders, liquids]}); + return true; +} + +func DrawPlatform(string material, int x0, int y0, int wdt, int hgt_up, int hgt_down) +{ + var ground_mask = this->Duplicate("~Background"); + for (var x=x0; xGetPixel(x,y); + if (px) break; + } + if (px) for (--y; y>y0; --y) this->SetPixel(x,y,px); + } + // Free top + if (hgt_up) this->Draw("Sky", nil, [x0,y0-hgt_up,wdt,hgt_up]); + // Draw platform itself + if (material) this->Draw(material, nil, [x0,y0,wdt,1]); +} + +func FindBottomPeaks(array rect, int min_dx) +{ + // Find downwards peaks in bottom-most nonzero pixels in rect + // Peaks are minimum min_dx apart horizontally + var x1,y1,x2,y2; + if (rect) + { x1=rect[0]; y1=rect[1]; x2=x1+rect[2]; y2=y1+rect[3]; } + else + { x2=this.Wdt; y2=this.Hgt; } + var last_y = y2+1, last_dy = 0, num_dy_0 = 0, last_peak_x = -min_dx-1; + var peaks = []; + for (var x=x1; xGetPixel(x,y)) if (y1>=--y) break; + var dy = y - last_y; + if (!dy) + { + ++num_dy_0; + } + else + { + if (dy < 0 && last_dy > 0) + { + var peak_x = x-1-num_dy_0/2; + if (num_dy_0%2 && !Random(2)) --peak_x; + if (peak_x-last_peak_x < min_dx) + { + if (!Random(2)) peaks[GetLength(peaks)-1] = {X=peak_x, Y=last_y}; + } + else + { + peaks[GetLength(peaks)] = {X=peak_x, Y=last_y}; + } + last_peak_x = peaks[GetLength(peaks)-1].X; + } + num_dy_0 = 0; + last_dy = dy; + } + last_y = y; + } + return peaks; +} + +func FillLiquid(string mat, int x, int y, max_wdt, int max_hgt) +{ + // Fill area downwards and sideways of given x and y with mat + // Stay within rectangle x-max_wdt and x+max_wdt horizontally and within y and y+max_hgt vertically + var background_mask = this->CreateMatTexMask("Background"); + var open_ranges = [[x,x]], n_open = 1; + max_hgt = BoundBy(max_hgt, 0, this.Hgt-y); + if (GetType(max_wdt) != C4V_Array) max_wdt = [max_wdt,max_wdt]; + var min_x1 = Max(x-max_wdt[0]), min_x2 = Max(x-max_wdt[1]); + var max_x1 = Min(x+max_wdt[0], this.Wdt-1), max_x2 = Min(x+max_wdt[1], this.Wdt-1); + var min_x = (min_x1+min_x2)/2, max_x = (max_x1+max_x2)/2; + var n_pix_set = 0; + while (n_open && max_hgt) + { + var next_ranges = [], n_next = 0; + x = -1; + for (var range in open_ranges) + { + var x1=range[0], x2=range[1]; + if (x>x1) continue; // two or more paths merged + while (x1>min_x && background_mask[this->GetPixel(x1-1,y)]) --x1; + while (x2GetPixel(x2+1,y)]) ++x2; + var below_was_background = false; + for (x=x1; x<=x2; ++x) + { + this->SetPixel(x,y,mat); ++n_pix_set; + var below_is_background = background_mask[this->GetPixel(x,y+1)]; + if (below_is_background) + { + if (!below_was_background) + next_ranges[n_next++] = [x,x]; + else + ++next_ranges[n_next-1][1]; + } + below_was_background = below_is_background; + } + } + open_ranges = next_ranges; + n_open = n_next; + ++y; --max_hgt; + min_x = BoundBy(min_x+Random(3)-1, min_x1,min_x2); + max_x = BoundBy(max_x+Random(3)-1, max_x1,max_x2); + } + return n_pix_set; +} diff --git a/planet/Objects.ocd/Libraries.ocd/MeleeWeapons.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/MeleeWeapons.ocd/Script.c index f84a52513..65e60bba3 100644 --- a/planet/Objects.ocd/Libraries.ocd/MeleeWeapons.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/MeleeWeapons.ocd/Script.c @@ -75,16 +75,6 @@ func FxIntWeaponChargeStart(pTarget, effect, iTemp, length) func FxIntWeaponChargeTimer(pTarget, effect, iEffectTime) { - // check whether the Clonk is still striking - /*if(this->GetChargeType() == L_WN_straight) - { - if(!pTarget->IsWalking()) - return -1; - } - else if(!pTarget->IsJumping()) - { - return -1; - }*/ if(this->Contained() != pTarget) return -1; if(!pTarget->~IsWalking() && !pTarget->~IsJumping()) return -1; var strikeTime=effect.length; @@ -102,7 +92,6 @@ func FxIntWeaponChargeTimer(pTarget, effect, iEffectTime) y=-Sin(step, 6)-3; if(GetChargeType() == L_WN_down) y*=-1; if(pTarget->GetDir() == DIR_Left) x *= -1; - CreateParticle("Blast", x, y, 0, 0, 20); var strength = 0; if(iEffectTime <= GetStrikeTime()) @@ -326,7 +315,6 @@ func GetJumpLength(pClonk) // not a very good approximation. I really think SimFlight should return the number of iterations return Sqrt((x - pClonk->GetX()) ** 2 + (y - pClonk->GetY()) ** 2); } - return -1; } func ApplyShieldFactor(pFrom, pTo, damage) @@ -385,7 +373,7 @@ func DoWeaponSlow(pClonk, iStrength) pClonk->SetYDir(-Cos(angle, s), 1000); if(e) - EffectCall(0, e, "AddWeaponSlow", iStrength); + EffectCall(nil, e, "AddWeaponSlow", iStrength); return true; } @@ -393,12 +381,12 @@ func GetWeaponSlow(pClonk) { var e=GetEffect("IntWeaponCharge", pClonk); if(!e) return 0; - return EffectCall(0, e, "GetWeaponSlow"); + return EffectCall(nil, e, "GetWeaponSlow"); } func ApplyWeaponBash(pTo, int strength, angle) { - AddEffect("IntIsBeingStruck", pTo, 2, 1, 0, GetID(), strength, angle); + AddEffect("IntIsBeingStruck", pTo, 2, 1, nil, GetID(), strength, angle); } func TranslateVelocity(object pTarget, int angle, int iLimited, int iExtraVelocity) diff --git a/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/Script.c index 83b32f6b9..06cd0977a 100644 --- a/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/Script.c @@ -1,9 +1,6 @@ -local Name = "$Name$"; -local Description = "$Description$"; - public func CanBeOwned(){return true;} -public func OnOwnerChanged(int old_owner) +public func OnOwnerChanged(int new_owner, int old_owner) { // ... } diff --git a/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/StringTblDE.txt deleted file mode 100644 index ae4fcbf27..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Ownable -Description=Objects that can be owned. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/StringTblUS.txt deleted file mode 100644 index ae4fcbf27..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Ownable.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Ownable -Description=Objects that can be owned. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Plant.ocd/Script.c deleted file mode 100644 index dc6272ae5..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/Script.c +++ /dev/null @@ -1,179 +0,0 @@ -/** - Plant - Basic functionality for all plants - - @author Clonkonaut -*/ - -// This is a plant -public func IsPlant() -{ - return true; -} - -/** Chance to reproduce plant. Chances are one out of return value. Default is 500. - @return the chance, higher = less chance. -*/ -private func SeedChance() { return 500; } - -/** Distance the seeds may travel. Default is 300. - @return the maximum distance. -*/ -private func SeedAreaSize() { return 300; } - -/** The amount of plants allowed within SeedAreaSize. Default is 8. - @return the maximum amount of plants. -*/ -private func SeedAmount() { return 8; } - -/** Automated positioning via RootSurface, make sure to call this if needed (in case Construction is overloaded) -*/ -protected func Construction() -{ - Schedule(this, "RootSurface()", 1); - _inherited(...); -} - -/** Reproduction. Make sure to call via TimerCall=Seed and Timer=350 (duration should be fixed so SeedChance controls the chance to reproduce) -*/ -private func Seed() -{ - if(!Random(SeedChance())) - { - var iSize = SeedAreaSize(); - var iOffset = iSize / -2; - if(ObjectCount(Find_ID(this->GetID()), Find_Distance(iSize)) < SeedAmount()) - { - PlaceVegetation(GetID(), iOffset, iOffset, iSize, iSize, 3); - } - } -} - -/* Chopping */ - -/** Determines whether this plant gives wood (we assume that are 'trees'). - @return \c true if the plant is choppable by the axe, \c false otherwise (default). -*/ -public func IsTree() -{ - return false; -} - -/** Determines whether the tree can still be chopped down (i.e. has not been chopped down). - @return \c true if the tree is still a valid axe target. -*/ -public func IsStanding() -{ - return GetCategory() & C4D_StaticBack; -} - -/** Maximum damage the tree can take before it falls. Each blow from the axe deals 10 damage. - @return \c the maximum amount of damage. -*/ -private func MaxDamage() -{ - return 50; -} - -protected func Damage() -{ - // do not grow for a few seconds - var g = GetGrowthValue(); - if(g) - { - StopGrowth(); - ScheduleCall(this, "RestartGrowth", 36 * 10, 0, g); - } - - // Max damage reached -> fall down - if (GetDamage() > MaxDamage() && IsStanding()) ChopDown(); - _inherited(...); -} - - -// restarts the growing of the tree (for example after taking damage) -func RestartGrowth(int old_value) -{ - var g = GetGrowthValue(); // safety - if(g) StopGrowth(); - g = Max(g, old_value); - StartGrowth(g); -} - -/** Called when the trees shall fall down (has taken max damage). Default behaviour is unstucking (5 pixel movement max) and removing C4D_StaticBack. -*/ -public func ChopDown() -{ - this.Touchable = 1; - SetCategory(GetCategory()&~C4D_StaticBack); - if (Stuck()) - { - var i = 5; - while(Stuck() && i) - { - SetPosition(GetX(), GetY()-1); - i--; - } - } - SetRDir(10); - if (Random(2)) SetRDir(-10); - // Crack! - if (GetCon() > 50) Sound("TreeDown?"); -} - -/* Harvesting */ - -/** Determines whether a plant may be harvested by the player. - @return \c true if the plant can be harvested, \c false otherwise (default). -*/ -private func IsCrop() -{ - return false; -} - -/** Determines whether the plant is harvestable right now (i.e. is fully grown). - @return \c true if the plant is ready to be harvested. -*/ -public func IsHarvestable() -{ - return GetCon() >= 100; -} - -public func IsInteractable(object clonk) -{ - return clonk->IsWalking() && IsCrop() && IsHarvestable() || _inherited(clonk); -} - -public func GetInteractionMetaInfo(object clonk) -{ - if (IsCrop()) - { - if (IsHarvestable()) - return { Description = Format("$Harvest$", GetName()) }; - else - return _inherited(clonk); - } - return _inherited(clonk); -} - -public func Interact(object clonk) -{ - if (IsCrop()) - { - if (IsHarvestable()) - return Harvest(clonk); - else - return _inherited(); - } - return _inherited(clonk); -} - -/** Called when the plant is harvested - @param The harvesting clonk - @return \c true is successfully harvested -*/ -public func Harvest(object clonk) -{ - Split2Components(); - return true; -} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Plant.ocd/StringTblDE.txt deleted file mode 100644 index 0589c7b05..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Pflanze -Harvest=%s ernten \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Plant.ocd/StringTblUS.txt deleted file mode 100644 index 4840d2d5a..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Plant -Harvest= Harvest %s \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/DefCore.txt new file mode 100644 index 000000000..e25f5a230 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Library_Crop +Version=5,2,0,1 +Category=C4D_StaticBack diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/Graphics.png new file mode 100644 index 000000000..9bb8607e9 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/Script.c new file mode 100644 index 000000000..472b1ead2 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/Script.c @@ -0,0 +1,70 @@ +/** + Crop + (Plants) that are harvestable + + @author Clonkonaut +*/ + +/** Determines whether a plant may be harvested by the player. + @return \c true if the plant can be harvested, \c false otherwise (default). +*/ +private func IsCrop() +{ + return false; +} + +/** Determines whether the plant can only be harvested when using a sickle. + These are very sturdy or economically important plants (like cotton or wheat). + @return \c true if the plant must be harvested with a sickle (default), \c false otherwise. +*/ +public func SickleHarvesting() +{ + return true; +} + +/** Determines whether the plant is harvestable right now (i.e. is fully grown). + @return \c true if the plant is ready to be harvested. +*/ +public func IsHarvestable() +{ + return GetCon() >= 100; +} + +public func IsInteractable(object clonk) +{ + return clonk->IsWalking() && IsCrop() && !SickleHarvesting() && (IsHarvestable() || _inherited(clonk)); +} + +public func GetInteractionMetaInfo(object clonk) +{ + if (IsCrop()) + { + if (IsHarvestable()) + return { Description = Format("$Harvest$", GetName()) }; + else + return _inherited(clonk); + } + return _inherited(clonk); +} + +public func Interact(object clonk) +{ + if (IsCrop()) + { + if (IsHarvestable()) + return Harvest(clonk); + else + return _inherited(); + } + return _inherited(clonk); +} + +/** Called when the plant is harvested + @param The harvesting clonk + @return \c true is successfully harvested +*/ +public func Harvest(object clonk) +{ + Split2Components(); + return true; +} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/StringTblDE.txt new file mode 100644 index 000000000..20ab0c048 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Harvest=%s ernten \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/StringTblUS.txt new file mode 100644 index 000000000..c4f836b91 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Crop.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Harvest= Harvest %s \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Plant.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/DefCore.txt similarity index 100% rename from planet/Objects.ocd/Libraries.ocd/Plant.ocd/DefCore.txt rename to planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/DefCore.txt diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/Graphics.png new file mode 100644 index 000000000..9bb8607e9 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/Script.c new file mode 100644 index 000000000..499721f35 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Plant.ocd/Script.c @@ -0,0 +1,249 @@ +/** + Plant + Basic functionality for all plants + + @author Clonkonaut +*/ + +// This is a plant +public func IsPlant() +{ + return true; +} + +/** Automated positioning via RootSurface, make sure to call this if needed (in case Construction is overloaded) +*/ +protected func Construction() +{ + Schedule(this, "RootSurface()", 1); + AddTimer("Seed", 72); + _inherited(...); +} + +/* Placement */ + +/** Places the given amount of plants inside the area. If no area is given, the whole landscape is used. + @param amount The amount of plants to be created (not necessarily every plant is created). + @param rectangle The area where to put the plants. + @param settings A proplist defining further setttings: { growth = 100000, keep_area = false }. Growth will get passed over to PlaceVegetation, keep_area will confine the plants and their offspring to rectangle. + @return Returns an array of all objects created. +*/ +public func Place(int amount, proplist rectangle, proplist settings) +{ + // No calls to objects, only definitions + if (GetType(this) == C4V_C4Object) return; + // Default parameters + if (!settings) settings = { growth = 100000, keep_area = false }; + if (!settings.growth) settings.growth = 100000; + if (!rectangle) + rectangle = Rectangle(0,0, LandscapeWidth(), LandscapeHeight()); + + var plants = CreateArray(), plant; + for (var i = 0 ; i < amount ; i++) + { + plant = PlaceVegetation(this, rectangle.x, rectangle.y, rectangle.w, rectangle.h, settings.growth); + if (plant) + { + plants[GetLength(plants)] = plant; + if (settings.keep_area) + plant->KeepArea(rectangle); + } + plant = nil; + } + return plants; +} + +/* Reproduction */ + +/** Will confine the the plant and its offspring to a certain area. + @params rectangle The confinement area. +*/ +func KeepArea(proplist rectangle) +{ + this.Confinement = rectangle; +} + +/** Chance to reproduce plant. Chances are one out of return value. Default is 500. + @return the chance, higher = less chance. +*/ +private func SeedChance() +{ + return 500; +} + +/** Distance the seeds may travel. Default is 250. + @return the maximum distance. +*/ +private func SeedArea() +{ + return 250; +} + +/** The amount of plants allowed within SeedAreaSize. Default is 10. + @return the maximum amount of plants. +*/ +private func SeedAmount() +{ + return 10; +} + +/** The closest distance a new plant may seed to its nearest neighbour. Default is 20. + @return the maximum amount of plants. +*/ +private func SeedOffset() +{ + return 20; +} + +/** Reproduction of plants: Called every 2 seconds by a timer. +*/ +public func Seed() +{ + // Find number of plants in seed area. + var size = SeedArea(); + var amount = SeedAmount(); + var area = Rectangle(size / -2, size / -2, size, size); + if (this.Confinement) + area = RectangleEnsureWithin(area, this.Confinement); + var plant_cnt = ObjectCount(Find_ID(GetID()), Find_InRect(area.x, area.y, area.w, area.h)); + // If there are not much plants in the seed area compared to seed amount + // the chance of seeding is improved, if there are much the chance is reduced. + var chance = SeedChance(); + var chance = chance / Max(1, amount - plant_cnt) + chance * Max(0, plant_cnt - amount); + // Place a plant if we are lucky, in principle there can be more than seed amount. + if (!Random(chance)) + { + // Place the plant but check if it is not close to another one. + var plant = PlaceVegetation(GetID(), area.x, area.y, area.w, area.h, 3); + if (plant) + { + var neighbour = FindObject(Find_ID(GetID()), Find_Exclude(plant), Sort_Distance(plant->GetX() - GetX(), plant->GetY() - GetY())); + var distance = ObjectDistance(plant, neighbour); + // Closeness check + if (distance < SeedOffset()) + plant->RemoveObject(); + else if (this.Confinement) + plant->KeepArea(this.Confinement); + } + } + return; +} + +/* Chopping */ + +/** Determines whether this plant gives wood (we assume that are 'trees'). + @return \c true if the plant is choppable by the axe, \c false otherwise (default). +*/ +public func IsTree() +{ + return false; +} + +/** Determines whether the tree can still be chopped down (i.e. has not been chopped down). + @return \c true if the tree is still a valid axe target. +*/ +public func IsStanding() +{ + return GetCategory() & C4D_StaticBack; +} + +/** Maximum damage the tree can take before it falls. Each blow from the axe deals 10 damage. + @return \c the maximum amount of damage. +*/ +private func MaxDamage() +{ + return 50; +} + +protected func Damage() +{ + // do not grow for a few seconds + var g = GetGrowthValue(); + if(g) + { + StopGrowth(); + ScheduleCall(this, "RestartGrowth", 36 * 10, 0, g); + } + + // Max damage reached -> fall down + if (GetDamage() > MaxDamage() && IsStanding()) ChopDown(); + _inherited(...); +} + +// restarts the growing of the tree (for example after taking damage) +func RestartGrowth(int old_value) +{ + var g = GetGrowthValue(); // safety + if(g) StopGrowth(); + g = Max(g, old_value); + StartGrowth(g); +} + +/** Called when the trees shall fall down (has taken max damage). Default behaviour is unstucking (5 pixel movement max) and removing C4D_StaticBack. +*/ +public func ChopDown() +{ + // stop growing! + ClearScheduleCall(this, "RestartGrowth"); + StopGrowth(); + this.Touchable = 1; + this.Plane = 300; + SetCategory(GetCategory()&~C4D_StaticBack); + if (Stuck()) + { + var i = 5; + while(Stuck() && i) + { + SetPosition(GetX(), GetY()-1); + i--; + } + } + Sound("TreeCrack"); + AddEffect("TreeFall", this, 1, 1, this); +} + +// determine a random falling direction and passes it on to the FxTreeFallTimer. +func FxTreeFallStart(object target, proplist effect) +{ + effect.direction = Random(2); + if (effect.direction == 0) effect.direction -= 1; +} + +/* animates the falling of the tree: First 10 slow degress then speed up and play the landing sound at 80+ degrees. +remember that degrees range from -180 to 180. */ +func FxTreeFallTimer(object target, proplist effect) +{ + //simple falling if tree is not fully grown + if (target->GetCon() <= 50) + { + target->SetRDir(effect.direction * 10); + } + //else rotate slowly first until about 10 degree. This will be the time needed for the crack sound and makes sense as a tree will start falling slowly. + else + { + if (Abs(target->GetR()) < 10) + { + target->SetRDir(effect.direction * 1); + //Turn of gravity so the tree doesn't get stuck before its done falling. + target->SetYDir(0); + } + else + { + //Then speed up and let gravity do the rest. + target->SetRDir(effect.direction * 10); + } + } + //if the tree does not lend on a cliff or sth. (is rotated more then 80 degrees in the plus or minus direction) Play the landing sound of the tree. + if (Abs(target->GetR()) > 80) + { + target->SetRDir(0); + if (target->GetCon() > 50) target->Sound("TreeLanding", false); + return -1; + } + //check every frame if the tree is stuck and stop rotation in that case this is necessary as a tree could get stuck before reaching 80 degrees + if ((target->GetContact(-1, CNAT_Left) | target->GetContact(-1, CNAT_Right)) > 0) + { + target->SetRDir(0); + return -1; + } +} diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/DefCore.txt new file mode 100644 index 000000000..8cc61004f --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Library_Tree +Version=5,2,0,1 +Category=C4D_StaticBack diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/Graphics.png new file mode 100644 index 000000000..9bb8607e9 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/Script.c new file mode 100644 index 000000000..424dab0a4 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Plants.ocd/Tree.ocd/Script.c @@ -0,0 +1,125 @@ +/** + Tree + Basic functionality for everything choppable (trees) + + @author Clonkonaut +*/ + +/* Chopping */ + +/** Determines whether this plant gives wood (we assume that are 'trees'). + @return \c true if the plant is choppable by the axe (default), \c false otherwise. +*/ +public func IsTree() +{ + return true; +} + +/** Determines whether the tree can still be chopped down (i.e. has not been chopped down). + @return \c true if the tree is still a valid axe target. +*/ +public func IsStanding() +{ + return GetCategory() & C4D_StaticBack; +} + +/** Maximum damage the tree can take before it falls. Each blow from the axe deals 10 damage. + @return \c the maximum amount of damage. +*/ +private func MaxDamage() +{ + return 50; +} + +protected func Damage() +{ + // do not grow for a few seconds + var g = GetGrowthValue(); + if(g) + { + StopGrowth(); + ScheduleCall(this, "RestartGrowth", 36 * 10, 0, g); + } + + // Max damage reached -> fall down + if (GetDamage() > MaxDamage() && IsStanding()) ChopDown(); + _inherited(...); +} + +// restarts the growing of the tree (for example after taking damage) +func RestartGrowth(int old_value) +{ + var g = GetGrowthValue(); // safety + if(g) StopGrowth(); + g = Max(g, old_value); + StartGrowth(g); +} + +/** Called when the trees shall fall down (has taken max damage). Default behaviour is unstucking (5 pixel movement max) and removing C4D_StaticBack. +*/ +public func ChopDown() +{ + // stop growing! + ClearScheduleCall(this, "RestartGrowth"); + StopGrowth(); + this.Touchable = 1; + this.Plane = 300; + SetCategory(GetCategory()&~C4D_StaticBack); + if (Stuck()) + { + var i = 5; + while(Stuck() && i) + { + SetPosition(GetX(), GetY()-1); + i--; + } + } + Sound("TreeCrack"); + AddEffect("TreeFall", this, 1, 1, this); +} + +// determine a random falling direction and passes it on to the FxTreeFallTimer. +func FxTreeFallStart(object target, proplist effect) +{ + effect.direction = Random(2); + if (effect.direction == 0) effect.direction -= 1; +} + +/* animates the falling of the tree: First 10 slow degress then speed up and play the landing sound at 80+ degrees. +remember that degrees range from -180 to 180. */ +func FxTreeFallTimer(object target, proplist effect) +{ + //simple falling if tree is not fully grown + if (target->GetCon() <= 50) + { + target->SetRDir(effect.direction * 10); + } + //else rotate slowly first until about 10 degree. This will be the time needed for the crack sound and makes sense as a tree will start falling slowly. + else + { + if (Abs(target->GetR()) < 10) + { + target->SetRDir(effect.direction * 1); + //Turn of gravity so the tree doesn't get stuck before its done falling. + target->SetYDir(0); + } + else + { + //Then speed up and let gravity do the rest. + target->SetRDir(effect.direction * 10); + } + } + //if the tree does not lend on a cliff or sth. (is rotated more then 80 degrees in the plus or minus direction) Play the landing sound of the tree. + if (Abs(target->GetR()) > 80) + { + target->SetRDir(0); + if (target->GetCon() > 50) target->Sound("TreeLanding", false); + return -1; + } + //check every frame if the tree is stuck and stop rotation in that case this is necessary as a tree could get stuck before reaching 80 degrees + if ((target->GetContact(-1, CNAT_Left) | target->GetContact(-1, CNAT_Right)) > 0) + { + target->SetRDir(0); + return -1; + } +} diff --git a/planet/Objects.ocd/Libraries.ocd/Power.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Power.ocd/Script.c index 9330c352e..2152b8001 100644 --- a/planet/Objects.ocd/Libraries.ocd/Power.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Power.ocd/Script.c @@ -10,14 +10,12 @@ globals: MakePowerConsumer(int amount) + Note: power consumers include the library Library_PowerConsumer and should use UnmakePowerConsumer to turn off as power consumers MakePowerProducer(int amount) IsPowerAvailable(int amount) */ -local Name = "$Name$"; -local Description = "$Description$"; - static Library_Power_power_compounds; // for the helper definitions @@ -59,17 +57,13 @@ func AddPowerConsumer(object p, int a) // message var diff = 0; { - var t = CreateObject(FloatingMessage, o.obj->GetX() - GetX(), o.obj->GetY() - GetY(), NO_OWNER); - t->SetMessage(Format("%d{{Library_PowerConsumer}}", diff)); - t->SetColor(255, 0, 0); - t->SetYDir(-10); - t->FadeOut(4, 8); + VisualizePowerChange(o.obj, 0, o.amount, false); } o.obj->~OnRemovedFromPowerSleepingQueue(); return true; } - sleeping_links[i].amount = a; + sleeping_links[i].amount = -a; return true; } } @@ -111,10 +105,10 @@ func AddPowerLink(object p, int a, bool surpress_balance_check) diff = a - o.amount; power_balance += diff; + before = power_links[i].amount; if(a == 0) { - before = power_links[i].amount; power_links[i] = nil; } else power_links[i] = n; @@ -135,22 +129,13 @@ func AddPowerLink(object p, int a, bool surpress_balance_check) power_balance += diff; } - diff = n.amount; - if((diff > 0) || ((a == 0) && (before > 0))) + if((n.amount > 0) || ((n.amount == 0) && (before > 0))) { - var t = CreateObject(FloatingMessage, n.obj->GetX() - GetX(), n.obj->GetY() - GetY(), NO_OWNER); - t->SetMessage(Format("+%d{{Library_PowerConsumer}}", diff)); - t->SetColor(0, 255, 0); - t->SetYDir(-10); - t->FadeOut(4, 8); + VisualizePowerChange(n.obj, n.amount, before, false); } - else if((diff < 0) || ((a == 0) && (before < 0))) + else if((n.amount < 0) || ((n.amount == 0) && (before < 0))) { - var t = CreateObject(FloatingMessage, n.obj->GetX() - GetX(), n.obj->GetY() - GetY(), NO_OWNER); - t->SetMessage(Format("%d{{Library_PowerConsumer}}", diff)); - t->SetColor(255, 0, 0); - t->SetYDir(-10); - t->FadeOut(4, 8); + VisualizePowerChange(n.obj, n.amount, before, false); } if(n.amount < 0) n.obj->~OnEnoughPower(); // might be reverted soon, though @@ -278,6 +263,7 @@ func SleepLink(int index) // sadly not enough power anymore o.obj->~OnNotEnoughPower(); + VisualizePowerChange(o.obj, 0, o.amount, true); return true; } @@ -325,6 +311,68 @@ public func Init() Library_Power_power_compounds = []; } +// static +func VisualizePowerChange(object obj, int to, int before, bool loss) +{ + var before_current = nil; + var e = GetEffect("VisualPowerChange", obj); + if(!e) + e = AddEffect("VisualPowerChange", obj, 1, 5, nil, Library_Power); + else before_current = e.current; + + var to_abs = Abs(to); + var before_abs = Abs(before); + + e.max = Max(to_abs, before_abs); + e.current = before_current ?? before_abs; + e.to = to_abs; + + + + if(loss) + e.back_graphics_name = "Red"; + else e.back_graphics_name = nil; + + if(to < 0) e.graphics_name = "Yellow"; + else if(to > 0) e.graphics_name = "Green"; + else // off now + { + if(before < 0) e.graphics_name = "Yellow"; + else e.graphics_name = "Green"; + } + + EffectCall(obj, e, "Refresh"); +} + +func FxVisualPowerChangeRefresh(target, effect) +{ + if(effect.bar) effect.bar->Close(); + var vis = VIS_Allies | VIS_Owner; + var controller = target->GetController(); + if(controller == NO_OWNER) vis = VIS_All; + var off_x = -(target->GetDefCoreVal("Width", "DefCore") * 3) / 8; + var off_y = target->GetDefCoreVal("Height", "DefCore") / 2 - 10; + + effect.bar = target->CreateProgressBar(GUI_BarProgressBar, effect.max, effect.current, 35 + , controller, {x = off_x, y = off_y}, vis + , {size = 1000, bars = effect.max / 25, graphics_name = effect.graphics_name, back_graphics_name = effect.back_graphics_name, image = Icon_Lightbulb, fade_speed = 1}); + // appear on a GUI level in front of other objects (f.e. trees) + effect.bar->SetPlane(1010); +} + +func FxVisualPowerChangeTimer(target, effect, time) +{ + if(!effect.bar) return -1; + if(effect.current == effect.to) return 1; + + if(effect.to < effect.current) effect.current = Max(effect.current - 15, effect.to); + else effect.current = Min(effect.current + 15, effect.to); + + effect.bar->SetValue(effect.current); + return 1; +} + + // static func GetPowerHelperForObject(object who) { @@ -341,7 +389,7 @@ func GetPowerHelperForObject(object who) { for(var obj in Library_Power_power_compounds) { - if(!obj.neutral) continue; + if(!obj || !obj.neutral) continue; helper = obj; break; } @@ -377,6 +425,7 @@ func GetPowerHelperForObject(object who) return helper; } +// returns the amount of unavailable power that is currently being request global func GetPendingPowerAmount() { if(!this) return 0; @@ -384,6 +433,8 @@ global func GetPendingPowerAmount() return (Library_Power->GetPowerHelperForObject(this))->GetPendingPowerAmount(); } +// returns the current power balance of the area an object is in. +// this is roughly equivalent to produced_power - consumed_power global func GetCurrentPowerBalance() { if(!this) return 0; @@ -391,13 +442,23 @@ global func GetCurrentPowerBalance() return (Library_Power->GetPowerHelperForObject(this))->GetPowerBalance(); } -global func MakePowerProducer(int amount) +// turns the object into a power producer that produces /amount/ power until the function is called again with amount = 0 +global func MakePowerProducer(int amount /* the amount of power to produce constantly, 0 to turn off */) { if(!this) return false; Library_Power->Init(); - return (Library_Power->GetPowerHelperForObject(this))->AddPowerProducer(this, amount); + var power_helper = Library_Power->GetPowerHelperForObject(this); + if (!power_helper) return false; + return power_helper->AddPowerProducer(this, amount); } +/** Turns the power producer into an object that does not produce power */ +global func UnmakePowerProducer() +{ + MakePowerProducer(0); +} + +// returns true if the current power balance is bigger or equal amount global func IsPowerAvailable(int amount) { if(!this) return false; @@ -405,11 +466,17 @@ global func IsPowerAvailable(int amount) return (Library_Power->GetPowerHelperForObject(this))->IsPowerAvailable(this, amount); } -global func MakePowerConsumer(int amount) +// turns the object into a power consumer +global func MakePowerConsumer(int amount /* the amount of power to request, 0 to turn off */) { if(!this) return false; Library_Power->Init(); return (Library_Power->GetPowerHelperForObject(this))->AddPowerConsumer(this, amount); } -// helper object \ No newline at end of file +// helper object should not be saved +func SaveScenarioObject() +{ + if (GetID() == Library_Power) return false; + return inherited(...); +} diff --git a/planet/Objects.ocd/Libraries.ocd/Power.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Power.ocd/StringTblDE.txt deleted file mode 100644 index 7210f2d27..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Power.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Energy -Description=Kümmert sich um das Energiemanagement. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Power.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Power.ocd/StringTblUS.txt deleted file mode 100644 index 468234fbd..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Power.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Power -Description=Cares about power management of a base. \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/PowerConsumer.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/PowerConsumer.ocd/Script.c index 4a199170f..05511ae06 100644 --- a/planet/Objects.ocd/Libraries.ocd/PowerConsumer.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/PowerConsumer.ocd/Script.c @@ -2,10 +2,31 @@ Power consumer Cares about showing the "No Power"-symbol and provides CurrentlyHasPower() - The rest is handled by Library_Power + also handles requesting 0 power and the NoPowerNeed-rule correctly + + The main part of the power system is handled by Library_Power + + Usage: + a power consumer should always include this library. + production (or anything else) should /only/ be started or continued in the callback OnEnoughPower. + in the callback OnNotEnoughPower the user should pause the production. + + when everything is ready to produce the user should call MakePowerConsumer(amount) where amount is the amount of power to request (works with 0). + when the production is done or the building wants to cease consuming power, it should call UnmakePowerConsumer() - note that the callback OnNotEnoughPower is not called this way. + + other: + the callback GetActualPowerConsumer can return another object that acts as the power consumer when checking for the affiliation to a flag. For example the elevator case could be the power consumer but use the elevator building as the actual power consumer. + CurrentlyHasPower() returns true when the object has requested power and is not in the sleeping queue. */ -local PowerConsumer_has_power = 0; +local PowerConsumer_has_power = false; + +// states for being able to handle 0-power requests +static const PowerConsumer_LPR_None = 0; +static const PowerConsumer_LPR_Zero = 1; +static const PowerConsumer_LPR_NonZero = 2; +local PowerConsumer_last_power_request = 0; +local PowerConsumer_last_power_request_amount = 0; public func IsPowerConsumer() { return true; } @@ -59,8 +80,90 @@ public func OnEnoughPower() this->RemoveStatusSymbol(Library_PowerConsumer); } +// Add/Remove an effect such that this structure does not need power +func SetNoPowerNeed(bool to_val) +{ + if (to_val) + AddEffect("NoPowerNeed", this, 1); + else + RemoveEffect("NoPowerNeed", this); + return true; +} + +// wrapper for MakePowerConsumer to handle requesting 0 power and the NoPowerNeed rule correctly +func MakePowerConsumer(int amount, bool just_pass_to_global /* whether to skip special treatment for 0 power request */) +{ + if(just_pass_to_global == true) + { + return inherited(amount, just_pass_to_global, ...); + } + + var no_power_need = !!ObjectCount(Find_ID(Rule_NoPowerNeed)) || GetEffect("NoPowerNeed", this); + + if((amount > 0) && !no_power_need) // requesting non-zero? + if(PowerConsumer_last_power_request == PowerConsumer_LPR_NonZero) // having requested non-zero before? + if(PowerConsumer_last_power_request_amount == amount) // requesting the exact amount again? (successive call) + // nothing has changed + return true; + + // special handling for amount == 0 + if((amount == 0) || no_power_need) + { + if(PowerConsumer_last_power_request == PowerConsumer_LPR_None) // initially requesting 0 power? + { + PowerConsumer_last_power_request = PowerConsumer_LPR_Zero; + PowerConsumer_last_power_request_amount = amount; + // always enable + this->~OnEnoughPower(); + return true; + } + else if(PowerConsumer_last_power_request == PowerConsumer_LPR_Zero)// requesting 0 power as a second request + { + PowerConsumer_last_power_request_amount = amount; + // should still have power at this point + return true; + } + else // requesting 0 power after having requested nonzero power + { + PowerConsumer_last_power_request = PowerConsumer_LPR_Zero; + PowerConsumer_last_power_request_amount = amount; + inherited(0); // removes as official power consumer + // re-enable power supply + this->~OnEnoughPower(); + return true; + } + } + else + { + PowerConsumer_last_power_request = PowerConsumer_LPR_NonZero; // requesting power != 0 + PowerConsumer_last_power_request_amount = amount; + } + + return inherited(amount, just_pass_to_global, ...); +} + +// turns the object off as a power consumer +func UnmakePowerConsumer() +{ + // succesive calls have no effect + if(PowerConsumer_last_power_request == PowerConsumer_LPR_None) + return true; + + // we don't have no power anymore + PowerConsumer_has_power = false; + + // we were not officially registered as power consumer anyway + if(PowerConsumer_last_power_request == PowerConsumer_LPR_Zero) + { + PowerConsumer_last_power_request = PowerConsumer_LPR_None; + return true; + } + PowerConsumer_last_power_request = PowerConsumer_LPR_None; + return MakePowerConsumer(0, true); +} + func Destruction() { - MakePowerProducer(0); + UnmakePowerConsumer(); return _inherited(...); } \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Producer.ocd/ProductionMenu.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/ProductionMenu.ocd/Script.c index 0004ed85b..775ffe473 100644 --- a/planet/Objects.ocd/Libraries.ocd/Producer.ocd/ProductionMenu.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/ProductionMenu.ocd/Script.c @@ -51,7 +51,7 @@ protected func Construction() public func AddMenuProducts(object producer) { - for (var product in producer->GetProducts()) + for (var product in producer->GetProducts(GetMenuObject())) { var item = CreateObject(GUI_MenuItem); if (!AddItem(item)) @@ -91,13 +91,15 @@ public func ShowProductInfo(object item) var product_id = item->GetSymbol(); var costs = menu_commander->ProductionCosts(product_id); var cost_msg = "@"; - var liquid; + var liquid, material; for (var comp in costs) - cost_msg = Format("%s %dx {{%i}}", cost_msg, comp[1], comp[0]); + cost_msg = Format("%s %s {{%i}}", cost_msg, GetCostString(comp[1], menu_commander->CheckComponent(comp[0], comp[1])), comp[0]); if (menu_commander->FuelNeed(product_id)) - cost_msg = Format("%s 1x {{Icon_Producer_Fuel}}", cost_msg); + cost_msg = Format("%s %s {{Icon_Producer_Fuel}}", cost_msg, GetCostString(1, menu_commander->CheckFuel(product_id))); if (liquid = menu_commander->LiquidNeed(product_id)) - cost_msg = Format("%s %dx {{Icon_Producer_%s}}", cost_msg, liquid[1], liquid[0]); + cost_msg = Format("%s %s {{Icon_Producer_%s}}", cost_msg, GetCostString(liquid[1], menu_commander->CheckLiquids(product_id)), liquid[0]); + if (material = menu_commander->MaterialNeed(product_id)) + cost_msg = Format("%s %s {{%i}}", cost_msg, GetCostString(material[1], menu_commander->CheckMaterials(product_id)), product_id->~GetMaterialIcon(material[0])); if (menu_commander->PowerNeed(product_id)) cost_msg = Format("%s + {{Library_PowerConsumer}}", cost_msg); @@ -106,6 +108,13 @@ public func ShowProductInfo(object item) return; } +private func GetCostString(int amount, bool available) +{ + // Format amount to colored string; make it red if it's not available + if (available) return Format("%dx", amount); + return Format("%dx", amount); +} + public func HideProductInfo() { CustomMessage("", this, GetOwner()); @@ -308,3 +317,9 @@ public func OnMouseOutItem(object out_item, object dragged_item) return _inherited(out_item, dragged_item, ...); } +// Don't save open menus in scenarios +public func SaveScenarioObject() +{ + if (GetID() == Library_ProductionMenu) return false; + return inherited(...); +} diff --git a/planet/Objects.ocd/Libraries.ocd/Producer.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/Script.c index 492254181..307f42711 100644 --- a/planet/Objects.ocd/Libraries.ocd/Producer.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/Script.c @@ -45,7 +45,7 @@ public func IsInteractable() { return GetCon() >= 100; } public func GetInteractionMetaInfo(object clonk) { - return { Description = "Produce items", IconName = nil, IconID = nil }; + return { Description = "$DescInteraction$", IconName = nil, IconID = nil }; } // On interaction the production menu should be opened. @@ -100,21 +100,24 @@ private func IsProduct(id product_id) /** Returns an array with the ids of products which can be produced at this producer. @return array with products. */ -public func GetProducts() +public func GetProducts(object for_clonk) { + var for_plr = GetOwner(); + if (for_clonk) + for_plr = for_clonk-> GetOwner(); var products = []; // Cycle through all definitions to find the ones this producer can produce. var index = 0, product; - if (!IgnoreKnowledge() && GetOwner() != NO_OWNER) + if (!IgnoreKnowledge() && for_plr != NO_OWNER) { - while (product = GetPlrKnowledge(GetOwner(), nil, index, C4D_Object)) + while (product = GetPlrKnowledge(for_plr, nil, index, C4D_Object)) { if (IsProduct(product)) products[GetLength(products)] = product; index++; } index = 0; - while (product = GetPlrKnowledge(GetOwner(), nil, index, C4D_Vehicle)) + while (product = GetPlrKnowledge(for_plr, nil, index, C4D_Vehicle)) { if (IsProduct(product)) products[GetLength(products)] = product; @@ -336,6 +339,7 @@ protected func FxProcessQueueTimer(object target, proplist effect) private func ProductionTime(id product) { return product->~GetProductionTime(); } private func FuelNeed(id product) { return product->~GetFuelNeed(); } private func LiquidNeed(id product) { return product->~GetLiquidNeed(); } +private func MaterialNeed(id product) { return product->~GetMaterialNeed(); } private func PowerNeed() { return 200; } @@ -347,16 +351,19 @@ private func Produce(id product) // Check if components are available. if (!CheckComponents(product)) - return false; + return false; // Check need for fuel. if (!CheckFuel(product)) - return false; + return false; // Check need for liquids. if (!CheckLiquids(product)) - return false; + return false; + // Check need for materials. + if (!CheckMaterials(product)) + return false; // Check need for power. if (!CheckForPower()) - return false; + return false; // Everything available? Start production. // Remove needed components, fuel and liquid. @@ -364,6 +371,7 @@ private func Produce(id product) CheckComponents(product, true); CheckFuel(product, true); CheckLiquids(product, true); + CheckMaterials(product, true); // Add production effect. AddEffect("ProcessProduction", this, 100, 2, this, nil, product); @@ -377,8 +385,7 @@ private func CheckComponents(id product, bool remove) { var mat_id = item[0]; var mat_cost = item[1]; - var mat_av = ObjectCount(Find_Container(this), Find_ID(mat_id)); - if (mat_av < mat_cost) + if (!CheckComponent(mat_id, mat_cost)) return false; // Components missing. else if (remove) { @@ -389,7 +396,13 @@ private func CheckComponents(id product, bool remove) return true; } -private func CheckFuel(id product, bool remove) +public func CheckComponent(id component, int amount) +{ + // check if at least the given amount of the given component is available to be used for production + return (ObjectCount(Find_Container(this), Find_ID(component)) >= amount); +} + +public func CheckFuel(id product, bool remove) { if (FuelNeed(product) > 0) { @@ -415,7 +428,7 @@ private func CheckFuel(id product, bool remove) return true; } -private func CheckLiquids(id product, bool remove) +public func CheckLiquids(id product, bool remove) { var liq_need = LiquidNeed(product); if (liq_need) @@ -445,6 +458,36 @@ private func CheckLiquids(id product, bool remove) return true; } +public func CheckMaterials(id product, bool remove) +{ + var mat_need = MaterialNeed(product); + if (mat_need) + { + var material_amount = 0; + var material = mat_need[0]; + var need = mat_need[1]; + // Find liquid containers in this producer. + for (var mat_container in FindObjects(Find_Container(this), Find_Func("IsMaterialContainer"))) + if (mat_container->~GetContainedMaterial() == material) + material_amount += mat_container->~GetFillLevel(); + if (material_amount < need) + return false; + else if (remove) + { + // Remove the material needed. + var extracted = 0; + for (var mat_container in FindObjects(Find_Container(this), Find_Func("IsMaterialContainer"))) + { + var val = mat_container->~RemoveContainedMaterial(material, need - extracted); + extracted += val; + if (extracted >= need) + break; + } + } + } + return true; +} + private func CheckForPower() { return true; // always assume that power is available @@ -518,7 +561,7 @@ protected func FxProcessProductionTimer(object target, proplist effect, int time //Log("Production in progress on %i, %d frames, %d time", effect.Product, effect.Duration, time); // Check if production time has been reached. - if (effect.Duration >= ProductionTime()) + if (effect.Duration >= ProductionTime(effect.Product)) return -1; return 1; @@ -529,7 +572,7 @@ protected func FxProcessProductionStop(object target, proplist effect, int reaso if(temp) return; // no need to consume power anymore - MakePowerConsumer(0); + UnmakePowerConsumer(); if (reason != 0) return 1; @@ -552,7 +595,12 @@ public func OnProductEjection(object product) { var x = GetX(); var y = GetY() + GetDefHeight()/2 - product->GetDefHeight()/2; - product->SetPosition(x, y); + product->SetPosition(x, y); + // Sometimes, there is material in front of the building. Move vehicles upwards in that case + var max_unstick_range = Max(GetDefHeight()/5,5); // 8 pixels for tools workshop + var y_off = 0; + while (product->Stuck() && y_off < max_unstick_range) + product->SetPosition(x, y-++y_off); } // Items should stay inside. else @@ -641,5 +689,12 @@ protected func RejectEntrance(object obj) if (LiquidNeed(product)) return false; } + // Material containers may be collected if a product needs them. + if (obj->~IsMaterialContainer()) + { + for (var product in GetProducts()) + if (MaterialNeed(product)) + return false; + } return true; } diff --git a/planet/Objects.ocd/Libraries.ocd/Producer.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/StringTblDE.txt new file mode 100644 index 000000000..37d14d262 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/StringTblDE.txt @@ -0,0 +1 @@ +DescInteraction=Produktion \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Producer.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/StringTblUS.txt new file mode 100644 index 000000000..d1824c6d5 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Producer.ocd/StringTblUS.txt @@ -0,0 +1 @@ +DescInteraction=Production diff --git a/planet/Objects.ocd/Libraries.ocd/RopePhysics.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/RopePhysics.ocd/Script.c index 7db116f73..4ba9ae676 100644 --- a/planet/Objects.ocd/Libraries.ocd/RopePhysics.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/RopePhysics.ocd/Script.c @@ -23,7 +23,7 @@ local Max_Length; func GetRopeGravity() { - return GetGravity()*Rope_Precision/500; + return GetGravity()*Rope_Precision/100; } /** Starts a rope diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/DefCore.txt index b15575911..6cab0c1a3 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/DefCore.txt +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/DefCore.txt @@ -2,7 +2,7 @@ id=Scoreboard_Death Version=5,2,0,1 Category=C4D_StaticBack|C4D_Rule -Picture=0,0,128,128 -Width=128 -Height=128 -Offset=-64,-64 +Picture=0,0,32,32 +Width=32 +Height=32 +Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Graphics.png index 4ba0d50c8..4bdba1dd1 100644 Binary files a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Graphics.png and b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Script.c index bce3846a5..173ccb4e0 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Death.ocd/Script.c @@ -15,21 +15,33 @@ local score_death_list; // Here the death count of all players is stored, access /*-- Callbacks --*/ +// called by the scoreboard, assigns a symbol to the scoreboard field +// used by Scoreboard_Relaunch too +public func ScoreboardCondition(x) +{ + if(GetType(x) != C4V_Int) return x; + + if(x == -1) return Rule_KillLogs; + return x; +} + protected func Initialize() { // Make sure it is a list. score_death_list = []; - // Set scoreboard death count caption. - SetScoreboardData(SBRD_Caption, GetDeathCol(), "{{Scoreboard_Death}}", SBRD_Caption); + // init scoreboard + Scoreboard->Init( + [{key = "deaths", title = Scoreboard_Death, sorted = true, desc = true, default = 0, priority = 75, conditional = Scoreboard_Death.ScoreboardCondition}] + ); return _inherited(...); } protected func InitializePlayer(int plr) { var plrid = GetPlayerID(plr); - // Create scoreboard death count entry for this player. + // Create scoreboard entry for this player, will only do it once score_death_list[plrid] = 0; - SetScoreboardData(plrid, GetDeathCol(), Format("%d", score_death_list[plrid]), score_death_list[plrid]); + Scoreboard->NewPlayerEntry(plr); return _inherited(plr, ...); } @@ -38,15 +50,12 @@ protected func RelaunchPlayer(int plr, int killer) var plrid = GetPlayerID(plr); // Modify scoreboard death count entry for this player. score_death_list[plrid]++; - SetScoreboardData(plrid, GetDeathCol(), Format("%d", score_death_list[plrid]), score_death_list[plrid]); + Scoreboard->SetPlayerData(plr, "deaths", score_death_list[plrid]); return _inherited(plr, killer, ...); } protected func RemovePlayer(int plr) { - var plrid = GetPlayerID(plr); - // Clear scoreboard death count entry for this player. - SetScoreboardData(plrid, GetDeathCol(), nil, nil); return _inherited(plr, ...); } @@ -56,6 +65,7 @@ public func SetDeathCount(int plr) { var plrid = GetPlayerID(plr); score_death_list[plrid] = 0; + Scoreboard->SetPlayerData(plr, "deaths", score_death_list[plrid]); return; } @@ -65,10 +75,4 @@ public func GetDeathCount(int plr) return score_death_list[plrid]; } -public func GetDeathCol() -{ - //return ScoreboardCol(Scoreboard_Death); - return 101; -} - local Name = "Scoreboard Deaths"; diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/DefCore.txt index d17825be5..956d1ab73 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/DefCore.txt +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/DefCore.txt @@ -2,7 +2,7 @@ id=Scoreboard_Kill Version=5,2,0,1 Category=C4D_StaticBack|C4D_Rule -Picture=0,0,128,128 -Width=128 -Height=128 -Offset=-64,-64 +Picture=0,0,32,32 +Width=32 +Height=32 +Offset=-16,-16 diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Graphics.png index 1d7d03d7b..ff851f2f7 100644 Binary files a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Graphics.png and b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Script.c index 7442718b9..a7b581de5 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Kill.ocd/Script.c @@ -19,17 +19,19 @@ protected func Initialize() { // Make sure it is a list. score_kill_list = []; - // Set scoreboard kill count caption. - SetScoreboardData(SBRD_Caption, GetKillCol(), "{{Scoreboard_Kill}}", SBRD_Caption); + // init scoreboard + Scoreboard->Init( + [{key = "kills", title = Scoreboard_Kill, sorted = true, desc = true, default = 0, priority = 50}] + ); return _inherited(...); } protected func InitializePlayer(int plr) { var plrid = GetPlayerID(plr); - // Create scoreboard kill count entry for this player. + // init scoreboard for player score_kill_list[plrid] = 0; - SetScoreboardData(plrid, GetKillCol(), Format("%d", score_kill_list[plrid]), score_kill_list[plrid]); + Scoreboard->NewPlayerEntry(plr); return _inherited(plr, ...); } @@ -44,15 +46,12 @@ protected func RelaunchPlayer(int plr, int killer) return _inherited(plr, killer, ...); // Modify scoreboard kill count entry for killer. score_kill_list[plrid]++; - SetScoreboardData(plrid, GetKillCol(), Format("%d", score_kill_list[plrid]), score_kill_list[plrid]); + Scoreboard->SetPlayerData(killer, "kills", score_kill_list[plrid]); return _inherited(plr, killer, ...); } protected func RemovePlayer(int plr) { - var plrid = GetPlayerID(plr); - // Clear scoreboard kill count entry for this player. - SetScoreboardData(plrid, GetKillCol(), nil, nil); return _inherited(plr, ...); } @@ -62,6 +61,7 @@ public func SetKillCount(int plr, int value) { var plrid = GetPlayerID(plr); score_kill_list[plrid] = value; + Scoreboard->SetPlayerData(plr, "kills", score_kill_list[plrid]); return; } @@ -75,13 +75,8 @@ public func DoKillCount(int plr, int value) { var plrid = GetPlayerID(plr); score_kill_list[plrid] += value; + Scoreboard->SetPlayerData(plr, "kills", score_kill_list[plrid]); return; } -public func GetKillCol() -{ - //return ScoreboardCol(Scoreboard_Kill); - return 107; -} - local Name = "Scoreboard Kills"; diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/DefCore.txt index e64603e44..7cae8997c 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/DefCore.txt +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/DefCore.txt @@ -2,7 +2,7 @@ id=Scoreboard_KillStreak Version=5,2,0,1 Category=C4D_StaticBack|C4D_Rule -Picture=0,0,128,128 -Width=128 -Height=128 -Offset=-64,-64 +Picture=0,0,32,32 +Width=32 +Height=32 +Offset=-16,-16 diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Graphics.png index 28bb8bbd4..1f85d9bdb 100644 Binary files a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Graphics.png and b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Script.c index 4ca9848c9..bd08ef644 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/KillStreak.ocd/Script.c @@ -19,17 +19,19 @@ protected func Initialize() { // Make sure it is a list. score_killstreak_list = []; - // Set scoreboard kill streak count caption. - SetScoreboardData(SBRD_Caption, GetKillStreakCol(), "{{Scoreboard_KillStreak}}", SBRD_Caption); + // init scoreboard + Scoreboard->Init( + [{key = "killstreaks", title = Scoreboard_KillStreak, sorted = true, desc = true, default = "", priority = 20}] + ); return _inherited(...); } protected func InitializePlayer(int plr) { var plrid = GetPlayerID(plr); - // Create scoreboard kill streak count entry for this player. + // make scoreboard entry for player score_killstreak_list[plrid] = 0; - SetScoreboardData(plrid, GetKillStreakCol(), Format("%d", score_killstreak_list[plrid]), score_killstreak_list[plrid]); + Scoreboard->NewPlayerEntry(plr); return _inherited(plr, ...); } @@ -37,10 +39,10 @@ protected func RelaunchPlayer(int plr, int killer) { var plrid = GetPlayerID(plr); var killerid = GetPlayerID(killer); - // Modify scoreboard kill streak count entry for killed player. + // reset scoreboard kill streak count entry for killed player. score_killstreak_list[plrid] = 0; - SetScoreboardData(plrid, GetKillStreakCol(), Format("%d", score_killstreak_list[plrid]), score_killstreak_list[plrid]); - // Only if killer exists and has not committed suicide. + Scoreboard->SetPlayerData(plr, "killstreaks", nil); +// Only if killer exists and has not committed suicide. if (plr == killer || !GetPlayerName(killer)) return _inherited(plr, killer, ...); // Only if killer and victim are on different teams. @@ -48,15 +50,12 @@ protected func RelaunchPlayer(int plr, int killer) return _inherited(plr, killer, ...); // Modify scoreboard kill streak count entry for killer. score_killstreak_list[killerid]++; - SetScoreboardData(killerid, GetKillStreakCol(), Format("%d", score_killstreak_list[killerid]), score_killstreak_list[killerid]); + Scoreboard->SetPlayerData(killer, "killstreaks", score_killstreak_list[killerid]); return _inherited(plr, killer, ...); } protected func RemovePlayer(int plr) { - var plrid = GetPlayerID(plr); - // Clear scoreboard kill streak count entry for this player. - SetScoreboardData(plrid, GetKillStreakCol(), nil, nil); return _inherited(plr, ...); } @@ -66,6 +65,7 @@ public func SetKillStreakCount(int plr, int value) { var plrid = GetPlayerID(plr); score_killstreak_list[plrid] = value; + Scoreboard->SetPlayerData(plr, "killstreaks", score_killstreak_list[plrid]); return; } @@ -79,13 +79,8 @@ public func DoKillStreakCount(int plr, int value) { var plrid = GetPlayerID(plr); score_killstreak_list[plrid] += value; + Scoreboard->SetPlayerData(plr, "killstreaks", score_killstreak_list[plrid]); return; } -public func GetKillStreakCol() -{ - //return ScoreboardCol(Scoreboard_KillStreak); - return 109; -} - local Name = "Scoreboard Kill streaks"; diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/DefCore.txt deleted file mode 100644 index d76950a12..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/DefCore.txt +++ /dev/null @@ -1,8 +0,0 @@ -[DefCore] -id=Scoreboard_Player -Version=5,2,0,1 -Category=C4D_StaticBack|C4D_Rule -Picture=0,0,128,128 -Width=128 -Height=128 -Offset=-64,-64 diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/Graphics.png deleted file mode 100644 index 4df4a928a..000000000 Binary files a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/Script.c deleted file mode 100644 index 8f8fa4af0..000000000 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Player.ocd/Script.c +++ /dev/null @@ -1,41 +0,0 @@ -/*-- - Modular scoreboard: Players - Author: Maikel - - This script can be included to create a player column in the scoreboard. - Make sure that the following functions return _inherited(...); - * Initialize(); - * InitializePlayer(int plr); - * RelaunchPlayer(int plr, int killer); - * RemovePlayer(int plr); ---*/ - - -/*-- Callbacks --*/ - -protected func Initialize() -{ - // Set general scoreboard caption. - SetScoreboardData(SBRD_Caption, SBRD_Caption, "Scoreboard", SBRD_Caption); - return _inherited(...); -} - -protected func InitializePlayer(int plr) -{ - var plrid = GetPlayerID(plr); - // Create scoreboard player entry for this player (its name). - SetScoreboardData(plrid, SBRD_Caption, GetTaggedPlayerName(plr), plrid); - return _inherited(plr, ...); -} - -protected func RemovePlayer(int plr) -{ - var plrid = GetPlayerID(plr); - // Clear scoreboard player entry for this player. - SetScoreboardData(plrid, SBRD_Caption, nil, nil); - return _inherited(plr, ...); -} - -/*-- Misc --*/ - -local Name = "Scoreboard Players"; diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/DefCore.txt index db8575985..99c6ed7a7 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/DefCore.txt +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/DefCore.txt @@ -2,7 +2,7 @@ id=Scoreboard_Relaunch Version=5,2,0,1 Category=C4D_StaticBack|C4D_Rule -Picture=0,0,128,128 -Width=128 -Height=128 -Offset=-64,-64 +Picture=0,0,32,32 +Width=32 +Height=32 +Offset=-16,-16 diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Graphics.png index 9916e556b..03451ccc1 100644 Binary files a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Graphics.png and b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c index d03f3b88a..03ff2bebc 100644 --- a/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Scoreboard.ocd/Relaunch.ocd/Script.c @@ -13,23 +13,33 @@ local score_relaunch_list; // Here the relaunch count of all players is stored, access through plrid. +// Overload this. +public func RelaunchCount() +{ + return 5; +} + /*-- Callbacks --*/ protected func Initialize() { // Make sure it is a list. score_relaunch_list = []; - // Set scoreboard relaunch count caption. - SetScoreboardData(SBRD_Caption, GetRelaunchCol(), "{{Scoreboard_Relaunch}}", SBRD_Caption); + // init scoreboard + // init scoreboard, uses the condition of Scoreboard_Deaths too + Scoreboard->Init( + [{key = "relaunches", title = Scoreboard_Relaunch, sorted = true, desc = true, default = "", priority = 75, conditional = Scoreboard_Death.ScoreboardCondition}] + ); return _inherited(...); } protected func InitializePlayer(int plr) { var plrid = GetPlayerID(plr); - // Create scoreboard relaunch count entry for this player. + // create scoreboard entry score_relaunch_list[plrid] = RelaunchCount(); - SetScoreboardData(plrid, GetRelaunchCol(), Format("%d", score_relaunch_list[plrid]), score_relaunch_list[plrid]); + Scoreboard->NewPlayerEntry(plr); + Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); return _inherited(plr, ...); } @@ -38,15 +48,12 @@ protected func RelaunchPlayer(int plr, int killer) var plrid = GetPlayerID(plr); // Modify scoreboard relaunch count entry for this player. score_relaunch_list[plrid]--; - SetScoreboardData(plrid, GetRelaunchCol(), Format("%d", score_relaunch_list[plrid]), score_relaunch_list[plrid]); + Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); return _inherited(plr, killer, ...); } protected func RemovePlayer(int plr) { - var plrid = GetPlayerID(plr); - // Clear scoreboard relaunch count entry for this player. - SetScoreboardData(plrid, GetRelaunchCol(), nil, nil); return _inherited(plr, ...); } @@ -56,6 +63,7 @@ public func SetRelaunchCount(int plr, int value) { var plrid = GetPlayerID(plr); score_relaunch_list[plrid] = value; + Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); return; } @@ -69,19 +77,8 @@ public func DoRelaunchCount(int plr, int value) { var plrid = GetPlayerID(plr); score_relaunch_list[plrid] += value; + Scoreboard->SetPlayerData(plr, "relaunches", score_relaunch_list[plrid]); return; } -public func GetRelaunchCol() -{ - //return ScoreboardCol(Scoreboard_Relaunch); - return 103; -} - -// Overload this. -public func RelaunchCount() -{ - return 5; -} - local Name = "Scoreboard Relaunches"; diff --git a/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/Script.c index 1198a8f56..db0732d45 100644 --- a/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/Script.c @@ -12,6 +12,7 @@ To take one object of the stack, call TakeObject(). As long as the object exists, one can always take an object, even if it is the last one (self). This object is always outside. + Infinite stackable count can by achieved using SetInfiniteStackCount. On entrance (or to be more precise: on RejectEntrance), it will be checked if the entering stackable object can be distributed over the other objects @@ -37,7 +38,19 @@ --*/ -local count; +local count, count_is_infinite; + +// Max size of stack +static const Stackable_Max_Count = 999; + +// What GetStackCount should return if the count is set to infinite +// Set this to a fairly large number and not e.g. -1, so naive +// implementations that update their graphics by GetStackCount() show a +// bunch of items. However, the number shouldn't be too large so the +// object doesn't get overly heavy. +// Note that count_is_infinite is a separate variable, so we can support +// stacks >999 but GetID() != GetID()) return 0; + // Infinite stacks can always take everything + if (IsInfiniteStackCount()) return obj->GetStackCount(); + if (obj->~IsInfiniteStackCount()) + { + SetInfiniteStackCount(); + return obj->GetStackCount(); + } + var howmany = Min(obj->GetStackCount(), MaxStackCount() - GetStackCount()); - if (count + howmany > 999) + if (count + howmany > Stackable_Max_Count) return 0; SetStackCount(count + howmany); @@ -65,8 +87,20 @@ public func Stack(object obj) public func SetStackCount(int amount) { - count = BoundBy(amount, 0, 999); - Update(); + count = BoundBy(amount, 0, Stackable_Max_Count); + count_is_infinite = false; + UpdateStackDisplay(); + return true; +} + +public func IsInfiniteStackCount() { return count_is_infinite; } + +public func SetInfiniteStackCount() +{ + count = Stackable_Infinite_Count; + count_is_infinite = true; + UpdateStackDisplay(); + return true; } public func TakeObject() @@ -78,15 +112,15 @@ public func TakeObject() } else if (count > 1) { - SetStackCount(count - 1); + if (!count_is_infinite) SetStackCount(count - 1); var take = CreateObject(GetID(), 0, 0, GetOwner()); take->SetStackCount(1); - Update(); + if (!count_is_infinite) UpdateStackDisplay(); return take; } } -public func Update() +public func UpdateStackDisplay() { UpdatePicture(); UpdateMass(); @@ -109,38 +143,54 @@ public func Update() private func UpdatePicture() { - var one = GetStackCount() % 10; - var ten = (GetStackCount() / 10) % 10; - var hun = (GetStackCount() / 100) % 10; - + // Put a small number showing the stack count in the bottom right + // corner of the picture var s = 400; var yoffs = 14000; var xoffs = 22000; var spacing = 14000; - - if (hun > 0) - { - SetGraphics(Format("%d", hun), Icon_Number, 10, GFXOV_MODE_Picture); - SetObjDrawTransform(s, 0, xoffs - 2 * spacing, 0, s, yoffs, 10); - } - else - SetGraphics(nil, nil, 10); - if (ten > 0 || hun > 0) + if (count_is_infinite) { - SetGraphics(Format("%d", ten), Icon_Number, 11, GFXOV_MODE_Picture); - SetObjDrawTransform(s, 0, xoffs - spacing, 0, s, yoffs, 11); + SetGraphics(nil, nil, 10); + SetGraphics(nil, nil, 11); + SetGraphics("Inf", Icon_Number, 12, GFXOV_MODE_Picture); + SetObjDrawTransform(s, 0, xoffs, 0, s, yoffs, 12); } else - SetGraphics(nil, nil, 11); + { + var one = GetStackCount() % 10; + var ten = (GetStackCount() / 10) % 10; + var hun = (GetStackCount() / 100) % 10; - SetGraphics(Format("%d", one), Icon_Number, 12, GFXOV_MODE_Picture); - SetObjDrawTransform(s, 0, xoffs, 0, s, yoffs, 12); + if (hun > 0) + { + SetGraphics(Format("%d", hun), Icon_Number, 10, GFXOV_MODE_Picture); + SetObjDrawTransform(s, 0, xoffs - 2 * spacing, 0, s, yoffs, 10); + } + else + SetGraphics(nil, nil, 10); + + if (ten > 0 || hun > 0) + { + SetGraphics(Format("%d", ten), Icon_Number, 11, GFXOV_MODE_Picture); + SetObjDrawTransform(s, 0, xoffs - spacing, 0, s, yoffs, 11); + } + else + SetGraphics(nil, nil, 11); + + SetGraphics(Format("%d", one), Icon_Number, 12, GFXOV_MODE_Picture); + SetObjDrawTransform(s, 0, xoffs, 0, s, yoffs, 12); + } + return _inherited(...); } private func UpdateName() { - SetName(Format("%dx %s", GetStackCount(), GetID()->GetName())); + if (IsInfiniteStackCount()) + SetName(Format("$Infinite$ %s", GetID()->GetName())); + else + SetName(Format("%dx %s", GetStackCount(), GetID()->GetName())); } private func UpdateMass() @@ -195,6 +245,18 @@ private func TryPutInto(object into) } } - Update(); + UpdateStackDisplay(); return false; } + +// Save stack counts in saved scenarios +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + props->Remove("Name"); + if (IsInfiniteStackCount()) + props->AddCall("Stack", this, "SetInfiniteStackCount"); + else if (GetStackCount() != MaxStackCount()) + props->AddCall("Stack", this, "SetStackCount", GetStackCount()); + return true; +} diff --git a/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/StringTblDE.txt new file mode 100644 index 000000000..08b6e732d --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Infinite=Endlos \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/StringTblUS.txt new file mode 100644 index 000000000..54faa6511 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Stackable.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Infinite=Infinite \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Structure.ocd/DefCore.txt b/planet/Objects.ocd/Libraries.ocd/Structure.ocd/DefCore.txt new file mode 100644 index 000000000..298ed3eab --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Structure.ocd/DefCore.txt @@ -0,0 +1,4 @@ +[DefCore] +id=Library_Structure +Version=5,2,2,0 +Category=C4D_StaticBack \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Structure.ocd/Graphics.png b/planet/Objects.ocd/Libraries.ocd/Structure.ocd/Graphics.png new file mode 100644 index 000000000..9bb8607e9 Binary files /dev/null and b/planet/Objects.ocd/Libraries.ocd/Structure.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/Structure.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Structure.ocd/Script.c new file mode 100644 index 000000000..f577724d8 --- /dev/null +++ b/planet/Objects.ocd/Libraries.ocd/Structure.ocd/Script.c @@ -0,0 +1,30 @@ +/** + Structure Library + Basic library for structures, handles: + * Damage + * Energy bar if rule active + + @author Maikel +*/ + +func Initialize() +{ + if (ObjectCount(Find_ID(Rule_EnergyBarsAboveStructures)) > 0) + { + if (this.HitPoints != nil) + AddEnergyBar(); + } + return _inherited(...); +} + +public func Damage(int change, int cause, int cause_plr) +{ + // Only do stuff if the object has the HitPoints property. + if (this && this.HitPoints != nil) + if (GetDamage() >= this.HitPoints) + { + // Destruction callback is made by the engine. + return RemoveObject(); + } + return _inherited(change, cause, cause_plr); +} \ No newline at end of file diff --git a/planet/Objects.ocd/Libraries.ocd/Tank.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Tank.ocd/Script.c index 8d9c9082d..5406cfbca 100644 --- a/planet/Objects.ocd/Libraries.ocd/Tank.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Tank.ocd/Script.c @@ -59,3 +59,21 @@ public func LiquidInput(string sznMaterial, int inMaxAmount, object pnPump, obje iLiquidAmount += inMaxAmount; return inMaxAmount; } + +// Set tank liquid type and amount directly +public func SetLiquid(string szNewLiquid, int iNewLiquidAmount) +{ + szLiquid = szNewLiquid; + iLiquidAmount = iNewLiquidAmount; + return true; +} + + +// Scenario saving of liquid fill levels +// Untested. This library is not used. Plus it's called "Libary_Tank" o_O +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (szLiquid) props->AddCall("Tank", this, "SetLiquid", Format("%v", szLiquid), iLiquidAmount); + return true; +} diff --git a/planet/Objects.ocd/Rules.ocd/BuyAtFlagpole.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/BuyAtFlagpole.ocd/Graphics.png index dc2070c5c..0b03b8697 100644 Binary files a/planet/Objects.ocd/Rules.ocd/BuyAtFlagpole.ocd/Graphics.png and b/planet/Objects.ocd/Rules.ocd/BuyAtFlagpole.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/Energy.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/Energy.ocd/Graphics.png deleted file mode 100644 index 65e28c949..000000000 Binary files a/planet/Objects.ocd/Rules.ocd/Energy.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Rules.ocd/Energy.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Energy.ocd/StringTblDE.txt deleted file mode 100644 index 33a41729e..000000000 --- a/planet/Objects.ocd/Rules.ocd/Energy.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Strombedarf -Description=Stromverbraucher müssen durch Stromkabel mit Stromerzeugern verbunden sein. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Energy.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Energy.ocd/StringTblUS.txt deleted file mode 100644 index 3432cf07f..000000000 --- a/planet/Objects.ocd/Rules.ocd/Energy.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Power need -Description=Power consumers need to be connected to a power source using power lines. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/DefCore.txt new file mode 100644 index 000000000..7697ce954 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Rule_EnergyBarsAboveStructures +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Rule +Picture=0,0,64,64 diff --git a/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/Graphics.png new file mode 100644 index 000000000..1b3fde096 Binary files /dev/null and b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/Energy.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/Script.c similarity index 62% rename from planet/Objects.ocd/Rules.ocd/Energy.ocd/Script.c rename to planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/Script.c index bc2c10a37..fd2d4f76f 100644 --- a/planet/Objects.ocd/Rules.ocd/Energy.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/Script.c @@ -1,4 +1,8 @@ -/*-- Power usage --*/ +/*-- energy bars above buildings --*/ + +/* + The energy bar itself is created in the structure library. +*/ protected func Activate(int iByPlayer) { diff --git a/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/StringTblDE.txt new file mode 100644 index 000000000..a31c2a0ad --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Energiebalken über Gebäuden +Description=Gebäude zeigen ihren Schaden in Energiebalken an. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/StringTblUS.txt new file mode 100644 index 000000000..e3c2c5c61 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/EnergyBarsAboveStructures.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Energy bar above buildings +Description=Buildings show their damage with energy bars above them. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Energy.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/DefCore.txt similarity index 79% rename from planet/Objects.ocd/Rules.ocd/Energy.ocd/DefCore.txt rename to planet/Objects.ocd/Rules.ocd/Gravestones.ocd/DefCore.txt index c3108738c..a70af0c66 100644 --- a/planet/Objects.ocd/Rules.ocd/Energy.ocd/DefCore.txt +++ b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/DefCore.txt @@ -1,5 +1,5 @@ [DefCore] -id=Rule_EnergyNeed +id=Rule_Gravestones Version=5,2,0,1 Category=C4D_StaticBack|C4D_Rule Picture=0,0,64,64 diff --git a/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/Graphics.png new file mode 100644 index 000000000..da49dfa40 Binary files /dev/null and b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/Script.c new file mode 100644 index 000000000..d90f9abad --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/Script.c @@ -0,0 +1,63 @@ +/*-- Gravestones --*/ + + +protected func Initialize() +{ + // Under no circumstance there may by multiple copies of this rule. + if (ObjectCount(Find_ID(Rule_Gravestones)) > 1) + return RemoveObject(); + return; +} + + +public func OnClonkDeath(object clonk) +{ + if (!clonk->GetAlive()) + AddEffect("AddGravestone", clonk, 1, 1, this); + return; +} + +public func FxAddGravestoneTimer(object target, proplist effect, int timer) +{ + // Wait for the death animation to be over. + if (timer >= 20) + { + AddEffect("IntGravestone", target, 1, nil, this); + return -1; + } +} + +public func FxIntGravestoneStart(object clonk, proplist effect) +{ + effect.grave = clonk->CreateObject(Clonk_Grave, 0, 0, clonk->GetController()); + clonk->Enter(effect.grave); + + //smoke effect + var particles = + { + Prototype = Particles_Dust(), + R = 200, + G = 100, + B = 50, + Size = PV_KeyFrames(0, 0, 0, 300, 40, 1000, 15) + }; + effect.grave->CreateParticle("Dust", 0, 0, PV_Random(-3, 3), PV_Random(-3, 3), PV_Random(18, 1 * 36), particles, 6); +} + +public func FxIntGravestoneStop(object clonk, proplist effect, int reason) +{ + if (reason != FX_Call_RemoveClear) + { + clonk->Exit(); + effect.grave->RemoveObject(); + } +} + +protected func Activate(int iByPlayer) +{ + MessageWindow(GetProperty("Description"), iByPlayer); + return true; +} + +local Name = "$Name$"; +local Description = "$Description$"; diff --git a/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/StringTblDE.txt new file mode 100644 index 000000000..7b2366baa --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Grabsteine +Description=Ein Grabstein wird errichtet wenn ein Clonk stirbt. Er wird mit einer Grabinschrift versehen. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/StringTblUS.txt new file mode 100644 index 000000000..d430c45b1 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/Gravestones.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Gravestones +Description=Gravestones are created to cover a clonk's corpse, providing monuments for the dead. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Graphics.png index d49b65527..c64f0da1a 100644 Binary files a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Graphics.png and b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c index 004986935..ee0a6081b 100644 --- a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/Script.c @@ -23,6 +23,9 @@ func OnClonkDeath(object clonk, int killed_by) return _inherited(clonk, killed_by, ...); } +// parameters: clonk, owner, killed_by +global func GetAdditionalPlayerRelaunchString(){return _inherited(...);} // dummy + func OnClonkDeathEx(object clonk, int plr, int killed_by) { if(!GetPlayerName(plr)) return; @@ -82,6 +85,11 @@ func OnClonkDeathEx(object clonk, int plr, int killed_by) log=Format("%s %s", log, other); } + // also allow global callback function to add to death messages + other = GetAdditionalPlayerRelaunchString(clonk, plr, killed_by); + if(other) + log = Format("%s, %s", log, other); + Log(log); } diff --git a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/StringTblUS.txt index 01e8c6ddf..97b7075c5 100644 --- a/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Rules.ocd/Killlogs.ocd/StringTblUS.txt @@ -1,5 +1,5 @@ Name=Kill logs -Description=When this rule is activated, the deaths of the players' are announced in the log. +Description=When this rule is activated, the deaths of the players are announced in the log. Selfkill1=%s killed his own %s. Selfkill2=%s didn't like his %s any more. @@ -7,8 +7,8 @@ Selfkill3=%s committed suicide! Poor %s. KilledByPlayer1=%s has lost his %s to %s. KilledByPlayer2=%s's %s couldn't do anything against %s. KilledByPlayer3=%s's %s was not able to defeat %s. -KilledByGaya1=%s has got one %s spirited away. -KilledByGaya2=%s's %s dies on its own. +KilledByGaya1=%s's %s was spirited away. +KilledByGaya2=%s's %s died on its own. KilledByGaya3=%s lost a %s to Gaya. Teamkill1=%s has lost a %s to %s. Teamkiller! Teamkill2=%s's %s fell out of %s's favour. diff --git a/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/DefCore.txt new file mode 100644 index 000000000..4af1fbbe4 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=Rule_NoPowerNeed +Version=5,2,0,1 +Category=C4D_StaticBack|C4D_Rule +Picture=0,0,64,64 diff --git a/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/Graphics.png new file mode 100644 index 000000000..0bf5cf27f Binary files /dev/null and b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/Script.c new file mode 100644 index 000000000..6c4a0f6e6 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/Script.c @@ -0,0 +1,100 @@ +/*-- Power usage --*/ + +func Initialize() +{ + // we are not the first? + if(ObjectCount(Find_ID(GetID())) != 1) return; + + // no power consumers yet, nothing to be done + if(Library_Power_power_compounds == nil) return; + + // update all consumers forcefully + var remember = []; + + // get all power compounds (bases) + for(var base in Library_Power_power_compounds) + { + // iterate through all registered consumers & producers + // these are not the sleeping power links! + for(var i = GetLength(base.power_links) - 1; i >= 0; --i) + { + var obj_data = base.power_links[i]; + if(obj_data == nil) continue; + // is a power producer? + if(!obj_data.obj->~CurrentlyHasPower()) continue; + if(obj_data.amount > 0) continue; + + // temporarily stop consuming power to make sure the callback order is correct + obj_data.obj->~OnNotEnoughPower(); + + // power consumer behavior + var lpr = obj_data.obj.PowerConsumer_last_power_request; + obj_data.obj.PowerConsumer_last_power_request = 0; + var lpr_a = obj_data.obj.PowerConsumer_last_power_request_amount; + obj_data.obj.PowerConsumer_last_power_request_amount = 0; + + // remove from list + RemoveArrayIndexUnstable(base.power_links, i); + + // make new power consumer later + PushBack(remember, {obj = obj_data.obj, amount = lpr_a}); + } + + // now awake the sleeping links (later) + for(var i = GetLength(base.sleeping_links) - 1; i >= 0; --i) + { + var obj_data = base.sleeping_links[i]; + PushBack(remember, {obj = obj_data.obj, amount = obj_data.amount}); + } + + base.sleeping_links = []; + } + + // let all remembered consumers consume again! + for(var obj_data in remember) + { + if(obj_data == nil) continue; + obj_data.obj->MakePowerConsumer(Abs(obj_data.amount)); + } +} + +func Destruction() +{ + // we are not the last? + if(ObjectCount(Find_ID(GetID())) != 1) return; + + // schedule the call so that the removal is complete + Schedule(nil, "Rule_NoPowerNeed->DestructionEx()", 1); +} + +func DestructionEx() +{ + // we were not the last? + if(ObjectCount(Find_ID(Rule_NoPowerNeed)) != 0) return; + + // update consumers again + // go through all existing consumers and see whether they are consuming atm + for(var obj in FindObjects(Find_Func("IsPowerConsumer"))) + { + var last_request = obj.PowerConsumer_last_power_request; + var last_amount = obj.PowerConsumer_last_power_request_amount; + + // had not requested power aka "is not running" + if(last_request == PowerConsumer_LPR_None) continue; + // temporarily stop consuming power to make sure the callback order is correct + obj->OnNotEnoughPower(); + + obj.PowerConsumer_last_power_request = PowerConsumer_LPR_None; + obj.PowerConsumer_last_power_request_amount = 0; + obj->MakePowerConsumer(last_amount); + } +} + +protected func Activate(int iByPlayer) +{ + MessageWindow(GetProperty("Description"), iByPlayer); + return true; +} + +local Name = "$Name$"; +local Description = "$Description$"; diff --git a/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/StringTblDE.txt b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/StringTblDE.txt new file mode 100644 index 000000000..d9c85a91e --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Kein Strombedarf +Description=Stromverbraucher benötigen keinen Strom mehr. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/StringTblUS.txt new file mode 100644 index 000000000..bc86b4394 --- /dev/null +++ b/planet/Objects.ocd/Rules.ocd/NoEnergy.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=No power need +Description=Power consuming buildings function without power. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/DefCore.txt index 74a5c634b..04929cc2f 100644 --- a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/DefCore.txt +++ b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/DefCore.txt @@ -5,4 +5,3 @@ Category=C4D_StaticBack|C4D_Rule Width=1 Height=1 Picture=0,0,64,64 -TimerCall=Timer diff --git a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Graphics.png index 1e5e94e08..35ad633c0 100644 Binary files a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Graphics.png and b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Script.c b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Script.c index 6e428773b..5763531ef 100644 --- a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Script.c +++ b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/Script.c @@ -29,6 +29,7 @@ protected func Initialize() return RemoveObject(); } fade_time = 18; // 18, because the timer will check once per second, so it's aproximately a second. + AddTimer("Timer"); } protected func Timer() @@ -39,7 +40,7 @@ protected func Timer() continue; if (fade->GetEffect("IntFadeOut", fade)) continue; - if (GBackSolid(AbsX(fade->GetX()), AbsY(fade->GetY()))) + if (fade->Stuck()) continue; if (fade->~HasNoFadeOut()) continue; diff --git a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/StringTblUS.txt b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/StringTblUS.txt index d1e3883a7..d6244fe3f 100644 --- a/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Rules.ocd/ObjectFade.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Fading objects -Description=When this rule is activated, dropped objects fade out over time \ No newline at end of file +Description=When this rule is activated, dropped objects fade away after a certain amount of time. \ No newline at end of file diff --git a/planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.png index 1e5e94e08..d725b854d 100644 Binary files a/planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.png and b/planet/Objects.ocd/Rules.ocd/Restart.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/DefCore.txt b/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/DefCore.txt index 23cd65de1..c01aa6625 100644 --- a/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/DefCore.txt +++ b/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/DefCore.txt @@ -2,4 +2,4 @@ id=Rule_TeamAccount Version=4,10,0,0 Category=C4D_StaticBack|C4D_Rule -Picture=0,0,128,128 +Picture=0,0,64,64 diff --git a/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/Graphics.png b/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/Graphics.png index 42102deca..1fe0cb9a4 100644 Binary files a/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/Graphics.png and b/planet/Objects.ocd/Rules.ocd/TeamAccount.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/Armory.material b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Armory.material new file mode 100644 index 000000000..06df29c0d --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Armory.material @@ -0,0 +1,36 @@ +// Armory genrated by blender2ogre 0.5.8 + +material Armory +{ + receive_shadows off + + technique + { + pass Armory + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0 + specular 0.0 0.0 0.0 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + + scene_blend alpha_blend + depth_write on + cull_hardware none + + texture_unit + { + texture Armory.png + tex_address_mode wrap + scale 1.0 1.0 + colour_op alpha_blend + } + + texture_unit Light + { + // apply lighting + colour_op_ex modulate src_current src_diffuse + alpha_op_ex modulate src_current src_diffuse + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/Armory.png b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Armory.png new file mode 100644 index 000000000..1673c439c Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Armory.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Armory.ocd/DefCore.txt new file mode 100644 index 000000000..0ab579d26 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Armory.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Armory +Version=5,2,90,21 +Category=C4D_Structure +Width=95 +Height=52 +Offset=-47,-26 +Vertices=6 +VertexX=-1,20,30,-43,-43,0 +VertexY=-13,-15,-14,24,24,24 +VertexFriction=50,50,50,100,100,100 +Value=200 +Mass=4500 +Components=Wood=3;Metal=2;Loam=2 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Graphics.mesh new file mode 100644 index 000000000..161031fe9 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Script.c new file mode 100644 index 000000000..8328fa35d --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Armory.ocd/Script.c @@ -0,0 +1,80 @@ +/*-- Armory --*/ + +#include Library_Structure +#include Library_Ownable +#include Library_Producer + +local hold_production; + +func Construction(object creator) +{ + SetAction("Default"); + this.MeshTransformation = Trans_Rotate(RandomX(0, 20), 0, 1, 0); + return _inherited(creator, ...); +} + +/*-- Production --*/ + +public func IsProduct(id product_id) +{ + return product_id->~IsArmoryProduct(); +} + +private func ProductionTime(id toProduce) { return 100; } +private func PowerNeed() { return 100; } + +public func OnProductionStart(id product) +{ + AddEffect("Working", this, 100, 1, this); + hold_production = false; +} + +public func OnProductionHold(id product) +{ + hold_production = true; +} + +public func OnProductionContinued(id product) +{ + hold_production = false; +} + +public func OnProductionFinish(id product) +{ + RemoveEffect("Working", this); +} + +protected func FxWorkingTimer() +{ + if(!hold_production) + Smoking(); +} + +private func Smoking() +{ + var x = 8; + var y = -17; + if (!Random(2)) + Smoke(x,y + 4,20); + if(!Random(2)) + CreateParticle("Fire", PV_Random(x-1, x+1), PV_Random(y-2, y+2), 0, PV_Random(-1, 0), PV_Random(18, 36), Particles_Fire(), 2); +} + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Default", + }, +}; + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Armory.ocd/StringTblDE.txt new file mode 100644 index 000000000..77c6455ea --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Armory.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=Keine Baupläne vorhanden +Construction=Konstruktion +Production=Produktion +Name=Waffenschmiede +Description=Zur Herstellung von kleinen und großen Waffen. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Armory.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Armory.ocd/StringTblUS.txt new file mode 100644 index 000000000..2137ea64d --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Armory.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=No construction plans +Construction=Construction +Production=Production +Name=Armory +Description=This is where weapons are produced, both large and small. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/DefCore.txt new file mode 100644 index 000000000..e8c592352 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=ChemicalLab +Version=5,2,90,21 +Category=C4D_Structure +Width=50 +Height=52 +Offset=-25,-26 +Vertices=6 +VertexX=-1,10,20,-23,-23,0 +VertexY=-17,-25,-14,25,25,25 +VertexFriction=50,50,50,100,100,100 +Value=200 +Mass=4500 +Components=Wood=3;Metal=3 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Graphics.mesh new file mode 100644 index 000000000..2dfd659c5 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Scene.material new file mode 100644 index 000000000..b087345e9 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Scene.material @@ -0,0 +1,18 @@ +material Chemlab +{ + receive_shadows on + technique + { + pass + { + diffuse 1.0 1.0 1.0 1.0 + scene_blend alpha_blend + texture_unit + { + texture chemtex.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Script.c new file mode 100644 index 000000000..04b13026f --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/Script.c @@ -0,0 +1,84 @@ +/*-- Chemical Lab --*/ + +#include Library_Structure +#include Library_Ownable +#include Library_Producer + +local hold_production; + +func Construction(object creator) +{ + SetAction("Default"); + return _inherited(creator, ...); +} + +/*-- Production --*/ + +public func IsProduct(id product_id) +{ + return product_id->~IsChemicalProduct(); +} + +private func ProductionTime(id toProduce) { return 100; } +private func PowerNeed() { return 100; } + +public func NeedRawMaterial(id rawmat_id) +{ + return true; +} + +public func OnProductionStart(id product) +{ + AddEffect("Working", this, 100, 1, this); + hold_production = false; + Sound("Boiling", false, nil, nil, 1); +} + +public func OnProductionHold(id product) +{ + hold_production = true; + Sound("Boiling", false, nil, nil, -1); + Sound("Blowout"); +} + +public func OnProductionContinued(id product) +{ + hold_production = false; + Sound("Boiling", false, nil, nil, 1); +} + +public func OnProductionFinish(id product) +{ + RemoveEffect("Working", this); + Sound("Boiling", false, nil, nil, -1); +} + +protected func FxWorkingTimer() +{ + if(!hold_production) + Smoking(); +} + +private func Smoking() +{ + Smoke(-10, -40, 6); +} + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Default", + }, +}; + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/StringTblDE.txt new file mode 100644 index 000000000..97b895656 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=Keine Baupläne vorhanden +Construction=Konstruktion +Production=Produktion +Name=Chemielabor +Description=Produktionsort von chemischen Produkten, wie Sprengmaterial. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/StringTblUS.txt new file mode 100644 index 000000000..8ddcb2554 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=No construction plans +Construction=Construction +Production=Production +Name=Chemical lab +Description=Production site for chemical products like explosives. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/chemtex.png b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/chemtex.png new file mode 100644 index 000000000..264f32acc Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/ChemicalLab.ocd/chemtex.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestClose.ogg b/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestClose.ogg index e2d598d1b..c5d42a67f 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestClose.ogg and b/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestClose.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestOpen.ogg b/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestOpen.ogg index c5cf15fa5..eebb183c5 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestOpen.ogg and b/planet/Objects.ocd/Structures.ocd/Chest.ocd/ChestOpen.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Chest.ocd/Scene.material index 51a840cfd..aa5f8d143 100644 --- a/planet/Objects.ocd/Structures.ocd/Chest.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/Chest.ocd/Scene.material @@ -32,7 +32,7 @@ material Chest emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture chest.png + texture chest.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Chest.ocd/Script.c index da266265a..9fe7bffd9 100644 --- a/planet/Objects.ocd/Structures.ocd/Chest.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Chest.ocd/Script.c @@ -6,27 +6,39 @@ */ -local chestanim; +#include Library_Structure + +local is_open; protected func Construction() { - chestanim = PlayAnimation("Open", 1, Anim_Linear(0, 0, 1, 20, ANIM_Hold), Anim_Const(1000)); + PlayAnimation("Open", 1, Anim_Linear(0, 0, 1, 20, ANIM_Hold), Anim_Const(1000)); SetProperty("MeshTransformation",Trans_Rotate(RandomX(20,80),0,1,0)); + is_open = false; return _inherited(...); } /*-- Contents --*/ public func IsContainer() { return true; } +public func IsInteractable() { return true; } private func MaxContentsCount() { - return 5; + return 25; } + +// Open contentsmenu via interaction +public func Interact(object clonk, int mode) +{ + // Interaction does the same as the content control. + clonk->ObjectControl(clonk->GetOwner(), CON_Contents); +} + protected func RejectCollect() { - if (ContentsCount() >= MaxContentsCount()) + if (ContentsCount() >= this->MaxContentsCount()) return true; return false; } @@ -44,19 +56,28 @@ public func OnContentMenuClosed() private func Open() { - chestanim = PlayAnimation("Open", 5, Anim_Linear(0, 0, GetAnimationLength("Open"), 22, ANIM_Hold), Anim_Const(1000)); + if (is_open) + return; + is_open = true; + PlayAnimation("Open", 5, Anim_Linear(0, 0, GetAnimationLength("Open"), 22, ANIM_Hold), Anim_Const(1000)); Sound("ChestOpen"); } private func Close() { + if (!is_open) + return; + is_open = false; PlayAnimation("Close", 5, Anim_Linear(0, 0, GetAnimationLength("Close"), 15, ANIM_Hold), Anim_Const(1000)); Sound("ChestClose"); } +public func NoConstructionFlip() { return true; } + protected func Definition(def) { - SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,-3000,-5000), Trans_Rotate(-30,1,0,0), Trans_Rotate(30,0,1,0), Trans_Translate(1000,1,0)),def); + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,-3000,-5000), Trans_Rotate(-30,1,0,0), Trans_Rotate(30,0,1,0), Trans_Translate(1000,1,0)),def); } local Name = "$Name$"; +local HitPoints = 50; diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblDE.txt index e1a20cf44..a8e232135 100644 --- a/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblDE.txt @@ -1,3 +1 @@ -Name=Truhe -OpenChest=Truhe öffnen -CloseChest=Truhe schließen +Name=Truhe \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblUS.txt index c66dc0110..62034f01c 100644 --- a/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Chest.ocd/StringTblUS.txt @@ -1,3 +1 @@ -Name=Chest -OpenChest=Open chest -CloseChest=Close chest +Name=Chest \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/chest.jpg b/planet/Objects.ocd/Structures.ocd/Chest.ocd/chest.jpg new file mode 100644 index 000000000..08b7461ed Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Chest.ocd/chest.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Chest.ocd/chest.png b/planet/Objects.ocd/Structures.ocd/Chest.ocd/chest.png deleted file mode 100644 index c28ebb542..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Chest.ocd/chest.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/DefCore.txt index 80f31c3aa..576d58782 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/DefCore.txt @@ -14,6 +14,3 @@ Components=Compensatory_BurningBattery=1 Projectile=1 Rotate=1 NoStabilize=1 -Timer=2 -TimerCall=DoSmoke - diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/Script.c index bfda4154f..a0af107f0 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/BurningBattery.ocd/Script.c @@ -11,6 +11,7 @@ local time; func Initialize() { SetRDir(RandomX(-200, 200)); + AddTimer("DoSmoke", 2); } func Hit() @@ -21,5 +22,5 @@ func Hit() func DoSmoke() { ++time; - CreateParticle("ExploSmokeFastFade", RandomX(-5,5), RandomX(-5,5), 0, 0, Max(10, 300 - time * 5), RGB(100, 100, 100)); + Smoke(RandomX(-5, 5), RandomX(-5, 5), 2); } \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/ChargeShower.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/ChargeShower.ocd/Script.c index 4acf6e3ec..e6ccd7365 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/ChargeShower.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/ChargeShower.ocd/Script.c @@ -70,4 +70,6 @@ public func Initialize() current=0; Set(to); return true; -} \ No newline at end of file +} + +public func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/DefCore.txt index 7bfcc20d4..700e84054 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Compensator Version=5,2,0,1 Category=C4D_Structure -TimerCall=EnergyCheck -Timer=100 Width=30 Height=20 Offset=-15,-10 @@ -15,6 +13,5 @@ Value=20 Mass=100 Components=Coal=1;Metal=1 Exclusive=1 -BlastIncinerate=1 -ContactIncinerate=1 Construction=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Scene.material index e71e23fdc..352d9e59f 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Scene.material @@ -10,7 +10,6 @@ material Compensator specular 0.000000 0.000000 0.000000 1.000000 12.500000 emissive 0.000000 0.000000 0.000000 1.000000 scene_blend alpha_blend - depth_write off cull_hardware none texture_unit { diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Script.c index cf23af5b4..000f4556d 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/Script.c @@ -1,8 +1,12 @@ /*-- compensator --*/ +#include Library_Structure #include Library_Ownable #include Library_PowerProducer #include Library_PowerConsumer +#include Library_Flag + +local DefaultFlagRadius = 90; static const Compensator_max_seconds = 15; static const Compensator_power_usage = 50; @@ -15,22 +19,24 @@ local Description = "$Description$"; local leftcharge, rightcharge, lastcharge; local anim; -func Construction() +func Construction(object creator) { power_seconds = 0; lastcharge = 0; anim = PlayAnimation("Charge", 1, Anim_Const(GetAnimationLength("Charge")), Anim_Const(1000)); - - return _inherited(...); + + SetAction("Default"); + return _inherited(creator, ...); } func Initialize() { - leftcharge = CreateObject(Compensator_ChargeShower, -7, 10, NO_OWNER); + leftcharge = CreateObject(Compensator_ChargeShower, 7 * GetCalcDir(), 10, NO_OWNER); leftcharge->Init(this); - rightcharge = CreateObject(Compensator_ChargeShower, 6, 10, NO_OWNER); + rightcharge = CreateObject(Compensator_ChargeShower, -6 * GetCalcDir(), 10, NO_OWNER); rightcharge->Init(this); + AddTimer("EnergyCheck", 100); return _inherited(...); } @@ -44,8 +50,6 @@ func OnNotEnoughPower() return _inherited(...); } -func UnmakePowerConsumer(){MakePowerConsumer(0);} - // devour energy func OnEnoughPower() { @@ -77,7 +81,7 @@ func FxConsumePowerTimer(target, effect, time) // fully charged? if(power_seconds >= Compensator_max_seconds) { - MakePowerConsumer(0); + UnmakePowerConsumer(); return -1; } return 1; @@ -139,9 +143,7 @@ func FxSparkleTimer(target, effect, time) { effect.Interval *= 2; if(effect.Interval > 35*3) return -1; - - CreateParticle("StarSpark", RandomX(-3,3), RandomX(-14, -10), RandomX(-5,5), RandomX(-8, 0), 30, RGB(200, 200, 255), this); - CreateParticle("StarSpark", RandomX(-3,3), RandomX(-14, -10), RandomX(-5,5), RandomX(-8, 0), 30, RGB(200, 200, 255), this); + CreateParticle("StarSpark", PV_Random(-3, 3), PV_Random(-14, -10), PV_Random(-5, 5), PV_Random(-8, 0), 10, Particles_Magic(), 4); } func FxProducePowerTimer(target, effect, time) @@ -180,9 +182,26 @@ func Incineration() var x = -7 + 14 * i; var b = CreateObject(Compensator_BurningBattery, x, 6, NO_OWNER); b->SetController(GetController()); // killtracing - + b->SetSpeed(-30 + 60 * i + RandomX(-10, 10), RandomX(-50, -30)); } Explode(30); } + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Default", + }, +}; +local BlastIncinerate = 1; +local HitPoints = 25; +local ContactIncinerate = 1; diff --git a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/StringTblUS.txt index 792454958..25e08e844 100644 --- a/planet/Objects.ocd/Structures.ocd/Compensator.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Compensator.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Compensator -Description=Is able to puffer a small amount of energy over some time. +Description=Is able to buffer a small amount of energy over some time. diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/DefCore.txt new file mode 100644 index 000000000..08dc3c921 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/DefCore.txt @@ -0,0 +1,12 @@ +[DefCore] +id=Elevator_Case_Back +Version=5,2,0,1 +Width=24 +Height=45 +Offset=-12,-26 +Category=C4D_StaticBack +# for attachment +Vertices=1 +VertexX=-12 +VertexY=-2 +VertexFriction=0 diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Graphics.mesh new file mode 100644 index 000000000..aa0a9032d Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Scene.material new file mode 100644 index 000000000..4da3ad6d7 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Scene.material @@ -0,0 +1,21 @@ +material elevatorCase +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.0 0.0 0.0 0.0 12.5 + emissive 0.0 0.0 0.0 0.0 + texture_unit + { + texture case.png + tex_address_mode wrap + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Script.c new file mode 100644 index 000000000..3b8157f8f --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/Script.c @@ -0,0 +1,24 @@ +// Elevator case back + +func Initialize() +{ + //SetProperty("MeshTransformation", Trans_Mul(Trans_Scale(800), Trans_Translate(0, -2000))); +} + +func AttachTargetLost() +{ + RemoveObject(); +} + +func SaveScenarioObject() { return false; } + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Directions = 1, + FacetBase = 1, + NextAction = "Attach" + } +}; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/case.png b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/case.png new file mode 100644 index 000000000..3ba3036bd Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/case.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/caseBack.skeleton b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/caseBack.skeleton new file mode 100644 index 000000000..ef09787ae Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseBack.ocd/caseBack.skeleton differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/DefCore.txt new file mode 100644 index 000000000..6af347aaa --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/DefCore.txt @@ -0,0 +1,13 @@ +[DefCore] +id=Elevator_Case_Front +Version=5,2,0,1 +Width=24 +Height=34 +Offset=-12,-17 +Category=C4D_StaticBack + +# for attachment +Vertices=1 +VertexX=-12 +VertexY=-5 +VertexFriction=0 diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/Graphics.mesh new file mode 100644 index 000000000..e6340af07 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/Script.c new file mode 100644 index 000000000..9fb4ae0a4 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/Script.c @@ -0,0 +1,26 @@ +// Elevator case front + +local Plane = 505; + +func Initialize() +{ + //SetProperty("MeshTransformation", Trans_Scale(800)); +} + +func AttachTargetLost() +{ + RemoveObject(); +} + +func SaveScenarioObject() { return false; } + +local ActMap = { + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Directions = 1, + FacetBase = 1, + NextAction = "Attach" + } +}; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/caseFront.skeleton b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/caseFront.skeleton new file mode 100644 index 000000000..ef09787ae Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/CaseFront.ocd/caseFront.skeleton differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/DefCore.txt index 0b5ccd718..e7e0b5bb6 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/DefCore.txt @@ -5,18 +5,20 @@ Category=C4D_Vehicle Width=24 Height=26 Offset=-12,-13 -Vertices=4 -VertexX=-12,11,-12,11 -VertexY=-10,-10,10,10 -VertexCNAT=5,6,9,10 -VertexFriction=100,100,100,100 +# important: 4 vertices (5 to 8) are used in script! +# if you change the number of vertices, make sure to adjust the script +Vertices=8 +VertexX=-12,11,-12,11, -12,11,-12,11 +VertexY=-10,-10,9,9, -10,-10,9,9 +VertexCNAT=5,6,9,10, 5,6,9,10 +VertexFriction=100,100,100,100, 100,100,100,100 Value=0 Mass=30 Components=Wood=1 -SolidMask=0,26,24,2,0,24 +SolidMask=0,0,24,2,0,24 TopFace=0,0,24,26,0,0 +Picture=24,0,152,128 HorizontalFix=1 NoPushEnter=1 -Timer=1 -TimerCall=Movement -ContactCalls=1 \ No newline at end of file +ContactCalls=1 + diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Graphics.png b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Graphics.png index 3046d3d52..6f8d6851a 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Graphics.png and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Script.c index 95d101c36..71aacfceb 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/Script.c @@ -1,161 +1,187 @@ /*-- Elevator case --*/ +#include Library_Structure #include Library_PowerConsumer -local elevator; +static const ElevatorCase_move_speed = 20; +static const ElevatorCase_up = -1; +static const ElevatorCase_down = 1; +// if you change the vertices in the defcore make sure to adjust this +static const ElevatorCase_additional_vertex_index_begin = 4; +static const ElevatorCase_normal_vertex_index_begin = 0; +static const ElevatorCase_additional_vertex_count = 4; + +// Meshes +local front, back; + +local elevator; +local partner, partner_was_synced, is_master; + +// can be changed from outside +// standard: ElevatorCase_move_speed, 2 * ElevatorCase_move_speed +local case_speed; // when user controls case +local case_speed_automatic; // when case goes to user + +/* Callbacks */ + +func GetDrillSpeed() +{ + return ElevatorCase_move_speed / 2; +} + +func Initialize() +{ + AddEffect("CheckAutoMoveTo", this, 1, 30, this); + AddEffect("ElevatorUpperLimitCheck", this, 1, 1, this); + AddEffect("FetchVehicles", this, 1, 10, this); + + case_speed = ElevatorCase_move_speed; + case_speed_automatic = 2 * case_speed; + + partner_was_synced = false; + + front = CreateObject(Elevator_Case_Front, 0,13, GetOwner()); + back = CreateObject(Elevator_Case_Back, 0,13, GetOwner()); + + front->SetAction("Attach", this); + back->SetAction("Attach", this); +} + +// Called by the elevator func Connect(object connect_to) { elevator = connect_to; SetComDir(COMD_None); - SetAction("Drive"); + SetAction("DriveIdle"); +} + +func Destruction() +{ + if(partner) + partner->LoseConnection(); + if(elevator) + elevator->LostCase(); + + for(var i = 0; i < 3; ++i) + { + var wood = CreateObject(Wood, 0, 0, NO_OWNER); + wood->Incinerate(); + wood->SetXDir(RandomX(-10, 10)); + wood->SetYDir(RandomX(-2, 0)); + } +} + +func LostElevator() +{ + // die x.x + RemoveObject(); +} + +// Called by the elevator in case a partner elevator was constructed +func StartConnection(object case) +{ + partner = case; + partner_was_synced = false; + if(case.partner != this) + { + case->StartConnection(this); + is_master = true; + AddEffect("TryToSync", this, 1, 1, this); + } + else // is slave + { + is_master = false; + MoveTo(nil, 0, case); + } +} + +// Called when the other elevator is destroyed or moved +func LoseConnection() +{ + partner = nil; + is_master = nil; + partner_was_synced = false; + if(GetEffect("TryToSync", this)) + RemoveEffect("TryToSync", this); + SetPartnerVertices(0, 0); + SetActionData(0); - // request power - MakePowerConsumer(50); -} - -/* Movement behaviour */ - -local move_to, // Y-coordinate to move to on its own - move_to_delay, // Delay before moving - move_to_target; // Target to move to - -// for the position -func GetActualPowerConsumer() -{ - return elevator; -} - -// the lift may not need power when not used -func QueryWaivePowerRequest() -{ - if(!movement && !drill) - return 10; - else return 0; -} - -func OnNotEnoughPower() -{ - // Stop movement if moving Halt(); - movement = 0; - ClearMoveTo(); - if (drill) - { - SetAction("Drive"); - Sound("ElevatorDrilling", nil, nil, nil, -1); - drill = false; - } - return _inherited(...); } -func OnEnoughPower() +// slave loses attach to master? +func AttachTargetLost() { - return _inherited(...); + LoseConnection(); } -func Movement() // TimerCall +func ExecuteSync() { - // No elevator?! - if (!elevator) - { - // Elevator crash, oh the horror! - if (!ActIdle()) SetAction("Idle"); - return; - } + if(!is_master) FatalError("ExecuteSync() called on slave elevator case!"); + partner_was_synced = true; + partner.partner_was_synced = true; + ForceSync(); + SetPartnerVertices(partner->GetX() - GetX(), partner->GetY() - GetY()); + // reset power usage + UnmakePowerConsumer(); + partner->UnmakePowerConsumer(); - // Fetch vehicles - for (var vehicle in FindObjects(Find_InRect(-5, -5, 10, 10), Find_Category(C4D_Vehicle), Find_NoContainer(), Find_Func("FitsInElevator"))) - { - if (GetEffect("ElevatorControl", vehicle)) continue; - - vehicle->SetPosition(GetX(), GetY() + 12 - vehicle->GetObjHeight()/2 ); - vehicle->SetSpeed(); - vehicle->SetR(); - AddEffect("ElevatorControl", vehicle, 30, 5, vehicle, nil, this); - } + // can now attach partner on one of the new vertices + partner->SetAction("Attach", this); + var vertex_data = (ElevatorCase_normal_vertex_index_begin << 8) + ElevatorCase_additional_vertex_index_begin; + partner->SetActionData(vertex_data); - // no power? - if(!CurrentlyHasPower()) - return; + Sound("Click"); +} + +// sets additional vertices to partner's position +func SetPartnerVertices(int off_x, int off_y) +{ + var update_mode = 2; // force immediate update and store information - // Start or stop drilling - if (drill && GetAction() == "Drive") + for(var i = 0; i < ElevatorCase_additional_vertex_count; ++i) { - SetAction("Drill"); - Sound("ElevatorDrilling", nil, nil, nil, 1); - } - if (!drill && GetAction() == "Drill") - { - SetAction("Drive"); - Sound("ElevatorDrilling", nil, nil, nil, -1); + SetVertex(ElevatorCase_additional_vertex_index_begin + i, VTX_X, GetVertex(ElevatorCase_normal_vertex_index_begin + i, VTX_X) + off_x, update_mode); + SetVertex(ElevatorCase_additional_vertex_index_begin + i, VTX_Y, GetVertex(ElevatorCase_normal_vertex_index_begin + i, VTX_Y) + off_y, update_mode); } +} - // Stop if at upmost position - if (GetY() - 20 <= elevator->GetY() && movement < 0) - { - if (GetYDir() < 0) Halt(); - movement = 0; - SetPosition(GetX(), elevator->GetY() + 20); - ClearMoveTo(); - return; - } +func IsMaster() { return partner && is_master && partner_was_synced; } +func IsSlave() { return partner && !is_master && partner_was_synced; } - // Move or stop - if (movement && GetYDir() != this.Speed * movement) - { - if (movement < 0 && GetContact(-1) & CNAT_Top) - { - movement = 0; - } else if (movement > 0 && GetContact(-1) & CNAT_Bottom) - { - movement = 0; - } else - { - if (Abs(GetYDir()) == 1) elevator->StartEngine(); - SetYDir(GetYDir() + movement); - return; - } - } - if (!movement && !move_to && GetYDir()) - { - Halt(); - } +func FxTryToSyncTimer(object target, effect, int time) +{ + var diff = Abs(partner->GetY() - GetY()); + if(diff > 5) return 1; + ExecuteSync(); + return -1; +} - // Idle? - if (!CheckIdle()) return; - - // Move-to job? - if (move_to) +func FxCheckAutoMoveToTimer(object target, effect, int time) +{ + if(!elevator) return -1; + if(IsSlave()) return 1; + if(!CheckIdle()) return 1; + if(GetEffect("MoveTo", this)) return 1; + + // look for Clonks at shaft + var additional = 20; + var x = GetX() - additional; + var w = GetX() + additional; + var y = elevator->GetY(); + var h = LandscapeHeight(); + + if(IsMaster()) { - if (move_to_delay) - { - move_to_delay--; - if (move_to_target) - if (move_to_target->GetComDir() != COMD_Stop || AbsX(GetX() - move_to_target->GetX()) > 20) - return ClearMoveTo(); - if (!move_to_delay) move_to_target = nil; - return; - } - if (Inside(move_to, GetY()-2, GetY()+2)) - { - ClearMoveTo(); - Halt(); - return; - } - if (move_to < GetY() && GetYDir() > -this.RushSpeed) - SetYDir(GetYDir() - 1); - if (move_to > GetY() && GetYDir() < this.RushSpeed) - SetYDir(GetYDir() + 1); - if (Abs(GetYDir()) == 1) elevator->StartEngine(); - return; + x = Min(x, partner->GetX() - additional); + w = Max(w, partner->GetX() + additional); } - - // Search for waiting clonks var clonk, best; - for (clonk in FindObjects(Find_InRect(-20, AbsY(elevator->GetY()), 40, LandscapeHeight() - elevator->GetY()), Find_OCF(OCF_CrewMember), Find_OCF(OCF_Alive), Find_NoContainer(), Find_Allied(GetOwner()), Sort_Distance(), Sort_Reverse())) + + for (clonk in FindObjects(Find_InRect(x - GetX(), y - GetY(), w - x, h - y), Find_OCF(OCF_CrewMember), Find_OCF(OCF_Alive), Find_NoContainer(), Find_Allied(GetOwner()), Sort_Distance(), Sort_Reverse())) { var proc = clonk.Action.Procedure; if (clonk->GetComDir() != COMD_Stop && !((proc == "SWIM") && Inside(clonk->GetXDir(), -5, 5))) @@ -167,7 +193,11 @@ func Movement() // TimerCall if (clonk->GetY() > GetY() + 7) if (!PathFree(GetX(), GetY() + 16, GetX(), clonk->GetY())) continue; - if (clonk->GetY() > GetY() && GetContact(-1) & CNAT_Bottom) continue; + if ((clonk->GetY() > GetY()) && GetContact(-1, CNAT_Bottom)) continue; + + // do not move to very close Clonks + if(Abs(GetY() - clonk->GetY()) < 5) continue; + // Priority rules: Cursor is better than no cursor, nearer is better than farer (Sort_Distance() & Sort_Reverse() do this) // So unlike in CR's elevator, no distance check has to be done because later cycles are always nearer clonks if (!best) best = clonk; @@ -176,105 +206,451 @@ func Movement() // TimerCall else if (GetCursor(best->GetController()) != best) best = clonk; } - if (best) return MoveTo(best->GetY(), 35, best); - - // Stop, why do you move? - Halt(); + if (best) + MoveTo(best->GetY(), 10, best); + return 1; } -func Halt() +func FxElevatorUpperLimitCheckTimer(target, effect, time) { - if (!elevator) return; - if (GetYDir()) elevator->StopEngine(); + if(!elevator) return -1; + if(IsSlave()) return -1; + + var d = GetY() - (elevator->GetY() + 20); + + // HOW COULD THIS HAPPEN :C + if(d <= 0) + { + if(GetYDir() < 0) + { + SetPosition(GetX(), GetY() - d); + ForceSync(); + ContactTop(); + } + else + if(GetYDir() == 0) + SetPosition(GetX(), GetY() - d); + + effect.Interval = 1; + return 1; + } + + // everything okay, adjust timer accordingly + // check less often if far away from elevator + // note: d > 0 + var t = BoundBy(d / 3, 1, 20); + effect.Interval = t; + return 1; +} + +// for vehicle control +func OutOfRange(object vehicle) +{ + if(Abs(GetY() - vehicle->GetY()) > 10) return true; + + var min_x = GetX() - 12; + var max_x = GetX() + 12; + if(IsMaster()) + { + min_x = Min(min_x, partner->GetX() - 12); + max_x = Max(max_x, partner->GetX() + 12); + } + + if(vehicle->GetX() < min_x) return true; + if(vehicle->GetX() > max_x) return true; + return false; +} + +func FxFetchVehiclesTimer(target, effect, time) +{ + if(!elevator) return -1; + if(IsSlave()) return 1; + + // look for vehicles + var additional = -5; + var x = GetX() - 12 - additional; + var w = GetX() + 12 + additional; + var y = GetY() - 12; + var h = GetY() + 15; + + if(IsMaster()) + { + x = Min(x, partner->GetX() - 12 - additional); + w = Max(w, partner->GetX() + 12 + additional); + } + + // Fetch vehicles + for (var vehicle in FindObjects(Find_InRect(x - GetX(), y - GetY(), w - x, h - y), Find_Category(C4D_Vehicle), Find_NoContainer(), Find_Func("FitsInElevator"))) + { + if (GetEffect("ElevatorControl", vehicle)) continue; + vehicle->SetPosition(vehicle->GetX(), GetY() + 12 - vehicle->GetObjHeight()/2); + vehicle->SetSpeed(); + vehicle->SetR(); + AddEffect("ElevatorControl", vehicle, 30, 5, vehicle, nil, this); + } + + return 1; +} + +/* Energy */ + +func GetNeededPower() +{ + var p = Elevator_needed_power; + if(partner_was_synced) p = 2 * p; + return p; +} + + +// for the position +func GetActualPowerConsumer() +{ + return elevator; +} + +// the lift may not need power when not used +func QueryWaivePowerRequest() +{ + // no clonk on elevator? must be automatic + if(CheckIdle()) return 20; + return 0; +} + +func OnNotEnoughPower() +{ + _inherited(...); // on purpose before the rest + + if(GetYDir()) + StoreMovementData(); + else; // already has data stored + + if(GetAction() != "DriveIdle") + Halt(false, true); +} + +func OnEnoughPower() +{ + _inherited(...); // on purpose before the rest + RestoreMovementData(); +} + +func StoreMovementData(int y_dir, string action, bool user_requested) +{ + y_dir = y_dir ?? GetYDir(); + action = action ?? GetAction(); + user_requested = user_requested ?? !CheckIdle(); + var e = GetEffect("StoredMovementData", this); + if(!e) e = AddEffect("StoredMovementData", this, 1, 0, this); + e.y_dir = y_dir; + e.action = action; + e.user_requested = user_requested; +} + +func RestoreMovementData() +{ + var e = GetEffect("StoredMovementData", this); + if(!e) return; + var drill = false; + if(e.action == "Drill") + drill = true; + SetMoveDirection(BoundBy(e.y_dir, -1, 1), e.user_requested, drill); + RemoveEffect(nil, this, e); +} + +func SetMoveDirection(int dir, bool user_requested, bool drill) +{ + if(IsSlave()) + return partner->SetMoveSpeed(dir, user_requested, drill); + + if(user_requested) StopAutomaticMovement(); + + var e; + if(e = GetEffect("StopPowerConsumption", this)) + RemoveEffect(nil, this, e); + + // no change? + if((dir < 0) && (GetYDir() < 0)) return; + if((dir > 0) && (GetYDir() > 0)) return; + + // already reached top/bottom? + if(GetContact(-1, CNAT_Bottom) && (dir > 0) && !drill) + return; + if(GetContact(-1, CNAT_Top) && (dir < 0)) + return; + if(dir == 0) return Halt(); + + var speed = case_speed; + // note: can not move down with full speed because of solidmask problem + // todo.. + if(!user_requested && dir < 0) speed = case_speed_automatic; + + var action = "Drive"; + if(drill) + { + action = "Drill"; + speed = GetDrillSpeed(); + } + + if(CurrentlyHasPower()) + { + SetYDir(dir * speed); + SetAction(action); + SetComDir(COMD_None); + ForceSync(); + + elevator->StartEngine(); + } + else + { + StoreMovementData(dir * speed, action); + MakePowerConsumer(GetNeededPower()); + } +} + +func Halt(bool user_requested, bool power_out) +{ + if(IsSlave()) return; + + StopAutomaticMovement(); + + if(GetYDir()) + { + if(elevator) + elevator->StopEngine(); + } + + // clear speed + SetAction("DriveIdle"); SetYDir(); + ForceSync(); + + if(user_requested) + { + UnmakePowerConsumer(); + } + else + { + // if not stopped because of lack of power, stop consuming power + if(!power_out) + AddEffect("StopPowerConsumption", this, 1, 40, this); + } +} + +func FxStopPowerConsumptionTimer(object target, effect, int time) +{ + UnmakePowerConsumer(); + return -1; +} + +func ForceSync() +{ + if(!IsMaster()) return; + // clear rounding errors + SetPosition(GetX(), GetY()); + // adjust partner + partner->SetPosition(partner->GetX(), GetY()); + partner->SetYDir(0); } func ContactTop() { Halt(); + Sound("WoodHit*"); } + func ContactBottom() { + // try to dig free + if(GetAction() == "Drill") + { + Drilling(); + + // wee! + if(!GetContact(-1, CNAT_Bottom)) + { + SetYDir(GetDrillSpeed()); + return; + } + } Halt(); - movement = 0; - drill = false; - ClearMoveTo(); + Sound("WoodHit*"); } // Checks whether the elevator should not move because someone's holding it // Returns true if idle func CheckIdle() { - for (var pusher in FindObjects(Find_InRect(-13, -13, 26, 26), Find_Action("Push"))) + // I have no mind of my own + if(IsSlave()) return; + + var in_rect = Find_InRect(-13, -13, 26, 26); + if (IsMaster()) + { + if (partner->GetX() < GetX()) + in_rect = Find_InRect(-39, -13, 52, 26); + else + in_rect = Find_InRect(-13, -13, 52, 26); + } + for (var pusher in FindObjects(in_rect, Find_Action("Push"))) { if (pusher->GetActionTarget() == this) return false; if (GetEffect("ElevatorControl", pusher->GetActionTarget()) && GetEffect("ElevatorControl", pusher->GetActionTarget()).case == this) return false; + + if (IsMaster()) + { + if (pusher->GetActionTarget() == partner) return false; + if (GetEffect("ElevatorControl", pusher->GetActionTarget()) && GetEffect("ElevatorControl", pusher->GetActionTarget()).case == partner) return false; + } } return true; } +func StopAutomaticMovement() +{ + var done = false; + if(GetEffect("MoveTo", this)) + { + RemoveEffect("MoveTo", this); + done = true; + } + + // todo: check if sensible + if(done) Halt(); +} + // Moves the case to the specific y-coordinate // delay in frames, so the elevator does not freak out // target will be checked again for COMD_Stop and distance after delay run out -func MoveTo(int y, int delay, object target) +func MoveTo(int y, int delay, object target, bool user_requested) { // Not idle? - if (!CheckIdle()) return false; + if (!CheckIdle() && !user_requested) return false; Halt(); - move_to = BoundBy(y, elevator->GetY() + 20, LandscapeHeight()); - move_to_delay = delay; - move_to_target = target; + var e = AddEffect("MoveTo", this, 1, 2, this); + e.delay = delay; + e.move_to_y = y; + e.target = target; + e.user_requested = user_requested; return true; } -func ClearMoveTo() +func FxMoveToTimer(target, effect, time) { - move_to = nil; - move_to_target = nil; - move_to_delay = nil; + if(time < effect.delay) return 1; + // what would take more than 10 seconds? + if((time - effect.delay) / 36 > 10) return -1; + + var y = effect.move_to_y; + if(effect.target) y = effect.target->GetY(); + + // target dead? + if(y == nil) + { + Halt(); + return -1; + } + + // target moves away from elevator shaft, finish movement but stop following + if(effect.target) + if(Abs(GetX() - effect.target->GetX()) > 100) + { + effect.move_to_y = effect.target->GetY(); + effect.target = nil; + } + + // destination reached + if(Abs(GetY() - y) < 5) + { + Halt(); + return -1; + } + var dir = ElevatorCase_up; + if(y > GetY()) dir = ElevatorCase_down; + SetMoveDirection(dir, effect.user_requested, false); + return 1; +} + +func StartDrilling() +{ + SetAction("Drill"); +} + +func StopDrilling() +{ + SetAction("Drive"); +} + +func Drilling() +{ + var additional_y = 1; + var rect = Rectangle(GetX() - 12, GetY() - 13 - additional_y, GetX() + 12, GetY() + 13 + additional_y); + if(IsMaster()) + { + rect.x = Min(rect.x, partner->GetX() - 12); + rect.y = Min(rect.y, partner->GetY() - 13 - additional_y); + rect.w = Max(rect.w, partner->GetX() + 12); + rect.h = Max(rect.h, partner->GetY() + 13 + additional_y); + } + DigFreeRect(rect.x, rect.y, rect.w - rect.x, rect.h - rect.y); } /* Controls */ -local movement, drill; +func ControlUseStart(object clonk, int x, int y) // send elevator to position +{ + if (IsSlave()) return Control2Master("ControlUseStart", clonk, x, y); + MoveTo(GetY() + y, 60, nil, true); + Sound("Click", nil, nil, clonk->GetOwner()); + // does not want UseStop-callback + return false; +} -func ControlUseStart(object clonk) // Drilling -{ - ClearMoveTo(); - drill = true; - movement = 1; - return true; -} -func ControlUseStop(object clonk) -{ - drill = false; - movement = 0; - return true; -} func ControlDown(object clonk) { - ClearMoveTo(); - if (!drill) - movement = 1; + if (IsSlave()) return Control2Master("ControlDown", clonk); + + // pressing down when already on ground results in drilling + var drill = !!GetContact(-1, CNAT_Bottom); + + SetMoveDirection(ElevatorCase_down, true, drill); + return true; } func ControlUp(object clonk) { - ClearMoveTo(); - if (!drill) - movement = -1; + if (IsSlave()) return Control2Master("ControlUp", clonk); + + // what is that player even doing + if(GetY() <= elevator->GetY() + 20) + { + Sound("Click", nil, nil, clonk->GetOwner()); + return true; + } + + SetMoveDirection(ElevatorCase_up, true, false); + return true; } func ControlStop(object clonk, int control) { - if (control == CON_Up || control == CON_Down) - { - if (!drill) - movement = 0; - return true; - } + if (IsSlave()) return Control2Master("ControlStop", clonk, control); + + if(control == CON_Up && GetYDir() <= 0) + Halt(true); + else if(control == CON_Down && GetYDir() >= 0) + Halt(true); + + return true; } +func Control2Master(string call, object clonk) +{ + if (!IsSlave()) return false; + return partner->Call(call, clonk, ...); +} + +func SaveScenarioObject() { return false; } + local ActMap = { Drive = { Prototype = Action, @@ -285,7 +661,18 @@ local ActMap = { Y = 0, Wdt = 24, Hgt = 26, - NextAction = "Drive" + NextAction = "Drive", + }, + DriveIdle = { + Prototype = Action, + Name = "DriveIdle", + Procedure = DFA_FLOAT, + Directions = 1, + X = 0, + Y = 0, + Wdt = 24, + Hgt = 26, + NextAction = "DriveIdle", }, Drill = { Prototype = Action, @@ -296,13 +683,28 @@ local ActMap = { Y = 0, Wdt = 24, Hgt = 26, + Delay = 1, + Length = 1, + PhaseCall = "Drilling", NextAction = "Drill", + Sound = "ElevatorDrilling", DigFree = 1 + }, + Attach = { + Prototype = Action, + Name = "Attach", + Procedure = DFA_ATTACH, + Directions = 1, + X = 0, + Y = 0, + Wdt = 24, + Hgt = 26, + NextAction = "Attach" } }; local Name = "$Name$"; local Description = "$Description$"; local Touchable = 2; -local Speed = 15; -local RushSpeed = 20; // When moving on its own \ No newline at end of file +local HitPoints = 50; +local Plane = 250; diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/SolidMask.png b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/SolidMask.png new file mode 100644 index 000000000..7ed056bfd Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Case.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/DefCore.txt index 7ab7db6a6..9397424e0 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/DefCore.txt @@ -2,9 +2,9 @@ id=Elevator Version=5,2,0,1 Category=C4D_Structure -Width=60 +Width=62 Height=66 -Offset=-30,-33 +Offset=-31,-33 Vertices=5 VertexX=-25,25,-5,-25,28 VertexY=-27,-27,32,32,32 @@ -13,6 +13,6 @@ Value=50 Mass=1500 Components=Wood=3;Metal=1 Exclusive=1 -BlastIncinerate=100 Construction=1 -ContainBlast=1 \ No newline at end of file +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.jpg b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.jpg new file mode 100644 index 000000000..ad6c7445d Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.png b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.png deleted file mode 100644 index 90268a0ec..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.skeleton b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.skeleton new file mode 100644 index 000000000..20b168412 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Elevator.skeleton differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorDrilling.ogg b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorDrilling.ogg index 790a2cbdb..24fb8856a 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorDrilling.ogg and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorDrilling.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorMoving.ogg b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorMoving.ogg index f53288e2e..0a96bf913 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorMoving.ogg and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorMoving.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStart.ogg b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStart.ogg index 37315f05c..7bfccf157 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStart.ogg and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStart.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStop.ogg b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStop.ogg index e526d813a..9511af4d9 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStop.ogg and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/ElevatorStop.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Graphics.mesh index 3934971ce..24fae5b43 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Graphics.mesh and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Rope.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Rope.ocd/Script.c index 371a90f08..2f7b582be 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Rope.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Rope.ocd/Script.c @@ -2,6 +2,8 @@ // I'm just a mindless worker +func SaveScenarioObject() { return false; } + local ActMap = { Be = { Prototype = Action, diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Scene.material index 4d868a96d..72020334f 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Scene.material @@ -12,10 +12,30 @@ material Elevator texture_unit { - texture Elevator.png + texture Elevator.jpg tex_address_mode wrap filtering trilinear } } } } + +material elevatorCable +{ + receive_shadows on + technique + { + pass + { + diffuse 1.000000 1.000000 1.000000 1.000000 + + texture_unit + { + texture cable.png + tex_address_mode wrap + filtering trilinear + } + } + } +} + diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Script.c index 8939815a2..764503fbb 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/Script.c @@ -1,8 +1,13 @@ /*-- Elevator --*/ +#include Library_Structure #include Library_Ownable +// used in the elevator case +static const Elevator_needed_power = 50; + local case, rope; +local partner, slave; // Frees a rectangle for the case func CreateShaft(int length) @@ -14,59 +19,185 @@ func CreateShaft(int length) case->SetPosition(case->GetX(), GetY()+20); } +func SetCasePosition(int y) +{ + // Move case to specified absolute y position + if (case) return case->SetPosition(case->GetX(), y); + return false; +} + /* Initialization */ -func Construction() +func Construction(object creator) { SetProperty("MeshTransformation", Trans_Rotate(-44,0,1,0)); + SetAction("Default"); + return _inherited(creator, ...); } func Initialize() { + SetCategory(C4D_StaticBack); CreateCase(); CreateRope(); + + if (partner) + { + if (Inside(partner->GetY(), GetY()-3, GetY()+3)) + { + partner->LetsBecomeFriends(this); + SetPosition(GetX(), partner->GetY()); + } + else + partner = nil; + } + return _inherited(); } func CreateCase() { - case = CreateObject(ElevatorCase, 19, 33, GetOwner()); + case = CreateObject(ElevatorCase, -19 * GetCalcDir(), 33, GetOwner()); case->Connect(this); } func CreateRope() { - rope = CreateObject(ElevatorRope, 19, -11, GetOwner()); - rope->SetAction("Be", case); + rope = CreateObject(ElevatorRope, -19 * GetCalcDir(), -11, GetOwner()); + rope->SetAction("Be", case.back); +} + +/* Scenario saving */ + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + props->Remove("Category"); + if (partner && slave) + { + props->AddCall("Friends", partner, "LetsBecomeFriends", this); + } + if (case && case->GetY() > GetY() + 20) + { + props->AddCall("Shaft", this, "CreateShaft", case->GetY() - GetY() - 20); + props->AddCall("Shaft", this, "SetCasePosition", case->GetY()); + } + return true; } /* Destruction */ func Destruction() { - rope->RemoveObject(); + if(rope) rope->RemoveObject(); + if(case) case->LostElevator(); + if (partner) partner->LoseCombination(); +} + +func LostCase() +{ + if(partner) partner->LoseCombination(); + if(rope) rope->RemoveObject(); + + // for now: the elevator dies, too + Incinerate(); } /* Effects */ func StartEngine() { - Sound("ElevatorStart"); + Sound("ElevatorStart", nil, nil, nil, nil, 100); ScheduleCall(this, "EngineLoop", 34); - Sound("ElevatorMoving", nil, nil, nil, 1); + //Sound("ElevatorMoving", nil, nil, nil, 1); } func EngineLoop() { - Sound("ElevatorMoving", nil, nil, nil, 1); + Sound("ElevatorMoving", nil, nil, nil, 1, 100); } func StopEngine() { Sound("ElevatorMoving", nil, nil, nil, -1); ClearScheduleCall(this, "EngineLoop"); - Sound("ElevatorStop"); + Sound("ElevatorStop", nil, nil, nil, nil, 100); } +/* Construction */ + +// Sticking to other elevators +func ConstructionCombineWith() { return "IsElevator"; } + +// Called to determine if sticking is possible +func IsElevator(object previewer) +{ + if (!previewer) return true; + + if (GetDir() == DIR_Left) + { + if (previewer.direction == DIR_Right && previewer->GetX() > GetX()) return true; + } + else + { + if (previewer.direction == DIR_Left && previewer->GetX() < GetX()) return true; + } + return false; +} + +// Called when the elevator construction site is created +func CombineWith(object other) +{ + // Save for use in Initialize + partner = other; +} + +/* Combination */ + +// Called by a new elevator next to this one +// The other elevator will be the slave +func LetsBecomeFriends(object other) +{ + partner = other; + other.slave = true; // Note: This is liberal slavery + if (case) case->StartConnection(other.case); +} + +// Partner was destroyed or moved +func LoseCombination() +{ + partner = nil; + slave = false; + if (case) case->LoseConnection(); +} + +// Called by our case because the case has a timer anyway +func CheckSlavery() +{ + // Check if somehow we moved away from our fellow + if (ObjectDistance(partner) > 62 || !Inside(partner->GetY(), GetY()-1, GetY()+1)) + { + LoseCombination(); + partner->LoseCombination(); + } +} + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Default", + }, +}; + func Definition(def) { SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(-20,1,0), Trans_Rotate(-20, 0, 1, 0))); } local Name = "$Name$"; -local Description = "$Description$"; \ No newline at end of file +local Description = "$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; +local Plane = 249; diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/StringTblUS.txt index d2fab50cf..2122a3a33 100644 --- a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/StringTblUS.txt @@ -1,2 +1,2 @@ Name=Elevator -Description=Simple vertical transport. \ No newline at end of file +Description=Simple vertical transport. Two eleavtors placed side-by-side can join together. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Elevator.ocd/cable.png b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/cable.png new file mode 100644 index 000000000..fcd09b509 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Elevator.ocd/cable.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/DefCore.txt index 1ebc2f0a5..51b6e3df8 100644 --- a/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/DefCore.txt @@ -11,7 +11,7 @@ VertexY=-34,-29,-29,34,34 VertexFriction=50,50,50,100,100 Value=200 Mass=100 -Components=Wood=4;Metal=1 +Components=Wood=3;Metal=1 Picture=30,0,80,94 Exclusive=1 Construction=1 diff --git a/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/Script.c index 4f38236a7..5919afcdc 100644 --- a/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Flagpole.ocd/Script.c @@ -1,5 +1,6 @@ /*-- Flagpole --*/ +#include Library_Structure #include Library_Flag #include Library_GoldSeller #include Library_Base // Needed for DuBuy... @@ -19,6 +20,7 @@ protected func Construction() return _inherited(...); } +public func NoConstructionFlip() { return true; } /*-- Interaction --*/ @@ -37,10 +39,10 @@ public func GetInteractionMetaInfo(object clonk) public func Interact(object clonk) { var menu; - var i=0,item,player=clonk->GetOwner(), amount; - while (item = GetHomebaseMaterial(player, nil, i++)) + var i = 0, item, amount; + while (item = GetHomebaseMaterial(GetOwner(), nil, i++)) { - amount = GetHomebaseMaterial(player, item); + amount = GetHomebaseMaterial(GetOwner(), item); // Add even if amount==0 if (!menu) menu = clonk->CreateRingMenu(Flagpole, this); if (!menu) return false; @@ -63,8 +65,19 @@ public func Selected(object menu, proplist menu_item, bool alt) // Excess objects exit flag (can't get them out...) var i = ContentsCount(); var obj; - while (i--) if (obj = Contents(i)) Contents(i)->Exit(); + while (i--) + if (obj = Contents(i)) + Contents(i)->Exit(0, GetDefHeight() / 2); // Update available count - menu_item->SetAmount(GetHomebaseMaterial(clonk->GetOwner(), def)); + menu_item->SetAmount(GetHomebaseMaterial(GetOwner(), def)); + menu->Show(); + return true; +} + +func OnOwnerRemoved(int new_owner) +{ + // Our owner is dead :( + // Flag is passed on to the next best owner + SetOwner(new_owner); return true; } diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/DefCore.txt index cafcb7e0f..ebd0d1cc5 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/DefCore.txt @@ -12,8 +12,7 @@ VertexFriction=50,50,50,100,100,100 Value=200 Mass=4500 Components=Rock=4;Wood=2; -Collection=16,3,13,13 Exclusive=1 -BlastIncinerate=100 Construction=1 ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Foundry.jpg b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Foundry.jpg new file mode 100644 index 000000000..8b0a59f0b Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Foundry.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Foundry.png b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Foundry.png deleted file mode 100644 index 2b140f789..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Foundry.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceLoop.ogg b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceLoop.ogg index ae2715318..86eb65e59 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceLoop.ogg and b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceLoop.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStart.ogg b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStart.ogg index 2c8f784ec..9ea164f08 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStart.ogg and b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStart.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStop.ogg b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStop.ogg index 28aec28c0..a7f58ab38 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStop.ogg and b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/FurnaceStop.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Scene.material index 7a3659f4d..9f2cbe225 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Scene.material @@ -47,7 +47,7 @@ material Foundry emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Foundry.png + texture Foundry.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c index 9397280df..f944a9812 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c @@ -5,17 +5,20 @@ Melts iron ore to metal, using some sort of fuel. --*/ +#include Library_Structure #include Library_Ownable #include Library_Producer // does not need power func PowerNeed() { return 0; } -public func Construction() +public func Construction(object creator) { //SetProperty("MeshTransformation",Trans_Rotate(RandomX(-40,20),0,1,0)); - return _inherited(...); + SetAction("Default"); + AddTimer("CollectionZone", 1); + return _inherited(creator, ...); } /*-- Production --*/ @@ -26,7 +29,7 @@ private func IsProduct(id product_id) { return product_id->~IsFoundryProduct(); } -private func ProductionTime() { return 290; } +private func ProductionTime(id toProduce) { return 290; } public func NeedRawMaterial(id rawmat_id) { @@ -54,7 +57,16 @@ public func OnProductionFinish(id product) return; } -protected func Collection() +// Timer, check for objects to collect in the designated collection zone +func CollectionZone() +{ + if (GetCon() < 100) return; + + for (var object in FindObjects(Find_InRect(16 - 45 * GetDir(),3,13,13), Find_OCF(OCF_Collectible), Find_NoContainer(), Find_Layer(GetObjectLayer()))) + Collect(object); +} + +func Collection() { Sound("Clonk"); return; @@ -64,14 +76,14 @@ public func FxSmeltingTimer(object target, proplist effect, int time) { //Message(Format("Smelting %d",timer)); // Fire in the furnace. - CreateParticle("Fire",10,20,RandomX(-1,1),RandomX(-1,1),RandomX(25,50),RGB(255,255,255), this); + CreateParticle("Fire", -10 * GetCalcDir(), 20, PV_Random(-1, 1), PV_Random(-1, 1), PV_Random(18, 36), Particles_Fire(), 2); // Smoke from the pipes. - CreateParticle("ExploSmoke", 9, -31, RandomX(-2,1), -7 + RandomX(-2,2), RandomX(60,125), RGBa(255,255,255,50)); - CreateParticle("ExploSmoke", 16, -27, RandomX(-1,2), -7 + RandomX(-2,2), RandomX(30,90), RGBa(255,255,255,50)); + Smoke( -9*GetCalcDir(), -31, 6); + Smoke(-16*GetCalcDir(), -27, 3); // Furnace sound after some time. - if (time == 100) + if (time == 30) Sound("FurnaceLoop", false, 100, nil, +1); // Pour after some time. @@ -84,7 +96,7 @@ public func FxSmeltingTimer(object target, proplist effect, int time) // Fire from the pouring exit. if (Inside(time, 244, 290)) - CreateParticle("Fire",-17,19,-1 + RandomX(-1,1), 2+ RandomX(-1,1),RandomX(5,15),RGB(255,255,255)); + CreateParticle("Fire", 17 * GetCalcDir(), 19, PV_Random(-2, 0), PV_Random(1, 3), PV_Random(18, 36), Particles_Fire(), 2); if (time == 290) { @@ -98,14 +110,31 @@ public func FxSmeltingTimer(object target, proplist effect, int time) public func OnProductEjection(object product) { - product->SetPosition(GetX() - 18, GetY() + 16); + product->SetPosition(GetX() + 18 * GetCalcDir(), GetY() + 16); product->SetSpeed(0, -17); product->SetR(30 - Random(59)); Sound("Pop"); return; } +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Default", + }, +}; + 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 BlastIncinerate = 100; +local HitPoints = 100; diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt index 205924920..2d8fcd903 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt @@ -1 +1,2 @@ -Name=Hochofen \ No newline at end of file +Name=Hochofen +Description=Im Hochofen können Erze zu Barren geschmolzen werden. Dafür wird ein Brennstoff benötigt. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt index a782fc5ee..b533f560e 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt @@ -1 +1,2 @@ -Name=Foundry \ No newline at end of file +Name=Foundry +Description=In the foundry, ore can be smelted into ingots. Fuel, such as coal, is necessary for this. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/authors.txt b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/authors.txt index 8c89f446c..dfa1d5a25 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/authors.txt +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/authors.txt @@ -1,5 +1,5 @@ -FurnaceLoop.ogg, FurnaceStart.ogg, FurnaceStop.ogg - by Dynamicell (http://www.freesound.org/people/Dynamicell/sounds/17548/), License: CC Attribution 3.0 - Pop.ogg - by Traveler (http://www.freesound.org/people/Traveler/sounds/16064/), License: CC Attribution 3.0 \ No newline at end of file + by Traveler (http://www.freesound.org/people/Traveler/sounds/16064/), License: CC Attribution 3.0 + +FurnaceStart.ogg, FurnaceStop.ogg, FurnaceLoop.ogg + by tc630 (http://www.freesound.org/people/tc630/sounds/47835/), License: CC 0 (Public Domain) \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Idol.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Idol.ocd/Script.c index 54f4fd760..ec7555228 100644 --- a/planet/Objects.ocd/Structures.ocd/Idol.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Idol.ocd/Script.c @@ -3,3 +3,5 @@ local Name = "$Name$"; local Touchable = 1; + +public func NoConstructionFlip() { return true; } \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblDE.txt index 31ec78608..65b18e8c8 100644 --- a/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblDE.txt @@ -1 +1 @@ -Name=Idol +Name=Goldene Statue \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblUS.txt index 31ec78608..d243f12db 100644 --- a/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Idol.ocd/StringTblUS.txt @@ -1 +1 @@ -Name=Idol +Name=Golden statue \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/DefCore.txt new file mode 100644 index 000000000..44c3f3e91 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=InventorsLab +Version=5,2,90,21 +Category=C4D_Structure +Width=82 +Height=82 +Offset=-41,-41 +Vertices=7 +VertexX= 1, 1,-24,17,35, 32,-28 +VertexY=41,-41, 41,41,41,11,2 +VertexFriction=100,10,100,100,100,10,10 +Value=200 +Mass=4500 +Components=Wood=3;Metal=3 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Graphics.mesh new file mode 100644 index 000000000..2d4540865 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Inventor.material b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Inventor.material new file mode 100644 index 000000000..d13322ae8 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Inventor.material @@ -0,0 +1,73 @@ +material inventorsLab +{ + receive_shadows on + technique + { + pass + { + diffuse 1.0 1.0 1.0 1.0 + texture_unit + { + texture inventorMain.png + tex_address_mode wrap + } + } + } +} + +material inventorsLabNoCull +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + cull_hardware none + + diffuse 1.0 1.0 1.0 1.0 + texture_unit + { + texture inventorMain.png + tex_address_mode wrap + } + } + } +} + +material inventorsLabDetail +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + + diffuse 1.0 1.0 1.0 1.0 + texture_unit + { + texture inventorDetail.png + tex_address_mode wrap + } + } + } +} + +material inventorsLabTeleScope +{ + receive_shadows on + technique + { + pass + { + diffuse 1.0 1.0 1.0 1.0 + + texture_unit + { + texture inventorTelescope.png + tex_address_mode wrap + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Script.c new file mode 100644 index 000000000..38608d101 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/Script.c @@ -0,0 +1,75 @@ +/*-- Inventor's Lab --*/ + +#include Library_Structure +#include Library_Ownable +#include Library_Producer + +local hold_production; + +func Construction(object creator) +{ + SetAction("Default"); + return _inherited(creator, ...); +} + +/*-- Production --*/ + +public func IsProduct(id product_id) +{ + return product_id->~IsInventorProduct(); +} + +private func ProductionTime(id toProduce) { return 100; } +private func PowerNeed() { return 100; } + +public func OnProductionStart(id product) +{ + AddEffect("Working", this, 100, 1, this); + hold_production = false; +} + +public func OnProductionHold(id product) +{ + hold_production = true; +} + +public func OnProductionContinued(id product) +{ + hold_production = false; +} + +public func OnProductionFinish(id product) +{ + RemoveEffect("Working", this); +} + +protected func FxWorkingTimer() +{ + if(!hold_production) + Smoking(); +} + +private func Smoking() +{ + if (!Random(4)) Smoke(16 * GetCalcDir(),-14,16); + if (!Random(6)) Smoke(10 * GetCalcDir(),-14,15+Random(3)); +} + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Default", + }, +}; + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/StringTblDE.txt new file mode 100644 index 000000000..df8baa7bc --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=Keine Baupläne vorhanden +Construction=Konstruktion +Production=Produktion +Name=Erfinderlabor +Description=Hier können fortgeschrittene Technologien entwickelt werden. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/StringTblUS.txt new file mode 100644 index 000000000..eb44ef2b5 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=No construction plans +Construction=Construction +Production=Production +Name=Inventor's lab +Description=The right place to research advanced technology. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorDetail.png b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorDetail.png new file mode 100644 index 000000000..a2d12c239 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorDetail.png differ diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorMain.png b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorMain.png new file mode 100644 index 000000000..8f87ba502 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorMain.png differ diff --git a/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorTelescope.png b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorTelescope.png new file mode 100644 index 000000000..7e7dcd563 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/InventorsLab.ocd/inventorTelescope.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/DefCore.txt new file mode 100644 index 000000000..ee94b9735 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Kitchen +Version=5,2,90,21 +Category=C4D_Structure +Width=50 +Height=52 +Offset=-25,-26 +Vertices=6 +VertexX=-1,10,20,-23,-23,0 +VertexY=-17,-25,-14,25,25,25 +VertexFriction=50,50,50,100,100,100 +Value=200 +Mass=4500 +Components=Wood=3;Rock=2;Metal=1 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Graphics.mesh new file mode 100644 index 000000000..53264e571 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Kitchen.material b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Kitchen.material new file mode 100644 index 000000000..c719057b4 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Kitchen.material @@ -0,0 +1,18 @@ +material Kitchen +{ + receive_shadows on + technique + { + pass + { + scene_blend alpha_blend + + diffuse 1.0 1.0 1.0 1.0 + texture_unit + { + texture kitchen.png + tex_address_mode wrap + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Script.c new file mode 100644 index 000000000..5e39c5b0c --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/Script.c @@ -0,0 +1,85 @@ +/*-- Kitchen --*/ + +#include Library_Structure +#include Library_Ownable +#include Library_Producer + +local hold_production; + +func Construction(object creator) +{ + SetAction("Default"); + return _inherited(creator, ...); +} + +/*-- Production --*/ + +func IsProduct(id product_id) +{ + return product_id->~IsKitchenProduct(); +} + +private func ProductionTime(id toProduce) { return 500; } +private func PowerNeed() { return 0; } + +public func NeedRawMaterial(id rawmat_id) +{ + if (rawmat_id->~IsFuel() || rawmat_id == Flour) + return true; + return false; +} + +public func OnProductionStart(id product) +{ + AddEffect("Working", this, 100, 1, this); + hold_production = false; +} + +public func OnProductionHold(id product) +{ + hold_production = true; +} + +public func OnProductionContinued(id product) +{ + hold_production = false; +} + +public func OnProductionFinish(id product) +{ + RemoveEffect("Working", this); +} + +protected func FxWorkingTimer() +{ + if(!hold_production) + Smoking(); +} + +private func Smoking() +{ + if (!Random(4)) Smoke(16 * GetCalcDir(),-14,16); + if (!Random(6)) Smoke(10 * GetCalcDir(),-14,15+Random(3)); + + //Fire + CreateParticle("Fire", 13 * GetCalcDir(), 16, PV_Random(-1, 1), PV_Random(-1, 1), PV_Random(18, 36), Particles_Fire(), 2); +} + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Default", + }, +}; + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/StringTblDE.txt new file mode 100644 index 000000000..fe135be14 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=Keine Baupläne vorhanden +Construction=Konstruktion +Production=Produktion +Name=Küche +Description=Ermöglicht die Zubereitung von aller Art Nahrungsmitteln. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/StringTblUS.txt new file mode 100644 index 000000000..27422667c --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=No construction plans +Construction=Construction +Production=Production +Name=Kitchen +Description=A place to prepare various meals. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/kitchen.png b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/kitchen.png new file mode 100644 index 000000000..51f4734bd Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Kitchen.ocd/kitchen.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Loom.ocd/DefCore.txt new file mode 100644 index 000000000..bc4a246cf --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Loom.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Loom +Version=5,2,0,1 +Category=C4D_Structure +Width=40 +Height=29 +Offset=-20,-15 +Vertices=4 +VertexX=-20,20,-18,18 +VertexY=-4,-3,14,14 +VertexFriction=50,50,100,100 +Value=100 +Mass=1000 +Components=Wood=3;Metal=1;Rock=1 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Graphics.mesh new file mode 100644 index 000000000..b117c7d2e Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.material b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.material new file mode 100644 index 000000000..cbeb3e52c --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.material @@ -0,0 +1,29 @@ +material Loom +{ + receive_shadows on + + technique + { + pass Loom + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0 + specular 0.5 0.5 0.5 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + + alpha_to_coverage off + cull_hardware clockwise + depth_check on + depth_write on + scene_blend one zero + + texture_unit + { + texture Loom.png + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.png b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.png new file mode 100644 index 000000000..6fc12c819 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.skeleton b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.skeleton new file mode 100644 index 000000000..1604db1fa Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Loom.skeleton differ diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Script.c new file mode 100644 index 000000000..f39ac152c --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Loom.ocd/Script.c @@ -0,0 +1,103 @@ +/*-- Loom --*/ + +#include Library_Structure +#include Library_Ownable +#include Library_Producer + +local animWork; +local meshAttach; + +func Initialize() +{ + animWork = PlayAnimation("Working", 1, Anim_Const(0), Anim_Const(1000)); + return _inherited(...); +} + +func Construction(object creator) +{ + SetAction("Wait"); + return _inherited(creator, ...); +} + +/*-- Production --*/ + +public func IsProduct(id product_id) +{ + return product_id->~IsLoomProduct(); +} + +private func ProductionTime(id toProduce) { return 140; } +private func PowerNeed() { return 100; } + +public func NeedRawMaterial(id rawmat_id) +{ + return true; +} + +private func FxIntWorkAnimTimer(object target, proplist effect, int timer) +{ + if(effect.paused == true) return 1; + + var tickAmount = 50; + var animSpot = GetAnimationPosition(animWork); + //-50 is to dodge around an engine crash. If it reaches (near) the end of the + //animation, it dies for some reason. :( + var animLength = GetAnimationLength("Working") - 50; + + //loop anim + if(animSpot + tickAmount > animLength){ + SetAnimationPosition(animWork, Anim_Const(animSpot + tickAmount - animLength)); + } + //otherwise, advance animation + else SetAnimationPosition(animWork, Anim_Const(animSpot + tickAmount)); +} + +local workEffect; + +public func OnProductionStart(id product) +{ + workEffect = AddEffect("IntWorkAnim", this, 1,1,this); + return _inherited(...); +} + +public func OnProductionHold(id product) +{ + workEffect.paused = true; + return _inherited(...); +} + +public func OnProductionContinued(id product) +{ + workEffect.paused = false; + return _inherited(...); +} + +public func OnProductionFinish(id product) +{ + RemoveEffect(nil, this, workEffect); + return _inherited(...); +} + +func Definition(def){ + SetProperty("MeshTransformation", Trans_Rotate(70, 0,1,0), def); + SetProperty("PictureTransformation", Trans_Rotate(65,0,1,0), def); +} + +local ActMap = { + Wait = { + Prototype = Action, + Name = "Wait", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Wait", + }, +}; + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Loom.ocd/StringTblDE.txt new file mode 100644 index 000000000..feb616dbb --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Loom.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=Keine Baupläne vorhanden +Construction=Konstruktion +Production=Produktion +Name=Webstuhl +Description=Hier werden Stoffe hergestellt. diff --git a/planet/Objects.ocd/Structures.ocd/Loom.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Loom.ocd/StringTblUS.txt new file mode 100644 index 000000000..4292d6199 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Loom.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=No construction plans +Construction=Construction +Production=Production +Name=Loom +Description=Cloth is created here. diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Pump.ocd/DefCore.txt index 62d1f732f..593c0e1fe 100644 --- a/planet/Objects.ocd/Structures.ocd/Pump.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Pump.ocd/DefCore.txt @@ -11,8 +11,8 @@ VertexY=-3,15,15 VertexFriction=50,100,100 Value=40 Mass=400 -Components=Wood=3;Metal=1 -Picture=280,0,28,32 +Components=Wood=1;Metal=3; +Picture=3360,0,112,128,0,0 Exclusive=1 -BlastIncinerate=50 Construction=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Graphics.mesh new file mode 100644 index 000000000..9dd486b1b Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/Graphics.png b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Graphics.png deleted file mode 100644 index a323a008c..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Pump.ocd/Graphics.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Scene.material new file mode 100644 index 000000000..5d70528be --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Scene.material @@ -0,0 +1,25 @@ +// pumpJack genrated by blender2ogre 0.6.0 + +material pumpJack +{ + receive_shadows on + + technique + { + pass pumpJack + { + ambient 0.5 0.5 0.5 1.0 + diffuse 1 1 1 1.0 + specular 0.5 0.5 0.5 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + + texture_unit + { + texture pumpjack.png + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } + } + } +} diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Script.c index 28c821366..a0e67f191 100644 --- a/planet/Objects.ocd/Structures.ocd/Pump.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Pump.ocd/Script.c @@ -1,187 +1,399 @@ /*-- Pump - Author: Maikel, ST-DDT + Author: Maikel, ST-DDT, Sven2, Newton + + Pumps liquids using drain and source pipes. Features include: + + switch on and off + + consume/produce a variable amount of power depending on the height of + source and drain - Pumps liquids using drain and source pipes. --*/ +#include Library_Structure #include Library_Ownable #include Library_PowerConsumer - - -// This object is a liquid pump, thus pipes can be connected. -public func IsLiquidPump() { return true; } - -protected func Initialize() -{ - SetAction("Wait"); - MakePowerConsumer(100); - turned_on = true; - return; -} - -/*-- Interaction --*/ - -local turned_on; - -public func IsInteractable() { return GetCon() >= 100; } - -public func GetInteractionMetaInfo(object clonk) -{ - if (turned_on) - return { Description = "$MsgTurnOff$", IconName = nil, IconID = nil }; - return { Description = "$MsgTurnOn$", IconName = nil, IconID = nil }; -} - -// On interaction the pump can be turned on or off. -public func Interact(object clonk) -{ - if (turned_on) - { - turned_on = false; - SetAction("Wait"); - } - else - turned_on = true; - return true; -} - -/*-- Pipe connection --*/ - -local source_pipe; -local drain_pipe; - -// Set-Getters for source and drain pipe. -public func SetSource(object pipe) { source_pipe = pipe; } -public func GetSource() { return source_pipe; } -public func SetDrain(object pipe) { drain_pipe = pipe; } -public func GetDrain() { return drain_pipe; } - -func QueryWaivePowerRequest() -{ - // don't need power if not pumping anyway - if(GetAction() == "Wait") - return 50; - return 0; -} - -func OnNotEnoughPower() -{ - if(GetAction() == "Pump") - SetAction("Wait"); - return _inherited(...); -} - -func OnEnoughPower() -{ - OnWaitStart(); - return _inherited(...); -} - -protected func OnPumpStart() -{ - if (!ReadyToPump()) - SetAction("Wait"); - return; -} - -protected func OnWaitStart() -{ - if (ReadyToPump()) - SetAction("Pump"); - return; -} - -local aMaterials=["", 0]; //contained liquids -local pumpable_materials; // materials that can be pumped - -protected func Pumping() -{ - // Only if turned on. - if (!turned_on) - return SetAction("Wait"); - // Pump liquids. - if (!source_pipe) - return SetAction("Wait"); - //IsEmpty? - if ((aMaterials[1] == 0) || (aMaterials[0] == "")) - { - //Get new Materials - aMaterials = source_pipe->GetLiquid(pumpable_materials, 5, this, true); - //No Material to pump? - if ((aMaterials[0] == "") || (aMaterials[1] == 0)) - return; - } - if (drain_pipe) - aMaterials[1] -= BoundBy(drain_pipe->PutLiquid(aMaterials[0], aMaterials[1], this), 0, aMaterials[1]); - else - { - var i = Max(0, aMaterials[1]), itMaterial = Material(aMaterials[0]); - while (i--) - InsertMaterial(itMaterial); - aMaterials = ["", 0]; - } - //maybe add the possebility to empty pump (invaild mats?) - return; -} - -// Returns whether the pump can pump some liquid. -private func ReadyToPump() -{ - // no power? - if(!CurrentlyHasPower()) - return false; - // If there is no source pipe, return false. - if (!source_pipe) - return false; - // If there is nothing to pump at the source return false. - var source = source_pipe->GetConnectedObject(this); - if (!source) - return false; - if (!source->GBackLiquid()) - return false; - // TODO: Account for pumping into buildings. - // Pumping is okay. - return true; -} - -/** -Set name or wildcard string of materials this pump can pump -@param to_val: Material that can be pumped. 0 or "*" for any material. -*/ -public func SetPumpableMaterials(string to_val) -{ - pumpable_materials = to_val; - return true; -} +#include Library_PowerProducer local Name = "$Name$"; +local Description = "$Description$"; +local BlastIncinerate = 50; +local HitPoints = 70; + +/* + States + "Wait": turned off or source pipe not connected + "WaitForPower": turned on but no power (does consume power) + "WaitForLiquid": turned on but no liquid (does not consume power) + "Pump": currently working and consuming/producing power + +*/ local ActMap = { Pump = { Prototype = Action, Name = "Pump", - Procedure = DFA_NONE, - Length = 20, + Length = 30, Delay = 3, - X = 0, - Y = 0, - Wdt = 28, - Hgt = 32, + Sound = "Pumpjack", NextAction = "Pump", - StartCall = "OnPumpStart", + StartCall = "CheckState", PhaseCall = "Pumping" }, Wait = { Prototype = Action, Name = "Wait", - Procedure = DFA_NONE, - Length = 1, - Delay = 50, - X = 0, - Y = 0, - Wdt = 28, - Hgt = 32, + Delay = 90, NextAction = "Wait", - StartCall = "OnWaitStart" + EndCall = "CheckState" + }, + WaitForPower = { + Prototype = Action, + Name = "WaitForPower", + Delay = 30, + NextAction = "WaitForPower", + EndCall = "CheckState" + }, + WaitForLiquid = { + Prototype = Action, + Name = "WaitForLiquid", + Delay = 30, + NextAction = "WaitForLiquid", + EndCall = "CheckState" } }; + +local animation; // animation handle + +local switched_on; // controlled by Interaction. Indicates whether the user wants to pump or not + +local powered; // whether the pump has enough power as a consumer, always true if producing +local power_used; // the amount of power currently consumed or (if negative) produced + +local stored_material_index; //contained liquid +local stored_material_amount; + +local source_pipe; +local drain_pipe; + +/** This object is a liquid pump, thus pipes can be connected. */ +public func IsLiquidPump() { return true; } + +func Definition(def) +{ + // for title image + SetProperty("PictureTransformation",Trans_Rotate(50,0,1,0),def); + // for building preview + SetProperty("MeshTransformation",Trans_Rotate(50,0,1,0),def); +} + +func Construction() +{ + // Rotate at a 45 degree angle towards viewer and add a litte bit of Random + this.MeshTransformation = Trans_Rotate(50 + RandomX(-10,10),0,1,0); +} + +func Initialize() +{ + switched_on = true; + var start = 0; + var end = GetAnimationLength("pump"); + animation = PlayAnimation("pump", 5, Anim_Linear(GetAnimationPosition(animation), start, end, 35, ANIM_Loop), Anim_Const(1000)); + SetState("Wait"); +} + + +/*-- Interaction --*/ + +public func IsInteractable() { return GetCon() >= 100; } + +public func GetInteractionMetaInfo(object clonk) +{ + if (switched_on) + return { Description = "$MsgTurnOff$", IconName = nil, IconID = Icon_Stop }; + else + return { Description = "$MsgTurnOn$", IconName = nil, IconID = Icon_Play }; +} + +/** Turn on or off. */ +public func Interact(object clonk) +{ + switched_on = !switched_on; + CheckState(); + + return true; +} + +/*-- Pipe connection --*/ + +public func GetSource() { return source_pipe; } +public func SetDrain(object pipe) { drain_pipe = pipe; } +public func GetDrain() { return drain_pipe; } + +public func SetSource(object pipe) +{ + source_pipe = pipe; + CheckState(); +} + +/*-- Power stuff --*/ + +func QueryWaivePowerRequest() +{ + // has less priority than other objects, but not too low + return 10; +} + +func OnNotEnoughPower() +{ + _inherited(...); + powered = false; + CheckState(); +} + +func OnEnoughPower() +{ + _inherited(...); + powered = true; + CheckState(); +} + +/** Returns object to which the liquid is pumped */ +private func GetDrainObject() +{ + if (drain_pipe) return drain_pipe->GetConnectedObject(this) ?? this; + return this; +} + +/** Re turns object to which the liquid is pumped */ +private func GetSourceObject() +{ + if (source_pipe) return source_pipe->GetConnectedObject(this) ?? this; + return this; +} + +/** Returns amount of pixels to pump per 30 frames */ +public func GetPumpSpeed() +{ + return 50; +} + +/** PhaseCall of Pump: Pump the liquid from the source to the drain pipe */ +protected func Pumping() +{ + // at this point we can assert that we have power + + // something went wrong in the meantime? + // let the central function handle that on next check + if (!source_pipe) return; + + var pump_ok = true; + + // is empty? -> try to get liquid + if (!stored_material_amount) + { + + // get new materials + var aMat = GetSourceObject()->ExtractLiquidAmount(0,0, GetPumpSpeed()/10); + + // no material to pump? + if (aMat) + { + stored_material_index = aMat[0]; + stored_material_amount = aMat[1]; + } + else + { + pump_ok = false; + } + } + if (pump_ok) + { + var i = stored_material_amount; + while (i > 0) + { + if (GetDrainObject()->InsertMaterial(stored_material_index)) + { + i--; + } + // Drain is stuck. + else + { + pump_ok = false; + break; + } + } + + stored_material_amount = i; + if (stored_material_amount <= 0) + stored_material_index = nil; + } + + if(!pump_ok) + { + SetState("WaitForLiquid"); + } +} + +/** Re check state and change the state if needed */ +func CheckState() +{ + var is_fullcon = GetCon() >= 100; + var can_pump = source_pipe && is_fullcon && switched_on; + + // can't pump at all -> wait + if (!can_pump) + { + SetState("Wait"); + } + else + { + // can pump but has no liquid -> wait for liquid + if (!HasLiquidToPump()) + { + SetState("WaitForLiquid"); + } + else + { + // can pump, has liquid but has no power -> wait for power + if (!powered) + { + SetState("WaitForPower"); + } + // otherwise, pump! :-) + else + { + SetState("Pump"); + } + + // regularly update the power usage while pumping or waiting for power + UpdatePowerUsage(); + } + } +} + +/** Get current height the pump has to push liquids upwards (input.y - output.y) */ +private func GetPumpHeight() +{ + // compare each the surfaces of the bodies of liquid pumped + + // find Y position of surface of liquid that is pumped to target + var source_y = 0; + if (GetSourceObject()->GBackLiquid()) + { + var src_mat = GetSourceObject()->GetMaterial(); + while (src_mat == GetSourceObject()->GetMaterial(0, source_y-1)) + --source_y; + } + // same for target (use same function as if inserting) + var target_pos = {X=0, Y=0}; + GetDrainObject()->CanInsertMaterial(Material("Water"),0,0,target_pos); + return (GetSourceObject()->GetY() + source_y) - target_pos.Y; +} + +/** Recheck power usage/production for current pump height + and make the pump a producer / consumer for the power system */ +private func UpdatePowerUsage() +{ + var new_power; + if(IsUsingPower()) + new_power = PumpHeight2Power(GetPumpHeight()); + else + new_power = 0; + + // do nothing if not necessary + if (new_power == power_used) + return; + + // and update energy system + if (new_power > 0) + { + if (power_used < 0) + { + powered = false; // needed since the flag was set manually + UnmakePowerProducer(); + } + MakePowerConsumer(new_power); + + } + else if (new_power < 0) + { + if (power_used > 0) + UnmakePowerConsumer(); + MakePowerProducer(-new_power); + powered = true; // when producing, we always have power + } + else // new_power == 0 + { + if (power_used < 0) UnmakePowerProducer(); + else if (power_used > 0) UnmakePowerConsumer(); + powered = true; + } + + power_used = new_power; +} + +/** Return whether the pump should be using power in the current state */ +private func IsUsingPower() +{ + return switched_on && (GetAction() == "Pump" || GetAction() == "WaitForPower"); +} + +/** Transform pump height (input.y - output.y) to required power */ +private func PumpHeight2Power(int pump_height) +{ + // pumping downwards will only produce energy after an offset + var power_offset = 40; + // max power consumed/produced + var max_power = 150; + + return BoundBy((pump_height + power_offset)/15*5, -max_power,max_power+power_offset); +} + +/** Returns whether there is liquid at the source pipe to pump */ +private func HasLiquidToPump() +{ + if (!source_pipe) + return false; + + // source + if(!GetSourceObject()->GBackLiquid()) + return false; + + // target (test with the very popular liquid "water") + if(!GetDrainObject()->CanInsertMaterial(Material("Water"),0,0)) + return false; + + return true; +} + +/** Set the state of the pump, retaining the animation position and updating the power usage */ +func SetState(string act) +{ + if(act == GetAction()) return; + + var start = 0; + var end = GetAnimationLength("pump"); + var anim_pos = GetAnimationPosition(animation); + if (act == "Pump") + { + SetAnimationPosition(animation, Anim_Linear(anim_pos, start, end, 35, ANIM_Loop)); + } + else if(act == "WaitForLiquid") + { + SetAnimationPosition(animation, Anim_Linear(anim_pos, start, end, 350, ANIM_Loop)); + } + else + { + SetAnimationPosition(animation, Anim_Const(anim_pos)); + } + + // deactivate power usage when not pumping + if (powered && (act == "Wait" || act == "WaitForLiquid")) + { + if (power_used < 0) UnmakePowerProducer(); + else if(power_used > 0) UnmakePowerConsumer(); + power_used = 0; + powered = false; + } + // finally, set the action + SetAction(act); +} \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblDE.txt index 1900cce26..3094f587f 100644 --- a/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblDE.txt @@ -1,3 +1,4 @@ Name=Pumpe +Description=Die Pumpe kann beliebige Flüssigkeiten von A nach B pumpen. Pumpt sie Flüssigkeiten abwärts, erzeugt sie dabei sogar ein wenig Strom. MsgTurnOff=Pumpe abschalten MsgTurnOn=Pumpe anschalten \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblUS.txt index b63eb7d14..1766dc927 100644 --- a/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Pump.ocd/StringTblUS.txt @@ -1,3 +1,4 @@ Name=Pump +Description=The pump can transport liquid from A to B. If it pumps liquids downwards, it even generates a bit of power. MsgTurnOff=Turn off pump MsgTurnOn=Turn on pump \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/pumpjack.png b/planet/Objects.ocd/Structures.ocd/Pump.ocd/pumpjack.png new file mode 100644 index 000000000..7c16c4342 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Pump.ocd/pumpjack.png differ diff --git a/planet/Objects.ocd/Structures.ocd/Pump.ocd/pumpjack.skeleton b/planet/Objects.ocd/Structures.ocd/Pump.ocd/pumpjack.skeleton new file mode 100644 index 000000000..81fe650b3 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Pump.ocd/pumpjack.skeleton differ diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Authors.txt b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Authors.txt index 96d7232a6..515ef3c3c 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Authors.txt +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Authors.txt @@ -1,3 +1,3 @@ -CC-BY-3.0 +CC0 1.0 -SawmillRipcut - benboncan (http://www.freesound.org/people/Benboncan/sounds/87952/) \ No newline at end of file +SawmillRipcut - kolczok (http://freesound.org/people/kolczok/sounds/198988/) \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Belt.jpg b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Belt.jpg new file mode 100644 index 000000000..2afb31419 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Belt.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Belt.png b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Belt.png deleted file mode 100644 index 771408c41..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Belt.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/DefCore.txt index 94292fc63..ea0c20609 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Sawmill Version=5,2,0,1 Category=C4D_Structure -TimerCall=FindTrees -Timer=35 Width=50 Height=31 Offset=-25,-15 @@ -13,10 +11,8 @@ VertexY=-14,-13,14,-13,14,14 VertexFriction=50,50,100,50,100,100 Value=50 Mass=1500 -Components=Rock=4;Wood=2; -Collection=0,0,13,13 -#Entrance=-30,-15,30,30 +Components=Rock=4;Wood=1; Exclusive=1 -BlastIncinerate=100 Construction=1 -ContainBlast=1 \ No newline at end of file +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Sawmill.jpg b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Sawmill.jpg new file mode 100644 index 000000000..aececb22e Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Sawmill.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Sawmill.png b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Sawmill.png deleted file mode 100644 index 25bce39c4..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Sawmill.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/SawmillRipcut.ogg b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/SawmillRipcut.ogg index a54846079..a19896f7a 100644 Binary files a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/SawmillRipcut.ogg and b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/SawmillRipcut.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Scene.material index 7d051262f..e87883280 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Scene.material @@ -47,7 +47,7 @@ material SawmillBelt emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Belt.png + texture Belt.jpg tex_address_mode wrap filtering trilinear } @@ -81,7 +81,7 @@ material Sawmill emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Sawmill.png + texture Sawmill.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c index 97b82d3e5..995e52b87 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c @@ -5,19 +5,21 @@ Cuts trees or other objects into wood. Accepts only objects purely made from wood. --*/ +#include Library_Structure #include Library_Ownable #include Library_Producer -public func Construction() +public func Construction(object creator) { - SetProperty("MeshTransformation",Trans_Rotate(-20,0,1,0)); - return _inherited(...); + SetAction("Default"); + return _inherited(creator, ...); } public func Initialize() { this.SpinAnimation = PlayAnimation("work", 10, Anim_Const(0), Anim_Const(1000)); + AddTimer("CollectionZone", 1); return _inherited(...); } @@ -26,12 +28,15 @@ public func Initialize() // Sawmill can't be accessed as a container. public func IsContainer() { return false; } +// Sawmill can't be interacted with. +public func IsInteractable() { return false; } + // Automatically search for trees in front of sawmill // Temporary solution? protected func FindTrees() { var tree = FindObject(Find_AtPoint(), Find_Func("IsTree"), Find_Not(Find_Func("IsStanding")), Find_Func("GetComponent", Wood)); - if (!tree || GetCon() < 100) return; + if (!tree) return; Saw(tree); } @@ -60,8 +65,8 @@ private func IsProduct(id product_id) { return product_id->~IsSawmillProduct(); } -private func ProductionTime() { return 100; } -private func PowerNeed() { return 100; } +private func ProductionTime(id toProduce) { return 100; } +private func PowerNeed() { return 50; } public func NeedRawMaterial(id rawmat_id) { @@ -103,6 +108,17 @@ public func OnProductionFinish(id product) } } +// Timer, check for objects to collect in the designated collection zone +func CollectionZone() +{ + if (GetCon() < 100) return; + + // Only take one tree at a time + if (!(FrameCounter() % 35)) + if (GetLength(queue) == 0) + FindTrees(); +} + protected func Collection() { Sound("Clonk"); @@ -110,17 +126,18 @@ protected func Collection() public func FxSawingTimer(object target, proplist effect, int time) { + var dir = GetCalcDir(); if (time >= this.SpinStep * 3 && time % 5) - CreateParticle("Axe_WoodChip", 6 - Random(3), RandomX(1,4), 5 + Random(11), -RandomX(2,4), 15+Random(10), RGB(255,255,255), this); + CreateParticle("WoodChip", PV_Random(-7 * dir, -3 * dir), PV_Random(3, 6), PV_Random(-5 * dir, -11 * dir), PV_Random(-4, -2), PV_Random(36 * 3, 36 * 10), Particles_WoodChip(), 3); if (!(time % 20)) - Smoke(-10,10,10); + Smoke(10 * GetCalcDir(),10,10); } public func OnProductEjection(object product) { - product->SetPosition(GetX() + 25, GetY() - 8); - product->SetSpeed(7, 5); + product->SetPosition(GetX() - 25 * GetCalcDir(), GetY() - 8); + product->SetSpeed(-7 * GetCalcDir(), 5); product->SetR(30 - Random(59)); Sound("Pop"); } @@ -171,8 +188,25 @@ private func SpinOff(int call, int animation_no) ScheduleCall(this, "SpinOff", this.SpinStep * 2, nil, call+1); } +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Default", + }, +}; + 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 SpinStep = 30; \ No newline at end of file +local Description = "$Description$"; +local SpinStep = 30; +local BlastIncinerate = 100; +local HitPoints = 70; diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblDE.txt index 754ee28b4..a090cc26d 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblDE.txt @@ -1 +1,2 @@ -Name=Sägewerk \ No newline at end of file +Name=Sägewerk +Description=Das Sägewerk kann Bäume effizient in Holz zersägen, braucht dazu aber Strom. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblUS.txt index 3a112470f..abfa9c73f 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/StringTblUS.txt @@ -1 +1,2 @@ -Name=Sawmill \ No newline at end of file +Name=Sawmill +Description=The sawmill can efficiently saw trees into wooded logs, but needs power to function. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/DefCore.txt new file mode 100644 index 000000000..33d13c576 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Shipyard +Version=5,2,90,21 +Category=C4D_Structure +Width=128 +Height=106 +Offset=-64,-53 +Vertices=6 +VertexX=0,-64,58,-64,59, 0 +VertexY=53,53,53, 3, 3,-17 +VertexFriction=100,100,100,50,50,50 +Value=200 +Mass=4500 +Components=Wood=12;Metal=6 +Exclusive=1 +Construction=1 +ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Graphics.mesh b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Graphics.mesh new file mode 100644 index 000000000..41cef9ab6 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Scene.material new file mode 100644 index 000000000..9f611ba68 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Scene.material @@ -0,0 +1,50 @@ +material Shipyard +{ + receive_shadows on + technique + { + pass + { + diffuse 1.0 1.0 1.0 1.0 + texture_unit + { + texture shipyard.jpg + tex_address_mode wrap + filtering trilinear + } + } + } +} + +material Shipyard.Door +{ + receive_shadows on + technique + { + pass + { + diffuse 1.0 1.0 1.0 1.0 + texture_unit + { + texture shipyardDoor.png + tex_address_mode wrap + filtering trilinear + } + } + } +} + +material Shipyard.DoorRaise : Shipyard.Door +{ + technique 0 + { + pass 0 + { + scene_blend alpha_blend + texture_unit 0 + { + scroll_anim 0 0.75 + } + } + } +} \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Script.c new file mode 100644 index 000000000..6fe1ea86b --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Script.c @@ -0,0 +1,105 @@ +/*-- Shipyard --*/ + +#include Library_Structure +#include Library_Ownable +#include Library_Producer + +local animWork; +local meshAttach; + +func Initialize() +{ + animWork = PlayAnimation("Work", 1, Anim_Const(0), Anim_Const(1000)); + return _inherited(...); +} + +func Construction(object creator) +{ + SetAction("Wait"); + return _inherited(creator, ...); +} + +/*-- Production --*/ + +public func IsProduct(id product_id) +{ + return product_id->~IsShipyardProduct(); +} + +private func ProductionTime(id toProduce) { return 400; } +private func PowerNeed() { return 150; } + +public func NeedRawMaterial(id rawmat_id) +{ + return true; +} + +private func FxIntWorkAnimTimer(object target, proplist effect, int timer) +{ + if(effect.paused == true) return 1; + +// Message("Working..."); + + var tickAmount = 50; + var animSpot = GetAnimationPosition(animWork); + //-50 is to dodge around an engine crash. If it reaches (near) the end of the + //animation, it dies for some reason. :( + var animLength = GetAnimationLength("Work") - 50; + + //loop anim + if(animSpot + tickAmount > animLength){ + SetAnimationPosition(animWork, Anim_Const(animSpot + tickAmount - animLength)); + } + //otherwise, advance animation + else SetAnimationPosition(animWork, Anim_Const(animSpot + tickAmount)); +} + +local workEffect; + +public func OnProductionStart(id product) +{ + workEffect = AddEffect("IntWorkAnim", this, 1,1,this); + return _inherited(...); +} + +public func OnProductionHold(id product) +{ + workEffect.paused = true; + return _inherited(...); +} + +public func OnProductionContinued(id product) +{ + workEffect.paused = false; + return _inherited(...); +} + +public func OnProductionFinish(id product) +{ + RemoveEffect(nil, this, workEffect); + return _inherited(...); +} + +func Definition(def){ + SetProperty("MeshTransformation", Trans_Rotate(8, 0,1,0), def); + SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,-25000,50000), Trans_Scale(500)), def); +} + +local ActMap = { + Wait = { + Prototype = Action, + Name = "Wait", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Wait", + }, +}; + +local Name = "$Name$"; +local Description ="$Description$"; +local BlastIncinerate = 100; +local HitPoints = 70; diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Shipyard.skeleton b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Shipyard.skeleton new file mode 100644 index 000000000..722d737c0 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/Shipyard.skeleton differ diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/StringTblDE.txt new file mode 100644 index 000000000..aeccef599 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/StringTblDE.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=Keine Baupläne vorhanden +Construction=Konstruktion +Production=Produktion +Name=Schiffswerft +Description=Wird zur Herstellung von Luftschiffen benötigt. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/StringTblUS.txt new file mode 100644 index 000000000..c2067cacc --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/StringTblUS.txt @@ -0,0 +1,5 @@ +NoPlrKnowledge=No construction plans +Construction=Construction +Production=Production +Name=Shipyard +Description=Needed for the production of airships. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/shipyard.jpg b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/shipyard.jpg new file mode 100644 index 000000000..6c3c781cc Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/shipyard.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/shipyardDoor.png b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/shipyardDoor.png new file mode 100644 index 000000000..461a5bf47 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Shipyard.ocd/shipyardDoor.png differ diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/DefCore.txt index db8738e8d..b877be01e 100644 --- a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/DefCore.txt @@ -2,7 +2,6 @@ id=SteamEngine Version=5,2,0,1 Category=C4D_Structure -TimerCall=ContentsCheck Width=66 Height=48 Offset=-33,-24 @@ -13,8 +12,8 @@ VertexFriction=50,50,100,100 Value=180 Mass=4000 Components=Rock=6;Metal=3 -Collection=-31,9,10,10 +Collection=-33,7,12,12 Exclusive=1 -BlastIncinerate=130 Construction=1 ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Scene.material index 42a1053b2..2cf2f5951 100644 --- a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Scene.material @@ -11,7 +11,7 @@ material Steam emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture steam.png + texture steam.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c index d6f783931..2b29d13fe 100644 --- a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c @@ -1,33 +1,39 @@ /*-- Steam engine --*/ +#include Library_Structure #include Library_Ownable #include Library_PowerProducer +#include Library_Flag + +local DefaultFlagRadius = 200; static const SteamEngine_produced_power = 300; local iFuelAmount; local power_seconds; -func Construction() +func Construction(object creator) { iFuelAmount = 0; power_seconds = 0; - return _inherited(...); + + SetAction("Default"); + AddTimer("ContentsCheck", 30); + return _inherited(creator, ...); } public func IsContainer() { return true; } -protected func RejectEntrance(object obj) +func RejectCollect(id item, object obj) { - if (obj->~IsFuel()) + if (obj->~IsFuel()) return false; return true; } -protected func RejectCollect(id item, object obj) +func Collection(object obj, bool put) { - // Just return RejectEntrance for this object. - return RejectEntrance(obj); + Sound("Clonk"); } func ContentsCheck() @@ -41,7 +47,7 @@ func ContentsCheck() } // Still active? - if(!ActIdle()) return true; + if(GetAction() == "Work") return true; // or still warm water in the tank?! if(GetEffect("CreatesPower", this)) return true; @@ -79,7 +85,7 @@ func ConsumeFuel() // All used up? if(!iFuelAmount || ((GetPendingPowerAmount() == 0) && (GetCurrentPowerBalance() >= SteamEngine_produced_power))) { - SetAction("Idle"); + SetAction("Default"); ContentsCheck(); } } @@ -91,6 +97,7 @@ func FxCreatesPowerStart(target, effect, temp) MakePowerProducer(SteamEngine_produced_power); AddEffect("Smoking", this, 1, 5, this); + Sound("SteamEngine", false, nil, nil, 1); } func FxCreatesPowerTimer(target, effect) @@ -107,30 +114,46 @@ func FxCreatesPowerStop(target, effect, reason, temp) if(GetEffect("Smoking", this)) RemoveEffect("Smoking", this); + Sound("SteamEngine", false, nil, nil, -1); } func FxSmokingTimer() { - Smoke(20, -15, 10); + Smoke(-20 * GetCalcDir(), -15, 10); return 1; } local ActMap = { -Work = { - Prototype = Action, - Name = "Work", - Procedure = DFA_NONE, - Directions = 2, - FlipDir = 1, - Length = 20, - Delay = 2, - NextAction = "Work", - Animation = "Work", - EndCall = "ConsumeFuel", -}, + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Default", + }, + Work = { + Prototype = Action, + Name = "Work", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 20, + Delay = 2, + FacetBase = 1, + NextAction = "Work", + Animation = "Work", + EndCall = "ConsumeFuel", + }, }; -local Name = "$Name$"; func Definition(def) { SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(25,0,1,0), Trans_Scale(625)), def); -} \ No newline at end of file +} +local BlastIncinerate = 130; +local HitPoints = 100; +local Name = "$Name$"; +local Description = "$Description$"; diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblDE.txt index 6d14c0fff..ab6fca619 100644 --- a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblDE.txt @@ -1,2 +1,2 @@ Name=Dampfmaschine - +Description=Die Dampfmaschine erzeugt Strom aus Brennstoffen wie Kohle, Holz oder Öl. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblUS.txt index bb4b5325e..bda144dd0 100644 --- a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/StringTblUS.txt @@ -1 +1,2 @@ Name=Steam engine +Description=The steam engine generates electricity from fuel, such as coal, wood or oil. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/steam.jpg b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/steam.jpg new file mode 100644 index 000000000..cc989880f Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/steam.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/steam.png b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/steam.png deleted file mode 100644 index 825fd9338..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/steam.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/DefCore.txt index 2ccfc208d..7709303a2 100644 --- a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/DefCore.txt @@ -9,7 +9,8 @@ Vertices=2 VertexX=0,0, VertexY=-19,19 VertexCNAT=4,8 -SolidMask=8,0,8,40,0,0 +SolidMask=0,0,8,40,0,0 Value=10 Mass=1000 Components=Rock=10; +HorizontalFix=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Graphics.4.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Graphics.4.png index cec18f99b..89c9295cf 100644 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Graphics.4.png and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Graphics.4.png differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked1.4.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked1.4.png index f4186e04d..cba8e9569 100644 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked1.4.png and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked1.4.png differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked2.4.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked2.4.png index 805083aea..c7fe8b371 100644 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked2.4.png and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked2.4.png differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked3.4.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked3.4.png index e6a241eb2..da4cc24b0 100644 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked3.4.png and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/GraphicsCracked3.4.png differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Script.c index 8c1b6ea36..fc368c4ab 100644 --- a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/Script.c @@ -72,7 +72,7 @@ protected func FxAutoControlTimer(object target, effect, int time) { var plr = clonk->GetOwner(); var plr_team = GetPlayerTeam(plr); - if (plr_team == team) + if (team == 0 || plr_team == team) open_door = true; } // Player control @@ -91,6 +91,12 @@ protected func FxAutoControlTimer(object target, effect, int time) return 1; } +func FxAutoControlSaveScen(obj, fx, props) +{ + props->AddCall("AutoControl", obj, "SetAutoControl", fx.team); + return true; +} + /*-- Destruction --*/ private func GetStrength() { return 180; } diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SolidMask.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SolidMask.png new file mode 100644 index 000000000..38b25f49c Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Base.jpg b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Base.jpg new file mode 100644 index 000000000..ead18778e Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Base.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Base.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Base.png deleted file mode 100644 index 8c3de3691..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Base.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Brass.jpg b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Brass.jpg new file mode 100644 index 000000000..2e9982515 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Brass.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Brass.png b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Brass.png deleted file mode 100644 index 30867f541..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Brass.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Chain.ogg b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Chain.ogg index c4fed2dd6..b1705e13e 100644 Binary files a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Chain.ogg and b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Chain.ogg differ diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Scene.material index 37302f4f0..219a74469 100644 --- a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Scene.material @@ -11,7 +11,7 @@ material Base emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Base.png + texture Base.jpg tex_address_mode wrap filtering trilinear } @@ -31,7 +31,7 @@ material Gear emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Brass.png + texture Brass.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Script.c index 8134b1924..6caa1d633 100644 --- a/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/StoneDoor.ocd/SpinWheel.ocd/Script.c @@ -33,6 +33,13 @@ public func ControlDown(object clonk) } } +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (targetdoor) props->AddCall("Target", this, "SetStoneDoor", targetdoor); + return true; +} + local ActMap = { Still = { Prototype = Action, diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/DefCore.txt index e945cc51d..af51ac5d6 100644 --- a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/DefCore.txt @@ -12,8 +12,7 @@ VertexFriction=50,50,100,100 Value=200 Mass=4500 Components=Wood=6;Metal=3 -Collection=2,5,20,10 Exclusive=1 -BlastIncinerate=100 Construction=1 ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Scene.material index 132aee54a..4e22db41d 100644 --- a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Scene.material @@ -11,7 +11,7 @@ material ToolsWorkshop emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture workshop.png + texture workshop.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Script.c index f1521ea88..4059aeb7e 100644 --- a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/Script.c @@ -1,20 +1,24 @@ /*-- Tools workshop --*/ +#include Library_Structure #include Library_Ownable #include Library_Producer local hold_production; +public func Construction(object creator) +{ + SetAction("Default"); + return _inherited(creator, ...); +} + public func Initialize() { - // SetProperty("MeshTransformation", Trans_Rotate(RandomX(-30,30),0,1,0)); hold_production = false; return _inherited(...); } - - /*-- Production --*/ public func IsProduct(id product_id) @@ -22,7 +26,7 @@ public func IsProduct(id product_id) return product_id->~IsToolProduct(); } -private func ProductionTime() { return 150; } +private func ProductionTime(id toProduce) { return 150; } private func PowerNeed() { return 100; } public func NeedRawMaterial(id rawmat_id) @@ -66,33 +70,36 @@ protected func FxWorkingTimer() private func Smoking() { - if (Random(6)) Smoke(+16,-14,16); - if (Random(8)) Smoke(10,-14,15+Random(3)); + if (Random(6)) Smoke(16 * GetCalcDir(),-14,16); + if (Random(8)) Smoke(10 * GetCalcDir(),-14,15+Random(3)); return 1; } public func SetSign(id def) { if (!def) - return SetGraphics("", nil, 1, 4); - SetGraphics("", def, 1, 4); - SetObjDrawTransform(200, 0, 19500, 0, 200, 2500, 1); + return SetGraphics("", nil, GFX_Overlay, 4); + SetGraphics("", def, GFX_Overlay, 4); + SetObjDrawTransform(200, 0, -19500 * GetCalcDir(), 0, 200, 2500, GFX_Overlay); } local ActMap = { - Build = { + Default = { Prototype = Action, - Name = "Build", + Name = "Default", Procedure = DFA_NONE, - Length = 40, - Delay = 1, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, FacetBase=1, - NextAction = "Build", - //Animation = "Turn", - PhaseCall="Smoking", + NextAction = "Default", }, }; 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 BlastIncinerate = 100; +local HitPoints = 70; diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblDE.txt index e4fa198e1..f150b9126 100644 --- a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblDE.txt @@ -1,4 +1,5 @@ NoPlrKnowledge=Keine Baupläne vorhanden Construction=Konstruktion Production=Produktion -Name=Werkzeughütte \ No newline at end of file +Name=Werkzeughütte +Description=Hier können viele wichtige Werkzeuge zum Bergbau, zum Bäume fällen und zur Erkundung hergestellt werden. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblUS.txt index eb20a5b4a..0daebb91a 100644 --- a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/StringTblUS.txt @@ -1,4 +1,5 @@ NoPlrKnowledge=No construction plans Construction=Construction Production=Production -Name=Tools workshop \ No newline at end of file +Name=Tools workshop +Description=Many important tools for mining, chopping down trees and exploration can be produced here. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/workshop.jpg b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/workshop.jpg new file mode 100644 index 000000000..8d0611362 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/workshop.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/workshop.png b/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/workshop.png deleted file mode 100644 index 4e80dbcf1..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/ToolsWorkshop.ocd/workshop.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/DefCore.txt index b7f6f2921..23d6c06bd 100644 --- a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/DefCore.txt @@ -2,21 +2,17 @@ id=WindGenerator Version=5,2,0,1 Category=C4D_Structure -TimerCall=Wind2Turn -Timer=35 Width=24 Height=70 Offset=-12,-35 Vertices=5 VertexX=0,-9,9,-9,9 -VertexY=-33,-25,-25,34,34 +VertexY=-27,-25,-25,34,34 VertexFriction=50,50,50,100,100 Value=45 Mass=900 -Components=Wood=4;Metal=1 +Components=Wood=3;Metal=1 Exclusive=1 -ContactIncinerate=4 -BlastIncinerate=60 Construction=1 Rotate=1 Float=1 diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Scene.material index f0ac04246..8592b44f2 100644 --- a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Scene.material @@ -11,7 +11,7 @@ material Windgenerator emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture windgenerator.png + texture windgenerator.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Script.c index 62c79dd96..a36d02f3a 100644 --- a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Script.c @@ -1,15 +1,20 @@ /*-- Wind generator --*/ +#include Library_Structure #include Library_Ownable #include Library_PowerProducer +#include Library_Flag -public func GetCapacity() { return 500; } -public func GetGeneratorPriority() { return 256; } +local DefaultFlagRadius = 90; /* Initialisierung */ local wind_anim; local last_wind; + +func TurnAnimation(){return "Turn";} +func MinRevolutionTime(){return 4500;} // in frames + protected func Construction() { SetProperty("MeshTransformation",Trans_Mul(Trans_Rotate(RandomX(-15,15),0,1,0), Trans_Translate(1200,0,0))); @@ -18,49 +23,73 @@ protected func Construction() protected func Initialize() { - wind_anim = PlayAnimation("Turn", 5, Anim_Const(0), Anim_Const(1000)); + // create wheel + (this.wheel = CreateObject(WindGenerator_Wheel, 0, 0, NO_OWNER))->Set(this); + + // Start animation + wind_anim = PlayAnimation(TurnAnimation(), 5, this.wheel->Anim_R(0, GetAnimationLength(TurnAnimation())), Anim_Const(1000)); + // Set initial position + AddTimer("Wind2Turn"); Wind2Turn(); return _inherited(...); } +// used by the windmill too +// returns the wind weighted over several points - not the absolute value! +func GetWeightedWind() +{ + // hardcoded for performance reasons + return ( + (10 * (GetWind(-150, -30))) + + (25 * (GetWind(-75, -30))) + + (30 * (GetWind(0, -30))) + + (25 * (GetWind(+75, -30))) + + (10 * (GetWind(+150, -30))) + ) / 100; +} + +// used by the windmill too func Wind2Turn() { if(GetCon() < 100) return; - var power = Abs(GetWind()); - if(power < 5) power = 0; - else power = Max(((power + 5) / 25), 1) * 50; - + var current_wind = this->GetWeightedWind(); + var power = 0; + if(this.wheel->Stuck() || this.wheel->HasStopped()) + { + power = 0; + } + else + { + power = Abs(this.wheel->GetRDir(this->MinRevolutionTime()/90)); + if(power < 5) power = 0; + else power = Max(((power + 5) / 25), 1) * 50; + } + if(last_wind != power) { last_wind = power; MakePowerProducer(last_wind); } - // Fade linearly in time until next timer call - var start = 0; - var end = GetAnimationLength("Turn"); - if(GetWind() < 0) - { - start = end; - end = 0; - } - // Number of frames for one revolution: the more wind the more - // revolutions per frame. - var wind = Abs(GetWind()); - if(wind == 0) wind = 1; - var l = 4500/wind; - - // Note ending is irrelevant since this is called again after 35 frames - if(l > 0) + // adjust wheel speed + this.wheel->SetRDir(current_wind*90, this->MinRevolutionTime()); + // make sounds + if (Abs(current_wind) >= 10 && Random(15 - Abs(current_wind / 10)) < 5) { - SetAnimationPosition(wind_anim, Anim_Linear(GetAnimationPosition(wind_anim), start, end, l, ANIM_Loop)); - } - else - { - SetAnimationPosition(wind_anim, Anim_Const(GetAnimationPosition(wind_anim))); + if (!Random(2)) + Sound("WoodCreak?",false,nil,nil,nil, 75); + else + Sound("HingeCreak?",false,nil,nil,nil, 75); } } +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 BlastIncinerate = 60; +local ContactIncinerate = 5; +local HitPoints = 50; diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblDE.txt index 2357b3908..20d3becc9 100644 --- a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblDE.txt @@ -1 +1,2 @@ Name=Windrad +Description=Erzeugt Strom bei Wind. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblUS.txt index cfd91cfa3..c3eb8f927 100644 --- a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/StringTblUS.txt @@ -1 +1,2 @@ Name=Wind generator +Description=Generates electricity from the wind. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/DefCore.txt new file mode 100644 index 000000000..a1ddf8de5 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/DefCore.txt @@ -0,0 +1,16 @@ +[DefCore] +id=WindGenerator_Wheel +Version=4,10,0,0 +Category=C4D_Vehicle | C4D_MouseIgnore +Width=50 +Height=50 +Offset=-25,-25 +Vertices=6 +VertexX=0,4,25,13,-20, -25 +VertexY=0,-24,-3,25,21, -10 +VertexFriction=100, 100, 100, 100, 100 +Rotate=1 +NoStabilize=1 +IncompleteActivity=1 +StretchGrowth=1 +Oversize=1 diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/Graphics.png b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/Graphics.png new file mode 100644 index 000000000..420625dee Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/Script.c new file mode 100644 index 000000000..d739441d0 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/Script.c @@ -0,0 +1,42 @@ +/** + Wheel + Invisible helper object. Takes care of collisions. + +*/ + +local ActMap = { + Turn = { + Prototype = Action, + Name = "Turn", + Procedure = DFA_ATTACH, + Length = 1, + Delay = 0, + FacetBase=1, + NextAction = "Hold", + } +}; + +func Initialize() +{ + +} + +func AttachTargetLost() +{ + return RemoveObject(); +} + +func HasStopped() +{ + return !GetRDir(1000); +} + +func Set(to, con) +{ + con = con ?? 100; + SetCon(con); + SetAction("Turn", to); +} + +// Don't duplicate on scenario load +func SaveScenarioObject() { return false; } \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/StringTblDE.txt new file mode 100644 index 000000000..ad6bd3366 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Wheel.ocd +Description=Invisible helper object. Takes care of collisions. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/StringTblUS.txt new file mode 100644 index 000000000..ad6bd3366 --- /dev/null +++ b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/Wheel.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Wheel.ocd +Description=Invisible helper object. Takes care of collisions. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/windgenerator.jpg b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/windgenerator.jpg new file mode 100644 index 000000000..8a1f4550c Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/windgenerator.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/windgenerator.png b/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/windgenerator.png deleted file mode 100644 index 57d83cd7f..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/WindGenerator.ocd/windgenerator.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/DefCore.txt index ef3dbd41d..5996f1897 100644 --- a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/DefCore.txt @@ -2,20 +2,17 @@ id=Windmill Version=5,2,0,1 Category=C4D_Structure -TimerCall=Wind2Turn -Timer=35 Width=50 Height=96 Offset=-25,-48 Vertices=5 VertexX=0,25,15,-15,-25 -VertexY=-47,-20,47,47,-20 +VertexY=-10,-20,47,47,-20 VertexFriction=50,50,100,100,50 Value=150 Mass=2500 Components=Rock=6;Wood=2; -Collection=-18,35,15,15 Exclusive=1 -BlastIncinerate=100 Construction=1 ContainBlast=1 +IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Scene.material index 29d01d305..f36febd26 100644 --- a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Scene.material @@ -11,7 +11,7 @@ material Windmill emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Windmill.png + texture Windmill.jpg tex_address_mode wrap filtering trilinear } @@ -46,7 +46,7 @@ material Windmill.NoCull emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture Windmill.png + texture Windmill.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Script.c index fd6e0e8e7..23d47d96b 100644 --- a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Script.c @@ -5,64 +5,48 @@ Crushes seeds into flour using power - is an own power producer too --*/ +#include Library_Structure #include Library_Ownable #include Library_Producer #include Library_PowerConsumer #include Library_PowerProducer +#include Library_Flag + +local DefaultFlagRadius = 90; local wind_anim; local last_wind; -protected func Construction() +func TurnAnimation(){return "Spin";} +func MinRevolutionTime(){return 18000;} // in frames + +protected func Construction(object creator) { SetProperty("MeshTransformation", Trans_Rotate(-30,0,1,0)); - return _inherited(...); + SetAction("Default"); + + // uses functions of the wind generator + this.Wind2TurnEx = WindGenerator.Wind2Turn; + this.GetWeightedWind = WindGenerator.GetWeightedWind; + AddTimer("CollectionZone", 1); + + return _inherited(creator, ...); } protected func Initialize() { + // create wheel + (this.wheel = CreateObject(WindGenerator_Wheel, 0, 0, NO_OWNER))->Set(this, 150); + // Set initial position - wind_anim = PlayAnimation("Spin", 5, Anim_Const(0), Anim_Const(1000)); - Wind2Turn(); + wind_anim = PlayAnimation(TurnAnimation(), 5, this.wheel->Anim_R(GetAnimationLength(TurnAnimation()), 0), Anim_Const(1000)); return _inherited(...); } func Wind2Turn() -{ - if(GetCon() < 100) return; - - // Fade linearly in time until next timer call - var start = 0; - var end = GetAnimationLength("Spin"); - if(GetWind() < 0) - { - start = end; - end = 0; - } - - var power = Abs(GetWind()); - if(power < 5) power = 0; - else power = Max(((power + 5) / 25), 1) * 50; - - if(last_wind != power) - { - last_wind = power; - MakePowerProducer(last_wind); - } - - // Number of frames for one revolution: the more wind the more revolutions per frame. - if(last_wind == 0) last_wind = 1; - var l = 18000/last_wind; - - // Note ending is irrelevant since this is called again after 35 frames - if(l > 0) - { - SetAnimationPosition(wind_anim, Anim_Linear(GetAnimationPosition(wind_anim), start, end, l, ANIM_Loop)); - } - else - { - SetAnimationPosition(wind_anim, Anim_Const(GetAnimationPosition(wind_anim))); - } +{ + // dummy, uses the function of the WindGenerator + this->Wind2TurnEx(); } @@ -74,7 +58,7 @@ private func IsProduct(id product_id) { return product_id->~IsWindmillProduct(); } -private func ProductionTime() { return 290; } +private func ProductionTime(id toProduce) { return 290; } private func PowerNeed() { return 75; } public func NeedRawMaterial(id rawmat_id) @@ -108,6 +92,17 @@ public func OnProductionFinish(id product) return; } +// Timer, check for objects to collect in the designated collection zone +func CollectionZone() +{ + if (GetCon() < 100) return; + + if (!(FrameCounter() % 35)) Wind2Turn(); + + for (var object in FindObjects(Find_InRect(-18 + 21 * GetDir(),35,15,15), Find_OCF(OCF_Collectible), Find_NoContainer(), Find_Layer(GetObjectLayer()))) + Collect(object); +} + protected func Collection() { Sound("Clonk"); @@ -116,13 +111,22 @@ protected func Collection() public func FxCrushingTimer(object target, proplist effect, int time) { - CreateParticle("Axe_WoodChip", -12, 40, 5 - Random(11), RandomX(6,13) * -1, 20, RGB(255,255,255), this); + var dir = GetCalcDir(); + var particles = + { + Prototype = Particles_WoodChip(), + R = 255, + G = 200, + B = 100 + }; + CreateParticle("Dust", PV_Random(11 * dir, 13 * dir), 40, PV_Random(-5, 5), PV_Random(-13, -6), PV_Random(36 * 3, 36 * 10), particles, 3); + return 1; } public func OnProductEjection(object product) { - product->SetPosition(GetX() + 25, GetY() + 40); + product->SetPosition(GetX() - 25 * GetCalcDir(), GetY() + 40); product->SetSpeed(0, -17); product->SetR(30 - Random(59)); Sound("Pop"); @@ -136,7 +140,26 @@ protected func RejectCollect(id item, object collect) return true; } +func IsInteractable() { return true; } + +local ActMap = { + Default = { + Prototype = Action, + Name = "Default", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 1, + Length = 1, + Delay = 0, + FacetBase = 1, + NextAction = "Default", + }, +}; + 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 BlastIncinerate = 100; +local HitPoints = 70; local Name = "$Name$"; +local Description = "$Description$"; diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblDE.txt index 531c9839d..46a11b3b1 100644 --- a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblDE.txt @@ -1 +1,2 @@ -Name=Windmühle \ No newline at end of file +Name=Windmühle +Description=Die Windmühle verarbeitet Samen zu Mehl. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblUS.txt index 7a5e0d572..28ea37ae8 100644 --- a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/StringTblUS.txt @@ -1 +1,2 @@ -Name=Windmill \ No newline at end of file +Name=Windmill +Description=The windmill crushes seeds into flour. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Windmill.jpg b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Windmill.jpg new file mode 100644 index 000000000..624991528 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Windmill.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Windmill.png b/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Windmill.png deleted file mode 100644 index 1249e664f..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/Windmill.ocd/Windmill.png and /dev/null differ diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/DefCore.txt b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/DefCore.txt index 934c57a3b..200993f13 100644 --- a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/DefCore.txt +++ b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/DefCore.txt @@ -14,7 +14,6 @@ Mass=4000 Components=Wood=5;Rock=4 Entrance=-12,0,13,20 Exclusive=1 -BlastIncinerate=100 Construction=1 Rotate=1 ContainBlast=1 diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Scene.material b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Scene.material index 080b33399..9a19babfc 100644 --- a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Scene.material +++ b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Scene.material @@ -11,7 +11,7 @@ material WoodenCabin emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture woodencabin.png + texture woodencabin.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Script.c index 39de5b8c3..767f651a9 100644 --- a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/Script.c @@ -1,5 +1,6 @@ /*-- Wooden Cabin --*/ +#include Library_Structure #include Library_Ownable #include Library_DoorControl @@ -13,6 +14,13 @@ protected func IsBuilt() return GetCon() >= 100; } +protected func RejectCollect(id objid, object obj) +{ + return true; +} + +public func NoConstructionFlip() { return true; } + local ActMap = {/* Idle = { Prototype = Action, @@ -59,5 +67,7 @@ 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); SetProperty("MeshTransformation", Trans_Rotate(-8,0,1,0)); } - +local BlastIncinerate = 100; +local HitPoints = 70; local Name = "$Name$"; +local Description = "$Description$"; \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblDE.txt index 3da0879cf..308c3379d 100644 --- a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblDE.txt @@ -1 +1,2 @@ -Name=Holzhütte \ No newline at end of file +Name=Holzhütte +Description=Eine einfache Unterkunft. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblUS.txt index d79fda4f4..b98dcc202 100644 --- a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/StringTblUS.txt @@ -1 +1,2 @@ -Name=Wooden Cabin \ No newline at end of file +Name=Wooden Cabin +Description=A basic shelter. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/woodencabin.jpg b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/woodencabin.jpg new file mode 100644 index 000000000..d99f2dad9 Binary files /dev/null and b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/woodencabin.jpg differ diff --git a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/woodencabin.png b/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/woodencabin.png deleted file mode 100644 index 21921206b..000000000 Binary files a/planet/Objects.ocd/Structures.ocd/WoodenCabin.ocd/woodencabin.png and /dev/null differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/DefCore.txt similarity index 71% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/DefCore.txt index e14c65bb0..30c77731e 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Fern Version=5,2,0,1 Category=C4D_StaticBack -Timer=350 -TimerCall=Seed Width=28 Height=10 Offset=-14,-5 @@ -14,6 +12,4 @@ VertexCNAT=16,8 Mass=1 StretchGrowth=1 Oversize=1 -ContactIncinerate=3 -BlastIncinerate=1 Float=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Fern.skeleton b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Fern.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Fern.skeleton rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Fern.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Scene.material similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Scene.material diff --git a/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Script.c new file mode 100644 index 000000000..259f7447d --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/Script.c @@ -0,0 +1,29 @@ +/*-- Fern --*/ + +#include Library_Plant + +private func SeedChance() { return 400; } +private func SeedArea() { return 120; } +private func SeedAmount() { return 4; } + +func Construction() +{ + StartGrowth(1); + inherited(...); +} + +private func Initialize() +{ + SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); +} + +public func Incineration() +{ + CreateParticle("Grass", 0, 0, PV_Random(-20, 20), PV_Random(-20, 10), PV_Random(30, 100), Particles_Straw(), 30); + RemoveObject(); +} + +local Name = "$Name$"; +local BlastIncinerate = 1; +local ContactIncinerate = 3; +local Placement = 4; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/ferns.png b/planet/Objects.ocd/Vegetation.ocd/Fern.ocd/ferns.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Fern.ocd/ferns.png rename to planet/Objects.ocd/Vegetation.ocd/Fern.ocd/ferns.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/DefCore.txt similarity index 77% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Grass.ocd/DefCore.txt index de08dd6bf..5b0d5e66e 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/DefCore.txt @@ -9,8 +9,5 @@ Vertices=1 VertexY=1 Mass=1 Rotate=1 -Placement=0 StretchGrowth=1 Oversize=1 -ContactIncinerate=3 -BlastIncinerate=1 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Graphics.10.png b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Graphics.10.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Graphics.10.png rename to planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Graphics.10.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Graphics1.10.png b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Graphics1.10.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Graphics1.10.png rename to planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Graphics1.10.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Graphics.png b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Graphics.png rename to planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Graphics.png diff --git a/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Particle.txt b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Particle.txt new file mode 100644 index 000000000..0e5e2420b --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Grass.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Grass +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Script.c similarity index 67% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Script.c index daa8930e5..211da288b 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Script.c @@ -23,27 +23,38 @@ public func OnShockwaveHit() private func Destroy() { - CastParticles("Grass", 10, 35, 0, 0, 30, 50, RGB(255,255,255), RGB(255,255,255)); + CreateParticle("Grass", 0, 0, PV_Random(-20, 20), PV_Random(-20, 10), PV_Random(30, 100), Particles_Straw(), 30); RemoveObject(); } -global func PlaceGrass(int amount, int start, int end) +public func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + props->Remove("Con"); + return true; +} + +global func PlaceGrass(int amount, int start, int end, int height, int bottom) { if (!start) start = 0; if (!end) end = LandscapeWidth(); + if(!height) + height = 0; + if(!bottom) + bottom = LandscapeHeight(); var x = start, y; while (x < end) { - y = 0; - while (y < LandscapeHeight()) + y = height; + while (y < bottom) { if (GetMaterial(AbsX(x), AbsY(y)) == Material("Sky")) if (GetMaterial(AbsX(x), AbsY(y + 3)) == Material("Earth")) if (Random(100) < amount) - CreateObject(Grass, AbsX(x), AbsY(y + 4), NO_OWNER); + CreateObject(Grass, AbsX(x), AbsY(y + 1), NO_OWNER); y += 3; } x += 9; @@ -76,4 +87,7 @@ global func MakeGrasFunction() Log("}"); } +local Plane = -1; local Name = "Grass"; +local Placement = 0; +local BlastIncinerate = 1; diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Title.png b/planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Title.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Grass.ocd/Title.png rename to planet/Objects.ocd/Vegetation.ocd/Grass.ocd/Title.png diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/DefCore.txt new file mode 100644 index 000000000..f0f3e4d91 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=LargeCaveMushroom +Version=5,2,0,1 +Category=C4D_StaticBack +Width=44 +Height=64 +Offset=-22,-32 +Vertices=9 +VertexX=0,0,0,0,0,0,0,0,0 +VertexY=30,15,5,2,0,-2,-5,-15,-25 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Components=Wood=4 +Mass=100 +StretchGrowth=1 +Oversize=1 +Float=1 +Rotate=1 diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/Graphics.mesh new file mode 100644 index 000000000..1abf7644b Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeCaveMushroom.jpg b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeCaveMushroom.jpg new file mode 100644 index 000000000..a40b950f9 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeCaveMushroom.jpg differ diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeCaveMushroom.material b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeCaveMushroom.material new file mode 100644 index 000000000..73e5ab23f --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeCaveMushroom.material @@ -0,0 +1,30 @@ +// LargeCaveMushroom genrated by blender2ogre 0.5.8 + +material LargeCaveMushroom +{ + receive_shadows on + + technique + { + pass LargeCaveMushroom + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0 + specular 0.0 0.0 0.0 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + + alpha_to_coverage off + cull_hardware clockwise + depth_write on + scene_blend one zero + + texture_unit + { + texture LargeCaveMushroom.jpg + tex_address_mode wrap + scale 1.0 1.0 + colour_op modulate + } + } + } +} diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeMushroom.skeleton b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeMushroom.skeleton new file mode 100644 index 000000000..8e33d71ff Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/LargeMushroom.skeleton differ diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/Script.c new file mode 100644 index 000000000..72491d304 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/Script.c @@ -0,0 +1,208 @@ +/*-- Large Cave Mushroom --*/ + +#include Library_Plant +#include Library_Tree + +func Place(int amount, proplist rectangle, proplist settings) +{ + if (settings == nil) settings = {}; + // Default behaviour + var plants = []; + var terraform = settings.terrafom ?? true; + + var max_tries = 2 * amount; + var loc_area = nil; + if (rectangle) loc_area = Loc_InRect(rectangle); + + // look for free underground spot to place groups of three or so.. + while ((amount > 0) && (--max_tries > 0)) + { + var spot = FindLocation(Loc_Tunnel(), Loc_Wall(CNAT_Bottom), Loc_Space(20, true), Loc_Func(LargeCaveMushroom.GoodSpot), loc_area); + // can't place more + if (!spot && !terraform) return plants; + + if (!spot) + { + // note that the border is temporarily off until the bug with a turbulent-parent-overlay is fixed + var cave = Landscape_Cave->Place(1, rectangle, {width = 200 + Random(50), height = 100 + Random(50), borderheight = 0, bordermat = "Earth", bordertex = "earth_topSoil" }); + if (GetLength(cave) == 0) return plants; // can't place more + cave = cave[0]; + spot = { x = cave->GetX(), y = cave->GetY() }; + } + + // have center-spot now + // search random spots in vicinity and place mushrooms + var failsafe = 100; + for (var i = RandomX(2, 4); (i >= 0) && (failsafe > 0); --failsafe) + { + var angle = RandomX(-100, 100); + var r = RandomX(30, 50); + var end_x = spot.x + Sin(angle, r); + var end_y = spot.y - Cos(angle, r); + var distance = 0; + + while (!GBackSolid(end_x, end_y) && distance < 100) {++distance; ++end_y;} + + if (GBackSemiSolid(end_x, end_y - 1)) continue; + if (GetMaterial(end_x, end_y - 1) != Material("Tunnel")) continue; + + // enough space? + if (!PathFree(end_x, end_y - 1, end_x, end_y - 15)) continue; + + var plant = CreateConstruction(this, end_x, end_y - 1, NO_OWNER, 20 + Random(10), false, false); + if (!plant) continue; + PushBack(plants, plant); + --amount; + --i; + } + } + + if (GetLength(plants) == 0) return plants; + + for (var plant in plants) + if (!Random(3)) + plant.Plane = 510; + return plants; +} + +// for the placement +func GoodSpot(int x, int y) +{ + return ObjectCount(Find_Distance(100, x, y), Find_ID(LargeCaveMushroom)) < 5; +} + +private func SeedChance() { return 200; } +private func SeedArea() { return 200; } +private func SeedAmount() { return 5; } + +func Construction() +{ + AddTimer("Growing", 80); + // set random rotation so trees don't look alike too much + SetProperty("MeshTransformation", Trans_Rotate(RandomX(-90,90),0,1,0)); + + // every mushroom is unique! + var len = GetAnimationLength("Rotate1"); // length of all animations is the same + PlayAnimation("Pitch1", 1, Anim_Const(RandomX(0, len)), Anim_Const(500)); + PlayAnimation("Pitch2", 2, Anim_Const(RandomX(0, len)), Anim_Const(500)); + PlayAnimation("Rotate1", 2, Anim_Const(RandomX(0, len)), Anim_Const(500)); + + PlayAnimation("Head1", 2, Anim_Const(RandomX(0, len)), Anim_Const(500)); + PlayAnimation("Head2", 2, Anim_Const(RandomX(0, len)), Anim_Const(500)); + PlayAnimation("Head3", 2, Anim_Const(RandomX(0, len)), Anim_Const(500)); + PlayAnimation("Head4", 2, Anim_Const(RandomX(0, len)), Anim_Const(500)); + + + + var brightness = Random(25); + SetClrModulation(RGB(200 + brightness + Random(30), 200 + brightness + Random(30), 200 + brightness + Random(30))); + + inherited(...); +} + +func Growing() +{ + if(GetCon() >= Min(RandomX(80, 500), 100)) + { + RemoveTimer("Growing"); + return; + } + + if(!Random(4)) return; + + var top = ((-36) * GetCon()) / 100; + if(GBackSolid(0, Min(-5, top))) return; + DoCon(1); +} + +public func ChopDown() +{ + // Use Special Vertex Mode 1 (see documentation) so the removed vertex won't come back when rotating the tree. + SetVertex(0, VTX_Y, 0, 1); + // Remove the bottom vertex + RemoveVertex(0); + // Stop growing + RemoveTimer("Growing"); + + _inherited(...); +} + +func Damage() +{ + _inherited(); + + if (GetDamage() > MaxDamage() && OnFire()) + { + SetClrModulation(RGB(100, 100, 100)); + RemoveTimer("Growing"); + return; + } +} + +// called from the plant library +func Seed() +{ + if(GetCon() < 20) return; + + var size = SeedArea(); + var amount = SeedAmount(); + var chance = SeedChance(); + // Place a plant if we are lucky, in principle there can be more than seed amount. + if (!Random(chance)) + { + // select random angle at which we can throw the seed + var angle = RandomX(100, 140); + if(!Random(2)) angle = 360 - angle; + + var okay = false, x, y; + for (var i = 0; i < 3; ++i) // three is the magic number of tries + { + var point = PathFree2(GetX(), GetY() - (25 * GetCon()) / 100, GetX() + Sin(angle, size), GetY() - Cos(angle, size)); + if (!point) continue; + x = point[0]; + y = point[1]; + + if (Distance(GetX(), GetY(), x, y) < size/4) continue; + x -= GetX(); + y -= GetY(); + if (!GBackSolid(x, y + 2)) continue; + if (GetMaterial(x, y) != Material("Tunnel")) continue; + + var mat = GetMaterial(x, y + 2); + if (GetMaterialVal("Soil", "Material", mat) != 1) continue; + var neighbour = FindObjects(Find_Distance(size, x, y), Find_ID(GetID()), Find_Exclude(this), Sort_Distance(x, y)); + if (GetLength(neighbour) > 0) + { + var distance = Distance(GetX() + x, GetY() + y, neighbour[0]->GetX(), neighbour[0]->GetY()); + var len = GetLength(neighbour); + var c = (size * distance * amount) / (len * len * len); + if (!Random(c)) + continue; + } + + if (this.Confinement) + { + if (!IsPointInRectangle({x = x, y = y}, this.Confinement)) continue; + } + + okay = true; + break; + } + if (!okay) return; + // Place the plant but check if it is not close to another one. + var plant = CreateConstruction(GetID(), x, y, GetOwner(), 3, false, false); + + if (plant) + { + if (this.Confinement) + plant->KeepArea(this.Confinement); + } + } + return; +} + +local Name = "$Name$"; +local Touchable = 0; +local BlastIncinerate = 2; +local ContactIncinerate = 6; +local NoBurnDecay = 1; \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/StringTblDE.txt new file mode 100644 index 000000000..8eb9ea95b --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Großer Höhlenpilz \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/StringTblUS.txt new file mode 100644 index 000000000..6978ac700 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/LargeCaveMushroom.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Large cave mushroom \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/DefCore.txt similarity index 78% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/DefCore.txt index 1e14a1d74..3ba18a682 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Lichen Version=5,2,0,1 Category=C4D_StaticBack -Timer=350 -TimerCall=Seed Width=25 Height=25 Offset=-12,-12 @@ -13,5 +11,4 @@ VertexY=7,12 VertexFriction=50,100 VertexCNAT=16,8 Components=Moss=4 -Mass=10 -BlastIncinerate=1 \ No newline at end of file +Mass=10 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Graphics.8.png b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Graphics.8.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Graphics.8.png rename to planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Graphics.8.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png rename to planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png diff --git a/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt new file mode 100644 index 000000000..8f9cf836c --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Lichen +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Script.c similarity index 55% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Script.c index 0e790bd74..63800105c 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/Script.c @@ -1,12 +1,15 @@ /*-- Lichen --*/ #include Library_Plant +#include Library_Crop local grow_stage; private func SeedChance() { return 1000; } +private func SeedOffset() { return 10; } private func IsCrop() { return true; } +private func SickleHarvesting() { return false; } protected func Initialize() { @@ -22,8 +25,18 @@ public func Harvest(object clonk) { var moss = CreateObject(Moss, 0, GetObjHeight()/2, NO_OWNER); clonk->Collect(moss); - CreateParticle("Lichen", 0,0, 10, -2, 75, RGBa(128,128,128,255)); - CreateParticle("Lichen", 0,0,-10, -2, 75, RGBa(128,128,128,255)); + var particles = + { + Size = PV_Random(3, 7), + Alpha = PV_KeyFrames(0, 0, 255, 900, 255, 1000, 0), + ForceY = PV_Gravity(40), + DampingX = 900, DampingY = 900, + CollisionVertex = 750, + OnCollision = PC_Stop(), + Rotation = PV_Direction(PV_Random(900, 1100)), + Phase = PV_Random(0, 1) + }; + CreateParticle("Lichen", PV_Random(-5, 5), PV_Random(-5, 5), PV_Random(-30, 30), PV_Random(-30, 30), PV_Random(36, 36 * 4), particles, 40); if (grow_stage) { @@ -36,8 +49,17 @@ public func Harvest(object clonk) return true; } +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (GetAction() != "Grow" || GetPhase()) SaveScenarioObjectAction(props); + return true; +} + local Name = "$Name$"; local Description = "$Description$"; +local BlastIncinerate = 1; +local ContactIncinerate = 3; local ActMap = { Grow = { Prototype = Action, diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Lichen.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/StringTblUS.txt new file mode 100644 index 000000000..929156f62 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Lichen.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Lichen +Description=Thrives in dark, wet tunnels. Moss can be harvested from it. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/DefCore.txt similarity index 79% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/DefCore.txt index 402ab2fe4..a98366544 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Mushroom Version=5,2,0,1 Category=C4D_Object -Timer=350 -TimerCall=Seed Width=12 Height=20 Offset=-6,-10 @@ -14,5 +12,4 @@ VertexCNAT=16,8 VertexFriction=10,100 Mass=6 StretchGrowth=4 -Oversize=1 -Placement=4 \ No newline at end of file +Oversize=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Mushroom.skeleton b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Mushroom.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Mushroom.skeleton rename to planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Mushroom.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Scene.material similarity index 93% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Scene.material index 9d994141d..94efbc095 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Scene.material +++ b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Scene.material @@ -11,7 +11,7 @@ material Mushroom emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture mushroom.png + texture mushroom.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Script.c similarity index 68% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Script.c index cca495870..a488a9ecd 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Mushroom.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/Script.c @@ -1,10 +1,12 @@ /*-- Mushroom --*/ #include Library_Plant +#include Library_Crop -private func SeedChance() { return 250; } -private func SeedAreaSize() { return 150; } -private func SeedAmount() { return 5; } +private func SeedChance() { return 400; } +private func SeedArea() { return 150; } +private func SeedAmount() { return 6; } +private func SeedOffset() { return 10; } /* Initialisation */ @@ -22,6 +24,7 @@ private func Initialize() /* Harvesting */ private func IsCrop() { return true; } +private func SickleHarvesting() { return false; } public func Harvest(object clonk) { @@ -50,4 +53,7 @@ protected func ControlUse(object clonk, int iX, int iY) public func NutritionalValue() { return 5; } local Name = "$Name$"; -local Collectible = 0; \ No newline at end of file +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Collectible = 0; +local Placement = 4; \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/StringTblDE.txt new file mode 100644 index 000000000..574d8f4bd --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/StringTblDE.txt @@ -0,0 +1,4 @@ +Name=Pilz +PickMushroom=Pilz pflücken +Description=Gibt dem Clonk ein paar Lebenspunkte zurück. Koche ihn um ihn nahrhafter zu machen. +UsageHelp=Drücke [Benutzen] um den Pilz zu essen. \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/StringTblUS.txt new file mode 100644 index 000000000..553ed3399 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/StringTblUS.txt @@ -0,0 +1,4 @@ +Name=Mushroom +PickMushroom=Pick mushroom +Description=Restores a few health points. Cook it to make it more nutritious. +UsageHelp=Press [Use] to eat the mushroom. \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/mushroom.jpg b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/mushroom.jpg new file mode 100644 index 000000000..883a061fc Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Mushroom.ocd/mushroom.jpg differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/DefCore.txt similarity index 83% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/DefCore.txt index 71431882b..26fc831bd 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/DefCore.txt @@ -12,8 +12,5 @@ VertexCNAT=3,4 Mass=1 StretchGrowth=1 Oversize=1 -ContactIncinerate=3 -BlastIncinerate=1 Float=1 Rotate=1 - diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Rank.skeleton b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Rank.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Rank.skeleton rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Rank.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Scene.material similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Scene.material diff --git a/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Script.c new file mode 100644 index 000000000..d0eca6674 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/Script.c @@ -0,0 +1,22 @@ +/*-- Rank --*/ + +private func Initialize() +{ + SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); + SetR(RandomX(-30,30)); +} + +func Damage() +{ + if (GetDamage() > 15) + { + CastObjects(Wood, 1, 25); + RemoveObject(); + } + return; +} + +local Name = "$Name$"; +local BlastIncinerate = 1; +local ContactIncinerate = 3; +local Placement = 4; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/rank.png b/planet/Objects.ocd/Vegetation.ocd/Rank.ocd/rank.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Rank.ocd/rank.png rename to planet/Objects.ocd/Vegetation.ocd/Rank.ocd/rank.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/DefCore.txt similarity index 94% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/DefCore.txt index c7175ac16..c00338117 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/DefCore.txt @@ -11,6 +11,5 @@ VertexY=-7,7 VertexCNAT=4,3 VertexFriction=10,100 Mass=1 -Placement=1 StretchGrowth=4 Oversize=1 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Scene.material similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Scene.material diff --git a/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c new file mode 100644 index 000000000..a2ea0a774 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Script.c @@ -0,0 +1,58 @@ +/*-- Seaweed --*/ + +#include Library_Plant + +private func Initialize() +{ + SetAction("Sway"); +} + +private func Check() +{ + if(!GBackLiquid()) SetAction("Limp"); +} + +func SaveScenarioObject(props) +{ + if (!inherited(props, ...)) return false; + if (GetPhase()) props->AddCall("Phase", this, "SetPhase", GetPhase()); // ensure that not all seaweed are synced on scenario load + return true; +} + + + +local Name = "$Name$"; +local Placement = 1; +local ActMap = { + Sway = { + Prototype = Action, + Name = "Sway", + Procedure = DFA_NONE, + Directions = 2, + Length = 78, + Delay = 2, + X = 0, + Y = 0, + Wdt = 8, + Hgt = 8, + PhaseCall= "Check", + NextAction = "Sway", + Animation = "Sway", + }, + Limp = { + Prototype = Action, + Name = "Limp", + Procedure = DFA_NONE, + Directions = 2, + Length = 1, + Delay = 1, + X = 0, + Y = 0, + Wdt = 6, + Hgt = 6, + NextAction = "Limp", + InLiquidAction = "Sway", + Animation = "Limp", + }, +}; + diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Seaweed.skeleton b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Seaweed.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/Seaweed.skeleton rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/Seaweed.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/seaweed.png b/planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/seaweed.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Seaweed.ocd/seaweed.png rename to planet/Objects.ocd/Vegetation.ocd/Seaweed.ocd/seaweed.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/DefCore.txt similarity index 73% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/DefCore.txt index 6bf640a19..8c9f811ba 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=SproutBerryBush Version=5,2,0,1 Category=C4D_StaticBack -Timer=40 -TimerCall=Sprout Width=16 Height=16 Offset=-8,-8 @@ -15,8 +13,6 @@ VertexCNAT=0, 8 Mass=10 StretchGrowth=0 Oversize=0 -ContactIncinerate=0 -BlastIncinerate=0 Float=1 Rotate=0 IncompleteActivity=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/DefCore.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/DefCore.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Flower.skeleton b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Flower.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Flower.skeleton rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Flower.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Pedal.png b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Pedal.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Pedal.png rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Pedal.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Scene.material similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Scene.material diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Script.c similarity index 57% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Script.c index 9bd2f9dda..5dc421338 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/Script.c @@ -5,4 +5,7 @@ local Description = "$Description$"; public func Initialize() { return true; -} \ No newline at end of file +} + +// Only save main bush object +func SaveScenarioObject() { return false; } \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Flower.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Graphics.png b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Graphics.png rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Graphics.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/DefCore.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/DefCore.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.png b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.png rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.skeleton b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.skeleton rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Leaf.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Scene.material similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Scene.material diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Script.c similarity index 57% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Script.c index 9bd2f9dda..5dc421338 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/Script.c @@ -5,4 +5,7 @@ local Description = "$Description$"; public func Initialize() { return true; -} \ No newline at end of file +} + +// Only save main bush object +func SaveScenarioObject() { return false; } \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Leaf.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Script.c similarity index 78% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Script.c index 8eeed1ae6..6c7943da2 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Script.c @@ -19,14 +19,35 @@ static const SproutBerryBush_max_sprouts = 8; static const SproutBerryBush_evolve_steps_per_new_sprout = 2; // static function -func Place(int amount) +func Place(int amount, proplist rectangle, proplist settings) { - // place some sprout berries - var bush = PlaceVegetation(SproutBerryBush, 0, LandscapeHeight() / 3, LandscapeWidth(), LandscapeHeight(), 100000); - if(bush) - for (var i = 1; i < amount; i++) - PlaceVegetation(SproutBerryBush, bush->GetX() - 200, bush->GetY() - 200, 400, 400, 100000); - return true; + // No calls to objects, only definitions + if (GetType(this) == C4V_C4Object) return; + // Default parameters + amount = amount ?? (LandscapeWidth() / 150); + settings = settings ?? { growth = 100000, keep_area = false }; + settings.growth = settings.growth ?? 100000; + rectangle = rectangle ?? Rectangle(0,0, LandscapeWidth(), LandscapeHeight()); + + var plants = []; + while(amount > 0) + { + // place some sprout berries + var bush = PlaceVegetation(SproutBerryBush, rectangle.x, rectangle.y, rectangle.w, rectangle.h, 100000); + if(!bush) break; + --amount; + PushBack(plants, bush); + var cluster = Random(3) + 3; + while(cluster > 0 && amount > 0) + { + var p = PlaceVegetation(SproutBerryBush, bush->GetX() - 200, bush->GetY() - 200, 400, 400, 100000); + if(!p) break; + --amount; + --cluster; + PushBack(plants, p); + } + } + return plants; } func Construction() @@ -44,6 +65,7 @@ private func Initialize() // no instant berries! AddEffect("DontFlower", this, 1, 35 * SproutBerryBush_average_flower_time + RandomX(-400,400), this); + AddTimer("Sprout", 40); } public func IsTree() { return false; } diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/DefCore.txt similarity index 86% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/DefCore.txt index 61c439a5e..92257ea3d 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/DefCore.txt @@ -16,5 +16,3 @@ Rotate=1 NoStabilize=1 StretchGrowth=1 IncompleteActivity=1 -ContactIncinerate=2 -BlastIncinerate=1 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Scene.material similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Scene.material diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Script.c similarity index 95% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Script.c index e6f845333..b671fbdf1 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Script.c @@ -1,6 +1,4 @@ -// is a plant but does not have the Seed-timer-call! -// only for the harvesting -#include Library_Plant +#include Library_Crop local Name = "$Name$"; local Description = "$Description$"; @@ -21,9 +19,18 @@ Attach = { FacetBase=1, } }; +local BlastIncinerate = 1; +local ContactIncinerate = 2; // can be harvested? func IsCrop(){ return true; } + +// berries can simply be plucked +private func SickleHarvesting() +{ + return false; +} + public func IsHarvestable() { return !!Contents(); @@ -199,11 +206,11 @@ func FxLifeTimerTimer(target, effect, time) } } -func Damage(int damage, object from) +func Damage() { // splatter if(grow_anim) - CastParticles("MaterialParticle", 20, 30, 0, 0, 10, 20, RGB(200, 200, 200), RGB(200, 255, 200)); + CreateParticle("Dust", 0, 0, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(20, 60), Particles_Material(RGB(50, 50, 255)), 30); // ouch! Die(false); @@ -449,4 +456,7 @@ func FxQuickFadeTimer(target, effect, time) SetClrModulation(RGBa(255, 255, 255, effect.alpha)); if(effect.alpha <= 0) return -1; return 1; -} \ No newline at end of file +} + +// Only save main bush object +func SaveScenarioObject() { return false; } diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Sprout.skeleton b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Sprout.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Sprout.skeleton rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/Sprout.skeleton diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/Sprout.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblUS.txt new file mode 100644 index 000000000..f0029300c --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/SproutBerryBush.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Sprout-Berry bush +Description=A very fast-growing, water-loving bush that produces tasty berries which have to be eaten fast. \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/DefCore.txt new file mode 100644 index 000000000..c47dd3c45 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/DefCore.txt @@ -0,0 +1,20 @@ +[DefCore] +id=Coconut +Version=5,2,0,1 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Vertices=3 +VertexX=0,2,-2 +VertexY=1,-1,-1 +VertexFriction=20,20,20 +VertexCNAT=4,2,1 +Value=4 +Mass=9 +Components=Coconut=1 +ContactCalls=1 +Projectile=1 +Float=1 +Rotate=1 +StretchGrowth=1 diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/Graphics.8.png b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/Graphics.8.png new file mode 100644 index 000000000..bdbb3eaf2 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/Script.c new file mode 100644 index 000000000..bcc3e54ac --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/Script.c @@ -0,0 +1,94 @@ +/*--- Coconut ---*/ + +private func GetSeedTime() { return 15 * 2; } + +protected func Initialize() +{ + // AddEffect to grow trees, called every half a second. + var effect = AddEffect("IntSeed", this, 100, 18, this); + effect.SeedTime = GetSeedTime(); + return; +} + +public func FxIntSeedTimer(object coconut, proplist effect, int timer) +{ + // Start germination timer if in the environment + if (!Contained()) + effect.SeedTime--; + + // Germinate if the coconut is on the earth. + var has_soil = !!GetMaterialVal("Soil", "Material", GetMaterial(0, 3)); + if (effect.SeedTime <= 0 && !Contained() && has_soil && GetCon() >= 100) + { + // Are there any trees too close? Is the coconut underwater? + if (!FindObject(Find_Func("IsTree"), Find_Distance(40)) && !GBackLiquid()) + { + if (Germinate()) + return -1; + } + } + + // Destruct if sitting for too long + if (effect.SeedTime == -120) + coconut.Collectible = 0; + if (effect.SeedTime < -120) + coconut->DoCon(-5); + + return 0; +} + +public func Germinate() +{ + // Try to sprout a coconut tree. + var d = 8; + if (PlaceVegetation(Tree_Coconut, -d/2, -d/2, d, d, 100)) + { + this.Collectible = 0; + AddEffect("IntGerminate", this, 100, 1, this); + return true; + } + return false; +} + +public func FxIntGerminateTimer(object coconut, proplist effect, int timer) +{ + if (timer == 1) + { + this.Collectible = 0; + // Tree sprouts + PlaceVegetation(Tree_Coconut, 0, 0, 1,1, 100); + } + // Fade out + SetObjAlpha(255 - (timer * 255 / 100)); + if (timer == 100) + coconut->RemoveObject(); + return; +} + +/*-- Eating --*/ + +protected func ControlUse(object clonk, int iX, int iY) +{ + clonk->Eat(this); +} + +public func NutritionalValue() { return 5; } + +/*-- Bounce --*/ + +protected func Hit(int dx, int dy) +{ + // Bounce: useful for spreading seeds further from parent tree. + if (dy > 1) + SetSpeed(dx, dy / -2, 100); + + StonyObjectHit(dx, dy); + return; +} + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local Rebuy = true; +local BlastIncinerate = 8; +local ContactIncinerate = 2; diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/StringTblDE.txt new file mode 100644 index 000000000..aebd1d109 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Kokosnuss +Description=Ein große Saat aus Kokosussbaum. Schmeckt gut! \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/StringTblUS.txt new file mode 100644 index 000000000..891c26eee --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/CoconutSeed.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Coconut +Description=A heavy seed from the coconut tree. Tastes delicious! \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/DefCore.txt new file mode 100644 index 000000000..d69dfe827 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Tree_Coconut +Version=5,2,0,1 +Category=C4D_StaticBack +Width=80 +Height=80 +Offset=-40,-40 +Vertices=5 +VertexX=0,0,0,0,0 +VertexY=40,20,0,-20,-40 +VertexCNAT=8,16,16,16,4 +VertexFriction=50,25,25,25,50 +Components=Wood=4 +Mass=110 +StretchGrowth=1 +Oversize=1 +Float=1 +Rotate=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Graphics.mesh new file mode 100644 index 000000000..d8902c941 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Script.c new file mode 100644 index 000000000..57a2368b6 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Script.c @@ -0,0 +1,65 @@ +/*-- Coconut Tree --*/ + +#include Library_Plant +#include Library_Tree + +private func SeedChance() { return 100; } +private func SeedArea() { return 400; } +private func SeedAmount() { return 12; } + +func Construction() +{ + StartGrowth(5); + // set random rotation so trees don't look alike too much + // -12000 offset to fix model origin which is aligned to geometry centre on export instead of blender's given origin :( + SetProperty("MeshTransformation", Trans_Mul(Trans_Translate(-12000), Trans_Rotate(RandomX(0,359),0,1,0))); + inherited(...); +} + +public func Seed() +{ +// if(!IsStanding()) return false; + + // Find number of plants in seed area. + var size = SeedArea(); + var amount = SeedAmount(); + var offset = size / -2; + var plant_cnt = ObjectCount(Find_ID(GetID()), Find_InRect(offset, offset, size, size)); + // If there are not much plants in the seed area compared to seed amount + // the chance of seeding is improved, if there are much the chance is reduced. + var chance = SeedChance(); +// var chance = chance / Max(1, amount - plant_cnt) + chance * Max(0, plant_cnt - amount); + // Place a plant if we are lucky, in principle there can be more than seed amount. + if (!Random(chance) && GetCon() >= 100) + { + // Place the plant but check if it is not close to another one. +// var plant = PlaceVegetation(GetID(), offset, offset, size, size, 3); + var seed = CreateObject(Coconut, 0, -35); + seed->SetXDir(-5 + Random(11)); + seed->SetR(Random(360)); + seed->SetRDir(RandomX(-5,5)); + + //one coconut for each tree + if(ObjectCount(Find_ID(Coconut)) > ObjectCount(Find_ID(Tree_Coconut))) + { + seed->RemoveObject(); + } + } + return; +} + +public func IsTree() { return true; } + +public func ChopDown() +{ + // Remove the bottom vertex + SetVertex(0, VTX_Y, 0, 1); + RemoveVertex(0); + + _inherited(...); +} + +local Name = "$Name$"; +local Touchable = 0; +local BlastIncinerate = 1; +local ContactIncinerate = 3; \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/StringTblDE.txt new file mode 100644 index 000000000..4d6509f68 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Kokosnussbaum \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/StringTblUS.txt new file mode 100644 index 000000000..7f72f6ab9 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Coconut Tree \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Tree_Coconut.material b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Tree_Coconut.material new file mode 100644 index 000000000..94c62c430 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Tree_Coconut.material @@ -0,0 +1,23 @@ +material Tree_Coconut +{ + receive_shadows on + technique + { + pass + { + cull_hardware none + scene_blend alpha_blend + + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.0 0.0 0.0 0.0 0.0 + emissive 0.0 0.0 0.0 0.0 + + texture_unit + { + texture coconutTree.png + tex_address_mode wrap + } + } + } +} diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Tree_Coconut.skeleton b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Tree_Coconut.skeleton new file mode 100644 index 000000000..24c8b9c73 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/Tree_Coconut.skeleton differ diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/coconutTree.png b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/coconutTree.png new file mode 100644 index 000000000..1ac85a0e1 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coconut.ocd/coconutTree.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Coniferous.skeleton b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Coniferous.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Coniferous.skeleton rename to planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Coniferous.skeleton diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/DefCore.txt new file mode 100644 index 000000000..08f03c784 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/DefCore.txt @@ -0,0 +1,18 @@ +[DefCore] +id=Tree_Coniferous_Burned +Version=5,2,0,1 +Category=C4D_StaticBack +Width=60 +Height=110 +Offset=-30,-55 +Vertices=9 +VertexX=0,0,0,0,0,0,0,0,0 +VertexY=45,30,20,10,0,-10,-20,-30,-45 +VertexCNAT=8,16,16,16,16,16,16,16,4 +VertexFriction=50,50,25,25,25,25,50,50,50 +Components=Wood=5 +Mass=120 +StretchGrowth=1 +Oversize=1 +Float=1 +Rotate=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/Graphics.2.png b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/Graphics.2.png new file mode 100644 index 000000000..5c65a1923 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/Graphics.2.png differ diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/Script.c new file mode 100644 index 000000000..3b9fee773 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/Script.c @@ -0,0 +1,121 @@ +/*-- Coniferous Tree --*/ + +// Overloaded from the plant library to add the foreground parameter, foreground = true will roughly make every 3rd tree foreground (not the offspring though) +func Place(int amount, proplist rectangle, proplist settings, bool foreground) +{ + // Plant + // No calls to objects, only definitions + if (GetType(this) == C4V_C4Object) return; + // Default parameters + if (!settings) settings = { growth = 100000, keep_area = false }; + if (!settings.growth) settings.growth = 100000; + if (!rectangle) + rectangle = Rectangle(0,0, LandscapeWidth(), LandscapeHeight()); + + var plants = CreateArray(), plant; + for (var i = 0 ; i < amount ; i++) + { + plant = PlaceVegetation(this, rectangle.x, rectangle.y, rectangle.w, rectangle.h, settings.growth); + if (plant) + { + plants[GetLength(plants)] = plant; + if (settings.keep_area) + plant->~KeepArea(rectangle); + } + } + + // Coniferous + // Default behaviour + var trees = plants; + if (GetLength(trees) < 1) return trees; + + for (var tree in trees) + if (!Random(3)) + tree.Plane = 510; + return trees; +} + +public func IsPlant() { return true; } +public func IsTree() { return true; } + +func Construction() +{ + var scale = 1100; + var yoff = (110 * scale / 1000) - 110; + SetObjDrawTransform(scale, 0, 0, 0, scale, -yoff * 1000); +} + +public func IsStanding() +{ + return GetCategory() & C4D_StaticBack; +} + +private func MaxDamage() +{ + return 50; +} + +protected func Damage() +{ + // Max damage reached -> fall down + if (GetDamage() > MaxDamage() && IsStanding()) ChopDown(); + if(!IsStanding() && OnFire() && GetDamage() > MaxDamage() * 2) + BurstIntoAshes(); + _inherited(...); +} + + +public func ChopDown() +{ + // Use Special Vertex Mode 1 (see documentation) so the removed vertex won't come back when rotating the tree. + SetVertex(0, VTX_Y, 0, 1); + // Remove the bottom vertex + RemoveVertex(0); + + this.Touchable = 1; + this.Plane = 300; + SetCategory(GetCategory()&~C4D_StaticBack); + if (Stuck()) + { + var i = 5; + while(Stuck() && i) + { + SetPosition(GetX(), GetY()-1); + i--; + } + } + Sound("TreeCrack"); + AddEffect("TreeFall", this, 1, 1, nil, Library_Plant); +} + +func BurstIntoAshes() +{ + var particles = + { + Prototype = Particles_Dust(), + R = 50, G = 50, B = 50, + Size = PV_KeyFrames(0, 0, 0, 200, PV_Random(2, 10), 1000, 0), + }; + + var r = GetR(); + var size = GetCon() * 110 / 100; + + for(var cnt = 0; cnt < 10; ++cnt) + { + var distance = Random(size/2); + var x = Sin(r, distance); + var y = -Cos(r, distance); + + for(var mirror = -1; mirror <= 1; mirror += 2) + { + CreateParticle("Dust", x * mirror, y * mirror, PV_Random(-3, 3), PV_Random(-3, -3), PV_Random(18, 1 * 36), particles, 2); + CastPXS("Ashes", 5, 30, x * mirror, y * mirror); + } + } + RemoveObject(); +} + +local Name = "$Name$"; +local Touchable = 0; +local BlastIncinerate = 1; +local ContactIncinerate = 3; \ No newline at end of file diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/StringTblDE.txt new file mode 100644 index 000000000..e5bc526e6 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Verbrannter Nadelbaum diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/StringTblUS.txt new file mode 100644 index 000000000..718f7b60a --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/ConiferousBurned.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Burned cone tree diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/DefCore.txt similarity index 77% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/DefCore.txt index 84b98da97..201f2d501 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Tree_Coniferous Version=5,2,0,1 Category=C4D_StaticBack -Timer=350 -TimerCall=Seed Width=60 Height=110 Offset=-30,-55 @@ -12,11 +10,9 @@ VertexX=0,0,0,0,0,0,0,0,0 VertexY=45,30,20,10,0,-10,-20,-30,-45 VertexCNAT=8,16,16,16,16,16,16,16,4 VertexFriction=50,50,25,25,25,25,50,50,50 -Components=Wood=4 +Components=Wood=5 Mass=150 StretchGrowth=1 Oversize=1 -ContactIncinerate=3 -BlastIncinerate=1 Float=1 -Rotate=1 \ No newline at end of file +Rotate=1 diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Graphics.mesh new file mode 100644 index 000000000..2647f7dac Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Scene.material similarity index 95% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Scene.material index 4f2f9d513..a8e761390 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Scene.material +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Scene.material @@ -7,6 +7,7 @@ material Coniferous { cull_hardware none scene_blend alpha_blend + depth_check off ambient 1.000000 1.000000 1.000000 1.000000 diffuse 1.000000 1.000000 1.000000 1.000000 diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Script.c new file mode 100644 index 000000000..f704bf47d --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/Script.c @@ -0,0 +1,64 @@ +/*-- Coniferous Tree --*/ + +#include Library_Plant +#include Library_Tree + +// Overloaded from the plant library to add the foreground parameter, foreground = true will roughly make every 3rd tree foreground (not the offspring though) +func Place(int amount, proplist rectangle, proplist settings, bool foreground) +{ + // Default behaviour + var trees = inherited(amount, rectangle, settings); + if (GetLength(trees) < 1) return trees; + + for (var tree in trees) + if (!Random(3)) + tree.Plane = 510; + return trees; +} + +private func SeedChance() { return 500; } +private func SeedArea() { return 400; } +private func SeedAmount() { return 10; } + +func Construction() +{ + StartGrowth(5); + // set random rotation so trees don't look alike too much + SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); + inherited(...); +} + +public func ChopDown() +{ + // Use Special Vertex Mode 1 (see documentation) so the removed vertex won't come back when rotating the tree. + SetVertex(0, VTX_Y, 0, 1); + // Remove the bottom vertex + RemoveVertex(0); + + _inherited(...); +} + +func Damage() +{ + _inherited(); + + if (GetDamage() > MaxDamage() && OnFire()) + { + var burned = CreateObject(Tree_Coniferous_Burned, 0, 0, GetOwner()); + burned->SetCategory(GetCategory()); + burned.Touchable = this.Touchable; + burned->SetCon(GetCon()); + burned->SetR(GetR()); + burned->Incinerate(OnFire()); + burned->SetPosition(GetX(), GetY()); + Sound("TreeCrack", false); + RemoveObject(); + return; + } +} + +local Name = "$Name$"; +local Touchable = 0; +local BlastIncinerate = 2; +local ContactIncinerate = 6; +local NoBurnDecay = 1; \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/coniferous.png b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/coniferous.png new file mode 100644 index 000000000..79cdcbeb7 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trees.ocd/Coniferous.ocd/coniferous.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/DefCore.txt similarity index 57% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/DefCore.txt index 34d3bd44e..319bd59c3 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/DefCore.txt @@ -5,14 +5,13 @@ Category=C4D_StaticBack Width=20 Height=60 Offset=-10,-30 -Vertices=2 -VertexX=0,0 -VertexY=-25,25 -VertexCNAT=4,8 +Vertices=4 +VertexX=-3,-5,5,0 +VertexY=-23,17,17,25 +VertexCNAT=4,8,8,8 Mass=40 StretchGrowth=1 Oversize=1 -ContactIncinerate=3 -BlastIncinerate=1 Float=1 -Rotate=1 \ No newline at end of file +Rotate=1 +Components=Wood=3 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Graphics.mesh b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Graphics.mesh similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Graphics.mesh rename to planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Graphics.mesh diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Scene.material b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Scene.material similarity index 94% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Scene.material rename to planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Scene.material index f802096c5..c9bb6060b 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Scene.material +++ b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Scene.material @@ -14,7 +14,7 @@ material Trunk emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture trunk.png + texture trunk.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Script.c new file mode 100644 index 000000000..908d565f8 --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Script.c @@ -0,0 +1,81 @@ +/*-- Trunk --*/ + +private func Initialize() +{ + SetProperty("MeshTransformation", Trans_Rotate(RandomX(0,359),0,1,0)); +} + +public func IsPlant() { return true; } +public func IsTree() { return true; } + +public func IsStanding() { return GetCategory() & C4D_StaticBack; } + +public func ChopDown() +{ + // Use Special Vertex Mode 1 (see documentation) so the removed vertex won't come back when rotating the tree. + SetVertex(3, VTX_Y, 0, 1); + // Remove the bottom vertex + RemoveVertex(3); + // Make pushable + this.Touchable = 1; + this.Plane = 300; + SetCategory(GetCategory()&~C4D_StaticBack); + if (Stuck()) + { + var i = 5; + while(Stuck() && i) + { + SetPosition(GetX(), GetY()-1); + i--; + } + } + // Effect + Sound("TreeCrack"); + AddEffect("TreeFall", this, 1, 1, nil, Library_Plant); +} + +private func MaxDamage() +{ + return 50; +} + +protected func Damage() +{ + // Max damage reached -> fall down + if (GetDamage() > MaxDamage() && IsStanding()) ChopDown(); + if(!IsStanding() && OnFire() && GetDamage() > MaxDamage() * 2) + BurstIntoAshes(); + _inherited(...); +} + +func BurstIntoAshes() +{ + var particles = + { + Prototype = Particles_Dust(), + R = 50, G = 50, B = 50, + Size = PV_KeyFrames(0, 0, 0, 200, PV_Random(2, 10), 1000, 0), + }; + + var r = GetR(); + var size = GetCon() * 110 / 100; + + for(var cnt = 0; cnt < 10; ++cnt) + { + var distance = Random(size/2); + var x = Sin(r, distance); + var y = -Cos(r, distance); + + for(var mirror = -1; mirror <= 1; mirror += 2) + { + CreateParticle("Dust", x * mirror, y * mirror, PV_Random(-3, 3), PV_Random(-3, -3), PV_Random(18, 1 * 36), particles, 2); + CastPXS("Ashes", 5, 30, x * mirror, y * mirror); + } + } + RemoveObject(); +} + +local Name = "$Name$"; +local BlastIncinerate = 1; +local ContactIncinerate = 3; +local Placement = 4; diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/StringTblUS.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/StringTblUS.txt rename to planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/StringTblUS.txt diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Trunk.skeleton b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Trunk.skeleton similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Trunk.ocd/Trunk.skeleton rename to planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/Trunk.skeleton diff --git a/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/trunk.jpg b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/trunk.jpg new file mode 100644 index 000000000..397de42e2 Binary files /dev/null and b/planet/Objects.ocd/Vegetation.ocd/Trunk.ocd/trunk.jpg differ diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/DefCore.txt similarity index 86% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/DefCore.txt index 922754b17..13f6e30ca 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=Wheat Version=4,10,0,0 Category=C4D_StaticBack -Timer=350 -TimerCall=Seed Width=12 Height=20 Offset=-6,-10 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Graphics.png b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Graphics.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Graphics.png rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Graphics.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Script.c similarity index 93% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Script.c index 9e6b70e63..59a1a684e 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Script.c @@ -6,12 +6,19 @@ */ #include Library_Plant +#include Library_Crop + +private func SeedArea() { return 50; } +private func SeedChance() { return 250; } +private func SeedAmount() { return 15; } +private func SeedOffset() { return 10; } local stalks; protected func Construction() { StartGrowth(this.growth); + stalks = []; return _inherited(...); } @@ -20,7 +27,6 @@ protected func Initialize() if (GetLength(stalks)) return; // Create 3-5 stalks var num = Random(3); - stalks = CreateArray(); for (var i = 0; i < 3+num; i++) { var x = 12/(3+num) * i - 6; @@ -152,10 +158,10 @@ protected func FxWindCheckTimer(object obj, effect) protected func Destruction() { for (var stalk in stalks) - { - if (stalk) - stalk->RemoveObject(); - } + { + if (stalk) + stalk->RemoveObject(); + } } public func IsCrop() { return true; } diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/DefCore.txt b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/DefCore.txt similarity index 79% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/DefCore.txt rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/DefCore.txt index 0c9361b92..3ed96feec 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/DefCore.txt @@ -2,8 +2,6 @@ id=WheatStalk Version=4,10,0,0 Category=C4D_StaticBack -Timer=35 -TimerCall=AdjustGrowth Width=8 Height=20 Offset=-4,-10 diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Graphics.8.png b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Graphics.8.png similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Graphics.8.png rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Graphics.8.png diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Script.c b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Script.c similarity index 92% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Script.c rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Script.c index b55a131e0..c798b1de4 100644 --- a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Script.c +++ b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/Stalk.ocd/Script.c @@ -9,6 +9,7 @@ protected func Construction() { // Editable ActMap ActMap = { Prototype = this.Prototype.ActMap }; + AddTimer("AdjustGrowth"); } // The stalk will adjust its growth to the growth of the mother plant @@ -36,6 +37,9 @@ public func SetSwingSpeed(int delay) SetPhase(phase); } +// Only save main wheat object +func SaveScenarioObject() { return false; } + local ActMap = { Swing = { Prototype = Action, diff --git a/planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/StringTblDE.txt b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/StringTblDE.txt similarity index 100% rename from planet/Objects.ocd/Environment.ocd/Vegetation.ocd/Wheat.ocd/StringTblDE.txt rename to planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/StringTblDE.txt diff --git a/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/StringTblUS.txt b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/StringTblUS.txt new file mode 100644 index 000000000..bddf5039a --- /dev/null +++ b/planet/Objects.ocd/Vegetation.ocd/Wheat.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Wheat +Description=Provides seeds for flour production. Grows faster if watered. \ No newline at end of file diff --git a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/PropellerLoop.ogg b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/PropellerLoop.ogg index 038476f3a..c2b4e5e65 100644 Binary files a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/PropellerLoop.ogg and b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/PropellerLoop.ogg differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Scene.material b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Scene.material index 8a8e5016c..78f55742b 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Scene.material +++ b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Scene.material @@ -23,7 +23,7 @@ material Airplane } texture_unit Plane { - texture airplane.png + texture airplane.jpg tex_address_mode wrap filtering trilinear colour_op_ex blend_current_alpha src_current src_texture diff --git a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Script.c index 4cd70eb31..c89cd234c 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/Script.c @@ -14,6 +14,8 @@ local reticle; local health; local clonkmesh; +public func IsVehicle() { return true; } + protected func Construction(object byobj) { SetR(-90); @@ -67,14 +69,12 @@ public func ContainedUseStop(object clonk, int ix, int iy) var IX = Sin(GetR(), 30); var IY = -Cos(GetR(), 30); - for(var i=0; i<10; ++i) - { - var speed = RandomX(0,10); - var r = angle; - CreateParticle("ExploSmoke",IX,IY,+Sin(r,speed)+RandomX(-2,2) + GetXDir()/2,-Cos(r,speed)+RandomX(-2,2) + GetYDir()/2,RandomX(100,400),RGBa(255,255,255,50)); - } - CreateParticle("MuzzleFlash",IX,IY,+Sin(angle,500),-Cos(angle,500),600,RGB(255,255,255),this); - CreateParticle("Flash",0,0,GetXDir(),GetYDir(),800,RGBa(255,255,64,150)); + var x = Sin(angle, 20); + var y = -Cos(angle, 20); + CreateParticle("Smoke", IX, IY, PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), PV_Random(40, 60), Particles_Smoke(), 20); + + CreateMuzzleFlash(IX, IY, angle, 20); + CreateParticle("Flash", 0, 0, GetXDir(), GetYDir(), 8, Particles_Flash()); AddEffect("IntCooldown", this,1,1,this); } @@ -207,7 +207,13 @@ private func FxIntPlaneTimer(object target, effect, int timer) //Vfx var colour = 255 - (GetDamage() * 3); - CreateParticle("EngineSmoke",0,0,0,0,RandomX(70,90),RGB(colour,colour,colour)); + var particles = + { + Prototype = Particles_Smoke(), + R = colour, G = colour, B = colour, + Size = PV_Linear(PV_Random(20, 30), PV_Random(70, 100)) + }; + CreateParticle("Smoke", 0, 0, 0, 0, PV_Random(36, 2 * 36), particles, 2); } //Throttle-to-thrust lag @@ -286,9 +292,9 @@ public func FaceRight() public func IsProjectileTarget(target,shooter) { return true; } -public func Damage(int change, int byplayer) +public func Damage() { - if(GetDamage() > health) + if(GetDamage() >= health) { if(Random(2)) PlaneDeath(); else @@ -305,7 +311,7 @@ private func PlaneDeath() public func Hit() { - if(GetDamage() > health) PlaneDeath(); + if(GetDamage() >= health) PlaneDeath(); } public func ActivateEntrance(object clonk) @@ -342,7 +348,7 @@ public func Ejection(object obj) public func PlaneMount(object clonk) { SetOwner(clonk->GetController()); - clonk->PlayAnimation("Stand", 15, 0, Anim_Const(1000)); + clonk->PlayAnimation("Stand", 15, nil, Anim_Const(1000)); clonkmesh = AttachMesh(clonk,"pilot","skeleton_body",Trans_Mul(Trans_Rotate(180,0,1,0), Trans_Translate(0,-3000,-1000)),AM_DrawBefore); return true; } @@ -355,37 +361,41 @@ public func PlaneDismount(object clonk) return true; } -func Definition(def) { - SetProperty("ActMap", { -Fly = { - Prototype = Action, - Name = "Fly", - Procedure = DFA_NONE, - Directions = 2, - FlipDir = 0, - Length = 10, - Delay = 1, - X = 0, - Y = 0, - Wdt = 40, - Hgt = 56, - NextAction = "Fly", -}, -Land = { - Prototype = Action, - Name = "Land", - Procedure = DFA_NONE, - Directions = 2, - FlipDir = 0, - Length = 1, - Delay = 2, - X = 0, - Y = 0, - Wdt = 40, - Hgt = 56, - NextAction = "Land", -}, -}, def); +func IsShipyardProduct() { return true; } + +local ActMap = { + Fly = { + Prototype = Action, + Name = "Fly", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 0, + Length = 10, + Delay = 1, + X = 0, + Y = 0, + Wdt = 40, + Hgt = 56, + NextAction = "Fly", + }, + Land = { + Prototype = Action, + Name = "Land", + Procedure = DFA_NONE, + Directions = 2, + FlipDir = 0, + Length = 1, + Delay = 2, + X = 0, + Y = 0, + Wdt = 40, + Hgt = 56, + NextAction = "Land", + }, +}; + +func Definition(def) +{ SetProperty("Name", "$Name$", def); SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(90,0,0,1), Trans_Translate(-10000,-3375,0), Trans_Rotate(25,0,1,0))); SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(-5,1,0,0),Trans_Rotate(40,0,1,0),Trans_Translate(-20000,-4000,20000)),def); diff --git a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/StringTblUS.txt b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/StringTblUS.txt index 9c7381ab2..3c20f4751 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/StringTblUS.txt @@ -1,3 +1,3 @@ Name=Airplane -Description=Press [Up] and [Down] to stop and start engine. [Left] and [Right] control ailerons. Press [Down] again when the engine is off to reverse the plane. +Description=Press [Up] and [Down] to stop and start engine. [Left] and [Right] control orientation. Press [Down] again when the engine is off to reverse the plane. NoShots=No available lead shot! \ No newline at end of file diff --git a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/airplane.jpg b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/airplane.jpg new file mode 100644 index 000000000..fba1a2442 Binary files /dev/null and b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/airplane.jpg differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/airplane.png b/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/airplane.png deleted file mode 100644 index 5d5b5a8f3..000000000 Binary files a/planet/Objects.ocd/Vehicles.ocd/Airplane.ocd/airplane.png and /dev/null differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Scene.material b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Scene.material index fdb606f2d..261d931e3 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Scene.material +++ b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Scene.material @@ -12,7 +12,7 @@ material Airship emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture airship_uv.png + texture airship.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Script.c index 56f7732bb..79d95ac7a 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/Script.c @@ -1,4 +1,8 @@ -//Airship Graphic +/** + Airship Graphics + + @authors Ringwaul +*/ local propanim; local parent; @@ -6,6 +10,14 @@ local parent; protected func Initialize() { propanim = PlayAnimation("Flight", 5, Anim_Const(0), Anim_Const(1000)); + AddEffect("CheckParent", this, 1, 1,this); +} + +private func FxCheckParentTimer(object target, proplist effect, int timer) +{ + if (!parent) + target->RemoveObject(); + return; } //Moves the propeller 1 tick per call @@ -28,11 +40,24 @@ func AnimationForward() //SoundEffect? } +public func GetTurnAngle() +{ + var dir = parent->GetAnimDir(); + var r = GetAnimationPosition(parent.turnanim) * 1242 / 10000; + + if (dir == DIR_Left) + r = 180 - r; + return r; +} + public func SetAirshipParent(object airship) { parent = airship; } +// Only save main airship object +func SaveScenarioObject() { return false; } + local ActMap = { Attach = { Prototype = Action, diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship.jpg b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship.jpg new file mode 100644 index 000000000..c4e1b19c7 Binary files /dev/null and b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship.jpg differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship_burnt.png b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship_burnt.png deleted file mode 100644 index 07a540e4f..000000000 Binary files a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship_burnt.png and /dev/null differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship_uv.png b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship_uv.png deleted file mode 100644 index a2a449400..000000000 Binary files a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Airship3DGraphics.ocd/airship_uv.png and /dev/null differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipBurnt.ocd/DefCore.txt b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipBurnt.ocd/DefCore.txt index d9edcee2a..94bfa4e12 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipBurnt.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipBurnt.ocd/DefCore.txt @@ -13,4 +13,3 @@ VertexCNAT=6 Value=34 Mass=60 Components=Metal=4;Wood=1; -SolidMask=64,0,64,54,0,0 diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipHitbox.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipHitbox.ocd/Script.c index 94fc6c6f4..ff941724e 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipHitbox.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/AirshipHitbox.ocd/Script.c @@ -1,21 +1,23 @@ //Airship Hitbox -local health; local parent; -protected func Initialize() +public func Initialize() { - health = 30; + AddEffect("CheckParent", this,1,1,this); +} + +private func FxCheckParentTimer(object target, proplist, int timer) +{ + if(!parent) target->RemoveObject(); } public func IsProjectileTarget(target,shooter) { return true; } -public func Damage(int change, int byplayer) +public func Damage(int change) { - if(GetDamage() > health) - { - parent->AirshipDeath(); - } + //forward the damage to airship parent + parent->DoDamage(change); } public func SetAirshipParent(object airship) @@ -23,6 +25,9 @@ public func SetAirshipParent(object airship) parent = airship; } +// Only save main airship object +func SaveScenarioObject() { return false; } + local ActMap = { Attach = { Prototype = Action, diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/DefCore.txt b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/DefCore.txt index cc1aab4a0..515b54038 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/DefCore.txt @@ -6,14 +6,14 @@ Width=64 Height=54 Offset=-32,-27 Vertices=11 -VertexX=0,0,-20,+20,-30,+30,-20,+20,-15,+15,0 -VertexY=0,-30,-30,-30,-15,-15,-5,-5,+26,+26,+26 -VertexFriction=20,20,20,20,20,20,20,80,80,80 -VertexCNAT=6 +VertexX=0,0,-20,+20,-30,+30,-20,+20,-16,+16,0 +VertexY=0,-30,-30,-30,-15,-15,-5,-5,+27,+27,+27 +VertexCNAT=0,4,5,6,1,2,1,2,9,10,8 +VertexFriction=0,20,20,20,20,20,20,20,80,80,80 Value=50 Mass=5000 Components=Metal=4;Wood=4;Rope=2; Float=-27; -SolidMask=64,0,64,54,0,0 +SolidMask=0,0,36,4,11,49 Picture=128,0,128,128,0,0 BorderBound=7 \ No newline at end of file diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Graphics.png b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Graphics.png index f680c7b9b..895d53234 100644 Binary files a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Graphics.png and b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Script.c index 5a87c215d..3d5a2d7ac 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/Script.c @@ -1,38 +1,36 @@ -/*-- +/** Airship - Ringwaul - - Lighter-than-air travel and transport vehicle. - The airship uses several objects to function; the base control/collision object, - an attached graphics object (due to engine limitations with solidmasks), - and a hitbox for the balloon. ---*/ + Lighter-than-air travel and transport vehicle. The airship uses several objects to function; the base control/collision object, + an attached graphics object (due to former engine limitations with solidmasks), and a hitbox for the balloon. -local throttle; + @authors Ringwaul +*/ -//sums of x,y dir forces upon blimp -local xtarget; -local ytarget; +#include Library_AlignVehicleRotation -//Airship Control -local xthrottle; -local ythrottle; -//Attached modules +// Attached modules local graphic; local hitbox; -//Graphic module variables for animation -local animdir; +// Graphic module variables for animation local turnanim; + +local throttle; +local enginesound; + +local health = 30; + +//Rectangle defining where to look for objents contained in the gondola +local gondola = [-20,-2,40,30]; + + protected func Initialize() { SetAction("Fly"); SetComDir(COMD_None); throttle = 0; - xtarget = 0; - ytarget = 0; //Create 3D Graphic graphic = CreateObject(Airship_Graphic); @@ -44,112 +42,139 @@ protected func Initialize() hitbox->SetAction("Attach", this); hitbox->SetAirshipParent(this); - //The airship starts facing left; so default to that value - animdir = -1; + // The airship starts facing left; so default to that value + SetDir(DIR_Left); turnanim = graphic->PlayAnimation("TurnLeft", 10, Anim_Const(graphic->GetAnimationLength("TurnLeft")), Anim_Const(1000)); - //Start the Airship behaviour - AddEffect("FlyEffect",this,1,1,this); + // Start the Airship behaviour + AddEffect("IntAirshipMovement", this, 1, 1, this); } -local enginesound; - -public func FxFlyEffectTimer(object target, int num, int timer) +public func Damage() { - //Cancel effect if there is no graphic. - if(!graphic) return -1; + if(GetDamage() >= health) + { + AirshipDeath(); + } +} - //Is the engine running? - if(Abs(xthrottle) == 1 || Abs(ythrottle) == 1) +public func FxIntAirshipMovementStart(object target, proplist effect, int temporary) +{ + if (temporary) + return 1; + SetComDir(COMD_Stop); + effect.AnimDir = DIR_Left; + return 1; +} + + +public func FxIntAirshipMovementTimer(object target, proplist effect, int time) +{ + // Cancel effect if there is no graphic. + if (!graphic) + return -1; + + // Is the engine running? + if (GetComDir() != COMD_Stop && AirshipPilot()) { //Turn the propeller graphic->AnimationForward(); - //Emit engine smoke + // Emit engine smoke var i = 20; var colour = 240; - if(animdir == 1) i = -25; //Is the airship facing right? - if(graphic->GetAnimationPosition(turnanim) == graphic->GetAnimationLength("TurnLeft")) //Don't smoke if turning... airship blocks view - CreateParticle("EngineSmoke", i, 18,0,0,RandomX(20,40),RGBa(colour,colour,colour,colour)); - - //Fan-blade sound - if(!enginesound) + // Is the airship facing right? + if (effect.AnimDir == DIR_Right) + i = -25; + if (graphic->GetAnimationPosition(turnanim) == graphic->GetAnimationLength("TurnLeft")) //Don't smoke if turning... airship blocks view + { + var particles = + { + Prototype = Particles_Smoke(), + R = colour, G = colour, B = colour + }; + CreateParticle("Smoke", i, 18, 0, 0, PV_Random(36, 2 * 36), particles, 2); + } + // Fan-blade sound + if (!enginesound) { enginesound = true; Sound("FanLoop",nil,nil,nil,1); } } - else + else if(enginesound == true) { - if(enginesound == true) - { - Sound("FanLoop",nil,nil,nil,-1); - enginesound = nil; - } + Sound("FanLoop", nil, nil, nil, -1); + enginesound = false; } - //Control proxy - if(xthrottle) xtarget = (xthrottle * 12); - if(ythrottle) ytarget = (ythrottle * 6); - if(!xthrottle) xtarget = 0; - if(!ythrottle) ytarget = 0; + // Wind movement if in the air + if (!GetContact(-1)) + /* TODO: Implement */; - //Wind movement if in the air - if(!GetContact(-1)) - xtarget = xtarget + GetWind()/10; - - //Fall down if there is no water below nor pilot - if(!AirshipPilot() && !GBackLiquid(0,26) && !GetContact(-1)) + // Fall down if there no pilot and ground. + if (!AirshipPilot()) { - ytarget = 10; + if (GetContact(-1) & CNAT_Bottom) + SetComDir(COMD_Stop); + else + SetComDir(COMD_Down); } - + //Rise in water - if(GBackLiquid(0,25)) ytarget = -10; - if(GBackLiquid(0,25) && !GBackLiquid(0,24) && ytarget > 1) ytarget = 0; + if (GBackLiquid(0,25)) + //effect.SpeedY = -10; + if (GBackLiquid(0,25) && !GBackLiquid(0,24) && effect.SpeedY > 1) + //effect.SpeedY = 0; - //Fall to the ground if there is no pilot on board - if(!AirshipPilot()) - { - xthrottle = 0; - ythrottle = 0; - } + var dir = GetComDir(); + //Log("%v", dir ); + // Turn the airship around if needed + if (effect.AnimDir == DIR_Left && GetXDir(100) > 30) + if (GetComDir() == COMD_Right || GetComDir() == COMD_UpRight || GetComDir() == COMD_DownRight) + target->TurnAirship(DIR_Right); + if (effect.AnimDir == DIR_Right && GetXDir(100) < -30) + if (GetComDir() == COMD_Left || GetComDir() == COMD_UpLeft || GetComDir() == COMD_DownLeft) + target->TurnAirship(DIR_Left); + + //Log("animdir: %v, xdir: %v, comdir: %v", effect.AnimDir, GetXDir(100), GetComDir()); + + return 1; +} - //x target speed - if(GetXDir(100) != xtarget * 10) - { - if(GetXDir(100) > xtarget * 10) SetXDir(GetXDir(100) -1,100); - if(GetXDir(100) < xtarget * 10) SetXDir(GetXDir(100) +1,100); - } +func TurnAirship(int to_dir) +{ + // Default direction is left + var animName = "TurnLeft"; + if (to_dir == DIR_Right) + animName = "TurnRight"; - //y target speed - if(GetYDir() != ytarget) - { - if(GetYDir() > ytarget) SetYDir(GetYDir() -1); - if(GetYDir() < ytarget) SetYDir(GetYDir() +1); - } + StopAnimation(turnanim); + turnanim = graphic->PlayAnimation(animName, 10, Anim_Linear(0, 0, graphic->GetAnimationLength(animName), 36, ANIM_Hold), Anim_Const(1000)); + + SetAnimDir(to_dir); + + var g = gondola; + AlignObjectsToRotation(graphic, g[0],g[1],g[2],g[3]); + + return; +} - //Turn the airship right - if(animdir == -1 && GetXDir() > 1 && xthrottle == 1) - { - StopAnimation(turnanim); - turnanim = graphic->PlayAnimation("TurnRight", 10, Anim_Linear(0, 0, graphic->GetAnimationLength("TurnRight"), 36, ANIM_Hold), Anim_Const(1000)); - animdir = 1; - } +public func SetAnimDir(int to_dir) +{ + var effect = GetEffect("IntAirshipMovement", this); + if (effect) + effect.AnimDir = to_dir; + return; +} - //turn the airship left - if(animdir == 1 && GetXDir() < -1 && xthrottle == -1) - { - StopAnimation(turnanim); - turnanim = graphic->PlayAnimation("TurnLeft", 10, Anim_Linear(0, 0, graphic->GetAnimationLength("TurnLeft"), 36, ANIM_Hold), Anim_Const(1000)); - animdir = -1; - } - - //fun debug output stuff -/* if(!AirshipPilot()) Message(Format("^ 3^|XTAR:%d|YTAR:%d|XDIR:%d|YDIR:%d",xtarget,ytarget,GetXDir(),GetYDir())); - else - Message(Format("o _o|XTAR:%d|YTAR:%d|XDIR:%d|YDIR:%d",xtarget,ytarget,GetXDir(),GetYDir())); */ +public func GetAnimDir() +{ + var effect = GetEffect("IntAirshipMovement", this); + if (effect) + return effect.AnimDir; + return; } /* -- Control Inputs -- */ @@ -157,34 +182,97 @@ public func FxFlyEffectTimer(object target, int num, int timer) func ControlLeft(object clonk) { - xthrottle = -1; + if (GetComDir() == COMD_Up) + SetComDir(COMD_UpLeft); + else if (GetComDir() == COMD_Down) + SetComDir(COMD_DownLeft); + else + SetComDir(COMD_Left); + return true; } func ControlRight(object clonk) { - xthrottle = 1; + if (GetComDir() == COMD_Up) + SetComDir(COMD_UpRight); + else if (GetComDir() == COMD_Down) + SetComDir(COMD_DownRight); + else + SetComDir(COMD_Right); + return true; } func ControlUp(object clonk) { - ythrottle = -1; + if (GetComDir() == COMD_Left) + SetComDir(COMD_UpLeft); + else if (GetComDir() == COMD_Right) + SetComDir(COMD_UpRight); + else + SetComDir(COMD_Up); + return true; } func ControlDown(object clonk) { - ythrottle = 1; + if (GetComDir() == COMD_Left) + SetComDir(COMD_DownLeft); + else if (GetComDir() == COMD_Right) + SetComDir(COMD_DownRight); + else + SetComDir(COMD_Down); + return true; } func ControlStop(object clonk, int control) { - if(control == 11 || control == 12) xthrottle = 0; - if(control == 13 || control == 14) ythrottle = 0; + var comdir = GetComDir(); + var newdir; + if (control == CON_Left) + { + if (comdir == COMD_Left) + newdir = COMD_Stop; + if (comdir == COMD_UpLeft) + newdir = COMD_Up; + if (comdir == COMD_DownLeft) + newdir = COMD_Down; + } + if (control == CON_Right) + { + if (comdir == COMD_Right) + newdir = COMD_Stop; + if (comdir == COMD_UpRight) + newdir = COMD_Up; + if (comdir == COMD_DownRight) + newdir = COMD_Down; + } + if (control == CON_Up) + { + if (comdir == COMD_Up) + newdir = COMD_Stop; + if (comdir == COMD_UpLeft) + newdir = COMD_Left; + if (comdir == COMD_UpRight) + newdir = COMD_Right; + } + if (control == CON_Down) + { + if (comdir == COMD_Down) + newdir = COMD_Stop; + if (comdir == COMD_DownLeft) + newdir = COMD_Left; + if (comdir == COMD_DownRight) + newdir = COMD_Right; + } + SetComDir(newdir); + return true; } private func AirshipPilot() { //Looks for a clonk within the Gondola - var clonk = FindObject(Find_ID(Clonk), Find_OCF(OCF_Alive),Find_InRect(-19,0,35,20)); + var g = gondola; + var clonk = FindObject(Find_ID(Clonk), Find_OCF(OCF_Alive),Find_InRect(g[0],g[1],g[2],g[3])); if(clonk) return clonk; else @@ -221,19 +309,24 @@ func AirshipDeath() Explode(27); } +public func IsShipyardProduct() { return true; } +public func IsVehicle() { return true; } local ActMap = { - Fly = { - Prototype = Action, - Name = "Fly", - Procedure = DFA_FLOAT, - Directions = 1, - X = 0, - Y = 0, - Wdt = 64, - Hgt = 54, - NextAction = "Fly", - }, + Fly = { + Prototype = Action, + Name = "Fly", + Procedure = DFA_FLOAT, + Directions = 1, + X = 0, + Y = 0, + Wdt = 64, + Hgt = 54, + Speed = 100, + Accel = 4, + Decel = 8, + NextAction = "Fly", + }, }; func Definition(def) diff --git a/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/SolidMask.png b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/SolidMask.png new file mode 100644 index 000000000..4523edab5 Binary files /dev/null and b/planet/Objects.ocd/Vehicles.ocd/Airship.ocd/SolidMask.png differ diff --git a/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/DefCore.txt b/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/DefCore.txt index 2755471ed..a2c0d2a68 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/DefCore.txt @@ -17,6 +17,4 @@ Components=Metal=4;Wood=2; GrabPutGet=C4D_GrabGet|C4D_GrabPut Rotate=30 UprightAttach=8 -TimerCall=Timer -Timer=1 BorderBound=1 diff --git a/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/Script.c index 2acf6274a..9e9af18b7 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Cannon.ocd/Script.c @@ -8,19 +8,21 @@ #include Library_HasExtraSlot -local aim_anim; -local turn_anim; -local olddir; +local animAim; +local animTurn; +local turnDir; -static const Fire_Velocity = 175; +local Fire_Velocity = 175; -public func IsToolProduct() { return true; } +public func IsArmoryProduct() { return true; } +public func IsVehicle() { return true; } protected func Initialize() { + turnDir = 1; SetAction("Roll"); - olddir = GetDir(); - aim_anim = PlayAnimation("Aim", 1, Anim_Const(0),Anim_Const(1000)); + animAim = PlayAnimation("Aim", 1, Anim_Const(0),Anim_Const(1000)); + animTurn = PlayAnimation("TurnRight", 5, Anim_Const(0), Anim_Const(1000)); } //some left-overs from Lorry script. Not sure of it's purpose... @@ -69,7 +71,7 @@ private func UseAnyStart(object clonk, int ix, int iy, int item) //Animation var r = ConvertAngle(Angle(0,0,ix,iy)); - SetAnimationPosition(aim_anim, Anim_Const(AnimAngle(r)*3954444/100000)); //conversion. Apparently 90 blender frames is 3559 ogre frames. + SetAnimationPosition(animAim, Anim_Const(AnimAngle(r)*3954444/100000)); //conversion. Apparently 90 blender frames is 3559 ogre frames. return true; } @@ -102,6 +104,8 @@ public func ControlUseAltHolding(object clonk, int ix, int iy) return ControlUseHolding(clonk, ix, iy); } +local angPrec = 1000; + public func ControlUseHolding(object clonk, int ix, int iy) { if (!clonk) @@ -109,14 +113,14 @@ public func ControlUseHolding(object clonk, int ix, int iy) clonk->CancelUse(); return true; } - var r = ConvertAngle(Angle(0,0,ix,iy)); + var r = ConvertAngle(Angle(0,0,ix,iy,angPrec)); var iColor = RGB(255,255,255); if (!Contents(0) || GetEffect("IntCooldown",this)) iColor = RGB(255,0,0); - AddTrajectory(this, GetX() + 5, GetY() + 2, Cos(r-90, Fire_Velocity), Sin(r-90, Fire_Velocity), iColor, 20); + AddTrajectory(this, GetX() + 5, GetY() + 2, Cos(r - 90 * angPrec, Fire_Velocity,angPrec), Sin(r - 90 * angPrec, Fire_Velocity,angPrec), iColor, 20); - SetAnimationPosition(aim_anim, Anim_Const(AnimAngle(r)*3954444/100000)); + SetAnimationPosition(animAim, Anim_Const(AnimAngle(r/angPrec)*3954444/100000)); return true; } @@ -133,15 +137,17 @@ private func AnimAngle(int angle) private func ConvertAngle(int angle) { - //More confusing conversion ;) - var r = angle; - if(r > 90 + GetR() && GetDir() == 1) r = 90 + GetR(); - if(r < 270 + GetR() && r != 0 && GetDir() == 0) r = 270 + GetR(); - if(r == 360 + GetR() && GetDir() == 0) r = 0 + GetR(); - //second half. Makes it relative to current direction. - if(r - GetR() < 0 && GetDir() == 1) SetDir(); - if(r - GetR() > 359 && GetDir() == 0) SetDir(1); - return r; + var nR = BoundBy(Normalize(angle,-180 * angPrec,angPrec), (-90 * angPrec) + (GetR() * angPrec), (90 * angPrec) + (GetR() * angPrec)); + var r2 = nR - GetR() * angPrec; + //debug messages + //Message(Format("nR = %d|rL = %d",nR,r2)); + + //Turn the cannon into the pointed direction + if(nR - (GetR() * angPrec) < 0 && turnDir == 1) TurnCannon(0); + if(nR - (GetR() * angPrec) > 0 && turnDir == 0) TurnCannon(1); + + //renormalize the angle to 0/360 from -180/180 + return Normalize(nR,0,angPrec); } public func ControlUseStop(object clonk, int ix, int iy) @@ -175,14 +181,15 @@ private func UseAnyStop(object clonk, int ix, int iy, int item) if (projectile) { - DoFire(projectile, clonk, Angle(0,0,ix,iy)); + DoFire(projectile, clonk, Angle(0,0,ix,iy,angPrec)); var powder = Contents(0)->PowderCount(); - if(powder >= 1) + if(powder >= 1 || projectile->~IsSelfPropellent()) { var powderkeg = Contents(0); //If there is a powder keg, take powder from it powderkeg->SetPowderCount(powderkeg->PowderCount() -1); - DoFire(projectile, clonk, Angle(0,0,ix,iy)); + + DoFire(projectile, clonk, Angle(0,0,ix,iy, angPrec)); AddEffect("IntCooldown",this,1,1,this); if(powderkeg->PowderCount() == 0) { @@ -205,106 +212,85 @@ public func ControlUseAltCancel() return ControlUseCancel(); } +//Stops the player from shooting for the defined amount of frames public func FxIntCooldownTimer(object target, effect, int timer) { if(timer > 72) return -1; } -//Activate turn animations + func ControlLeft(object clonk) { - SetDir(); + if(turnDir == 1){ + TurnCannon(0); + } } func ControlRight(object clonk) { - SetDir(1); + if(turnDir == 0){ + TurnCannon(1); + } +} + +func TurnCannon(int dir) +{ + turnDir = dir; + //Remove any old effect + if(GetEffect("IntTurnCannon", this)) RemoveEffect("IntTurnCannon", this); + //Add a new one + return AddEffect("IntTurnCannon", this, 1, 1, this); +} + + +func FxIntTurnCannonTimer(object cannon, proplist effect, int timer) +{ + var current = GetAnimationPosition(animTurn); + var target = GetAnimationLength("TurnRight"); + if(turnDir == 1) target = 0; + var tickAmount = 50; //by how much the animation will move forward each frame + + //advance turn animation + if((current != GetAnimationLength("TurnRight") && turnDir == 0) || (current != 0 && turnDir == 1)){ + SetAnimationPosition(animTurn, Anim_Const(MoveTowards(current, target, tickAmount))); + } + else return -1; } protected func DoFire(object iammo, object clonk, int angle) { - if(iammo->~HasFuse()) - { - iammo->Fuse(); - } + iammo->~Fuse(); //Don't excede possible trajectory - var r = Normalize(angle,-180); - if(r > 90 + GetR()) r = 90 + GetR(); - if(r < -90 + GetR()) r = -90 + GetR(); + var r = Normalize(angle,-180 * angPrec, angPrec); + if(r > 90 * angPrec + GetR() * angPrec) r = 90 * angPrec + GetR() * angPrec; + if(r < -90 * angPrec + GetR() * angPrec) r = -90 * angPrec + GetR() * angPrec; //Send ammo flying - iammo->SetR(r); + iammo->SetR(r / angPrec); iammo->SetRDir(-4 + Random(9)); - iammo->LaunchProjectile(r, 17, Fire_Velocity); + iammo->LaunchProjectile(r, 17, Fire_Velocity, 0,0, angPrec); //Particles var dist = 25; - var px = Cos(r - 90,dist); - var py = Sin(r - 90,dist) - 4; - CreateParticle("Flash",px,py,0,0,420,RGB(255,255,255)); - for(var i=0; i<15; ++i) //liberated from musket script... I'm horrible at particles :p - { - var speed = RandomX(0,10); - CreateParticle("ExploSmoke",px,py,+Sin(r,speed)+RandomX(-2,2),-Cos(r,speed)+RandomX(-2,2),RandomX(100,400),RGBa(255,255,255,75)); - } - CreateParticle("MuzzleFlash",px,py,px,py+4,700,RGB(255,255,255)); //muzzle flash uses speed as Rotation... so I negate the -4 + var px = Cos(r/angPrec - 90,dist); + var py = Sin(r/angPrec - 90,dist) - 4; + CreateParticle("Flash", px, py, 0, 0, 8, Particles_Flash()); + var x = Sin(r/angPrec, 20); + var y = -Cos(r/angPrec, 20); + CreateParticle("Smoke", px, py, PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), PV_Random(40, 60), Particles_Smoke(), 20); + CreateMuzzleFlash(px, py, r / angPrec, 60); //sound Sound("Blast3"); } -func Timer() -{ - //Turning - if(olddir != GetDir()) - { - if(olddir == 0) - { - if(!GetEffect("IntTurning",this)) - { - StopAnimation(turn_anim); - turn_anim = PlayAnimation("TurnRight", 5, Anim_Linear(0, 0, GetAnimationLength("TurnRight"), 36, ANIM_Hold), Anim_Const(1000)); - AddEffect("IntTurning",this,1,1,this); - } - else - { - var new_dist = GetAnimationLength("TurnRight") - GetAnimationPosition(turn_anim); - var old_effect = 36 - GetEffect("IntTurning",this).Interval; - turn_anim = PlayAnimation("TurnRight", 5, Anim_Linear(new_dist, new_dist, GetAnimationLength("TurnLeft"), old_effect, ANIM_Remove), Anim_Const(1000)); - } - } - - if(olddir == 1) - { - if(!GetEffect("IntTurning",this)) - { - StopAnimation(turn_anim); - turn_anim = PlayAnimation("TurnLeft", 5, Anim_Linear(0, 0, GetAnimationLength("TurnLeft"), 36, ANIM_Hold), Anim_Const(1000)); - AddEffect("IntTurning",this,1,1,this); - } - else - { - var new_dist = GetAnimationLength("TurnLeft") - GetAnimationPosition(turn_anim); - var old_effect = 36 - GetEffect("IntTurning",this).Interval; - turn_anim = PlayAnimation("TurnLeft", 5, Anim_Linear(new_dist, new_dist, GetAnimationLength("TurnLeft"), old_effect, ANIM_Remove), Anim_Const(1000)); - } - } - } - olddir = GetDir(); -} - -private func FxIntTurningTimer(object target, effect, int timer) -{ - if(timer > 36) return -1; -} - local ActMap = { Roll = { Prototype = Action, Name = "Roll", Procedure = DFA_NONE, - Directions = 2, + Directions = 1, FlipDir = 1, Length = 50, Delay = 2, diff --git a/planet/Objects.ocd/Vehicles.ocd/Catapult.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Catapult.ocd/Script.c index 20ebe5eda..b753106f4 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Catapult.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Catapult.ocd/Script.c @@ -11,7 +11,8 @@ local olddir; local dir; local clonkmesh; -public func IsToolProduct() { return true; } +public func IsVehicle() { return true; } +public func IsArmoryProduct() { return true; } protected func Initialize() { @@ -224,7 +225,7 @@ Roll = { NextAction = "Roll", }, }; -func Definitio(def) +func Definition(def) { SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(6000,0,0),Trans_Rotate(-20,1,0,0),Trans_Rotate(35,0,1,0),Trans_Scale(1350)),def); } diff --git a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt index ca707aa38..4db4d0064 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/DefCore.txt @@ -18,6 +18,4 @@ Collection=-12,-8,24,10 GrabPutGet=C4D_GrabGet|C4D_GrabPut Rotate=30 UprightAttach=8 -TimerCall=TurnWheels -Timer=1 BorderBound=1 diff --git a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Scene.material b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Scene.material index dbc6b617d..e5251240e 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Scene.material +++ b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Scene.material @@ -11,7 +11,7 @@ material Lorry emissive 0.000000 0.000000 0.000000 1.000000 texture_unit { - texture lorry.png + texture lorry.jpg tex_address_mode wrap filtering trilinear } diff --git a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Script.c index cc4692cf5..69ed016bf 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/Script.c @@ -11,11 +11,13 @@ protected func Construction() } public func IsLorry() { return true; } +public func IsVehicle() { return true; } public func IsContainer() { return true; } public func IsToolProduct() { return true; } local drive_anim; local tremble_anim; +local wheel_sound; protected func Initialize() { @@ -24,6 +26,7 @@ protected func Initialize() iRotWheels = 0; iTremble = 0; + AddTimer("TurnWheels", 1); } /*-- Movement --*/ @@ -40,6 +43,11 @@ protected func ContactRight() SetRDir(RandomX(-7, +7)); } +func Hit3() +{ + Sound("DullMetalHit?"); +} + /*-- Contents --*/ private func MaxContentsCount() @@ -50,7 +58,7 @@ private func MaxContentsCount() protected func RejectCollect(id object_id, object obj) { // objects can still be collected - if (ContentsCount() < MaxContentsCount()) + if (ContentsCount() < this->MaxContentsCount()) { Sound("Clonk"); return false; @@ -102,6 +110,16 @@ func TurnWheels() if(iTremble > 2000) iTremble -= 2000; SetAnimationPosition(tremble_anim, Anim_Const(iTremble)); } + if (Abs(GetXDir()) > 1 && !wheel_sound) + { + if (!wheel_sound) Sound("WheelsTurn", false, nil, nil, 1); + wheel_sound = true; + } + else if (wheel_sound && !GetXDir()) + { + Sound("WheelsTurn", false, nil, nil, -1); + wheel_sound = false; + } } local ActMap = { diff --git a/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/lorry.jpg b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/lorry.jpg new file mode 100644 index 000000000..b29368e7e Binary files /dev/null and b/planet/Objects.ocd/Vehicles.ocd/Lorry.ocd/lorry.jpg differ diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/DescDE.rtf b/planet/Parkour.ocf/Boomrace.ocs/DescDE.rtf similarity index 71% rename from planet/BackToTheRocks.ocf/Boomrace.ocs/DescDE.rtf rename to planet/Parkour.ocf/Boomrace.ocs/DescDE.rtf index c55d8d2c7..5e7556114 100644 Binary files a/planet/BackToTheRocks.ocf/Boomrace.ocs/DescDE.rtf and b/planet/Parkour.ocf/Boomrace.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/Boomrace.ocs/DescUS.rtf b/planet/Parkour.ocf/Boomrace.ocs/DescUS.rtf new file mode 100644 index 000000000..900580ccb Binary files /dev/null and b/planet/Parkour.ocf/Boomrace.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/Map.bmp b/planet/Parkour.ocf/Boomrace.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/Boomrace.ocs/Map.bmp rename to planet/Parkour.ocf/Boomrace.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/Scenario.txt b/planet/Parkour.ocf/Boomrace.ocs/Scenario.txt similarity index 95% rename from planet/BackToTheRocks.ocf/Boomrace.ocs/Scenario.txt rename to planet/Parkour.ocf/Boomrace.ocs/Scenario.txt index 328acde40..a92bf4c8b 100644 --- a/planet/BackToTheRocks.ocf/Boomrace.ocs/Scenario.txt +++ b/planet/Parkour.ocf/Boomrace.ocs/Scenario.txt @@ -2,7 +2,7 @@ Icon=39 Title=Boomrace Version=5,2,0,1 -MaxPlayer=8 +Difficulty=30 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/Script.c b/planet/Parkour.ocf/Boomrace.ocs/Script.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomrace.ocs/Script.c rename to planet/Parkour.ocf/Boomrace.ocs/Script.c diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/System.ocg/Boompack.c b/planet/Parkour.ocf/Boomrace.ocs/System.ocg/Boompack.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomrace.ocs/System.ocg/Boompack.c rename to planet/Parkour.ocf/Boomrace.ocs/System.ocg/Boompack.c diff --git a/planet/Parkour.ocf/Boomrace.ocs/System.ocg/Clonk.c b/planet/Parkour.ocf/Boomrace.ocs/System.ocg/Clonk.c new file mode 100644 index 000000000..d06298055 --- /dev/null +++ b/planet/Parkour.ocf/Boomrace.ocs/System.ocg/Clonk.c @@ -0,0 +1,31 @@ +// The clonk can only hold one item and only collect boompacks. + +#appendto Clonk + +protected func RejectCollect(id objid, object obj) +{ + if (objid != Boompack) + return true; + return _inherited(objid, obj); +} + +public func MaxContentsCount() +{ + return 0; +} + +public func ObjectControl(int plr, int ctrl) +{ + if(IsThrowControl(ctrl)) + return; + if(IsDropControl(ctrl)) + return; + + return _inherited(plr, ctrl, ...); +} + +// no extra interactions in this scenario. like dropping carry-heavy objects. :( +public func GetExtraInteractions() +{ + return nil; +} \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/Boomrace.ocs/Title.txt b/planet/Parkour.ocf/Boomrace.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomrace.ocs/Title.txt rename to planet/Parkour.ocf/Boomrace.ocs/Title.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Base.png b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Base.png similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Base.png rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Base.png diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Brass.png b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Brass.png similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Brass.png rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Brass.png diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/DefCore.txt b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/DefCore.txt rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Graphics.mesh b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Graphics.mesh similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Graphics.mesh rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Graphics.mesh diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Scene.material b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Scene.material rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Scene.material diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Script.c b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Script.c similarity index 91% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Script.c rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Script.c index 376cf6d98..4898b0315 100644 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Script.c +++ b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Script.c @@ -20,7 +20,7 @@ public func ControlUp(object clonk) var arrw= CreateObject(Arrow,x,y,-1); arrw->Launch(30,80, clonk); arrw->SetGraphics("1"); - CastParticles("Straw",30,20,x,y,30,40,RGB(255,255,255),RGB(255,120,200)); + CreateParticle("Straw", 0, 0, PV_Random(-20, 20), PV_Random(-20,20), PV_Random(30, 120), Particles_Straw(), 20); } if(GetEffect("SparklingAttention",this)) RemoveEffect("SparklingAttention",this); } diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Spinwheel.skeleton b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Spinwheel.skeleton similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/Spinwheel.skeleton rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/Spinwheel.skeleton diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblDE.txt b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblDE.txt rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblUS.txt b/planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblUS.txt rename to planet/Parkour.ocf/Boomshire.ocs/ArrowWheel.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/BrickEdge.ocd/DefCore.txt b/planet/Parkour.ocf/Boomshire.ocs/BrickEdge.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/BrickEdge.ocd/DefCore.txt rename to planet/Parkour.ocf/Boomshire.ocs/BrickEdge.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/BrickEdge.ocd/Graphics.png b/planet/Parkour.ocf/Boomshire.ocs/BrickEdge.ocd/Graphics.png similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/BrickEdge.ocd/Graphics.png rename to planet/Parkour.ocf/Boomshire.ocs/BrickEdge.ocd/Graphics.png diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/BrickEdge.ocd/Script.c b/planet/Parkour.ocf/Boomshire.ocs/BrickEdge.ocd/Script.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/BrickEdge.ocd/Script.c rename to planet/Parkour.ocf/Boomshire.ocs/BrickEdge.ocd/Script.c diff --git a/planet/Parkour.ocf/Boomshire.ocs/DescDE.rtf b/planet/Parkour.ocf/Boomshire.ocs/DescDE.rtf new file mode 100644 index 000000000..7c8bdb579 Binary files /dev/null and b/planet/Parkour.ocf/Boomshire.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/Boomshire.ocs/DescUS.rtf b/planet/Parkour.ocf/Boomshire.ocs/DescUS.rtf new file mode 100644 index 000000000..729ae6b8a Binary files /dev/null and b/planet/Parkour.ocf/Boomshire.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Map.bmp b/planet/Parkour.ocf/Boomshire.ocs/Map.bmp similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Map.bmp rename to planet/Parkour.ocf/Boomshire.ocs/Map.bmp diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Scenario.txt b/planet/Parkour.ocf/Boomshire.ocs/Scenario.txt similarity index 96% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Scenario.txt rename to planet/Parkour.ocf/Boomshire.ocs/Scenario.txt index 1d930d1cf..21923c954 100644 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/Scenario.txt +++ b/planet/Parkour.ocf/Boomshire.ocs/Scenario.txt @@ -4,6 +4,7 @@ Title=Boomshire Version=4,10 MinPlayer=2 MaxPlayer=2 +Difficulty=50 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Script.c b/planet/Parkour.ocf/Boomshire.ocs/Script.c similarity index 97% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Script.c rename to planet/Parkour.ocf/Boomshire.ocs/Script.c index 880fd5342..cbbe16acb 100644 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/Script.c +++ b/planet/Parkour.ocf/Boomshire.ocs/Script.c @@ -60,7 +60,7 @@ func Initialize() DrawMaterialQuad("Tunnel-brickback",2680,1185,2750,1185,2750,1195,2680,1195); DrawMaterialQuad("Tunnel-brickback",2737,1195,2750,1190,2775,1255,2765,1255); - AddEffect("DynamiteEruption",0,100,130); + AddEffect("DynamiteEruption",nil,100,130); return 1; } @@ -91,7 +91,7 @@ global func FxAutoOpenTimer(object pTarget, effect, int timer) global func FxSparklingAttentionTimer(object pTarget, effect, int timer) { - CastParticles("Flash",Random(10)+10,60,pTarget->GetX(),pTarget->GetY(),100,120,RGBa(255,235,200,80+Random(36))); + CreateParticle("Flash", 0, 0, PV_Random(-20, 20), PV_Random(-20, 20), PV_Random(8, 15), {Prototype = Particles_Flash(), Size = 10}, 10); } protected func Decoration() @@ -137,8 +137,13 @@ global func FxPlaneResetTimer(object target, effect, int time) if(effect.count<4) return 1; - DrawParticleLine("AirIntake",target->GetX()+3,target->GetY(),3030,315,1,40); - DrawParticleLine("MagicSpark",target->GetX()-3,target->GetY(),3030,315,2,40); + var particles = + { + Prototype = Particles_Air(), + Size = PV_Linear(4, 0) + }; + DrawParticleLine("Air", target->GetX()+3, target->GetY(), 3030, 315, 1, PV_Random(-2, 2), PV_Random(-2, 2), PV_Random(10, 30), particles); + target->SetPosition(3030,315); target->SetR(-90); target->SetDir(0); @@ -228,7 +233,7 @@ global func PlaceEdges() protected func OnPlayerRespawn(int iPlr, object cp) { var clonk = GetCrew(iPlr); - clonk->CreateContents(JarOfWinds); + clonk->CreateContents(WindBag); return; } diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/Authors.txt b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/Authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/Authors.txt rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/Authors.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/DefCore.txt b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/DefCore.txt rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/GateHit.ogg b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/GateHit.ogg similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/GateHit.ogg rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/GateHit.ogg diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/Graphics.4.png b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/Graphics.4.png similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/Graphics.4.png rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/Graphics.4.png diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/Script.c b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/Script.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/Script.c rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/Script.c diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblDE.txt b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblDE.txt rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblUS.txt b/planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblUS.txt rename to planet/Parkour.ocf/Boomshire.ocs/StoneDoor.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StringTblDE.txt b/planet/Parkour.ocf/Boomshire.ocs/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StringTblDE.txt rename to planet/Parkour.ocf/Boomshire.ocs/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/StringTblUS.txt b/planet/Parkour.ocf/Boomshire.ocs/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/StringTblUS.txt rename to planet/Parkour.ocf/Boomshire.ocs/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Arrow.c b/planet/Parkour.ocf/Boomshire.ocs/System.ocg/Arrow.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Arrow.c rename to planet/Parkour.ocf/Boomshire.ocs/System.ocg/Arrow.c diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Blink.c b/planet/Parkour.ocf/Boomshire.ocs/System.ocg/Blink.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Blink.c rename to planet/Parkour.ocf/Boomshire.ocs/System.ocg/Blink.c diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Clonk.c b/planet/Parkour.ocf/Boomshire.ocs/System.ocg/Clonk.c similarity index 80% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Clonk.c rename to planet/Parkour.ocf/Boomshire.ocs/System.ocg/Clonk.c index 8b34626f4..d718b2301 100644 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Clonk.c +++ b/planet/Parkour.ocf/Boomshire.ocs/System.ocg/Clonk.c @@ -1,9 +1,9 @@ #appendto Clonk -// The clonk can only hold one item and only collect Jar of Winds. +// The clonk can only hold one item and only collect the windbag protected func RejectCollect(id objid, object obj) { - if (objid != JarOfWinds) + if (objid != WindBag) return true; return _inherited(objid, obj); } @@ -14,6 +14,11 @@ public func MaxContentsCount() return 1; } +public func HandObjects() +{ + return 1; +} + // Lose all items on death. func StartDead() { diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Dynamite.c b/planet/Parkour.ocf/Boomshire.ocs/System.ocg/Dynamite.c similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/System.ocg/Dynamite.c rename to planet/Parkour.ocf/Boomshire.ocs/System.ocg/Dynamite.c diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/DefCore.txt b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/DefCore.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/DefCore.txt rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/DefCore.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Graphics.mesh b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Graphics.mesh similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Graphics.mesh rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Graphics.mesh diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Scene.material b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Scene.material similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Scene.material rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Scene.material diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Script.c b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Script.c similarity index 84% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Script.c rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Script.c index a1ff56bea..7d2738a7e 100644 --- a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Script.c +++ b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Script.c @@ -1,9 +1,6 @@ /*-- Arrow target --*/ local gate; -func Definition(def) { - SetProperty("Name", "$Name$", def); -} protected func Initialize() { @@ -34,10 +31,10 @@ public func OnProjectileHit() public func Burst() { - DrawParticleLine("Straw",0,0,AbsX(gate->GetX()),AbsY(gate->GetY()),6,80,RGB(255,255,255),RGB(255,150,200)); - RemoveObject(); + DrawParticleLine("Straw", 0, 0, AbsX(gate->GetX()), AbsY(gate->GetY()), 6, PV_Random(-5, 5), PV_Random(-5, 0), PV_Random(30, 60), Particles_Straw()); + CreateParticle("Straw", 0, 0, PV_Random(-30, 30), PV_Random(-30,30), PV_Random(30, 120), Particles_Straw(), 200); gate->OpenDoor(); - CastParticles("Straw",130,30,0,-3,30,40,RGB(255,255,255),RGB(255,120,200)); + RemoveObject(); } public func Hit() @@ -51,6 +48,7 @@ protected func Tumble() } func Definition(def) { + SetProperty("Name", "$Name$", def); SetProperty("ActMap", { Fall = { diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/StringTblDE.txt b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/StringTblDE.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/StringTblDE.txt rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/StringTblDE.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/StringTblUS.txt b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/StringTblUS.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/StringTblUS.txt rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/StringTblUS.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Target.skeleton b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Target.skeleton similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/Target.skeleton rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/Target.skeleton diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/target.png b/planet/Parkour.ocf/Boomshire.ocs/Target.ocd/target.png similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Target.ocd/target.png rename to planet/Parkour.ocf/Boomshire.ocs/Target.ocd/target.png diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Teams.txt b/planet/Parkour.ocf/Boomshire.ocs/Teams.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Teams.txt rename to planet/Parkour.ocf/Boomshire.ocs/Teams.txt diff --git a/planet/BackToTheRocks.ocf/Boomshire.ocs/Title.txt b/planet/Parkour.ocf/Boomshire.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Boomshire.ocs/Title.txt rename to planet/Parkour.ocf/Boomshire.ocs/Title.txt diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/DescDE.rtf b/planet/Parkour.ocf/BristleRidge.ocs/DescDE.rtf similarity index 54% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/DescDE.rtf rename to planet/Parkour.ocf/BristleRidge.ocs/DescDE.rtf index 42422a6c1..c9a84ee1c 100644 Binary files a/planet/BackToTheRocks.ocf/BristleRidge.ocs/DescDE.rtf and b/planet/Parkour.ocf/BristleRidge.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/BristleRidge.ocs/DescUS.rtf b/planet/Parkour.ocf/BristleRidge.ocs/DescUS.rtf new file mode 100644 index 000000000..09beb23db Binary files /dev/null and b/planet/Parkour.ocf/BristleRidge.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Icon.png b/planet/Parkour.ocf/BristleRidge.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/Icon.png rename to planet/Parkour.ocf/BristleRidge.ocs/Icon.png diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Landscape.txt b/planet/Parkour.ocf/BristleRidge.ocs/Landscape.txt similarity index 100% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/Landscape.txt rename to planet/Parkour.ocf/BristleRidge.ocs/Landscape.txt diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Scenario.txt b/planet/Parkour.ocf/BristleRidge.ocs/Scenario.txt similarity index 96% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/Scenario.txt rename to planet/Parkour.ocf/BristleRidge.ocs/Scenario.txt index 726cc8c4d..ca8fd14b4 100644 --- a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Scenario.txt +++ b/planet/Parkour.ocf/BristleRidge.ocs/Scenario.txt @@ -2,7 +2,7 @@ Icon=34 Title=BristleRidge Version=4,10,0 -MaxPlayer=16 +Difficulty=40 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Script.c b/planet/Parkour.ocf/BristleRidge.ocs/Script.c similarity index 94% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/Script.c rename to planet/Parkour.ocf/BristleRidge.ocs/Script.c index dd2d62906..ab4ac3562 100644 --- a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Script.c +++ b/planet/Parkour.ocf/BristleRidge.ocs/Script.c @@ -3,7 +3,7 @@ Authors: Mimmo_O, Asmageddon, Maikel Parkour on a dynamic map, the player starts on the bottom left and has to make it to the upper right. - The landscape consists of several pillers seperated by abyss, the player must use the grappler, jar of winds + The landscape consists of several pillers seperated by abyss, the player must use the grappler, wind bag and shovel to cover the abyss and climb the pillars. --*/ @@ -55,7 +55,7 @@ protected func OnPlayerRespawn(int plr, object cp) { var clonk = GetCrew(plr); clonk->CreateContents(GrappleBow); - clonk->CreateContents(JarOfWinds)->DoFullLoad(); + clonk->CreateContents(WindBag)->DoFullLoad(); clonk->CreateContents(Shovel); return; } diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/System.ocg/DoubleTools.c b/planet/Parkour.ocf/BristleRidge.ocs/System.ocg/DoubleTools.c similarity index 58% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/System.ocg/DoubleTools.c rename to planet/Parkour.ocf/BristleRidge.ocs/System.ocg/DoubleTools.c index dc7173745..94ae25601 100644 --- a/planet/BackToTheRocks.ocf/BristleRidge.ocs/System.ocg/DoubleTools.c +++ b/planet/Parkour.ocf/BristleRidge.ocs/System.ocg/DoubleTools.c @@ -1,4 +1,4 @@ -// Clonks may only have one grapplebow and jar of winds. +// Clonks may only have one grapplebow and wind bag #appendto Clonk @@ -7,8 +7,8 @@ protected func RejectCollect(id def) if (def == GrappleBow) if (ObjectCount(Find_Container(this), Find_ID(GrappleBow)) >= 1) return true; - if (def == JarOfWinds) - if (ObjectCount(Find_Container(this), Find_ID(JarOfWinds)) >= 1) + if (def == WindBag) + if (ObjectCount(Find_Container(this), Find_ID(WindBag)) >= 1) return true; return _inherited(def, ...); } \ No newline at end of file diff --git a/planet/BackToTheRocks.ocf/BristleRidge.ocs/Title.txt b/planet/Parkour.ocf/BristleRidge.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/BristleRidge.ocs/Title.txt rename to planet/Parkour.ocf/BristleRidge.ocs/Title.txt diff --git a/planet/BackToTheRocks.ocf/Cavern.ocs/DescDE.rtf b/planet/Parkour.ocf/Cavern.ocs/DescDE.rtf similarity index 76% rename from planet/BackToTheRocks.ocf/Cavern.ocs/DescDE.rtf rename to planet/Parkour.ocf/Cavern.ocs/DescDE.rtf index 184e77614..e660b3bf0 100644 Binary files a/planet/BackToTheRocks.ocf/Cavern.ocs/DescDE.rtf and b/planet/Parkour.ocf/Cavern.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/Cavern.ocs/DescUS.rtf b/planet/Parkour.ocf/Cavern.ocs/DescUS.rtf new file mode 100644 index 000000000..dde370bf6 Binary files /dev/null and b/planet/Parkour.ocf/Cavern.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/Cavern.ocs/Landscape.txt b/planet/Parkour.ocf/Cavern.ocs/Landscape.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Cavern.ocs/Landscape.txt rename to planet/Parkour.ocf/Cavern.ocs/Landscape.txt diff --git a/planet/BackToTheRocks.ocf/Cavern.ocs/Scenario.txt b/planet/Parkour.ocf/Cavern.ocs/Scenario.txt similarity index 90% rename from planet/BackToTheRocks.ocf/Cavern.ocs/Scenario.txt rename to planet/Parkour.ocf/Cavern.ocs/Scenario.txt index 4d9b1ab0e..85c4a17bb 100644 --- a/planet/BackToTheRocks.ocf/Cavern.ocs/Scenario.txt +++ b/planet/Parkour.ocf/Cavern.ocs/Scenario.txt @@ -2,7 +2,7 @@ Icon=34 Title=Cavern Version=5,2,0,1 -MaxPlayer=12 +Difficulty=20 [Definitions] Definition1=Objects.ocd @@ -37,8 +37,5 @@ StartSeason=0,0,0,100 YearSpeed=0,0,0,100 Wind=1,100,-100,100 -[Environment] -Objects=Earthquake=10 - [Animals] Nest=Loam=50;Firestone=20 diff --git a/planet/BackToTheRocks.ocf/Cavern.ocs/Script.c b/planet/Parkour.ocf/Cavern.ocs/Script.c similarity index 96% rename from planet/BackToTheRocks.ocf/Cavern.ocs/Script.c rename to planet/Parkour.ocf/Cavern.ocs/Script.c index 7ba864b78..bf2c5facf 100644 --- a/planet/BackToTheRocks.ocf/Cavern.ocs/Script.c +++ b/planet/Parkour.ocf/Cavern.ocs/Script.c @@ -56,9 +56,9 @@ protected func Initialize() for (var i = 0; i < 4; i++) chest->CreateContents(content_list[Random(GetLength(content_list))]); // Create Disasters. - //CreateObject(Core_Disaster_Earthquake, 0, 0, NO_OWNER)->SetChance(100); + Earthquake->SetChance(50); // Snow - AddEffect("IntSnow", 0, 100, 1); + AddEffect("IntSnow", nil, 100, 1); return; } diff --git a/planet/BackToTheRocks.ocf/Cavern.ocs/Title.txt b/planet/Parkour.ocf/Cavern.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/Cavern.ocs/Title.txt rename to planet/Parkour.ocf/Cavern.ocs/Title.txt diff --git a/planet/Parkour.ocf/DescDE.rtf b/planet/Parkour.ocf/DescDE.rtf new file mode 100644 index 000000000..40cf82f27 Binary files /dev/null and b/planet/Parkour.ocf/DescDE.rtf differ diff --git a/planet/Parkour.ocf/DescUS.rtf b/planet/Parkour.ocf/DescUS.rtf new file mode 100644 index 000000000..7d938be2e Binary files /dev/null and b/planet/Parkour.ocf/DescUS.rtf differ diff --git a/planet/Parkour.ocf/Folder.txt b/planet/Parkour.ocf/Folder.txt new file mode 100644 index 000000000..fb9d2998a --- /dev/null +++ b/planet/Parkour.ocf/Folder.txt @@ -0,0 +1,2 @@ +[Head] +Index=4 \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/DescDE.rtf b/planet/Parkour.ocf/Maze.ocs/DescDE.rtf new file mode 100644 index 000000000..6f6a9b2b8 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/Maze.ocs/DescUS.rtf b/planet/Parkour.ocf/Maze.ocs/DescUS.rtf new file mode 100644 index 000000000..6f6a9b2b8 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/DescUS.rtf differ diff --git a/planet/Parkour.ocf/Maze.ocs/Landscape.txt b/planet/Parkour.ocf/Maze.ocs/Landscape.txt new file mode 100644 index 000000000..fc66f4be8 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Landscape.txt @@ -0,0 +1,79 @@ +/*-- + Cool Cavern + Author: Maikel + + Cavern with lots of snow, ice, rock and dirt. +--*/ + + +// Randomly placed material specks according to rndchecker. +overlay MatRC { + algo=rndchecker; a=8; + zoomX=-50; zoomY=-50; + turbulence=100; loosebounds=1; +}; + +// Fills an overlay with earth and materials. +overlay MatFill { + overlay { mat=Earth; tex=earth_dry; loosebounds=1; }; + MatRC { mat=Ore; tex=ore; a=20; }; + MatRC { mat=Snow; tex=snow1; a=20; }; + MatRC { mat=Granite; tex=granite; a=20; }; + MatRC { mat=Rock; tex=rock; a=20; }; + MatRC { mat=Ore; tex=ore; a=20; }; + MatRC { mat=Ice; tex=ice3; a=20; }; + MatRC { mat=Snow; tex=snow1; a=20; }; + MatRC { mat=Ice; tex=ice3; }; + MatRC { mat=Rock; tex=rock; }; + MatRC { mat=Tunnel; tex=tunnel; }; + MatRC { mat=Earth; tex=earth_dry; }; + MatRC { mat=Earth; tex=earth_rough; }; + overlay { + algo=lines; a=3; b=16; + rotate=45; + turbulence=100; + mat=Tunnel; tex=tunnel; + }; + overlay { + algo=lines; a=3; b=16; + rotate=-45; + turbulence=100; + mat=Tunnel; tex=tunnel; + }; +}; + +// Randomly placed material specks according to bozo. +overlay MatBozo { + algo=bozo; a=5; + turbulence=1000; loosebounds=1; +}; + +// Fills an overlay with ice, tunnel, rock and granite. +overlay BorderFill { + overlay { mat=Rock; tex=rock; loosebounds=1; + MatBozo { mat=Tunnel; tex=tunnel; }; + MatBozo { mat=Rock; tex=rock_cracked; a=6; }; + MatBozo { mat=Granite; tex=granite; a=14; }; + MatBozo { mat=Ice; tex=ice3; a=8; }; + MatBozo { mat=Tunnel; tex=tunnel; }; + }; +}; + +// A lengthy vertical cavern surrounded by ice, dirt and rock. +map Cavern { + overlay { + // Cut cavern out of the landscape. + x=40; wdt=20; y=-6; hgt=100; + turbulence=100; lambda=4; + loosebounds=1; + } ^ overlay { + // Fill remaining area with MatFill. + MatFill; + // And create a border around this area. + overlay { + algo=border; a=4; b=4; + // Fill border with BorderFill. + BorderFill; + }; + }; +}; diff --git a/planet/Parkour.ocf/Maze.ocs/Map.c b/planet/Parkour.ocf/Maze.ocs/Map.c new file mode 100644 index 000000000..feeb1e78a --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Map.c @@ -0,0 +1,261 @@ +/*-- + Dynamic maze + + Author: Sven2 +--*/ + +#include Library_Map + +static g_caves; + +local caves, n_caves, start_cave, end_cave; + +func FindCaves(int n) +{ //n=6; + var mask = CreateLayer(); + mask->Draw("Rock"); + caves = []; + var min_cave_dist = 12, border = 5; + while (n--) + { + var cave = {}; + if (!mask->FindPosition(cave, "Rock", [border,border,this.Wdt-border*2,this.Hgt-border*2])) continue; + mask->Draw("Tunnel", {Algo=MAPALGO_Ellipsis, X=cave.X, Y=cave.Y, Wdt=min_cave_dist, Hgt=min_cave_dist}); + cave.links = []; + cave.dirs = 0; + cave.rand = Random(65536); + cave.depth = -1; + caves[n_caves++] = cave; + } +/* caves[0].X = 10; caves[0].Y = 10; + caves[1].X = 30; caves[1].Y = 10; + caves[2].X = 10; caves[2].Y = 30; + caves[3].X = 30; caves[3].Y = 70; + caves[4].X = 50; caves[4].Y = 10; + caves[5].X = 50; caves[5].Y = 30;*/ + return n_caves; +} + +func GetCaveLinkDir(c1, c2) +{ + // Returns if c2 is left (1), right (2), atop (4) or below (8) c1. Returns only one direction. + var dx=c2.X-c1.X, dy=c2.Y-c1.Y, adx=Abs(dx), ady=Abs(dy); + //Log("%d,%d to %d,%d dx=%d dy=%d", c1.X, c1.Y, c2.X, c2.Y, dx, dy); + return (dx<-ady) | (dx>ady)<<1 | (dy<=-adx)<<2 | (dy>=adx)<<3; +} + +func IsLineOverlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) +{ + // Check if line from x1,y1 to x2,y2 crosses the line from x3,y3 to x4,y4 + var d1x=x2-x1, d1y=y2-y1, d2x=x4-x3, d2y=y4-y3, d3x=x3-x1, d3y=y3-y1; + var a = d1y*d3x-d1x*d3y; + var b = d2y*d3x-d2x*d3y; + var c = d2y*d1x-d2x*d1y; + if (!c) return !a && Inside(x3, x1,x2) && Inside(y3, y1,y2); // lines are parallel + return a*c>=0 && !(a*a/(c*c+1)) && b*c>=0 && !(b*b/(c*c+1)); +} + +func FindCaveConnections() +{ + var i, j, cave, cave2, caves2, dir, dir2, n, check_link, all_links = []; + // Connect all caves to neighbours + for (i=0; i> 1& 5|10 &dir << 1; + //Log("dir %d opposite to %d.", dir2, dir); + if (cave2.dirs & dir2) continue; + // Make sure the connectors don't cross each other + // Note that connectors may still overlap the edges of caves, effectively connecting them + // But since nothing really "breaks" on this occasion, just stick with the simple check for now. + var has_overlap = false; + for (check_link in all_links) + if (check_link[0] !== cave && check_link[1] !== cave) + if (check_link[0] !== cave2 && check_link[1] !== cave2) + if (IsLineOverlap(cave.X, cave.Y, cave2.X, cave2.Y, check_link[0].X, check_link[0].Y, check_link[1].X, check_link[1].Y)) + { has_overlap=true; break; } + if (has_overlap) continue; + // Connect these caves + cave.links[GetLength(cave.links)] = cave2; + cave2.links[GetLength(cave2.links)] = cave; + cave.dirs |= dir; + cave2.dirs |= dir2; + // Register and count connections + all_links[n++] = [cave, cave2]; + // All directions connected? + if (cave.dirs == 0xf) break; + } + } + return n; +} + +func FindStart() +{ + SortArrayByProperty(caves, "X"); + start_cave = caves[0]; + return start_cave; +} + +func MakeMaze() +{ + // Make maze by removing unnecesseriy links + start_cave.path = []; + var open = [start_cave], n_open = 1; + while (n_open) + { + var i_cave = n_open-1-Random(1+Random(n_open)); // Prefer depth-first generation so stray paths are deeper + var cave = open[i_cave]; + open[i_cave] = open[--n_open]; // SetLength(open, n_open) not nessessery because length is stored in n_open + var path_length = GetLength(cave.path); + var path_to_cave = cave.path[:]; + path_to_cave[path_length] = cave; + cave.depth = path_length; + for (var cave2 in cave.links[:]) // force a copy because cave.links is modified in the loop + { + if (path_length && cave2 === path_to_cave[path_length-1]) continue; + // Only first path survives + if (cave2.path) + { + // Remove circular path + RemoveCaveLinks(cave, cave2); + } + else + { + // Remember path to this cave + cave2.path = path_to_cave; + open[n_open++] = cave2; + } + } + } + // Sort from start to goal + SortArrayByProperty(caves, "depth"); + // Close one connection 2/3rds of the way to the goal + var main_path = caves[n_caves-1].path; + var main_path_length = GetLength(main_path); + if (main_path_length > 5) RemoveCaveLinks(main_path[main_path_length*2/3], main_path[main_path_length*2/3+1]); + // Kill unreachable caves + var i; + for (i=0; i=0) break; + caves = caves[i:n_caves]; + n_caves -= i; + end_cave = caves[n_caves-1]; + return true; +} + +func RemoveCaveLinks(c1, c2) +{ + var i = GetIndexOf(c1.links, c2), n = GetLength(c1.links) - 1; + if (i>=0) + { + c1.links[i] = c1.links[n]; + SetLength(c1.links, n); + c1.dirs &= ~GetCaveLinkDir(c1,c2); + } + i = GetIndexOf(c2.links, c1); n = GetLength(c2.links) - 1; + if (i>=0) + { + c2.links[i] = c2.links[n]; + SetLength(c2.links, n); + c2.dirs &= ~GetCaveLinkDir(c2,c1); + } + return true; +} + +func DrawVariations(string mat, int ratio, int sx, int sy) +{ + var rand_algo = {Algo=MAPALGO_RndChecker, Ratio=ratio, Wdt=sx, Hgt=sy}; + var turb_algo = {Algo=MAPALGO_Turbulence, Amplitude=12, Scale=8, Op=rand_algo}; + return Draw(mat, turb_algo); +} + +func DrawBackground() +{ + Draw("Rock"); + DrawVariations("Rock-rock_cracked", 50, 5,15); + DrawVariations("Ore", 10, 8,8); + DrawVariations("Firestone", 8, 12,3); + DrawVariations("Coal", 8, 8,3); + DrawVariations("Gold", 5, 4,4); + DrawVariations("Granite", 14, 15,5); + DrawVariations("Granite", 14, 5,15); + return true; +} + +func DrawCaves() +{ + for (var cave in caves) + { + Draw("Tunnel", {Algo=MAPALGO_Ellipsis, X=cave.X, Y=cave.Y, Wdt=4, Hgt=4}); + //var src = cave.path; + //if (src && GetLength(src)) src = Format("%d,%d", src[GetLength(src)-1].X, src[GetLength(src)-1].Y); + //Log("Cave at %d,%d src %v", cave.X, cave.Y, src); + } + return true; +} + +func DrawTunnels() +{ + for (var cave in caves) + { + for (var cave2 in cave.links) + { + if (cave2.done) continue; + Draw("Tunnel", {Algo=MAPALGO_Polygon, X=[cave.X, cave2.X], Y=[cave.Y, cave2.Y], Wdt=2, Open=1, Empty=1 }); + } + cave.done = true; + } + return true; +} + +func DrawStart() +{ + Draw("Tunnel", nil, [0, start_cave.Y - 4, start_cave.X, 4]); + Draw("Brick", nil, [0, start_cave.Y, start_cave.X-2, 1]); + return true; +} + +func DrawEnd() +{ + Draw("Ruby", {Algo=MAPALGO_Ellipsis, X=end_cave.X, Y=end_cave.Y, Wdt=4, Hgt=4}); + return true; +} + +protected func InitializeMap(map) +{ + map->Resize(300,300); + + FindCaves(200); + FindCaveConnections(); + FindStart(); + MakeMaze(); + + DrawBackground(); + DrawTunnels(); + DrawCaves(); + DrawStart(); + DrawEnd(); + + // Caves to global var: Need to clean up circular prop list references because they cause crashes + var cave; + for (cave in end_cave.path) + { + cave.is_main_path = true; + } + for (cave in caves) + { + cave.n_links = GetLength(cave.links); + cave.links = cave.path = nil; + } + g_caves = caves; + return true; +} + diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintGreen.png b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintGreen.png new file mode 100644 index 000000000..0fc2d3be5 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintGreen.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintRed.png b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintRed.png new file mode 100644 index 000000000..88f4fbeb4 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintRed.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintTeal.png b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintTeal.png new file mode 100644 index 000000000..bc12405fe Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintTeal.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintWhite.png b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintWhite.png new file mode 100644 index 000000000..583ab617e Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintWhite.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintYellow.png b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintYellow.png new file mode 100644 index 000000000..c33edafb1 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Material.ocg/PaintYellow.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/Ruby.jpg b/planet/Parkour.ocf/Maze.ocs/Material.ocg/Ruby.jpg new file mode 100644 index 000000000..c84122ce9 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Material.ocg/Ruby.jpg differ diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/Ruby.ocm b/planet/Parkour.ocf/Maze.ocs/Material.ocg/Ruby.ocm new file mode 100644 index 000000000..c7a631d97 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Material.ocg/Ruby.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Ruby +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Ruby +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Ruby diff --git a/planet/Parkour.ocf/Maze.ocs/Material.ocg/TEXMAP.TXT b/planet/Parkour.ocf/Maze.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..6199bf971 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,52 @@ +OverloadMaterials +OverloadTextures + +3=Tunnel-PaintRed +4=Tunnel-PaintGreen +5=Tunnel-PaintTeal +6=Tunnel-PaintYellow +7=Tunnel-PaintWhite + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore + +40=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +60=Ruby-Ruby + +65=Ice-ice2 +67=Ice-ice3 + +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Scenario.txt b/planet/Parkour.ocf/Maze.ocs/Scenario.txt similarity index 63% rename from planet/BackToTheRocks.ocf/MeleeMountain.ocs/Scenario.txt rename to planet/Parkour.ocf/Maze.ocs/Scenario.txt index af64f20bd..2572232d4 100644 --- a/planet/BackToTheRocks.ocf/MeleeMountain.ocs/Scenario.txt +++ b/planet/Parkour.ocf/Maze.ocs/Scenario.txt @@ -1,15 +1,14 @@ [Head] -Icon=24 -Title=MountainMelee -Version=4,10 -MinPlayer=2 -MaxPlayer=8 +Icon=34 +Title=Maze +Version=5,2,0,1 +Difficulty=20 [Definitions] Definition1=Objects.ocd [Game] -Goals=MELE +Goals=Goal_RubyHunt=1; [Player1] Crew=Clonk=1 @@ -24,12 +23,17 @@ Crew=Clonk=1 Crew=Clonk=1 [Landscape] -InEarth=Rock=1;Nugget=1;Firestone=5;Loam=2; -Sky=Mountains2 +Sky=Clouds2 +MapWidth=100 +MapHeight=100 MapZoom=10 +TopOpen=0 +BottomOpen=0 +SkyScrollMode=2 [Weather] Climate=0,0,0,100 StartSeason=0,0,0,100 YearSpeed=0,0,0,100 Wind=1,100,-100,100 + diff --git a/planet/Parkour.ocf/Maze.ocs/Script.c b/planet/Parkour.ocf/Maze.ocs/Script.c new file mode 100644 index 000000000..a7a5a0110 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Script.c @@ -0,0 +1,124 @@ +/*-- + Maze + Author: Sven2 + + Dynamic maze +--*/ + +static g_caves; +local goal_cave; + +func InitializePlayer(int plr) +{ + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,300,200,flag); + //SetPlayerZoomByViewRange(plr,LandscapeWidth(),LandscapeHeight(),flag); + SetPlayerViewLock(plr, true); + // Position and materials + LaunchPlayer(plr); + return true; +} + +func LaunchPlayer(int plr) +{ + // Position and materials + var starting_cave = g_caves[0]; + var i, crew, obj; + for (i=0; crew=GetCrew(plr,i); ++i) + { + crew->SetPosition(starting_cave.X/2, starting_cave.Y-18); + for (var tool in [Pickaxe, GrappleBow, SprayCan]) + if (obj = FindObject(Find_ID(tool), Find_Owner(plr), Find_NoContainer())) + obj->Enter(crew); + else + crew->CreateContents(tool); + crew->CreateContents(Loam,2); + crew->CreateContents(Dynamite,2); + } + return true; +} + +func RelaunchPlayer(int plr) +{ + var clonk = CreateObject(Clonk,0,0,plr); + if (!clonk) return false; + clonk->MakeCrewMember(plr); + SetCursor(plr, clonk); + return LaunchPlayer(plr); +} + +func CreateBonus(int x, int y, int value) +{ + var obj; + if (Random(value) > 50) + { + obj = CreateObject(Signpost, x,y); + if (obj) + { + if (Random(value) > 5) + { + var dx = goal_cave.X - x, dy = goal_cave.Y - y; + if (Abs(dx) > Abs(dy)) + if (dx>0) obj->SetText("$MsgGoalRight$"); else obj->SetText("$MsgGoalLeft$"); + else + if (dy>0) obj->SetText("$MsgGoalBelow$"); else obj->SetText("$MsgGoalAbove$"); + } + } + } + else + { + obj = CreateObject(Chest, x,y); + if (obj) + { + if (Random(value) > 90) obj->CreateContents(Shovel); + if (Random(value) > 90) obj->CreateContents(WindBag); + if (Random(value) > 90) obj->CreateContents(TeleGlove); + if (Random(value) > 90) obj->CreateContents(Sword); + if (Random(value) > 5) obj->CreateContents(Loam, 1+Random(2)); + if (Random(value) > 5) obj->CreateContents(Dynamite, 1+Random(2)); + if (Random(value) > 25) obj->CreateContents(DynamiteBox, 1+Random(2)); + if (Random(value) > 10) obj->CreateContents(Bread, 1+Random(2)); + } + } + return obj; +} + +protected func Initialize() +{ + var zoom = 10, cave, n_caves = GetLength(g_caves); + for (cave in g_caves) { cave.X *= zoom; cave.Y *= zoom; } + // Goal + var starting_cave = g_caves[0]; + var goal = FindObject(Find_ID(Goal_RubyHunt)); + if (!goal) goal = CreateObject(Goal_RubyHunt); + goal->SetPosition(); + goal->SetGoalRect(Rectangle(0, starting_cave.Y-40, starting_cave.X-20, 40)); + goal_cave = g_caves[n_caves-1]; + // Place extra elements in caves (except at start/end) + for (cave in g_caves) + { + if (cave == g_caves[0] || cave == g_caves[n_caves-1]) continue; + var x=cave.X, y=cave.Y; + while (!GBackSolid(x,y)) ++y; + if (cave.n_links <= 1) + { + // This is a dead end. + if (cave.dirs == 8) + { + // Facing downwards. Hard to reach, but cannot place a chest here :( + CreateObject(Trunk, cave.X, cave.Y)->SetR(160+Random(41)); + } + else + { + CreateBonus(x, y, 100); + } + } + else if (!(cave.dirs & 8)) + { + // Connecting cave without bottom + CreateBonus(x, y, 25 + 25 * !cave.is_main_path); + } + } + return true; +} diff --git a/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/DefCore.txt b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/DefCore.txt new file mode 100644 index 000000000..86c57cbe6 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/DefCore.txt @@ -0,0 +1,17 @@ +[DefCore] +id=Signpost +Version=5,2,0,1 +Category=C4D_StaticBack +Width=32 +Height=32 +Offset=-16,-16 +Vertices=1 +VertexX=4 +VertexY=15 +VertexCNAT=8 +VertexFriction=100 +Components=Wood=1; +Construction=1 +Value=5 +Mass=5 +Rotate=1 \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/Graphics.8.png b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/Graphics.8.png new file mode 100644 index 000000000..d9de69943 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/Graphics.8.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/Script.c b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/Script.c new file mode 100644 index 000000000..3c8c095da --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/Script.c @@ -0,0 +1,27 @@ +/* + Signpost + Author: Sven2 + + Storage for text. +*/ + +local text; + +func SetText(string t) { text=t; } + +public func IsInteractable() { return GetCon() >= 100; } + +public func GetInteractionMetaInfo(object clonk) +{ + return { Description = "$MsgRead$", IconName = nil, IconID = nil }; +} + +// Read on interaction +public func Interact(object clonk) +{ + var message = Format("%s ", text ?? "$MsgUnreadable$"); + CustomMessage(message, nil, clonk->GetController(), 150,150, nil, GUI_MenuDeco, Signpost); + return true; +} + +local Name = "$Name$"; diff --git a/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/StringTblDE.txt b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/StringTblDE.txt new file mode 100644 index 000000000..9a6cbb313 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Schild +MsgRead=Lesen +MsgUnreadable=Unlesbar. \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/StringTblUS.txt b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/StringTblUS.txt new file mode 100644 index 000000000..320c19066 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Signpost.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Signpost +MsgRead=Read +MsgUnreadable=Unreadable. \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/DefCore.txt b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/DefCore.txt new file mode 100644 index 000000000..abde83248 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/DefCore.txt @@ -0,0 +1,15 @@ +[DefCore] +id=SprayCan +Version=5,2,0,1 +Category=C4D_Object +Width=8 +Height=8 +Offset=-4,-4 +Picture=0,0,64,64 +Vertices=2 +VertexX=0,0 +VertexY=3,-3 +VertexFriction=40,40 +Value=5 +Mass=10 +Rotate=1 \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics.8.png b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics.8.png new file mode 100644 index 000000000..e002df3fb Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics.8.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics1.8.png b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics1.8.png new file mode 100644 index 000000000..a4210e5e7 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics1.8.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics2.8.png b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics2.8.png new file mode 100644 index 000000000..97b85c95e Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics2.8.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics3.8.png b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics3.8.png new file mode 100644 index 000000000..7cccdd3c9 Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics3.8.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics4.8.png b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics4.8.png new file mode 100644 index 000000000..7fc99599a Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Graphics4.8.png differ diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Script.c b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Script.c new file mode 100644 index 000000000..46ba83baa --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/Script.c @@ -0,0 +1,87 @@ +/* Spray can */ + +local last_x, last_y, last_ldx, last_ldy; +local paint_col; + +static SprayCan_last_col; + +protected func Construction() +{ + SetPaintCol(SprayCan_last_col++); + return true; +} + +func SetPaintCol(int idx) +{ + idx %= 5; + if (idx) SetGraphics(Format("%d",idx)); else SetGraphics(); + paint_col = Format("Tunnel-Paint%s", ["Red", "Green", "Teal", "Yellow", "White"][idx]); + return true; +} + +// Impact sound +func Hit() +{ + Sound("GeneralHit?"); +} + +// Item activation +func ControlUseStart(object clonk, int x, int y) +{ + x += GetX(); y += GetY(); + last_x = x; last_y = y; + 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); + SetAction("Spraying"); + return true; +} + +func HoldingEnabled() { return true; } + +func ControlUseHolding(object clonk, int new_x, int new_y) +{ + new_x += GetX(); new_y += GetY(); + 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); + last_x = new_x; last_y = new_y; + last_ldx = ldx; last_ldy = ldy; + return true; +} + +public func ControlUseStop(object clonk, int x, int y) +{ + SetAction("Idle"); + return true; +} + +public func ControlUseCancel(object clonk, int x, int y) +{ + SetAction("Idle"); + return true; +} + +local ActMap = { + Spraying = { + Prototype = Action, + FacetBase = 1, + Length = 1, + Delay = 1, + Name = "Spraying", + Sound = "SprayCan", + NextAction = "Spraying", + } +}; + + +local Collectible = 1; +local Name = "$Name$"; +local Description = "$Description$"; +local UsageHelp = "$UsageHelp$"; +local Rebuy = true; diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/SprayCan.wav b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/SprayCan.wav new file mode 100644 index 000000000..16ed40fde Binary files /dev/null and b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/SprayCan.wav differ diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/StringTblDE.txt b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/StringTblDE.txt new file mode 100644 index 000000000..bf144f02d --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/StringTblDE.txt @@ -0,0 +1,3 @@ +Name=Lehm +Description=Mit Lehm können kleine Lehmbrücken gebaut werden.|Benötigt ein Fass mit Wasser und einen Eimer Erde zur Produktion. +UsageHelp=Halte [Benutzen] gedrückt um eine Lehmbrücke in die gezeigte Richtung zu bauen. \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/StringTblUS.txt b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/StringTblUS.txt new file mode 100644 index 000000000..91975efdf --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/SprayCan.ocd/StringTblUS.txt @@ -0,0 +1,3 @@ +Name=Loam +Description=With loam one can build small loam bridges.|Needs a barrel of water and a bucket of water to produce. +UsageHelp=Hold down the [Use] key to build a bridge, move the mouse to control where it is created. \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/StringTblDE.txt b/planet/Parkour.ocf/Maze.ocs/StringTblDE.txt new file mode 100644 index 000000000..7d87b4942 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/StringTblDE.txt @@ -0,0 +1,4 @@ +MsgGoalAbove=Das Ziel ist oberhalb von hier. +MsgGoalBelow=Das Ziel ist unterhalb von hier. +MsgGoalLeft=Das Ziel ist links von hier. +MsgGoalRight=Das Ziel ist rechts von hier. diff --git a/planet/Parkour.ocf/Maze.ocs/StringTblUS.txt b/planet/Parkour.ocf/Maze.ocs/StringTblUS.txt new file mode 100644 index 000000000..449bffddb --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/StringTblUS.txt @@ -0,0 +1,4 @@ +MsgGoalAbove=The goal is above this post. +MsgGoalBelow=The goal is below this post. +MsgGoalLeft=The goal is left of this post. +MsgGoalRight=The goal is right of this post. \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/System.ocg/PlayerControl.c b/planet/Parkour.ocf/Maze.ocs/System.ocg/PlayerControl.c new file mode 100644 index 000000000..ef624dc80 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/System.ocg/PlayerControl.c @@ -0,0 +1,16 @@ +/*-- + Override screenshot functionality +--*/ + +global func PlayerControl(int plr, int ctrl) +{ + if (ctrl == CON_TryScreenshot) + { + CustomMessage(Format("$MsgCheater$", GetTaggedPlayerName(plr))); + Sound("Error", true); + var crew = GetCursor(plr); + if (crew) crew->Punch(crew, 50); + return true; + } + return _inherited(plr, ctrl, ...); +} \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/System.ocg/PlayerControls.txt b/planet/Parkour.ocf/Maze.ocs/System.ocg/PlayerControls.txt new file mode 100644 index 000000000..f902c7b02 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/System.ocg/PlayerControls.txt @@ -0,0 +1,14 @@ +[ControlDefs] + + [ControlDef] + Identifier=TryScreenshot + +[ControlSets] + + [ControlSet] + Name=* + + [Assignment] + Key=Ctrl+F9 + Priority=999 + Control=TryScreenshot diff --git a/planet/Parkour.ocf/Maze.ocs/System.ocg/StringTblDE.txt b/planet/Parkour.ocf/Maze.ocs/System.ocg/StringTblDE.txt new file mode 100644 index 000000000..90f34148c --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/System.ocg/StringTblDE.txt @@ -0,0 +1 @@ +MsgCheater=%s wollte cheaten! \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/System.ocg/StringTblUS.txt b/planet/Parkour.ocf/Maze.ocs/System.ocg/StringTblUS.txt new file mode 100644 index 000000000..29a501110 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/System.ocg/StringTblUS.txt @@ -0,0 +1 @@ +MsgCheater=%s tried to cheat! \ No newline at end of file diff --git a/planet/Parkour.ocf/Maze.ocs/Title.txt b/planet/Parkour.ocf/Maze.ocs/Title.txt new file mode 100644 index 000000000..99b7fc8f2 --- /dev/null +++ b/planet/Parkour.ocf/Maze.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Labyrinth +US:Maze \ No newline at end of file diff --git a/planet/Parkour.ocf/ShiverPeak.ocs/DescDE.rtf b/planet/Parkour.ocf/ShiverPeak.ocs/DescDE.rtf new file mode 100644 index 000000000..6ca677468 Binary files /dev/null and b/planet/Parkour.ocf/ShiverPeak.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/ShiverPeak.ocs/DescUS.rtf b/planet/Parkour.ocf/ShiverPeak.ocs/DescUS.rtf new file mode 100644 index 000000000..6cd24400a Binary files /dev/null and b/planet/Parkour.ocf/ShiverPeak.ocs/DescUS.rtf differ diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Icon.png b/planet/Parkour.ocf/ShiverPeak.ocs/Icon.png similarity index 100% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/Icon.png rename to planet/Parkour.ocf/ShiverPeak.ocs/Icon.png diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Landscape.txt b/planet/Parkour.ocf/ShiverPeak.ocs/Landscape.txt similarity index 97% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/Landscape.txt rename to planet/Parkour.ocf/ShiverPeak.ocs/Landscape.txt index 31056d270..a8c0e772d 100644 --- a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Landscape.txt +++ b/planet/Parkour.ocf/ShiverPeak.ocs/Landscape.txt @@ -24,8 +24,8 @@ map ShiverPeak overlay { algo=rndchecker; a=3; zoomX=-50; zoomY=-50; turbulence=100; mat=Granite; }; overlay { algo=rndchecker; a=6; zoomX=-20; zoomY=-20; turbulence=100; mat=Gold; } | overlay { algo=rndchecker; a=8; zoomX=10; zoomY=10; turbulence=100; mat=Gold; }; - overlay { algo=rndchecker; a=4; zoomX=-40; zoomY=-40; turbulence=100; mat=Sulphur; } - | overlay { algo=rndchecker; a=4; zoomX=-40; zoomY=-40; turbulence=100; mat=Sulphur; }; + overlay { algo=rndchecker; a=4; zoomX=-40; zoomY=-40; turbulence=100; mat=Firestone; } + | overlay { algo=rndchecker; a=4; zoomX=-40; zoomY=-40; turbulence=100; mat=Firestone; }; overlay { algo=rndchecker; a=3; zoomX=30; zoomY=30; turbulence=100; mat=Earth; tex=earth_rough;}; overlay { algo=rndchecker; a=2; zoomX=50; zoomY=50; turbulence=100; mat=Tunnel; diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Scenario.txt b/planet/Parkour.ocf/ShiverPeak.ocs/Scenario.txt similarity index 97% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/Scenario.txt rename to planet/Parkour.ocf/ShiverPeak.ocs/Scenario.txt index 12844f0da..4319b672e 100644 --- a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Scenario.txt +++ b/planet/Parkour.ocf/ShiverPeak.ocs/Scenario.txt @@ -2,7 +2,7 @@ Icon=24 Title=ShiverPeak Version=4,10 -MaxPlayer=8 +Difficulty=10 [Definitions] Definition1=Objects.ocd diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Script.c b/planet/Parkour.ocf/ShiverPeak.ocs/Script.c similarity index 98% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/Script.c rename to planet/Parkour.ocf/ShiverPeak.ocs/Script.c index 3d03c9dc5..29005de3d 100644 --- a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Script.c +++ b/planet/Parkour.ocf/ShiverPeak.ocs/Script.c @@ -54,7 +54,7 @@ protected func Initialize() // for (var i = 0; i < 30; i++) // CreateObject(CloudEffect, Random(LandscapeWidth()), Random(LandscapeHeight()))->Show(nil, nil, 5000, true); // Snow - AddEffect("Snowfall", 0, 1, 2); + AddEffect("Snowfall", nil, 1, 2); //Wind Sound("WindLoop",true,40,nil,+1); diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Teams.txt b/planet/Parkour.ocf/ShiverPeak.ocs/Teams.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/Teams.txt rename to planet/Parkour.ocf/ShiverPeak.ocs/Teams.txt diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/Title.txt b/planet/Parkour.ocf/ShiverPeak.ocs/Title.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/Title.txt rename to planet/Parkour.ocf/ShiverPeak.ocs/Title.txt diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/WinterMountains.jpg b/planet/Parkour.ocf/ShiverPeak.ocs/WinterMountains.jpg similarity index 100% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/WinterMountains.jpg rename to planet/Parkour.ocf/ShiverPeak.ocs/WinterMountains.jpg diff --git a/planet/BackToTheRocks.ocf/ShiverPeak.ocs/authors.txt b/planet/Parkour.ocf/ShiverPeak.ocs/authors.txt similarity index 100% rename from planet/BackToTheRocks.ocf/ShiverPeak.ocs/authors.txt rename to planet/Parkour.ocf/ShiverPeak.ocs/authors.txt diff --git a/planet/Parkour.ocf/Title.png b/planet/Parkour.ocf/Title.png new file mode 100644 index 000000000..42e9ea87e Binary files /dev/null and b/planet/Parkour.ocf/Title.png differ diff --git a/planet/Parkour.ocf/Title.txt b/planet/Parkour.ocf/Title.txt new file mode 100644 index 000000000..053fa58dd --- /dev/null +++ b/planet/Parkour.ocf/Title.txt @@ -0,0 +1,2 @@ +DE:Parkour +US:Parkour diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/DescDE.rtf b/planet/Parkour.ocf/VolcanoEscape.ocs/DescDE.rtf new file mode 100644 index 000000000..c5a3b3eb5 Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscape.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/DescUS.rtf b/planet/Parkour.ocf/VolcanoEscape.ocs/DescUS.rtf new file mode 100644 index 000000000..d7fd1ee07 Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscape.ocs/DescUS.rtf differ diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Landscape.txt b/planet/Parkour.ocf/VolcanoEscape.ocs/Landscape.txt new file mode 100644 index 000000000..4840c7c1a --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Landscape.txt @@ -0,0 +1,99 @@ +/* Escape the volcano - by Sven2 */ + +overlay VaryTex { mat=Earth; turbulence=10; algo=rndchecker; zoomX=-100; zoomY=-100; }; +overlay AshBorder { algo=border; mat=Ashes; tex=ashes; a=1; b=1; }; +overlay MixedBorder { algo=border; mat=Ashes; tex=ashes; a=1; b=1; + VaryTex { mat=Earth; tex=earth_topSoil; }; + VaryTex { mat=Rock; tex=rock_cracked; }; +}; +overlay RockyBorder { algo=border; mat=Rock; tex=rock_cracked; a=3; b=3; turbulence=10; + VaryTex { mat=Granite; tex=granite; a=1; }; + VaryTex { mat=Earth; tex=earth_topSoil; a=1; }; + VaryTex { mat=Ashes; tex=ashes; a=1; }; +}; + +map LavaParkour { + + // Basic background is earth + mat=Earth; tex=earth; + VaryTex { tex=earth_rough; a=0; }; + VaryTex { tex=earth_dry; a=2; }; + + // Tip of volcano + algo=poly; + point {x=-100%; y=25%; }; + point {x=0%; y=25%; }; + point {x=30%; y=10%; }; + point {x=70%; y=10%; }; + point {x=100%; y=25%; }; + point {x=200%; y=25%; }; + point {x=200%; y=200%; }; + point {x=-100%; y=200%; }; + turbulence=10; + + // Rock + overlay Rock { algo=rndchecker; zoomX=10; zoomY=-100; a=1; turbulence=10; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=rock; tex=rock; }; + }; + + // Granite + overlay Granite { algo=rndchecker; zoomX=10; zoomY=-100; a=1; turbulence=10; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=Granite; tex=granite; }; + }; + + // lava; lots of it + overlay LavaVeins { algo=rndchecker; zoomX=-50; zoomY=-50; a=6; turbulence=100; mat=DuroLava; tex=lava_red; + // some ashes to the bottom of lava veins + AshBorder { a=0; b=1; oy=-1px; turbulence=10; }; + // no ashes on top of lava vein + overlay { algo=border; a=0; b=2; oy=2px; mat=DuroLava; tex=lava_red; }; + }; LavaVeins; + + + // Extra caves + overlay Caves { algo=rndchecker; zoomX=-100; zoomY=-50; a=3; turbulence=100; mat=Tunnel; tex=tunnel; + // some ashes to the bottom of lava veins + AshBorder { a=0; b=1; oy=-1px; turbulence=10; }; + // no ashes on top of lava vein + MixedBorder; + }; + + // Some water + overlay Water { algo=rndchecker; zoomX=-100; zoomY=10; a=15; turbulence=100; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=Water; MixedBorder; }; + }; + + // Bottom end + overlay BottomWall { y=99; mat=Granite; tex=granite; }; + + // Starting cave + overlay { + algo=poly; mat=Tunnel; + point { x=10%; y=200%; }; + point { x=10%; y=100%; }; + point { x=20%; y=85%; }; + point { x=40%; y=85%; }; + point { x=80%; y=100%; }; + point { x=80%; y=200%; }; + turbulence=20; + + // Cave background + overlay { algo=sin; ox=20%; oy=93%; zoomY=-100; zoomX=-100; turbulence=10; mat=Tunnel; tex=brickback; }; + + // Cave floor + overlay { y=99%; mat=Brick; }; + overlay { x=55%; wdt=1px; y=99%; mat=Tunnel; tex=brickback; }; + + // Cave bounds + RockyBorder; + RockyBorder {a=1; b=1; turbulence=0; }; + }; + + RockyBorder; + RockyBorder {a=1; b=1; turbulence=0; }; + + // Left and right border is all granite + overlay SideWall { x=-45; y=25; wdt=50; turbulence=10; loosebounds=1; mat=Granite; tex=granite; + overlay { algo=border; mat=Rock; tex=rock_cracked; a=1; b=1; turbulence=0; }; }; + SideWall { x=94; }; +}; \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Material.ocg/TEXMAP.TXT b/planet/Parkour.ocf/VolcanoEscape.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..d27c38b8c --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,40 @@ +# Added Earth-earth for correct lava/earth boundraries + +OverloadMaterials +OverloadTextures + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore +40=Granite-granite +45=Gold-gold +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +65=Ice-ice2 +67=Ice-ice3 +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Scenario.txt b/planet/Parkour.ocf/VolcanoEscape.ocs/Scenario.txt new file mode 100644 index 000000000..92928ae5e --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Scenario.txt @@ -0,0 +1,38 @@ +[Head] +Icon=23 +Title=VolcanoEscape +Version=5,2,0,1 +Difficulty=50 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_Parkour=1; + +[Player1] +Crew=Clonk=1 + +[Player2] +Crew=Clonk=1 + +[Player3] +Crew=Clonk=1 + +[Player4] +Crew=Clonk=1 + +[Landscape] +InEarthLevel=0,0 +Sky=Clouds2 +MapWidth=50 +MapHeight=250 +TopOpen=1 +BottomOpen=1 +NoScan=1 + +[Weather] +Climate=0,0,0,100 +StartSeason=0,0,0,100 +YearSpeed=0,0,0,100 +Wind=1,100,-100,100 diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c b/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c new file mode 100644 index 000000000..c22f4cdc1 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Script.c @@ -0,0 +1,128 @@ +/*-- + Escape the volcano + Author: Sven2 + + Difficult upwards parkour. +--*/ + +// set to true to allow (endless) respawn +static const LavaParkour_AllowRespawn = false; + +protected func Initialize() +{ + // Create the parkour goal. + var goal = FindObject(Find_ID(Goal_Parkour)); + if (!goal) goal = CreateObject(Goal_Parkour, 0, 0, NO_OWNER); + if (!LavaParkour_AllowRespawn) goal->DisableRespawnHandling(); + // Set start point. + goal->SetStartpoint(LandscapeWidth()*2/5, LandscapeHeight()*97/100); + // Create check points + var checkpoint_locs = [], n_checkpoint_locs = 0, cave_loc; + for (var i=0; i<10; ++i) + { + // Find a good cave + cave_loc = FindLocation(Loc_InRect(50,LandscapeHeight()/6,LandscapeWidth()-100,LandscapeHeight()*17/25), Loc_Material("Tunnel"), Loc_Space(20), Loc_Space(20,true)); + if (cave_loc) + { + // No other check point nearby? + for (var check_loc in checkpoint_locs) + if (Distance(cave_loc.x, cave_loc.y, check_loc.x, check_loc.y) < 50) + { + cave_loc=nil; break; + } + // This spot is OK. + if (cave_loc) + { + checkpoint_locs[n_checkpoint_locs++] = cave_loc; + // max four extra checkpoints + if (n_checkpoint_locs >= 4) break; + } + } + } + SortArrayByProperty(checkpoint_locs, "y", true); + var mode = PARKOUR_CP_Check | PARKOUR_CP_Ordered; + if (LavaParkour_AllowRespawn) mode |= PARKOUR_CP_Respawn; + for (cave_loc in checkpoint_locs) + goal->AddCheckpoint(cave_loc.x, cave_loc.y, mode); + goal->SetFinishpoint(LandscapeWidth()/2, LandscapeHeight()*5/100); + // Create earth materials + // Create them in big clusters so the whole object arrangement looks a bit less uniform and more interesting + PlaceBatches([Firestone], 5, 100, 15); + PlaceBatches([Dynamite, Dynamite, Dynamite, DynamiteBox], 3, 50, 6); + PlaceBatches([Rock, Loam, Loam], 10, 200, 10); + // Starting chest + var start_chest = CreateObject(Chest, LandscapeWidth()*2/5, LandscapeHeight()*97/100); + if (start_chest) + { + start_chest->CreateContents(Loam,4); + start_chest->CreateContents(Bread,3); + start_chest->CreateContents(Firestone,3); + start_chest->CreateContents(DynamiteBox,2); + } + // Create Disasters. + //Earthquake->SetChance(2); - this is so random...not fair without relaunches + return; +} + +func InitializePlayer(int plr) +{ + // Players only + if (GetPlayerType(plr)!=C4PT_User) return; + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,400,250,flag); + SetPlayerViewLock(plr, true); + return true; +} + +private func PlaceBatches(array item_ids, int n_per_batch, int batch_radius, int n_batches) +{ + // place a number (n_batches) of batches of objects of types item_ids. Each batch has n_per_batch objects. + // fewer batches and/or objects may be placed if no space is found + var loc,loc2,n_item_ids=GetLength(item_ids), n_created=0, obj; + for (var i=0; iSetPosition(loc2.x,loc2.y); + ++n_created; + } + return n_created; +} + +// Gamecall from parkour goal, on respawning. +protected func OnPlayerRespawn(int plr, object cp) +{ + var clonk = GetCrew(plr); + RecoverItem(clonk, Shovel); + RecoverItem(clonk, Pickaxe); + RecoverItem(clonk, Loam); + return; +} + +private func RecoverItem(object clonk, id item_id) +{ + // Try to recover the player's item. if it can't be found, recreate one + // Don't fetch item from allied Clonks though + var item = FindObject(Find_ID(item_id), Find_Owner(clonk->GetOwner())); + if (!item || item->Contained() && item->Contained()->GetAlive()) + item = clonk->CreateContents(item_id); + else + item->Enter(clonk); + return item; +} + +// Gamecall from parkour goal, on reaching a bonus cp. +protected func GivePlrBonus(int plr, object cp) +{ + // No bonus. + return; +} + +// Lava is deadly. +global func OnInIncendiaryMaterial() +{ + return this->Incinerate(100, NO_OWNER); +} \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/StringTblDE.txt b/planet/Parkour.ocf/VolcanoEscape.ocs/StringTblDE.txt new file mode 100644 index 000000000..2d5013f53 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/StringTblDE.txt @@ -0,0 +1 @@ +TeamName=Abenteurer \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/StringTblUS.txt b/planet/Parkour.ocf/VolcanoEscape.ocs/StringTblUS.txt new file mode 100644 index 000000000..5a694e777 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/StringTblUS.txt @@ -0,0 +1 @@ +TeamName=Adventurers \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Teams.txt b/planet/Parkour.ocf/VolcanoEscape.ocs/Teams.txt new file mode 100644 index 000000000..108badbcf --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Teams.txt @@ -0,0 +1,6 @@ +[Teams] +TeamColors=false + + [Team] + id=1 + Name=$TeamName$ diff --git a/planet/Parkour.ocf/VolcanoEscape.ocs/Title.txt b/planet/Parkour.ocf/VolcanoEscape.ocs/Title.txt new file mode 100644 index 000000000..cd091742a --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscape.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Flucht aus dem Vulkan +US:Escape the volcano \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/BigVolcanoBubble1.wav b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/BigVolcanoBubble1.wav new file mode 100644 index 000000000..1175faf6b Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/BigVolcanoBubble1.wav differ diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/BigVolcanoBubble2.wav b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/BigVolcanoBubble2.wav new file mode 100644 index 000000000..c67bcb677 Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/BigVolcanoBubble2.wav differ diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/DefCore.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/DefCore.txt similarity index 82% rename from planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/DefCore.txt rename to planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/DefCore.txt index 720346599..21b366ff2 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/Barrel.ocd/BarrelTex.ocd/DefCore.txt +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/DefCore.txt @@ -1,7 +1,6 @@ [DefCore] -id=BarrelTex +id=BigVolcano Version=5,2,0,1 Category=C4D_StaticBack Width=1 Height=1 - diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/Graphics.png b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/Graphics.png new file mode 100644 index 000000000..2a11249d4 Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/Graphics.png differ diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/Script.c b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/Script.c new file mode 100644 index 000000000..f2fcfb41e --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/BigVolcano.ocd/Script.c @@ -0,0 +1,346 @@ +/* + BigVolcano + Author: Sven2 + + DESC +*/ + +static const BigVolcanoBehaviour_Fill = 0, + BigVolcanoBehaviour_Advance = 1, + BigVolcanoBehaviour_AdvanceLava = 2, + BigVolcanoBehaviour_Stop = 3; + +static const BigVolcano_XRes = 25; // step size of segments of lava_y array + +local lava_y; // array for current vertical lava positions +local lava_y_endpoint; // volcano is done when lava reaches this point +local n_lava_y; // size of lava_y array +local n_branches; +local mat_behaviours; // array of BigVolcanoBehaviour_*, indexed by GetMaterial(x,y)+1: How to behave in materials +local mat_advancespeeds; // array of ints from 0 to 100, indexed by GetMaterial(x,y)+1: How to behave in materials +local speed_multiplier = 1; // number of pixels by which the volcano advances when it does advance + +func Activate(int start_y, int end_y) +{ + if (lava_y) return; // already active + if (!start_y) start_y = LandscapeHeight(); + if (!end_y) end_y = 0; + lava_y_endpoint = end_y; + ScheduleCall(this, this.Execute, 10, 99999); + n_branches = 0; + mat_behaviours = CreateArray(20); + mat_advancespeeds = CreateArray(20); + mat_behaviours[0] = BigVolcanoBehaviour_Fill; + mat_advancespeeds[0] = 80; + for (var mat_idx=0, mat_name; mat_name=MaterialName(mat_idx); ++mat_idx) + { + var behaviour, density = GetMaterialVal("Density", "Material", mat_idx), speed; + if (WildcardMatch(mat_name, "*Lava")) // pass through lava + { + behaviour = BigVolcanoBehaviour_AdvanceLava; + speed = 100; + } + else if (WildcardMatch(mat_name, "*Water")) // fill into water to remove it + { + behaviour = BigVolcanoBehaviour_Fill; + speed = 10; + } + else if (density <= 0) // fill tunnels + { + behaviour = BigVolcanoBehaviour_Fill; + speed = 80; + } + else if (density <= 25) // pass through any other liquids + { + behaviour = BigVolcanoBehaviour_Advance; + speed = 60; + } + else if (GetMaterialVal("DigFree", "Material", mat_idx)) // pass through diggable materials + { + behaviour = BigVolcanoBehaviour_Advance; + speed = 50; + } + else // stop at rocks + minerals + { + behaviour = BigVolcanoBehaviour_Stop; + speed = 10; + } + mat_behaviours[mat_idx+1] = behaviour; + mat_advancespeeds[mat_idx+1] = speed; + } + n_lava_y = (LandscapeWidth()-1)/BigVolcano_XRes+2; + lava_y = CreateArray(n_lava_y); + for (var i=0; i lava_y_endpoint) + { + any_nonlava = true; + var x = BoundBy(i*BigVolcano_XRes-BigVolcano_XRes/2, 0, ls_w-BigVolcano_XRes) + Random(BigVolcano_XRes); + var y = GetLavaY(x); + var speed = mat_advancespeeds[GetMaterial(x,y-5)+1]; + if (i) if (lava_y[i] > lava_y[i-1]+BigVolcano_XRes*2) speed+=50; + if (i lava_y[i+1]+BigVolcano_XRes*2) speed+=50; + this_move = (Random(100) < speed); + if (this_move) + lava_y[i] -= speed_multiplier; + else if (!Random(3)) + { + if (speed<=10) + { + // Blast away solid + var blast_size = 5+Random(5); + BlastFree(x,y-3,blast_size,GetController()); + // gfx + var particle_speed = blast_size * 3; + CreateParticle("FireDense", PV_Random(x - 1, x + 1), PV_Random(y - 4, y - 2), PV_Random(-particle_speed, particle_speed), PV_Random(-particle_speed, particle_speed), PV_Random(30, 40), Particles_Fire(), 5); + if (!Random(5)) SoundAt("RockHit*", x,y-3, 100); + } + else if (speed <=50) + { + // Crumble away diggable + ShakeFree(x,y-Random(20),5); + } + } + if (last_move || (this_move && i)) + { + DrawMaterialQuad("DuroLava-lava_red", (i-1)*BigVolcano_XRes,lava_y[i-1], i*BigVolcano_XRes,lava_y[i], i*BigVolcano_XRes,lava_y[i]+speed_multiplier+1, (i-1)*BigVolcano_XRes,lava_y[i-1]+speed_multiplier+1, true); + } + last_move = this_move; + } + + } + // Lava risen to the max? + if (!any_nonlava) + { + ClearScheduleCall(this, this.Execute); + return; + } + } + return true; +} + +func GetLavaY(int x) +{ + var i = BoundBy(x/BigVolcano_XRes, 0, n_lava_y-2), ix = x%BigVolcano_XRes; + return (lava_y[i]*(BigVolcano_XRes-ix) + lava_y[i+1]*ix) / BigVolcano_XRes; +} + + +/* Branch effects */ +// draws a lava branch that walks ahead of the rising main lava lake +// branch effect variables: +// x,y: Branch tip position +// tip_progress: Progress from trace_x/y[end] towards dir_x/dir_y. From 0 to 100. +// dir_x,dir_y: Advance direction per segment +// len: Length of branch +// trace_x,trace_y: Array of previous positions. Index from oldest to newest. Currenct tip x/y not included. +// trace_len: length of trace_x,trace_y arrays + +local dbg_counter; + +func LaunchBranch(int x, int y, int dir_x, int dir_y, int parent_level) +{ + var fx = AddEffect("VolcanoBranch", this, 1, 3, this); + fx.x=x; fx.y=y; fx.dir_x=dir_x; fx.dir_y=dir_y; + fx.tip_progress=0; + fx.trace_x=[x]; fx.trace_y=[y]; fx.trace_len=fx.len=1; + fx.counter = ++dbg_counter; + fx.level = parent_level + 1; + //Log("LaunchBranch %d from %d/%d towards %d/%d", fx.counter,x,y,dir_x,dir_y); + ++n_branches; + return fx; +} + +func FxVolcanoBranchTimer(object q, fx, int time) +{ + // Progress tip + var next_tip_progress = fx.tip_progress + 10; + var last_segment = fx.trace_len-1; + var sx=fx.trace_x[last_segment], sy=fx.trace_y[last_segment]; + var nx=sx+next_tip_progress*(fx.dir_x)/100, ny=sy+next_tip_progress*(fx.dir_y)/100; + //Log("Go %d from %d/%d towards %d/%d", fx.counter,sx,sy,nx-sx,ny-sy); + if (nx==sx && ny==sy) { fx.tip_progress=next_tip_progress; return FX_OK; } + if (ny<0 || fx.len>20) return FX_Execute_Kill; // End here? + var behaviour = mat_behaviours[GetMaterial(nx,ny)+1]; + var i,dx,dy; + if (behaviour == BigVolcanoBehaviour_Fill) + { + CastPXS("DuroLava", 4+Cos(fx.fill_time*40,2), 30+Cos(fx.fill_time*40,25), nx,ny-1, 0,50); + if (!(fx.fill_time%20) && !GBackSemiSolid(nx,ny-6)) SoundAt("BigVolcanoBubble*", nx,ny, 10); + if (fx.fill_time++ > 31) return FX_Execute_Kill; // Done? + } + else if (behaviour != BigVolcanoBehaviour_Stop) + { + fx.fill_time = 0; + //if (behaviour == BigVolcanoBehaviour_AdvanceLava && !Random(5)) return FX_Execute_Kill; // prevent too many overlapping branches + DrawVerticalBranch(fx.x,fx.y,nx,ny,1); + fx.x=nx; fx.y=ny; + // Extend width of old segments + for (i=fx.tip_progress*last_segment/100; i6) return FX_Execute_Kill; + // Try to find a new spot to advance to + if (fx.tip_progress) + { + // Start searching from last pos we went to + sx+=fx.tip_progress*(fx.dir_x)/100; + sy+=fx.tip_progress*(fx.dir_y)/100; + } + dx = Sign(fx.dir_x); + if (!dx) dx = Random(2)*2-1; + dx *= 5; + var n_valid_branches=0; + for (i=0; i<2; ++i) + { + for (dy=-10; dy<10; dy+=2) + { + var b = mat_behaviours[GetMaterial(sx+dx,sy+dy)+1]; + if (b != BigVolcanoBehaviour_Stop && b != BigVolcanoBehaviour_AdvanceLava) + { + if (!n_valid_branches++) + { + // First valid branch: Take over this one + nx = sx+dx; + ny = sy+dy; + // Do not branch too deeply + if (fx.level>1) ++i; + } + else + { + // Second possible position: Branch off this one + LaunchBranch(sx,sy,dx,dy,fx.level++); + } + break; + } + } + dx*=-1; + } + // Caught in a corner? + if (!n_valid_branches) return FX_Execute_Kill; + // Spot found. Add segment if we already progressed in the last segment + /*if (fx.tip_progress) + { + fx.trace_x[fx.trace_len] = sx; fx.trace_y[fx.trace_len] = sy; + ++fx.trace_len; ++fx.len; + fx.tip_progress = 0; + }*/ + // Move to new spot + fx.dir_x = nx-fx.trace_x[last_segment]; + fx.dir_y = ny-fx.trace_y[last_segment]; + } + // End pos reached? + if (fx.tip_progress==100) + { + // Add new tip + fx.trace_x[fx.trace_len] = nx; fx.trace_y[fx.trace_len] = ny; + ++fx.trace_len; ++fx.len; + // Launch next branch + fx.tip_progress = 0; + fx.dir_x = BoundBy(fx.dir_x+Random(5)-2,-8,8); + fx.dir_y = BoundBy(fx.dir_y+Random(5)-2,-15,-20); + //Log("%v %v",fx.trace_y, fx.trace_len); + } + // Remove segments that fell below the main lake (max one at a time) + if (fx.trace_y[1] >= GetLavaY(fx.trace_x[1])) + { + fx.trace_x = fx.trace_x[1:fx.trace_len]; + fx.trace_y = fx.trace_y[1:fx.trace_len]; + --fx.trace_len; + } + return FX_OK; +} + +func FxVolcanoBranchStop(object q, fx, int reason, bool temp) +{ + if (!temp) + { + --n_branches; + //Log("DieBranch %d", fx.counter); + } + return FX_OK; +} + +func DrawVerticalBranch(int x1, int y1, int x2, int y2, int half_wdt) +{ + // Draw branch from x1/y1 to x2/y2 with width half_wdt*2 + //Log("BRANCH %d,%d,%d,%d, %d",x1,y1,x2,y2,half_wdt); + if (Abs(x2-x1)>Abs(y2-y1)) + return DrawMaterialQuad("DuroLava-lava_red",x1,y1-half_wdt, x1,y1+half_wdt, x2,y2+half_wdt, x2,y2-half_wdt, true); + else + return DrawMaterialQuad("DuroLava-lava_red",x1-half_wdt,y1, x1+half_wdt,y1, x2+half_wdt,y2, x2-half_wdt,y2, true); +} + +func ExtendVerticalBranch(int x1, int y1, int x2, int y2, int from_half_wdt, int to_half_wdt) +{ + //Log("EXTBRANCH %d,%d,%d,%d, %d->%d",x1,y1,x2,y2,from_half_wdt,to_half_wdt); + // Extend width of drawn branch from x1/y1 to x2/y2 from width from_half_wdt*2 to to_half_wdt*2 + // Effectively draws extra branch left and right, unless the branch had been pretty thin before + if (from_half_wdt <= 2) return DrawVerticalBranch(x1,y1,x2,y2,to_half_wdt); + if (Abs(x2-x1)>Abs(y2-y1)) + { + DrawMaterialQuad("DuroLava-lava_red",x1,y1-to_half_wdt, x1,y1-from_half_wdt, x2,y2-from_half_wdt, x2,y2-to_half_wdt, true); + DrawMaterialQuad("DuroLava-lava_red",x1,y1+to_half_wdt, x1,y1+from_half_wdt, x2,y2+from_half_wdt, x2,y2+to_half_wdt, true); + } + else + { + DrawMaterialQuad("DuroLava-lava_red",x1-to_half_wdt,y1, x1-from_half_wdt,y1, x2-from_half_wdt,y2, x2-to_half_wdt,y2, true); + DrawMaterialQuad("DuroLava-lava_red",x1+to_half_wdt,y1, x1+from_half_wdt,y1, x2+from_half_wdt,y2, x2+to_half_wdt,y2, true); + } + return true; +} + +func SoundAt(string sound_name, int x, int y, int vol) +{ + var sound_host = CreateObject(BigVolcano,x,y), r; + if (sound_host) + { + r = sound_host->Sound(sound_name, false, vol); + ScheduleCall(sound_host, Global.RemoveObject, 100); + } + return r; +} + +// Get highest point of lava surface +func GetLavaPeak() +{ + var y; for (var ly in lava_y) y += ly; + return y / n_lava_y; +} + +// Update speed of rising lava +func SetSpeedMultiplier(int new_multiplier) +{ + speed_multiplier = new_multiplier; + return true; +} + +local Name = "BigVolcano"; +local Description = "Volcano helper object"; diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/DescDE.rtf b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/DescDE.rtf new file mode 100644 index 000000000..a17d59e45 Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/DescDE.rtf differ diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/DescUS.rtf b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/DescUS.rtf new file mode 100644 index 000000000..787ad4649 Binary files /dev/null and b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/DescUS.rtf differ diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Landscape.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Landscape.txt new file mode 100644 index 000000000..0bcee2b3b --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Landscape.txt @@ -0,0 +1,103 @@ +/* Escape the volcano - by Sven2 */ + +overlay VaryTex { mat=Earth; turbulence=10; algo=rndchecker; zoomX=-100; zoomY=-100; }; +overlay EarthBorder { algo=border; mat=Earth; tex=earth_topSoil; a=1; b=1; }; +overlay MixedBorder { algo=border; mat=Earth; tex=earth_topSoil; a=1; b=1; + VaryTex { mat=Rock; tex=rock_cracked; }; +}; +overlay RockyBorder { algo=border; mat=Rock; tex=rock_cracked; a=3; b=3; turbulence=10; + VaryTex { mat=Granite; tex=granite; a=1; }; + VaryTex { mat=Earth; tex=earth_topSoil; a=1; }; +}; + +map LavaParkour { + + // Basic background is earth + mat=Earth; tex=earth; + VaryTex { tex=earth_rough; a=0; }; + VaryTex { tex=earth_dry; a=2; }; + + // Tip of volcano + algo=poly; + point {x=-100%; y=25%; }; + point {x=0%; y=25%; }; + point {x=30%; y=10%; }; + point {x=70%; y=10%; }; + point {x=100%; y=25%; }; + point {x=200%; y=25%; }; + point {x=200%; y=200%; }; + point {x=-100%; y=200%; }; + turbulence=10; + + // Ore + overlay Ore { algo=rndchecker; zoomX=-100; zoomY=1; a=1; turbulence=10; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=Ore; tex=ore; }; + }; + + // Rock + overlay Rock { algo=rndchecker; zoomX=10; zoomY=-100; a=1; turbulence=10; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=rock; tex=rock; }; + }; + + // Granite + overlay Granite { algo=rndchecker; zoomX=10; zoomY=-100; a=1; turbulence=10; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=Granite; tex=granite; }; + }; + + // caves; lots of it + overlay Caves { algo=rndchecker; zoomX=-50; zoomY=-50; a=6; turbulence=100; mat=Tunnel; + // some earth to the bottom of lava veins + EarthBorder { a=0; b=1; oy=-1px; turbulence=10; }; + }; Caves; + + + // Some lava + overlay LavaVeins { algo=rndchecker; zoomX=-100; zoomY=-50; a=3; turbulence=100; mat=DuroLava; + // some earth to the bottom of lava veins + EarthBorder { a=0; b=1; oy=-1px; turbulence=10; }; + // no ashes on top of lava vein + MixedBorder; + }; + + // Some water + overlay Water { algo=rndchecker; zoomX=-100; zoomY=10; a=15; turbulence=100; mask=1; + overlay { algo=border; a=0; b=2; invert=1; mat=Water; MixedBorder; }; + }; + + // Bottom volcano + overlay { y=95%; loosebounds=1; turbulence=10; x=-100%; wdt=300%;mat=DuroLava; }; + + // Starting cave + overlay { + algo=poly; mat=Tunnel; + point { x=10%; y=200%; }; + point { x=10%; y=100%; }; + point { x=20%; y=85%; }; + point { x=40%; y=85%; }; + point { x=80%; y=100%; }; + point { x=80%; y=200%; }; + turbulence=20; + + // Cave background + overlay { algo=sin; ox=20%; oy=93%; zoomY=-100; zoomX=-100; turbulence=10; mat=Tunnel; tex=brickback; }; + + // Cave floor + overlay { y=95%; mat=Brick; }; + overlay { y=96%; mat=Granite; }; + + // Cave bounds + RockyBorder; + RockyBorder {a=1; b=1; turbulence=0; }; + }; + + RockyBorder; + RockyBorder {a=1; b=1; turbulence=0; }; + + // Left and right border is all granite + overlay SideWall { x=-45; y=25; wdt=50; hgt=70; turbulence=10; loosebounds=1; mat=Granite; tex=granite; + overlay { algo=border; mat=Rock; tex=rock_cracked; a=1; b=1; turbulence=0; }; }; + SideWall { x=94; }; + + // Bottom volcano + overlay { y=97%; loosebounds=1; turbulence=10; x=-100%; wdt=300%;mat=DuroLava; }; +}; \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/Brick.ocm b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/Brick.ocm new file mode 100644 index 000000000..cf16eec62 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/Brick.ocm @@ -0,0 +1,8 @@ +[Material] +Name=Brick +Shape=Smoother +Density=50 +Friction=15 +Placement=80 +TextureOverlay=brick1 +BlastShiftTo=Granite diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/StableLava.ocm b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/StableLava.ocm new file mode 100644 index 000000000..3ef2a81d8 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/StableLava.ocm @@ -0,0 +1,14 @@ +[Material] +Name=StableLava +ColorAnimation=1 +Density=25 +Instable=0 +MaxAirSpeed=50 +MaxSlide=10000 +WindDrift=40 +Incindiary=1 +Placement=10 +TextureOverlay=lava_red +PXSGfxSize=6 +PXSGfx=Lava +PXSGfxRt=0,0,32,32,-16,-16 diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/TEXMAP.TXT b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..66a48f582 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,45 @@ +OverloadMaterials +OverloadTextures + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +18=StableLava-lava_red +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore + +40=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +65=Ice-ice2 +67=Ice-ice3 + +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Scenario.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Scenario.txt new file mode 100644 index 000000000..f314cd42e --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Scenario.txt @@ -0,0 +1,39 @@ +[Head] +Icon=23 +Title=VolcanoEscapeEx +Version=5,2,0,1 +Difficulty=70 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_Parkour=1; + +[Player1] +Crew=Clonk=1 + +[Player2] +Crew=Clonk=1 + +[Player3] +Crew=Clonk=1 + +[Player4] +Crew=Clonk=1 + +[Landscape] +InEarthLevel=0,0 +Sky=Clouds2 +MapWidth=50 +MapHeight=250 +TopOpen=1 +BottomOpen=1 +NoScan=1 +AutoScanSideOpen=0 + +[Weather] +Climate=0,0,0,100 +StartSeason=0,0,0,100 +YearSpeed=0,0,0,100 +Wind=1,100,-100,100 diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c new file mode 100644 index 000000000..07f796234 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Script.c @@ -0,0 +1,119 @@ +/*-- + Escape the volcano EXTREME + Author: Sven2 + + Difficult upwards parkour. Now with extra volcano coming from bottom! +--*/ + +static g_volcano; + +protected func Initialize() +{ + var w = LandscapeWidth(), h = LandscapeHeight(); + // Create the parkour goal. + var goal = FindObject(Find_ID(Goal_Parkour)); + if (!goal) goal = CreateObject(Goal_Parkour, 0, 0, NO_OWNER); + goal->DisableRespawnHandling(); + // Set start and finish point. + goal->SetStartpoint(w*2/5, h*93/100); + goal->SetFinishpoint(w/2, h*5/100); + // Create earth materials + // Create them in big clusters so the whole object arrangement looks a bit less uniform and more interesting + PlaceBatches([Firestone], 5, 100, 15); + PlaceBatches([Dynamite, Dynamite, Dynamite, DynamiteBox], 3, 50, 6); + PlaceBatches([Rock, Loam, Loam], 10, 200, 10); + // Starting chest + var start_chest = CreateObject(Chest, w*2/5, h*94/100); + if (start_chest) + { + start_chest->CreateContents(Loam,4); + start_chest->CreateContents(Bread,3); + start_chest->CreateContents(Firestone,3); + start_chest->CreateContents(DynamiteBox,2); + } + // Create big volcano + g_volcano=CreateObject(BigVolcano,0,0,NO_OWNER); + var h0 = h-10; + g_volcano->Activate(h0, h*10/100); + // Schedule script to update volcano speed multiplier + ScheduleCall(nil, Scenario.VolcanoTimer, 40, 99999); + // Bottom is open, so put some stable lava here to prevent remaining lava from just flowing out of the map + DrawMaterialQuad("StableLava",0,h0,w,h0,w,h,0,h); + return; +} + +// Timer callback: Update volcano speed (rubberband effect) +func VolcanoTimer() +{ + // Safety + if (!g_volcano) return; + // Get volcano height + var y_volcano = g_volcano->GetLavaPeak(); + // Get player progress + var y_plr, crew, n_crew; + for (var i=0; iGetY(); + ++n_crew; + } + // Calc rubber band + var new_multiplier; + if (n_crew) + new_multiplier = Max(1, (y_volcano - y_plr/n_crew) / 150); + else + new_multiplier = 1; + g_volcano->SetSpeedMultiplier(new_multiplier); + //Log("speed %v", new_multiplier); + return true; +} + +func InitializePlayer(int plr) +{ + // Players only + if (GetPlayerType(plr)!=C4PT_User) return; + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,400,250,flag); + SetPlayerViewLock(plr, false); // no view lock so you can see the volcano! + return true; +} + +private func PlaceBatches(array item_ids, int n_per_batch, int batch_radius, int n_batches) +{ + // place a number (n_batches) of batches of objects of types item_ids. Each batch has n_per_batch objects. + // fewer batches and/or objects may be placed if no space is found + var loc,loc2,n_item_ids=GetLength(item_ids), n_created=0, obj; + for (var i=0; iSetPosition(loc2.x,loc2.y); + ++n_created; + } + return n_created; +} + +// Gamecall from parkour goal, on respawning. +protected func OnPlayerRespawn(int plr, object cp) +{ + var clonk = GetCrew(plr); + RecoverItem(clonk, Shovel); + RecoverItem(clonk, Pickaxe); + RecoverItem(clonk, Loam); + return; +} + +private func RecoverItem(object clonk, id item_id) +{ + // Try to recover the player's item. if it can't be found, recreate one + // Don't fetch item from allied Clonks though + var item = FindObject(Find_ID(item_id), Find_Owner(clonk->GetOwner())); + if (!item || item->Contained() && item->Contained()->GetAlive()) + item = clonk->CreateContents(item_id); + else + item->Enter(clonk); + return item; +} diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/StringTblDE.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/StringTblDE.txt new file mode 100644 index 000000000..2d5013f53 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/StringTblDE.txt @@ -0,0 +1 @@ +TeamName=Abenteurer \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/StringTblUS.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/StringTblUS.txt new file mode 100644 index 000000000..5a694e777 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/StringTblUS.txt @@ -0,0 +1 @@ +TeamName=Adventurers \ No newline at end of file diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Teams.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Teams.txt new file mode 100644 index 000000000..108badbcf --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Teams.txt @@ -0,0 +1,6 @@ +[Teams] +TeamColors=false + + [Team] + id=1 + Name=$TeamName$ diff --git a/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Title.txt b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Title.txt new file mode 100644 index 000000000..12c31bc75 --- /dev/null +++ b/planet/Parkour.ocf/VolcanoEscapeEx.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Flucht aus dem Vulkan EXTREM +US:Escape the volcano EXTREME \ No newline at end of file diff --git a/planet/Sound.ocg/BalloonPop.wav b/planet/Sound.ocg/BalloonPop.wav index a885502a3..216c0c487 100644 Binary files a/planet/Sound.ocg/BalloonPop.wav and b/planet/Sound.ocg/BalloonPop.wav differ diff --git a/planet/Sound.ocg/Blowout.ogg b/planet/Sound.ocg/Blowout.ogg new file mode 100644 index 000000000..3e1976cbd Binary files /dev/null and b/planet/Sound.ocg/Blowout.ogg differ diff --git a/planet/Sound.ocg/Boiling.ogg b/planet/Sound.ocg/Boiling.ogg new file mode 100644 index 000000000..3b8ffc3e5 Binary files /dev/null and b/planet/Sound.ocg/Boiling.ogg differ diff --git a/planet/Sound.ocg/Catapult_Launch.ogg b/planet/Sound.ocg/Catapult_Launch.ogg index 6f1e218bc..f681aa46e 100644 Binary files a/planet/Sound.ocg/Catapult_Launch.ogg and b/planet/Sound.ocg/Catapult_Launch.ogg differ diff --git a/planet/Sound.ocg/Click.wav b/planet/Sound.ocg/Click.wav index be0570022..6712312dd 100644 Binary files a/planet/Sound.ocg/Click.wav and b/planet/Sound.ocg/Click.wav differ diff --git a/planet/Sound.ocg/DullMetalHit3.ogg b/planet/Sound.ocg/DullMetalHit3.ogg new file mode 100644 index 000000000..2413c1c6b Binary files /dev/null and b/planet/Sound.ocg/DullMetalHit3.ogg differ diff --git a/planet/Sound.ocg/Earthquake.ogg b/planet/Sound.ocg/Earthquake.ogg new file mode 100644 index 000000000..c7dc82705 Binary files /dev/null and b/planet/Sound.ocg/Earthquake.ogg differ diff --git a/planet/Sound.ocg/EarthquakeEnd.ogg b/planet/Sound.ocg/EarthquakeEnd.ogg new file mode 100644 index 000000000..a7c2e8a27 Binary files /dev/null and b/planet/Sound.ocg/EarthquakeEnd.ogg differ diff --git a/planet/Sound.ocg/Electrical.ogg b/planet/Sound.ocg/Electrical.ogg index 1f9f1dc5f..fbc5498ca 100644 Binary files a/planet/Sound.ocg/Electrical.ogg and b/planet/Sound.ocg/Electrical.ogg differ diff --git a/planet/Sound.ocg/FDie.ogg b/planet/Sound.ocg/FDie.ogg new file mode 100644 index 000000000..6f5b73e22 Binary files /dev/null and b/planet/Sound.ocg/FDie.ogg differ diff --git a/planet/Sound.ocg/FHurt1.ogg b/planet/Sound.ocg/FHurt1.ogg new file mode 100644 index 000000000..5ad88a95b Binary files /dev/null and b/planet/Sound.ocg/FHurt1.ogg differ diff --git a/planet/Sound.ocg/FHurt2.ogg b/planet/Sound.ocg/FHurt2.ogg new file mode 100644 index 000000000..1bef3840b Binary files /dev/null and b/planet/Sound.ocg/FHurt2.ogg differ diff --git a/planet/Sound.ocg/Fire.ogg b/planet/Sound.ocg/Fire.ogg new file mode 100644 index 000000000..8101210ea Binary files /dev/null and b/planet/Sound.ocg/Fire.ogg differ diff --git a/planet/Sound.ocg/FireLoop.ogg b/planet/Sound.ocg/FireLoop.ogg deleted file mode 100644 index c3435eef2..000000000 Binary files a/planet/Sound.ocg/FireLoop.ogg and /dev/null differ diff --git a/planet/Sound.ocg/Fuse.ogg b/planet/Sound.ocg/Fuse.ogg index bb7da4481..390750fb4 100644 Binary files a/planet/Sound.ocg/Fuse.ogg and b/planet/Sound.ocg/Fuse.ogg differ diff --git a/planet/Sound.ocg/FuseLoop.ogg b/planet/Sound.ocg/FuseLoop.ogg index de0b0c925..43d88e0db 100644 Binary files a/planet/Sound.ocg/FuseLoop.ogg and b/planet/Sound.ocg/FuseLoop.ogg differ diff --git a/planet/Sound.ocg/HingeCreak1.ogg b/planet/Sound.ocg/HingeCreak1.ogg new file mode 100644 index 000000000..c4b6bc9d4 Binary files /dev/null and b/planet/Sound.ocg/HingeCreak1.ogg differ diff --git a/planet/Sound.ocg/HingeCreak2.ogg b/planet/Sound.ocg/HingeCreak2.ogg new file mode 100644 index 000000000..606795715 Binary files /dev/null and b/planet/Sound.ocg/HingeCreak2.ogg differ diff --git a/planet/Sound.ocg/HingeCreak3.ogg b/planet/Sound.ocg/HingeCreak3.ogg new file mode 100644 index 000000000..c905d37df Binary files /dev/null and b/planet/Sound.ocg/HingeCreak3.ogg differ diff --git a/planet/Sound.ocg/Inflame.ogg b/planet/Sound.ocg/Inflame.ogg new file mode 100644 index 000000000..0a486dfdf Binary files /dev/null and b/planet/Sound.ocg/Inflame.ogg differ diff --git a/planet/Sound.ocg/Pumpjack.ogg b/planet/Sound.ocg/Pumpjack.ogg new file mode 100644 index 000000000..9362ca86a Binary files /dev/null and b/planet/Sound.ocg/Pumpjack.ogg differ diff --git a/planet/Sound.ocg/RockHit1.ogg b/planet/Sound.ocg/RockHit1.ogg index b75653d1d..5d75de1f1 100644 Binary files a/planet/Sound.ocg/RockHit1.ogg and b/planet/Sound.ocg/RockHit1.ogg differ diff --git a/planet/Sound.ocg/RockHit2.ogg b/planet/Sound.ocg/RockHit2.ogg index 837143929..835896ac4 100644 Binary files a/planet/Sound.ocg/RockHit2.ogg and b/planet/Sound.ocg/RockHit2.ogg differ diff --git a/planet/Sound.ocg/RockHit3.ogg b/planet/Sound.ocg/RockHit3.ogg index 5ae7ebd13..d79fb33fe 100644 Binary files a/planet/Sound.ocg/RockHit3.ogg and b/planet/Sound.ocg/RockHit3.ogg differ diff --git a/planet/Sound.ocg/Sizzle.ogg b/planet/Sound.ocg/Sizzle.ogg index 9eb5ab3a4..ecf550114 100644 Binary files a/planet/Sound.ocg/Sizzle.ogg and b/planet/Sound.ocg/Sizzle.ogg differ diff --git a/planet/Sound.ocg/SteamEngine.ogg b/planet/Sound.ocg/SteamEngine.ogg new file mode 100644 index 000000000..885992e19 Binary files /dev/null and b/planet/Sound.ocg/SteamEngine.ogg differ diff --git a/planet/Sound.ocg/TreeCrack.ogg b/planet/Sound.ocg/TreeCrack.ogg new file mode 100644 index 000000000..f20f99c9e Binary files /dev/null and b/planet/Sound.ocg/TreeCrack.ogg differ diff --git a/planet/Sound.ocg/TreeLanding.ogg b/planet/Sound.ocg/TreeLanding.ogg new file mode 100644 index 000000000..9f9acfc92 Binary files /dev/null and b/planet/Sound.ocg/TreeLanding.ogg differ diff --git a/planet/Sound.ocg/WheelsTurn.ogg b/planet/Sound.ocg/WheelsTurn.ogg new file mode 100644 index 000000000..d638ccc66 Binary files /dev/null and b/planet/Sound.ocg/WheelsTurn.ogg differ diff --git a/planet/Sound.ocg/WoodCreak1.ogg b/planet/Sound.ocg/WoodCreak1.ogg new file mode 100644 index 000000000..322416c86 Binary files /dev/null and b/planet/Sound.ocg/WoodCreak1.ogg differ diff --git a/planet/Sound.ocg/WoodCreak2.ogg b/planet/Sound.ocg/WoodCreak2.ogg new file mode 100644 index 000000000..bf4aba9dd Binary files /dev/null and b/planet/Sound.ocg/WoodCreak2.ogg differ diff --git a/planet/Sound.ocg/WoodCreak3.ogg b/planet/Sound.ocg/WoodCreak3.ogg new file mode 100644 index 000000000..4f4d9a385 Binary files /dev/null and b/planet/Sound.ocg/WoodCreak3.ogg differ diff --git a/planet/Sound.ocg/authors.txt b/planet/Sound.ocg/authors.txt index 8c49aca0c..50228ccb5 100644 --- a/planet/Sound.ocg/authors.txt +++ b/planet/Sound.ocg/authors.txt @@ -5,7 +5,7 @@ Author Work(s) =============================================================================== Ringwaul - MonsterGrowl*, MonsterDie, Snuff*, WipfAroof, WipfWhine -Clonkonaut - Confirm* +Clonkonaut - Confirm*, FDie Checkmaty - ProjectileHitLiving* dobroide - BirdsLoop (http://www.freesound.org/people/dobroide/sounds/54746/) Benboncan - Blast*/BlastMetal (http://www.freesound.org/people/Benboncan/sounds/73005/) @@ -19,7 +19,6 @@ Mirors_ - Sizzle (http://www.freesound.org/people/Mirors_/sounds/81205/) juskiddink - SoftHit1 (http://www.freesound.org/people/juskiddink/sounds/108617/) jenc - BlastMetal (http://www.freesound.org/people/jenc/sounds/511/) gelo_papas - BalloonInflate (http://www.freesound.org/people/gelo_papas/sounds/52070/) -suonho - FireLoop (http://www.freesound.org/people/suonho/sounds/17782/) FreqMan - Cash (http://www.freesound.org/people/FreqMan/sounds/31377/) fresco - Munch1 (http://www.freesound.org/people/fresco/sounds/48933/) cambra - FanLoop (http://www.freesound.org/people/Cambra/sounds/102710/) @@ -28,6 +27,11 @@ digifishmusic - LiquidBlast2 (http://www.freesound.org/people/digifishmusic/soun HerbertBoland - WoodHit* (http://www.freesound.org/people/HerbertBoland/sounds/33206/) Erdie - LightMetalHit1 (http://www.freesound.org/people/Erdie/sounds/27826/) Anton - DullWoodHit1 (http://www.freesound.org/people/Anton/sounds/1257/) +CGEffex - Inflame (http://www.freesound.org/people/CGEffex/sounds/94102/) +dobroide - Fire (http://www.freesound.org/people/dobroide/sounds/4211/) +bennychico11 - FHurt1, FHurt2 (http://www.freesound.org/people/bennychico11/sounds/80438/) +cmusounddesign - HingeCreak* (http://freesound.org/people/cmusounddesign/sounds/126302/) +earthsounds - WheelsTurn (http://freesound.org/people/earthsounds/sounds/101486/) The following sound effects are licensed under the CC 0 license (public domain): @@ -38,6 +42,7 @@ adcbicycle - SoftTouch* (http://www.freesound.org/people/adcbicycle/sounds/1387 - GeneralHit2 (http://www.freesound.org/people/adcbicycle/sounds/13899/) - DullMetalHit1 (http://www.freesound.org/people/adcbicycle/sounds/13854/) - DullMetalHit2 (http://www.freesound.org/people/adcbicycle/sounds/13876/) + - DullMetalHit3 (http://freesound.org/people/adcbicycle/sounds/13831/) - DullWoodHit2 (http://www.freesound.org/people/adcbicycle/sounds/13958/) - GlassHit1 (http://www.freesound.org/people/adcbicycle/sounds/13936/) - GlassHit2 (http://www.freesound.org/people/adcbicycle/sounds/13931/) @@ -47,4 +52,10 @@ thecheeseman - Hurt*, Die (http://www.freesound.org/people/thecheeseman/) Oddworld - LiquidBlast1 (http://www.freesound.org/people/Oddworld/sounds/75328/) mbezzola - RockHit* (http://www.freesound.org/people/mbezzola/sounds/105282/) RytmenPinnen - Fuse/FuseLoop (http://www.freesound.org/people/RytmenPinnen/sounds/102264/) -kibibu - LightMetalHit2 (http://www.freesound.org/people/kibibu/sounds/22435/) \ No newline at end of file +kibibu - LightMetalHit2 (http://www.freesound.org/people/kibibu/sounds/22435/) +prozaciswack - Earthquake (http://www.freesound.org/people/prozaciswack/sounds/82722/) +alienistcog - WoodCreak* (http://freesound.org/people/alienistcog/sounds/123712/) +fryzu82 - Boiling (http://freesound.org/people/fryzu82/sounds/142333/) +Adam_N - Blowout (http://freesound.org/people/Adam_N/sounds/166126/) +BenNevis - SteamEngine (http://freesound.org/people/BenNevis/sounds/203175/) +felix.blume - Pumpjack (http://freesound.org/people/felix.blume/sounds/203990/) \ No newline at end of file diff --git a/planet/System.ocg/Action.c b/planet/System.ocg/Action.c index d4a080e53..865dc61e5 100644 --- a/planet/System.ocg/Action.c +++ b/planet/System.ocg/Action.c @@ -26,4 +26,11 @@ static const Action = { Directions = 1, Step = 1, Procedure = DFA_NONE, -}; \ No newline at end of file +}; + +global func GameCall(string fn) { + if (!fn) return; + var f = Scenario[fn]; + if (!f) return; + return Scenario->Call(f, ...); +} diff --git a/planet/System.ocg/Array.c b/planet/System.ocg/Array.c index 24384e187..dc6292f3f 100644 --- a/planet/System.ocg/Array.c +++ b/planet/System.ocg/Array.c @@ -3,12 +3,10 @@ // concatenates two arrays and returns a new array global func Concatenate(array first, array second) { - var result = CreateArray(GetLength(first)+GetLength(second)); - var i = 0; - for (var something in first) - result[i++] = something; - for (var something in second) - result[i++] = something; + var len_first = GetLength(first); + var result = CreateArray(len_first+GetLength(second)); + result[:len_first] = first; + result[len_first:] = second; return result; } @@ -102,9 +100,9 @@ global func ShuffleArray(array arr) while(--len >= 0) { - var i = Random(GetLength(working)); + var i = Random(len); arr[len] = working[i]; - RemoveArrayIndexUnstable(working, i); + working[i] = working[-1]; } return true; @@ -116,10 +114,7 @@ global func RemoveArrayIndex(array arr, int index, bool unstable) if(unstable == true) return RemoveArrayIndexUnstable(arr, index); // move all elements right of index to the left - var len = GetLength(arr); - for(var i = index; i < len - 1; ++i) - arr[i] = arr[i+1]; - SetLength(arr, GetLength(arr) - 1); + arr[index:] = arr[index+1:]; return true; } @@ -141,11 +136,9 @@ global func PushBack(array arr, /*any*/ value) // inserts an element at the beginning of an array global func PushFront(array arr, /*any*/ value) { - SetLength(arr, GetLength(arr) + 1); - // move elements one to the right - for(var i = GetLength(arr)-1; i > 0;--i) - arr[i] = arr[i-1]; + arr[1:] = arr; + arr[0] = value; return true; } @@ -156,20 +149,16 @@ global func PopBack(array arr) if(GetLength(arr) == 0) return nil; var o = arr[-1]; - SetLength(arr, GetLength(arr) - 1); + arr[:] = arr[:-1]; return o; } // removes the first element from an array and returns it -// obviously a bit slower than PopBack global func PopFront(array arr) { - var len = GetLength(arr); - if(len == 0) + if(!GetLength(arr)) return nil; var o = arr[0]; - for(var i = 1; i < len; ++i) - arr[i - 1] = arr[i]; - SetLength(arr, GetLength(arr) - 1); + arr[:] = arr[1:]; return o; } \ No newline at end of file diff --git a/planet/System.ocg/Controls.c b/planet/System.ocg/Controls.c new file mode 100644 index 000000000..4fb2e3839 --- /dev/null +++ b/planet/System.ocg/Controls.c @@ -0,0 +1,118 @@ +/*-- + Controls.c + Authors: boni + + Helper functions to find out if a Control fits into a certain category. (Throwing, using, interacting,...) +--*/ + +/** Control tells the clonk to move */ +global func IsMovementControl(int ctrl) +{ + // up, up, down, down, left, right, left, right, B, A + if(ctrl == CON_Up + || ctrl == CON_Down + || ctrl == CON_Left + || ctrl == CON_Right) + return true; + + return false; +} + +/** Control throws selected item */ +global func IsThrowControl(int ctrl) +{ + // left mouse button + if(ctrl == CON_Throw + || ctrl == CON_ForcedThrow + || ctrl == CON_ThrowDelayed + // right mouse button + || ctrl == CON_ThrowAlt + || ctrl == CON_ForcedThrowAlt + || ctrl == CON_ThrowAltDelayed) + return true; + + return false; +} + +/** Control drops items from inventory (hotkey or selected items) */ +global func IsDropControl(int ctrl) +{ + // selected items + if(ctrl == CON_Drop + || ctrl == CON_DropAlt + // hotkeys + || ctrl == CON_DropHotkey0 + || ctrl == CON_DropHotkey1 + || ctrl == CON_DropHotkey2 + || ctrl == CON_DropHotkey3 + || ctrl == CON_DropHotkey4 + || ctrl == CON_DropHotkey5 + || ctrl == CON_DropHotkey6 + || ctrl == CON_DropHotkey7 + || ctrl == CON_DropHotkey8 + || ctrl == CON_DropHotkey9) + return true; + + return false; +} + +/** Control has the goal of interacting with some other object (Interaction, Grabbing, Entering,...) */ +global func IsInteractionControl(int ctrl) +{ + // Interaction itself + if(ctrl == CON_Interact + // other interactions + || ctrl == CON_Grab + || ctrl == CON_Ungrab + || ctrl == CON_GrabNext + || ctrl == CON_Enter + || ctrl == CON_Exit + || ctrl == CON_PushEnter + // hotkeys + || ctrl == CON_InteractionHotkey0 + || ctrl == CON_InteractionHotkey1 + || ctrl == CON_InteractionHotkey2 + || ctrl == CON_InteractionHotkey3 + || ctrl == CON_InteractionHotkey4 + || ctrl == CON_InteractionHotkey5 + || ctrl == CON_InteractionHotkey6 + || ctrl == CON_InteractionHotkey7 + || ctrl == CON_InteractionHotkey8 + || ctrl == CON_InteractionHotkey9) + return true; + + return false; +} + +/** Control has the goal of switching the currently selected crewmember */ +global func IsCrewControl(int ctrl) +{ + // next/previous + if(ctrl == CON_NextCrew + || ctrl == CON_PreviousCrew + // hotkeys + || ctrl == CON_PlayerHotkey0 + || ctrl == CON_PlayerHotkey1 + || ctrl == CON_PlayerHotkey2 + || ctrl == CON_PlayerHotkey3 + || ctrl == CON_PlayerHotkey4 + || ctrl == CON_PlayerHotkey5 + || ctrl == CON_PlayerHotkey6 + || ctrl == CON_PlayerHotkey7 + || ctrl == CON_PlayerHotkey8 + || ctrl == CON_PlayerHotkey9 + ) + return true; + + return false; +} + +/** Control uses selected item */ +global func IsUseControl(int ctrl) +{ + if(ctrl == CON_Use + || ctrl == CON_UseAlt) + return true; + + return false; +} \ No newline at end of file diff --git a/planet/System.ocg/Creation.c b/planet/System.ocg/Creation.c index 728729257..668bdea51 100644 --- a/planet/System.ocg/Creation.c +++ b/planet/System.ocg/Creation.c @@ -92,7 +92,7 @@ global func CastObjects(id def, int am, int lev, int x, int y, int angs, int ang angw = 360; for (var i = 0; i < am; i++) { - var obj = CreateObject(def , x, y, NO_OWNER); + var obj = CreateObject(def, x, y, NO_OWNER); var ang = angs - 90 + RandomX(-angw / 2, angw / 2); var xdir = Cos(ang, lev) + RandomX(-3, 3); obj->SetR(Random(360)); @@ -117,10 +117,10 @@ global func CastPXS(string mat, int am, int lev, int x, int y, int angs, int ang return; } -global func DrawParticleLine (string particle, int x0, int y0, int x1, int y1, int prtdist, int a, int b0, int b1, int ydir) +global func DrawParticleLine(string particle, int x0, int y0, int x1, int y1, int prtdist, xdir, ydir, lifetime, proplist properties) { // Right parameters? - if (!prtdist) + if (!properties) return 0; // Calculate required number of particles. var prtnum = Max(Distance(x0, y0, x1, y1) / prtdist, 2); @@ -132,12 +132,81 @@ global func DrawParticleLine (string particle, int x0, int y0, int x1, int y1, i i2 = i * 256 / prtnum; i1 = 256 - i2; - b = ((b0 & 16711935) * i1 + (b1 & 16711935) * i2) >> 8 & 16711935 - | ((b0 >> 8 & 16711935) * i1 + (b1 >> 8 & 16711935) * i2) & -16711936; - if (!b && (b0 | b1)) - b++; - CreateParticle(particle, x0 + (x1 - x0) * i / prtnum, y0 + (y1 - y0) * i-- / prtnum, 0, ydir, a, b); + CreateParticle(particle, x0 + (x1 - x0) * i / prtnum, y0 + (y1 - y0) * i-- / prtnum, xdir, ydir, lifetime, properties, 1); } // Succes, return number of created particles. return prtnum; +} + + + +/** Place a nice shaped forest. If no area is given, the whole landscape is used (which is not recommended!). + @param plants An array containing all plants that should be in the forest. plants[0] is the main plant, the others will be randomly scattered throughout the forest. + @param x The starting X-coordinate of the forest. + @param y The lowest line at which to start placing plants. Level ground is determined automatically, goind upwards. + @param width The width of the forest + @param foreground Will roughly make every third instance of plants[0] foreground +*/ +global func PlaceForest(array plants, int x, int y, int width, bool foreground) +{ + // Parameter check + if (GetLength(plants) == 0) return; + if (!x) x = 0; + if (!y) y = LandscapeHeight(); + if (!width) width = LandscapeWidth(); + if (this) { x = AbsX(x); y = AbsY(y); } + + // Roughly 20% of the size (10% per side) are taken for 'forest ending zones'. Plants will be smaller there. + var end_zone = width * 10 / 100; + // The width of the standard plants will roughly be the measure for our plant size + var plant_size = plants[0]->GetDefWidth()/2; + + var growth, y_pos, plant, x_variance, variance = 0, count, j, spot; + for (var i = plant_size; i < width; i += plant_size) + { + growth = 100; + y_pos = y; + x_variance = RandomX(-plant_size/2, plant_size/2); + // End zone check + if (i < end_zone) + growth = BoundBy(90 / ((end_zone * 100 / plant_size)/100) * (i/plant_size), 10, 90); + else if (i > width - end_zone) + growth = BoundBy(90 / ((end_zone * 100 / plant_size)/100) * ((width-i)/plant_size), 10, 90); + else if (!Random(10) && GetLength(plants) > 1) + { + variance = Random(GetLength(plants)-1)+1; + // Scatter some other plants + count = RandomX(2, 4); + for (j = 0; j < count; j++) + { + spot = (plant_size*2 / count) * j + RandomX(-5,5) - plant_size; + y_pos = y; + if (!GBackSolid(x + i + spot, y_pos)) continue; + while (!GBackSky(x + i + spot, y_pos) && y_pos > 0) y_pos--; + if (y_pos == 0) continue; + plant = CreateObject(plants[variance], x + i + spot, y_pos+5, NO_OWNER); + } + continue; + } + // No ground at y_pos? + if (!GBackSolid(x + i + x_variance, y_pos)) continue; + // Get level ground + while (!GBackSky(x + i + x_variance, y_pos) && y_pos > 0) y_pos--; + if (y_pos == 0) continue; + + plant = CreateObject(plants[0], x + i + x_variance, y_pos+5, NO_OWNER); + plant->SetCon(growth); + if (foreground && !Random(3)) plant.Plane = 510; + // Every ~7th plant: double plant! + if (x_variance != 0 && !Random(7)) + { + y_pos = y; + if (!GBackSolid(x + i - x_variance, y_pos)) continue; + while (!GBackSky(x + i - x_variance, y_pos) && y_pos > 0) y_pos--; + if (y_pos == 0) continue; + plant = CreateObject(plants[0], x + i - x_variance, y_pos+5, NO_OWNER); + plant->SetCon(growth); + if (foreground && !Random(3)) plant.Plane = 510; + } + } } \ No newline at end of file diff --git a/planet/System.ocg/Explode.c b/planet/System.ocg/Explode.c index 56c12e4f9..51fd99b44 100644 --- a/planet/System.ocg/Explode.c +++ b/planet/System.ocg/Explode.c @@ -6,6 +6,111 @@ TODO: documentation. --*/ +/*-- +Particle definitions used by the explosion effect. +They will be initialized lazily whenever the first blast goes off. +--*/ +static ExplosionParticles_Smoke; +static ExplosionParticles_Blast; +static ExplosionParticles_BlastSmooth; +static ExplosionParticles_BlastSmoothBackground; +static ExplosionParticles_Star; +static ExplosionParticles_Shockwave; +static ExplosionParticles_Glimmer; + +global func ExplosionParticles_Init() +{ + ExplosionParticles_Smoke = + { + Size = PV_KeyFrames(0, 180, 25, 1000, 50), + DampingY = PV_Random(890, 920, 5), + DampingX = PV_Random(900, 930, 5), + ForceY=-1, + ForceX = PV_Wind(20, PV_Random(-2, 2)), + Rotation=PV_Random(0,360,0), + R=PV_KeyFrames(0, 0, 255, 260, 64, 1000, 64), + G=PV_KeyFrames(0, 0, 128, 260, 64, 1000, 64), + B=PV_KeyFrames(0, 0, 0, 260, 108, 1000, 108), + Alpha = PV_KeyFrames(0, 0, 0, 100, 20, 500, 20, 1000, 0) + }; + + ExplosionParticles_Blast = + { + Size = PV_KeyFrames(0, 0, 0, 260, 25, 1000, 40), + DampingY = PV_Random(890, 920, 0), + DampingX = PV_Random(900, 930, 0), + ForceY = PV_Random(-8,-2,0), + ForceX = PV_Random(-5,5,0), + R = 255, + G = PV_Random(64, 120, 0), + Rotation = PV_Random(0, 360, 0), + B = 0, + Alpha = PV_KeyFrames(0, 260, 100, 1000, 0), + BlitMode = GFX_BLIT_Additive, + Phase = PV_Random(0, 1) + }; + + ExplosionParticles_BlastSmooth = + { + Size = PV_KeyFrames(0, 0, 0, 250, PV_Random(30, 50), 1000, 80), + R = PV_KeyFrames(0, 0, 255, 250, 128, 1000, 0), + G = PV_KeyFrames(0, 0, 255, 125, 64, 1000, 0), + Rotation = PV_Random(0, 360, 0), + B = PV_KeyFrames(0, 0, 100, 250, 64, 100, 0), + Alpha = PV_KeyFrames(0, 0, 255, 750, 250, 1000, 0), + BlitMode = GFX_BLIT_Additive + }; + + ExplosionParticles_BlastSmoothBackground = + { + Prototype = ExplosionParticles_BlastSmooth, + BlitMode = nil, + R = PV_Linear(50, 0), + G = PV_Linear(50, 0), + B = PV_Linear(50, 0), + Alpha = PV_Linear(128, 0) + }; + + ExplosionParticles_Star = + { + Size = PV_KeyFrames(0, 0, 0, 500, 60, 1000, 0), + R = PV_KeyFrames(0, 750, 255, 1000, 0), + G = PV_KeyFrames(0, 300, 255, 1000, 0), + B = PV_KeyFrames(0, 300, 255, 500, 0), + Rotation = PV_Random(0, 360, 4), + Alpha = PV_KeyFrames(0, 750, 255, 1000, 0), + BlitMode = GFX_BLIT_Additive, + Stretch = PV_Speed(1000, 1000) + }; + + ExplosionParticles_Shockwave = + { + Size = PV_Linear(0, 120), + R = 255, + G = 128, + B = PV_KeyFrames(0, 0, 128, 200, 0), + Rotation = PV_Step(20), + BlitMode = GFX_BLIT_Additive, + Alpha = PV_Linear(255, 0) + }; + + ExplosionParticles_Glimmer= + { + Size = PV_Linear(2, 0), + ForceY = GetGravity(), + DampingY = PV_Linear(1000,700), + DampingX = PV_Linear(1000,700), + Stretch = PV_Speed(1000, 500), + Rotation = PV_Direction(), + OnCollision = PC_Die(), + CollisionVertex = 500, + R = 255, + G = PV_Linear(128,32), + B = PV_Random(0, 128, 2), + Alpha = PV_Random(255,0,3), + BlitMode = GFX_BLIT_Additive, + }; +} /*-- Explosion --*/ @@ -77,27 +182,61 @@ global func DoExplosion(int x, int y, int level, object inobj, int cause_plr, ob return true; } -global func ExplosionEffect(int level, int x, int y) +/* +Creates a visual explosion effect at a position. +smoothness (in percent) determines how round the effect will look like +*/ +global func ExplosionEffect(int level, int x, int y, int smoothness) { - // Blast particle. - CreateParticle("Blast", x, y, 0, 0, level * 10, RGBa(255, 255, 255, 100)); - if(!GBackLiquid(x,y)) CastParticles("Spark", 10, 80 + level, x, y, 35, 40, RGB(255, 200, 0), RGB(255, 255, 150)); - if(GBackLiquid(x,y)) CastObjects(Fx_Bubble, level * 7 / 10, level, x, y); - //CastParticles("FSpark", level/5+1, level, x,y, level*5+10,level*10+10, 0x00ef0000,0xffff1010)); - - // Smoke trails. - var i = 0, count = 3 + level / 8, angle = Random(360); - while (count > 0 && ++i < count * 10) + // possibly init particle definitions? + if (!ExplosionParticles_Blast) + ExplosionParticles_Init(); + + smoothness = smoothness ?? 0; + var level_pow = level ** 2; + var level_pow_fraction = Max(level_pow / 25, 5 * level); + var wilderness_level = level * (100 - smoothness) / 100; + var smoothness_level = level * smoothness / 100; + + var smoke_size = PV_KeyFrames(0, 180, level, 1000, level * 2); + var blast_size = PV_KeyFrames(0, 0, 0, 260, level * 2, 1000, level); + var blast_smooth_size = PV_KeyFrames(0, 0, 0, 250, PV_Random(level, level * 2), 1000, level); + var star_size = PV_KeyFrames(0, 0, 0, 500, level * 2, 1000, 0); + var shockwave_size = PV_Linear(0, level * 4); + + CreateParticle("SmokeDirty", PV_Random(x - 10,x + 10), PV_Random(y - 10, y + 10), 0, PV_Random(-2, 0), PV_Random(50, 100), {Prototype = ExplosionParticles_Smoke, Size = smoke_size}, Max(2, wilderness_level / 10)); + CreateParticle("SmokeDirty", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), PV_Random(-1, 1), PV_Random(-1, 1), PV_Random(20, 40), {Prototype = ExplosionParticles_BlastSmoothBackground, Size = blast_smooth_size}, smoothness_level / 5); + CreateParticle("SmokeDirty", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), PV_Random(-1, 1), PV_Random(-1, 1), PV_Random(20, 40), {Prototype = ExplosionParticles_BlastSmooth, Size = blast_smooth_size}, smoothness_level / 5); + CreateParticle("Dust", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), 0, 0, PV_Random(18, 25), {Prototype = ExplosionParticles_Blast, Size = blast_size}, smoothness_level / 5); + CreateParticle("StarFlash", PV_Random(x - 6, x + 6), PV_Random(y - 6, y + 6), PV_Random(-wilderness_level/4, wilderness_level/4), PV_Random(-wilderness_level/4, wilderness_level/4), PV_Random(10, 12), {Prototype = ExplosionParticles_Star, Size = star_size}, wilderness_level / 3); + CreateParticle("Shockwave", x, y, 0, 0, 15, {Prototype = ExplosionParticles_Shockwave, Size = shockwave_size}, nil); + + // cast either some sparks on land or bubbles under water + if(GBackLiquid(x, y) && Global.CastBubbles) + { + Global->CastBubbles(level * 7 / 10, level, x, y); + } + else + { + CreateParticle("Magic", PV_Random(x - 5, x + 5), PV_Random(y - 5, y + 5), PV_Random(-level_pow_fraction, level_pow_fraction), PV_Random(-level_pow_fraction, level_pow_fraction), PV_Random(25, 70), ExplosionParticles_Glimmer, level); + } + + // very wild explosion? Smoke trails! + var smoke_trail_count = wilderness_level / 10; + var angle = Random(360); + var failsafe = 0; // against infinite loops + while (smoke_trail_count > 0 && (++failsafe < smoke_trail_count * 10)) { angle += RandomX(40, 80); var smokex = Sin(angle, RandomX(level / 4, level / 2)); var smokey = -Cos(angle, RandomX(level / 4, level / 2)); if (GBackSolid(x + smokex, y + smokey)) continue; - var lvl = 16 * level / 10; + var lvl = 2 * wilderness_level; CreateSmokeTrail(lvl, angle, x + smokex, y + smokey); - count--; + smoke_trail_count--; } + return; } @@ -195,6 +334,23 @@ global func BlastObjects(int x, int y, int level, object container, int cause_pl return true; } +global func BlastObject(int Level, CausedBy) +{ + var self = this; + if (CausedBy == nil) + CausedBy = GetController(); + + DoDamage(Level, FX_Call_DmgBlast, CausedBy); + if (!self) return; + + if (GetAlive()) + DoEnergy(-Level/3, false, FX_Call_EngBlast, CausedBy); + if (!self) return; + + if (this.BlastIncinerate && GetDamage() >= this.BlastIncinerate) + Incinerate(Level, CausedBy); +} + global func BlastObjectsShockwaveCheck(int x, int y) { var def = GetID(); @@ -306,46 +462,72 @@ global func FxShakeEffectStop() /*-- Smoke trails --*/ -global func CreateSmokeTrail(int strength, int angle, int x, int y, int color, bool noblast) { +global func CreateSmokeTrail(int strength, int angle, int x, int y, int color, bool noblast) +{ x += GetX(); y += GetY(); - var effect = AddEffect("SmokeTrail", nil, 300, 1, nil, nil, strength, angle, x, y); - if (!color) - color = RGBa(130, 130, 130, 70); - effect.color = color; - effect.noblast = noblast; + if (angle % 90 == 1) angle = 1; + + var effect = AddEffect("SmokeTrail", nil, 300, 1, nil, nil, color); + EffectCall(nil, effect, "SetAdditionalParameters", x, y, angle, strength, noblast); return; } -global func FxSmokeTrailStart(object target, proplist effect, int temp, strength, angle, x, y) +global func FxSmokeTrailSetAdditionalParameters(object target, proplist effect, int x, int y, int angle, int strength, bool noblast) +{ + effect.x = x; + effect.y = y; + effect.strength = strength; + effect.curr_strength = strength; + effect.xdir = Sin(angle, strength * 40); + effect.ydir = -Cos(angle, strength * 40); + effect.noblast = noblast; +} + +global func FxSmokeTrailStart(object target, proplist effect, int temp, color) { if (temp) return; - - if (angle % 90 == 1) - angle += 1; - strength = Max(strength, 5); - effect.strength = strength; - effect.curr_strength = strength; - effect.x = x; - effect.y = y; - effect.xdir = Sin(angle, strength * 40); - effect.ydir = -Cos(angle, strength * 40); + effect.color = color ?? RGBa(255, 128, 0, 200); + var alpha = (effect.color >> 24) & 0xff; + effect.particles_smoke = + { + R = PV_KeyFrames(0, 0, 200, 400, 0, 1000, 0), + G = PV_KeyFrames(0, 0, 200, 400, 0, 1000, 0), + B = PV_KeyFrames(0, 0, 200, 400, 0, 1000, 0), + Alpha = PV_KeyFrames(0, 0, 0, 300, alpha, 600, (alpha * 4) / 5, 1000, 0), + Rotation = PV_Random(0, 360), + ForceX = PV_Wind(20), + ForceY = PV_Gravity(-10), + }; + + effect.particles_blast = + { + R = PV_Linear((effect.color >> 16) & 0xff, 0), + G = PV_Linear((effect.color >> 8) & 0xff, 0), + B = PV_Linear((effect.color >> 0) & 0xff, 0), + Alpha = PV_KeyFrames(0, 0, alpha, 600, (alpha * 4) / 5, 1000, 0), + Rotation = PV_Direction(), + BlitMode = GFX_BLIT_Additive, + Stretch = PV_Speed(1500, 1000) + }; } global func FxSmokeTrailTimer(object target, proplist effect, int fxtime) { var strength = effect.strength; + effect.curr_strength = (effect.curr_strength * 5) / 6; + if (effect.curr_strength < 5) return -1; + var str = effect.curr_strength; var x = effect.x; var y = effect.y; + var x_dir = effect.xdir; var y_dir = effect.ydir; - str = Max(1, str - str / 5); - str--; - y_dir += GetGravity() * 2 / 3; + y_dir += GetGravity() * 10 / 3; var x_dir = x_dir * str / strength; var y_dir = y_dir * str / strength; @@ -355,18 +537,23 @@ global func FxSmokeTrailTimer(object target, proplist effect, int fxtime) y += RandomX(-3,3); // draw - CreateParticle("ExploSmoke", x, y, RandomX(-2, 2), RandomX(-2, 4), 150 + str * 12, effect.color); + effect.particles_smoke.Size = PV_KeyFrames(0, 0, 0, 250, str / 2, 1000, str); + effect.particles_blast.Size = PV_KeyFrames(0, 0, 0, 100, str / 3, 1000, 0); if (!effect.noblast) - CreateParticle("Blast", x, y, 0, 0, 10 + str * 8, RGBa(255, 100, 50, 150)); + { + var x_dir_blast = x_dir / 200; + var y_dir_blast = y_dir / 200; + CreateParticle("SmokeDirty", x, y, PV_Random(x_dir_blast - 2, x_dir_blast + 2), PV_Random(y_dir_blast - 2, y_dir_blast + 2), 18, effect.particles_blast, 2); + } + CreateParticle("Smoke", x, y, PV_Random(-2, 2), PV_Random(-2, 2), 50, effect.particles_smoke, 2); + // then calc next position x += x_dir / 100; y += y_dir / 100; if (GBackSemiSolid(x, y)) return -1; - if (str <= 3) - return -1; effect.curr_strength = str; effect.x = x; @@ -381,60 +568,38 @@ global func Fireworks(int color, int x, int y) if (!color) color = HSL(Random(8) * 32, 255, 127); - var speed = 12; - for (var i = 0; i < 36; ++i) + var glimmer = { - var oangle = Random(70); - var eff = AddEffect("Firework", nil, 300, 1, nil, nil, Cos(oangle,speed), i * 10 + Random(5), x + GetX(), y + GetY()); - eff.color = color; - } + Prototype = Particles_Glimmer(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + }; + CreateParticle("MagicFire", x, y, PV_Random(-100, 100), PV_Random(-100, 100), PV_Random(20, 200), glimmer, 100); - for (var i = 0; i < 16; ++i) + Smoke(x, y, 30); + + var sparks = { - CreateParticle("ExploSmoke", RandomX(-80, 80), RandomX(-80, 80), 0, 0, RandomX(500, 700), RGBa(255, 255, 255, 90)); - } - CastParticles("Spark", 60, 190, 0, 0, 40, 70, color, color); + Prototype = Particles_Spark(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + DampingX = 900, DampingY = 900, + ForceY = PV_Random(-10, 10), + ForceX = PV_Random(-10, 10), + Stretch = PV_Speed(500, 1000) + }; + CreateParticle("Spark", x, y, PV_Random(-200, 200), PV_Random(-200, 200), PV_Random(20, 60), sparks, 100); - CreateParticle("Flash", 0, 0, 0, 0, 3500, color | (200 & 255) << 24); + var flash = + { + Prototype = Particles_Flash(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + }; + CreateParticle("Flash", x, y, 0, 0, 8, flash); return; } -global func FxFireworkStart(object target, effect, int tmp, speed, angle, x, y, color) -{ - if (tmp) - return; - - effect.speed = speed * 100; - effect.angle = angle; - effect.x = x * 100; - effect.y = y * 100; -} - -global func FxFireworkTimer(object target, effect, int time) -{ - var speed = effect.speed; - var angle = effect.angle; - var x = effect.x; - var y = effect.y; - - if (time > 65) return -1; - - if (GBackSemiSolid(x / 100, y / 100)) - return -1; - - // lose speed - speed = 25 * speed / 26; - - var x_dir = Sin(angle, speed); - var y_dir = -Cos(angle, speed); - - CreateParticle("Flash", x / 100, y / 100, x_dir / 100, y_dir / 100, 50, effect.color | (200 & 255) << 24); - - // gravity - y_dir += GetGravity() * 18 / 100; - - effect.speed = speed; - effect.angle = Angle(0, 0, x_dir, y_dir); - effect.x = x + x_dir; - effect.y = y + y_dir; -} diff --git a/planet/System.ocg/Fade.c b/planet/System.ocg/Fade.c new file mode 100644 index 000000000..b7be3d098 --- /dev/null +++ b/planet/System.ocg/Fade.c @@ -0,0 +1,54 @@ +global func FadeOut(int time, bool del) +{ + //if there is an existing effect, remove it + if(GetEffect("ObjFade", this)) RemoveEffect("ObjFade", this); + + //add the effect itself + var effect = AddEffect("ObjFade", this, 1,1); + effect.fadeTime = time; + effect.delete = del; //delete the object when fade-out is done + effect.FadeOut = true; + return effect; +} + +global func FadeIn(int time) +{ + //if there is an existing effect, remove it + if(GetEffect("ObjFade", this)) RemoveEffect("ObjFade", this); + + //add the effect itself + var effect = AddEffect("ObjFade", this, 1,1); + effect.fadeTime = time; + return effect; +} + +global func FxObjFadeTimer(object target, proplist effect, int timer) +{ + //Is the fade timer up? + if(timer >= effect.fadeTime){ + //delete object at end if specified + if(effect.delete) target->RemoveObject(); + else{ + if(effect.FadeOut){ + //Callback to object when alpha is completely transparent + target->~OnFadeDisappear(); + target->SetObjAlpha(0); + } + else{ + //Callback to object when alpha is fully opaque + target->~OnFadeAppear(); + target->SetObjAlpha(255); + } + } + return -1; + } + + //find out what the alpha should be + var alpha = (timer * 1000 / effect.fadeTime) * 255 / 1000; + + //Does the object fade out or in? + if(effect.FadeOut) alpha = 255 - alpha; + + //shade object's alpha to match time + target->SetObjAlpha(alpha); +} \ No newline at end of file diff --git a/planet/System.ocg/FindLocation.c b/planet/System.ocg/FindLocation.c new file mode 100644 index 000000000..e38933f97 --- /dev/null +++ b/planet/System.ocg/FindLocation.c @@ -0,0 +1,282 @@ +/* + This script contains the function FindLocation which uses a parameter-system similar to FindObject. + This function should mainly be used for placement of objects at the start of a scenario. + FindLocation is not guaranteed to always return a spot if a fitting spot exists, it's just best effort. + + Examples: + finds a tunnel spot: + FindLocation([Loc_Tunnel()]); + finds a floor spot but not in front of tunnel: + FindLocation([Loc_Not(Find_Tunnel()), Loc_Wall(CNAT_Bottom)]); +*/ + +static const LOC_INVALID = 0; +static const LOC_SOLID = 1; +static const LOC_INRECT = 2; +static const LOC_MATERIAL = 3; +static const LOC_FUNC = 4; +static const LOC_WALL = 5; +static const LOC_SPACE = 6; +static const LOC_NOT = 7; +static const LOC_SKY = 8; +static const LOC_LIQUID = 9; +static const LOC_OR = 10; +static const LOC_AND = 11; +static const LOC_MAXTRIES = 12; + +/* + Returns a spot where a custom function returned "true". + For example: Loc_Condition(LargeCaveMushroom.GoodSpot) + with "func GoodSpot(int x, int y)" +*/ +global func Loc_Func(function) +{ + return [LOC_FUNC, function]; +} + +global func Loc_Not(cond) +{ + return [LOC_NOT, cond]; +} + +global func Loc_Or() +{ + var conds = [LOC_OR]; + for (var i = 0; i < 10; ++i) + { + if (Par(i) != nil) + PushBack(conds, Par(i)); + } + return conds; +} + +global func Loc_And() +{ + var conds = [LOC_AND]; + for (var i = 0; i < 10; ++i) + { + if (Par(i) != nil) + PushBack(conds, Par(i)); + } + return conds; +} +/* + only returns results in a rectangle defined by either the coordinates and size x, y, w, h or by passing a rectangle-proplist + as "x" to allow Loc_InRect(Rectangle(x, y, w, h)) +*/ +global func Loc_InRect(x, int y, int w, int h) +{ + if (x == nil) return [LOC_INVALID]; + if (GetType(x) == C4V_PropList) return [LOC_INRECT, x]; + return [LOC_INRECT, Rectangle(x, y, w, h)]; +} + +/* + Returns a point in a given material or material-texture-combination. + The texture-parameter is optional. +*/ +global func Loc_Material(string material, string texture) +{ + if (texture) + return [LOC_MATERIAL, Material(material), texture]; + else + return [LOC_MATERIAL, Material(material)]; +} + +global func Loc_Tunnel() +{ + return Loc_Material("Tunnel"); +} + +/* + Sets the maximum number of trying to find a position with a random point. + Should probably be larger than 1000 unless you are very sure that such a spot is common. +*/ +global func Loc_MaxTries(int number_of_tries) +{ + return [LOC_MAXTRIES, number_of_tries]; +} + +global func Loc_Sky() { return [LOC_SKY]; } +global func Loc_Solid() { return [LOC_SOLID]; } +global func Loc_Liquid() { return [LOC_LIQUID]; } + +/* + returns a point on a wall. /direction/ can be either CNAT_Bottom, CNAT_Top, CNAT_Left, CNAT_Right. + Note that this implies that you are looking for a non-solid spot. +*/ +global func Loc_Wall(int direction) +{ + var x = 0, y = 0; + if(direction & CNAT_Left) x = -1; + else + if(direction & CNAT_Right) x = 1; + + if(direction & CNAT_Top) y = -1; + else + if(direction & CNAT_Bottom) y = 1; + + var both_left_right = !!((direction & CNAT_Top) && (direction & CNAT_Bottom)); + var both_top_bottom = !!((direction & CNAT_Left) && (direction & CNAT_Right)); + + return [LOC_WALL, x, y, both_left_right, both_top_bottom]; +} + +/* + returns a spot with enough space either vertically or horizontally. + For example Loc_Space(20, true) would only return points where a Clonk could stand. +*/ +global func Loc_Space(int space, bool vertical) +{ + return [LOC_SPACE, space, vertical]; +} + +global func FindLocation(condition1) +{ + var rect = nil; + var xdir = 0, ydir = 0, xmod = nil, ymod = nil; + var flags = []; + // maximum number of tries + var repeat = 5000; + + // put parameters in array and filter out special parameters + for (var i = 0; i < 10; ++i) + { + var f = Par(i); + if (!f) continue; + + if (f[0] == LOC_INRECT) + { + rect = f[1]; + } + else if (f[0] == LOC_WALL) + { + xdir = f[1]; + ydir = f[2]; + xmod = f[3]; + ymod = f[4]; + } + else if (f[0] == LOC_MAXTRIES) + { + repeat = f[1]; + } + else + { + PushBack(flags, f); + } + } + rect = rect ?? Rectangle(0, 0, LandscapeWidth(), LandscapeHeight()); + + // repeat until a spot is found or max. number of tries exceeded + while (repeat-- > 0) + { + var x = RandomX(rect.x, rect.x + rect.w); + var y = RandomX(rect.y, rect.y + rect.h); + + // find wall-spot + // this part just moves the random point to left/right/up/down until a wall is hit + if (xdir || ydir) + { + var lx = xdir; + var ly = ydir; + if (xmod) if (Random(2)) lx *= -1; + if (ymod) if (Random(2)) ly *= -1; + + if (GBackSolid(x, y)) continue; + var valid = false; + var failsafe = 0; + do + { + if (GBackSolid(x + lx, y + ly)) {valid = true; break;} + x += lx; + y += ly; + } while (++failsafe < 100); + if (!valid) continue; + } + + // check every flag + var valid = true; + for (var flag in flags) + { + if (Global->FindLocationConditionCheckIsValid(flag, x, y)) continue; + valid = false; + break; + } + if (valid) + { + return {x = x, y = y}; + } + } + + // no spot found + return nil; +} + +global func FindLocationConditionCheckIsValid(flag, x, y) +{ + if (flag[0] == LOC_NOT) return !FindLocationConditionCheckIsValid(flag[1], x, y); + + if (flag[0] == LOC_OR) + { + var max = GetLength(flag); + for (var i = 1; i < max; ++i) + if (FindLocationConditionCheckIsValid(flag[i], x, y)) return true; + return false; + } + + if (flag[0] == LOC_AND) + { + var max = GetLength(flag); + for (var i = 1; i < max; ++i) + if (!FindLocationConditionCheckIsValid(flag[i], x, y)) return false; + return true; + } + + if (flag[0] == LOC_INRECT) + { + var rect = flag[1]; + return Inside(x, rect.x, rect.x + rect.w) && Inside(y, rect.y, rect.y + rect.h); + } + + if (flag[0] == LOC_SOLID) + return GBackSolid(x, y); + + if (flag[0] == LOC_SKY) + return GBackSky(x, y); + + if (flag[0] == LOC_LIQUID) + return GBackLiquid(x, y); + + if (flag[0] == LOC_MATERIAL) + { + if ((GetMaterial(x, y) != flag[1])) return false; + if (GetLength(flag) > 2) + if (GetTexture(x, y) != flag[2]) return false; + return true; + } + + // custom condition call + if (flag[0] == LOC_FUNC) + { + return Global->Call(flag[1], x, y); + } + + // has some space? + if (flag[0] == LOC_SPACE) + { + var xd = 0, yd = 0; + if (flag[2]) yd = flag[1]; + else xd = flag[1]; + + var d1 = PathFree2(x, y, x + xd, y + yd); + var d2 = PathFree2(x, y, x - xd, y - yd); + var d = 0; + if (d1) d += Distance(x, y, d1[0], d1[1]); + if (d2) d += Distance(x, y, d2[0], d2[1]); + if (d >= flag[1]) return true; + return false; + } + + // invalid flag? always fulfilled + return true; +} \ No newline at end of file diff --git a/planet/System.ocg/FindObject.c b/planet/System.ocg/FindObject.c index 52243d978..85999819e 100644 --- a/planet/System.ocg/FindObject.c +++ b/planet/System.ocg/FindObject.c @@ -45,27 +45,27 @@ global func Find_ID(id def) global func Find_InRect(int x, int y, int wdt, int hgt) { - return [C4FO_InRect, GetX() + x, GetY() + y, wdt, hgt]; + return [C4FO_InRect, x, y, wdt, hgt]; } global func Find_AtPoint(int x, int y) { - return [C4FO_AtPoint, GetX() + x, GetY() + y]; + return [C4FO_AtPoint, x, y]; } global func Find_AtRect(int x, int y, int wdt, int hgt) { - return [C4FO_AtRect, GetX() + x, GetY() + y, wdt, hgt]; + return [C4FO_AtRect, x, y, wdt, hgt]; } global func Find_OnLine(int x, int y, int x2, int y2) { - return [C4FO_OnLine, GetX() + x, GetY() + y, GetX() + x2, GetY() + y2]; + return [C4FO_OnLine, x, y, x2, y2]; } global func Find_Distance(int r, int x, int y) { - return [C4FO_Distance, GetX() + x, GetY() + y, r]; + return [C4FO_Distance, x, y, r]; } global func Find_OCF(int ocf) @@ -185,7 +185,7 @@ global func Sort_Multiple() global func Sort_Distance(int x, int y) { - return [C4SO_Distance, GetX() + x, GetY() + y]; + return [C4SO_Distance, x, y]; } global func Sort_Random() diff --git a/planet/System.ocg/Fire.c b/planet/System.ocg/Fire.c index 7487a65a9..f16f1fc6d 100644 --- a/planet/System.ocg/Fire.c +++ b/planet/System.ocg/Fire.c @@ -7,58 +7,74 @@ Functions to be used as documented in the docs. --*/ + // fire drawing modes -static const C4Fx_FireMode_Default=0; // determine mode by category -static const C4Fx_FireMode_LivingVeg = 2 ;// C4D_Living and C4D_StaticBack -static const C4Fx_FireMode_StructVeh = 1; // C4D_Structure and C4D_Vehicle -static const C4Fx_FireMode_Object = 3; // other (C4D_Object and no bit set (magic)) -static const C4Fx_FireMode_Last = 3; // largest valid fire mode - +static const C4Fx_FireMode_Default = 0; // determine mode by category +static const C4Fx_FireMode_LivingVeg = 2; // C4D_Living and C4D_StaticBack +static const C4Fx_FireMode_StructVeh = 1; // C4D_Structure and C4D_Vehicle +static const C4Fx_FireMode_Object = 3; // other (C4D_Object and no bit set (magic)) +static const C4Fx_FireMode_Last = 3; // largest valid fire mode +// Returns whether the object is burning. global func OnFire() { - if(!this) return false; + if (!this) + return false; var effect; - if(!(effect=GetEffect("Fire", this))) return false; + if (!(effect=GetEffect("Fire", this))) + return false; return effect.strength; } -global func Extinguish(strength) +// Extinguishes the calling object with specified strength. +global func Extinguish(strength /* strength between 0 and 100 */) { - if(!this) return false; - if(strength == nil) strength=100; - else if(!strength) return false; + if (!this) + return false; + if (strength == nil) + strength = 100; + else if (!strength) + return false; - var effect=GetEffect("Fire", this); - if(!effect) return false; + var effect = GetEffect("Fire", this); + if (!effect) + return false; effect.strength = BoundBy(effect.strength - strength, 0, 100); - if(effect.strength == 0) RemoveEffect(nil, this, effect); + if (effect.strength == 0) + RemoveEffect(nil, this, effect); return true; } -global func Incinerate(strength, int caused_by, blasted, incinerating_object) +// Incinerates the calling object with specified strength. +global func Incinerate( + strength /* strength between 0 and 100 */ + , int caused_by /* the player that caused the incineration */ + , blasted /* whether the object was incinerated by an explosion */ + , incinerating_object /* the object that caused the incineration */) { - if(!this) return false; - if(strength == nil) strength=100; - else if(!strength) return false; + if (!this) + return false; + if (strength == nil) + strength = 100; + else if (!strength) + return false; - var effect=GetEffect("Fire", this); - if(effect) {effect.strength = BoundBy(effect.strength + strength, 0, 100); return true;} - else AddEffect("Fire", this, 100, 2, this, nil, caused_by, !!blasted, incinerating_object, strength); + var effect = GetEffect("Fire", this); + if (effect) + { + effect.strength = BoundBy(effect.strength + strength, 0, 100); + return true; + } + else + AddEffect("Fire", this, 100, 2, this, nil, caused_by, !!blasted, incinerating_object, strength); return true; } -// called when an object is hit by an explosion (and can burn) -global func OnBlastIncinerationDamage(int level, int player) -{ - return this->Incinerate(level, player); -} - -// called if the object is for example in lava +// Called if the object is submerged in incendiary material (for example in lava). global func OnInIncendiaryMaterial() { - return this->Incinerate(5, NO_OWNER); + return this->Incinerate(10, NO_OWNER); } // Makes the calling object non flammable. @@ -67,7 +83,9 @@ global func MakeNonFlammable() if (!this) return; return AddEffect("IntNonFlammable", this, 300); -} +} + +/*-- Fire Effects --*/ global func FxIntNonFlammableEffect(string new_name) { @@ -78,7 +96,7 @@ global func FxIntNonFlammableEffect(string new_name) return 0; } -global func FxFireStart(object target, effect, bool temp, int caused_by, bool blasted, object incinerating_object, strength) +global func FxFireStart(object target, proplist effect, int temp, int caused_by, bool blasted, object incinerating_object, strength) { // safety if (!target) return -1; @@ -86,52 +104,60 @@ global func FxFireStart(object target, effect, bool temp, int caused_by, bool bl if (temp) return 1; // fail if already on fire //if (target->OnFire()) return -1; + // Fail if target is dead and has NoBurnDecay, to prevent eternal fires. + if (target->GetCategory() & C4D_Living && !target->GetAlive() && target.NoBurnDecay) + return -1; // structures must eject contents now, because DoCon is not guaranteed to be executed! // In extinguishing material - var fire_caused=true; - var burn_to=target->GetDefCoreVal("BurnTo", "DefCore"); + var fire_caused = true; + var burn_to = target.BurnTo; var mat; - if (MaterialName(mat=GetMaterial(target->GetX(),target->GetY()))) - if(GetMaterialVal("Extinguisher", "[Material]", mat, 0)) + if (MaterialName(mat = GetMaterial(target->GetX(), target->GetY()))) + if (GetMaterialVal("Extinguisher", "[Material]", mat)) { // blasts should changedef in water, too! - if (blasted) if(burn_to != nil) target->ChangeDef(burn_to); + if (blasted) + if (burn_to != nil) + target->ChangeDef(burn_to); // no fire caused fire_caused = false; } // BurnTurnTo - if (fire_caused) if(burn_to != nil) target->ChangeDef(burn_to); + if (fire_caused) + if (burn_to != nil) + target->ChangeDef(burn_to); // eject contents var obj; - if (!target->GetDefCoreVal("IncompleteActivity", "DefCore") && !target->GetDefCoreVal("NoBurnDecay", "DefCore")) + if (!target->GetDefCoreVal("IncompleteActivity", "DefCore") && !target.NoBurnDecay) { - for(var i=target->ContentsCount(); obj=target->Contents(--i);) + for (var i = target->ContentsCount(); obj = target->Contents(--i);) { - if(target->Contained()) obj->Enter(target->Contained()); - else obj->Exit(); - } - + if (target->Contained()) + obj->Enter(target->Contained()); + else + obj->Exit(); + } // Detach attached objects - for(obj in FindObjects(Find_ActionTarget(target))) + for (obj in FindObjects(Find_ActionTarget(target))) { - if(obj->GetProcedure() == "ATTACH") - obj->SetAction(0); + if (obj->GetProcedure() == "ATTACH") + obj->SetAction(nil); } } // fire caused? if (!fire_caused) { - // if object was blasted but not incinerated (i.e., inside extinguisher) - // do a script callback - if (blasted) target->~IncinerationEx(caused_by); + // if object was blasted but not incinerated (i.e., inside extinguisher), do a script callback + if (blasted) + target->~IncinerationEx(caused_by); return -1; } // determine fire appearance var fire_mode; - if (!(fire_mode=target->~GetFireMode())) + if (!(fire_mode = target->~GetFireMode())) { // set default fire modes var cat = target->GetCategory(); @@ -153,12 +179,15 @@ global func FxFireStart(object target, effect, bool temp, int caused_by, bool bl effect.caused_by = caused_by; // used in C4Object::GetFireCause and timer! <- fixme? effect.blasted = blasted; effect.incinerating_obj = incinerating_object; - effect.no_burn_decay = target->GetDefCoreVal("NoBurnDecay", "DefCore"); + effect.no_burn_decay = target.NoBurnDecay; // Set values //target->FirePhase=Random(MaxFirePhase); - if((target->GetDefCoreVal("Width", "DefCore") * target->GetDefCoreVal("Height", "DefCore")) > 500) target->Sound("Inflame", false, 100); - if(target->GetMass() >= 100) target->Sound("Fire", false, 100, 0, true); + if ((target->GetDefCoreVal("Width", "DefCore") * target->GetDefCoreVal("Height", "DefCore")) > 500) + target->Sound("Inflame", false, 100); + if (target->GetMass() >= 100) + if (target->Sound("Fire", false, 100, nil, 1)) + effect.fire_sound = true; // callback target->~Incineration(effect.caused_by); @@ -167,7 +196,7 @@ global func FxFireStart(object target, effect, bool temp, int caused_by, bool bl return FX_OK; } -global func FxFireTimer(object target, effect, int time) +global func FxFireTimer(object target, proplist effect, int time) { // safety if (!target) return FX_Execute_Kill; @@ -178,98 +207,133 @@ global func FxFireTimer(object target, effect, int time) // strength changes over time if(time % 4 == 0) { - if(effect.strength < 50){ if(time % 8 == 0) effect.strength=Max(effect.strength-1, 0); if(effect.strength <= 0) return FX_Execute_Kill;} - else effect.strength=Min(effect.strength+1, 100); + if (effect.strength < 50) + { + if (time % 8 == 0) + effect.strength = Max(effect.strength - 1, 0); + if (effect.strength <= 0) + return FX_Execute_Kill; + } + else + effect.strength = Min(effect.strength + 1, 100); } - var width=target->GetDefCoreVal("Width", "DefCore")/2; - var height=target->GetDefCoreVal("Height", "DefCore")/2; + var width = target->GetDefCoreVal("Width", "DefCore") / 2; + var height = target->GetDefCoreVal("Height", "DefCore") / 2; // target is in liquid? - if(time % 24 == 0) - { - + if (time % 24 == 0) + { var mat; - if(mat = GetMaterial()) - if(GetMaterialVal("Extinguisher", "Material", mat)) + if (mat = GetMaterial()) + if (GetMaterialVal("Extinguisher", "Material", mat)) return FX_Execute_Kill; // check spreading of fire - if(effect.strength > 10) - for(var obj in FindObjects(Find_AtRect(-width/2, -height/2, width, height), Find_Exclude(this))) + if (effect.strength > 10) { - if(obj->GetCategory() & C4D_Living) if(!obj->GetAlive()) continue; - - var inf = obj->GetDefCoreVal("ContactIncinerate", "DefCore"); - if(!inf) continue; - var amount = (effect.strength/3) / Max(1, inf); - - if(!amount) continue; - obj->Incinerate(Max(10, amount), effect.caused_by, false, effect.incinerating_obj); + var container = target->Contained(), inc_objs; + // If contained do not incinerate anything. This would mostly affect inventory items and burns the Clonk too easily while lacking feedback. + if (container) + { + inc_objs = []; + } + // Or if not contained incinerate all objects outside the burning object. + // Do not incinerate inventory objects, since this, too, would mostly affect Clonks and losing one's bow in a fight without noticing it is nothing but annoying to the player. + else + { + inc_objs = FindObjects(Find_AtRect(-width/2, -height/2, width, height), Find_Exclude(target), Find_Layer(target->GetObjectLayer()), Find_NoContainer()); + } + // Loop through the selected set of objects and check contact incinerate. + for (var obj in inc_objs) + { + if (obj->GetCategory() & C4D_Living) + if (!obj->GetAlive()) + continue; + + var inf = obj.ContactIncinerate; + if (!inf) + continue; + var amount = (effect.strength / 3) / Max(1, inf); + + if (!amount) + continue; + + var old_fire_value = obj->OnFire(); + if(old_fire_value < 100) // only if the object was not already fully ablaze + { + // incinerate the other object a bit + obj->Incinerate(Max(10, amount), effect.caused_by, false, effect.incinerating_obj); + + // Incinerating other objects weakens the own fire. + // This is done in order to make fires spread slower especially as a chain reaction. + var min = Min(10, effect.strength); + if(effect.strength > 50) min = 50; + effect.strength = BoundBy(effect.strength - amount/2, min, 100); + } + } } } -// if(time % 20 == 0)target->Message(Format("%d", effect.strength)); + //if(time % 20 == 0)target->Message(Format("%d", effect.strength)); // causes on object //target->ExecFire(effect_number, caused_by); - if(target->GetAlive()) + if (target->GetAlive()) { - target->DoEnergy(-effect.strength*2, true, FX_Call_EngFire, effect.caused_by); + target->DoEnergy(-effect.strength*4, true, FX_Call_EngFire, effect.caused_by); } else { - if((time*10) % 100 <= effect.strength) + if ((time*10) % 100 <= effect.strength) { target->DoDamage(2, true, FX_Call_DmgFire, effect.caused_by); - if(target) if(!Random(2)) if(!effect.no_burn_decay) target->DoCon(-1); + if (target && !Random(2) && !effect.no_burn_decay) + target->DoCon(-1); } } - if(!target) return FX_Execute_Kill; + if (!target) + return FX_Execute_Kill; //if(!(time % 2 == 0)) return FX_OK; //if(!target->OnFire()) {return FX_Execute_Kill;} - if(target->Contained()) return FX_OK; + if (target->Contained()) + return FX_OK; // particles - //var smoke;//, sparks, bright; - //smoke=BoundBy(effect.strength, 0, 100); - //sparks=BoundBy((effect.strength*3)/4, 0, 100); - //bright=BoundBy((effect.strength-50), 0, 100); if(time % 4 == 0) { - var size = BoundBy(10*Max(width, height), 50, 800); - if(size > 300) if(time % 8 == 0) return; + var size = BoundBy(Max(width, height), 5, 50); + if (size > 40) + if (time % 8 == 0) + return; - var wind=BoundBy(GetWind(target->GetX(), target->GetY()), -5, 5); - var smoke_color; if(effect.strength < 50) smoke_color=RGBa(255,255,255, 50); else smoke_color=RGBa(100, 100, 100, 50); - - CreateParticle("ExploSmoke", RandomX(-width, width), RandomX(-height, height), wind, -effect.strength/8, size, smoke_color); + var smoke_color; + if(effect.strength < 50) + smoke_color = RGBa(255,255,255, 50); + else + smoke_color = RGBa(100, 100, 100, 50); + + Smoke(RandomX(-width, width), RandomX(-height, height), size, smoke_color); } - - /*for(var i=0;iGetMass() >=100) target->Sound("Fire", false, 1, 0, false); + if (effect.fire_sound) + target->Sound("Fire", false, 100, nil, -1); + // callback + target->~Extinguishing(); // done, success return true; } @@ -277,4 +341,4 @@ global func FxFireStop(object target, int effect_number, int reason, bool temp) global func FxFireInfo(object target, effect) { return Format("Is on %d%% fire.", effect.strength); // todo: <-- -} \ No newline at end of file +} diff --git a/planet/System.ocg/FunctionOverview.txt b/planet/System.ocg/FunctionOverview.txt index 0d233465b..bc7c70658 100644 --- a/planet/System.ocg/FunctionOverview.txt +++ b/planet/System.ocg/FunctionOverview.txt @@ -66,7 +66,6 @@ Find_* and Sort_* function for FindObject(). OnFire() - Checks whether the object is on fire. Extinguish() - Extinguishes the object. Incinerate() - Set the object on fire. -OnBlastIncinerationDamage() - Explosion callback in inflammable objects. OnInIncendiaryMaterial() - Callback if an inflammable object falls into incendiary material. MakeNonFlammable() - Makes the object immune to fire. @@ -163,4 +162,4 @@ ClearScheduleCall() - Delete a schedule call. SetVertexXY() - Sets both the X and Y-coordinate of one vertex. VerticesStuck() - Returns the number of stuck vertices. -HasCNAT() - Returns whether the object has a vertex with the given CNAT value. \ No newline at end of file +HasCNAT() - Returns whether the object has a vertex with the given CNAT value. diff --git a/planet/System.ocg/GetXVal.c b/planet/System.ocg/GetXVal.c index 8917ae92f..59af5b827 100644 --- a/planet/System.ocg/GetXVal.c +++ b/planet/System.ocg/GetXVal.c @@ -28,18 +28,12 @@ global func GetDefMass() { return GetDefCoreVal("Mass", "DefCore"); } global func GetDefComponents(nr) { return GetDefCoreVal("Components", "DefCore", nr); } global func GetDefCollection(nr) { return GetDefCoreVal("Collection", "DefCore", nr); } global func GetDefFireTop() { return GetDefCoreVal("FireTop", "DefCore"); } -global func GetDefPlacement() { return GetDefCoreVal("Placement", "DefCore"); } -global func GetDefContactIncinerate() { return GetDefCoreVal("ContactIncinerate", "DefCore"); } -global func GetDefBlastIncinerate() { return GetDefCoreVal("BlastIncinerate", "DefCore"); } -global func GetDefBurnTo() { return GetDefCoreVal("BurnTo", "DefCore"); } -global func GetDefBase() { return GetDefCoreVal("Base", "DefCore"); } global func GetDefLine() { return GetDefCoreVal("Line", "DefCore"); } global func GetDefCrewMember() { return GetDefCoreVal("CrewMember", "DefCore"); } global func GetDefConstruction(){ return GetDefCoreVal("Construction", "DefCore"); } global func GetDefConstructTo() { return GetDefCoreVal("ConstructTo", "DefCore"); } global func GetDefGrab() { return GetDefCoreVal("Grab", "DefCore"); } global func GetDefGrabPutGet() { return GetDefCoreVal("GrabPutGet", "DefCore"); } -global func GetDefCollectible() { return GetDefCoreVal("Collectible", "DefCore"); } global func GetDefRotate() { return GetDefCoreVal("Rotate", "DefCore"); } global func GetDefFloat() { return GetDefCoreVal("Float", "DefCore"); } global func GetDefContainBlast(){ return GetDefCoreVal("ContainBlast", "DefCore"); } @@ -48,58 +42,53 @@ global func GetDefBorderBound() { return GetDefCoreVal("BorderBound", "DefCore") global func GetDefLiftTop() { return GetDefCoreVal("LiftTop", "DefCore"); } global func GetDefUprightAttach() { return GetDefCoreVal("UprightAttach", "DefCore"); } global func GetDefStretchGrowth() { return GetDefCoreVal("StretchGrowth", "DefCore"); } -global func GetDefBasement() { return GetDefCoreVal("Basement", "DefCore"); } -global func GetDefNoBurnDecay() { return GetDefCoreVal("NoBurnDecay", "DefCore"); } global func GetDefIncompleteActivity() { return GetDefCoreVal("IncompleteActivity", "DefCore"); } global func GetDefAttractLightning() { return GetDefCoreVal("AttractLightning", "DefCore"); } global func GetDefOversize() { return GetDefCoreVal("Oversize", "DefCore"); } global func GetDefFragile() { return GetDefCoreVal("Fragile", "DefCore"); } -global func GetDefExplosive() { return GetDefCoreVal("Explosive", "DefCore"); } global func GetDefProjectile() { return GetDefCoreVal("Projectile", "DefCore"); } global func GetDefNoPushEnter() { return GetDefCoreVal("NoPushEnter", "DefCore"); } global func GetDefVehicleControl() { return GetDefCoreVal("VehicleControl", "DefCore"); } global func GetDefNoComponentMass() { return GetDefCoreVal("NoComponentMass", "DefCore"); } global func GetDefClosedContainer() { return GetDefCoreVal("ClosedContainer", "DefCore"); } global func GetDefSilentCommands() { return GetDefCoreVal("SilentCommands", "DefCore"); } -global func GetDefNoBurnDamage(){ return GetDefCoreVal("NoBurnDamage", "DefCore"); } global func GetDefTemporaryCrew() { return GetDefCoreVal("TemporaryCrew", "DefCore"); } -global func GetDefSmokeRate() { return GetDefCoreVal("SmokeRate", "DefCore"); } global func GetDefNoBreath() { return GetDefCoreVal("NoBreath", "DefCore"); } global func GetDefConSizeOff() { return GetDefCoreVal("ConSizeOff", "DefCore"); } // GetObjectVal -global func GetObjOwnMass() { return GetObjectVal("OwnMass", 0); } -global func GetObjFixX() { return GetObjectVal("FixX", 0); } -global func GetObjFixY() { return GetObjectVal("FixY", 0); } -global func GetObjWidth() { return GetObjectVal("Width", 0); } -global func GetObjHeight() { return GetObjectVal("Height", 0); } -global func GetObjFireTop() { return GetObjectVal("FireTop", 0); } -global func GetObjMobile() { return GetObjectVal("Mobile", 0); } -global func GetObjOnFire() { return GetObjectVal("OnFire", 0); } -global func GetObjInLiquid() { return GetObjectVal("InLiquid", 0); } -global func GetObjEntranceStatus() { return GetObjectVal("EntranceStatus", 0); } -global func GetObjPhysicalTemporary() { return GetObjectVal("PhysicalTemporary", 0); } -global func GetObjNeedEnergy() { return GetObjectVal("NeedEnergy", 0); } -global func GetObjActionTime() { return GetObjectVal("ActionTime", 0); } -global func GetObjActionData() { return GetObjectVal("ActionData", 0); } -global func GetObjPhaseDelay() { return GetObjectVal("PhaseDelay", 0); } -global func GetObjActionTarget1() { return GetObjectVal("ActionTarget1", 0); } -global func GetObjActionTarget2() { return GetObjectVal("ActionTarget2", 0); } -global func GetObjPlrViewRange() { return GetObjectVal("PlrViewRange", 0); } +global func GetObjOwnMass() { return GetObjectVal("OwnMass", nil); } +global func GetObjFixX() { return GetObjectVal("FixX", nil); } +global func GetObjFixY() { return GetObjectVal("FixY", nil); } +global func GetObjWidth() { return GetObjectVal("Width", nil); } +global func GetObjHeight() { return GetObjectVal("Height", nil); } +global func GetObjFireTop() { return GetObjectVal("FireTop", nil); } +global func GetObjMobile() { return GetObjectVal("Mobile", nil); } +global func GetObjOnFire() { return GetObjectVal("OnFire", nil); } +global func GetObjInLiquid() { return GetObjectVal("InLiquid", nil); } +global func GetObjEntranceStatus() { return GetObjectVal("EntranceStatus", nil); } +global func GetObjPhysicalTemporary() { return GetObjectVal("PhysicalTemporary", nil); } +global func GetObjNeedEnergy() { return GetObjectVal("NeedEnergy", nil); } +global func GetObjActionTime() { return GetObjectVal("ActionTime", nil); } +global func GetObjActionData() { return GetObjectVal("ActionData", nil); } +global func GetObjPhaseDelay() { return GetObjectVal("PhaseDelay", nil); } +global func GetObjActionTarget1() { return GetObjectVal("ActionTarget1", nil); } +global func GetObjActionTarget2() { return GetObjectVal("ActionTarget2", nil); } +global func GetObjPlrViewRange() { return GetObjectVal("PlrViewRange", nil); } // GetPlayerVal -global func GetPlrClientNr(int plr) { return GetPlayerVal("AtClient", 0, plr); } -global func GetPlrClientName(int plr) { return GetPlayerVal("AtClientName", 0, plr); } +global func GetPlrClientNr(int plr) { return GetPlayerVal("AtClient", nil, plr); } +global func GetPlrClientName(int plr) { return GetPlayerVal("AtClientName", nil, plr); } //global func GetPlrColor(int plr) { return GetPlayerVal("ColorDw", 0, plr); } - use GetPlayerColor -global func GetPlrViewX(int plr) { return GetPlayerVal("ViewX", 0, plr); } //(!) -global func GetPlrViewY(int plr) { return GetPlayerVal("ViewY", 0, plr); } //(!) -global func GetPlrFogOfWar(int plr) { return GetPlayerVal("FogOfWar", 0, plr); } //(!) -global func GetPlrWealth(int plr) { return GetPlayerVal("Wealth", 0, plr); } -global func GetPlrPoints(int plr) { return GetPlayerVal("Points", 0, plr); } -global func GetPlrValue(int plr) { return GetPlayerVal("Value", 0, plr); } -global func GetPlrInitialValue(int plr) { return GetPlayerVal("InitialValue", 0, plr); } -global func GetPlrValueGain(int plr) { return GetPlayerVal("ValueGain", 0, plr); } -global func GetPlrObjectsOwned(int plr) { return GetPlayerVal("GetPlrObjectsOwned", 0, plr); } +global func GetPlrViewX(int plr) { return GetPlayerVal("ViewX", nil, plr); } //(!) +global func GetPlrViewY(int plr) { return GetPlayerVal("ViewY", nil, plr); } //(!) +global func GetPlrFogOfWar(int plr) { return GetPlayerVal("FogOfWar", nil, plr); } //(!) +global func GetPlrWealth(int plr) { return GetPlayerVal("Wealth", nil, plr); } +global func GetPlrPoints(int plr) { return GetPlayerVal("Points", nil, plr); } +global func GetPlrValue(int plr) { return GetPlayerVal("Value", nil, plr); } +global func GetPlrInitialValue(int plr) { return GetPlayerVal("InitialValue", nil, plr); } +global func GetPlrValueGain(int plr) { return GetPlayerVal("ValueGain", nil, plr); } +global func GetPlrObjectsOwned(int plr) { return GetPlayerVal("GetPlrObjectsOwned", nil, plr); } // GetScenarioVal global func GetScenTitle() { return GetScenarioVal("Title", "Head"); } //(!) diff --git a/planet/System.ocg/HitChecks.c b/planet/System.ocg/HitChecks.c index e2e6c0fcd..8e4bbe324 100644 --- a/planet/System.ocg/HitChecks.c +++ b/planet/System.ocg/HitChecks.c @@ -15,7 +15,7 @@ global func FxHitCheckStart(object target, proplist effect, int temp, object by_ return; effect.x = target->GetX(); effect.y = target->GetY(); - if (!by_obj) + if (!by_obj || GetType(by_obj) != C4V_C4Object) by_obj = target; if (by_obj->Contained()) by_obj = by_obj->Contained(); diff --git a/planet/System.ocg/LanguageDE.txt b/planet/System.ocg/LanguageDE.txt index c706d448b..201420472 100644 --- a/planet/System.ocg/LanguageDE.txt +++ b/planet/System.ocg/LanguageDE.txt @@ -1,50 +1,33 @@ IDS_LANG_NAME=Deutsch -IDS_LANG_INFO=Original-Sprachpaket von RedWolf Design. +IDS_LANG_INFO=Original-Sprachpaket. IDS_LANG_FALLBACK= -IDS_BTN_ACCEPT=Annehmen IDS_BTN_ACTIVATE=Aktivieren IDS_BTN_BACK=Zurück -IDS_BTN_BROWSE=Durchsuchen... -IDS_BTN_CANCEL=Abbrechen IDS_BTN_CHAT=&Chat IDS_BTN_CHECKFORUPDATES=&Updates suchen IDS_BTN_CONNECT=Verbinden IDS_BTN_CONTINUEGAME=Diese Runde &weiterspielen -IDS_BTN_NEXTSCENARIO=&Nächstes Szenario -IDS_DESC_NEXTSCENARIO=Nächstes Szenario starten. IDS_BTN_DEACTIVATE=Deaktivieren IDS_BTN_DELETE=Löschen -IDS_BTN_DL=Herunterladen -IDS_BTN_DUPLICATE=Duplizieren IDS_BTN_ENDROUND=Runde &beenden -IDS_BTN_EXPLODE=Zerlegen -IDS_BTN_EXTENDED=Erweitert -> IDS_BTN_GAMES=&Spiele -IDS_BTN_JOIN=Beitreten IDS_BTN_LOCALGAME=&Spiel starten -IDS_BTN_MESSAGE=Nachricht IDS_BTN_NETWORKGAME=&Netzwerkspiel IDS_BTN_NEW=Neu IDS_BTN_NEXTMISSION=&Nächste Mission IDS_BTN_NO=Nein IDS_BTN_OBJECTS=Objekte -IDS_BTN_OK=OK IDS_BTN_OPEN=Öffnen -IDS_BTN_PACK=Packen -IDS_BTN_PRESETS=Vorgaben IDS_BTN_PROPERTIES=Eigenschaften -IDS_BTN_REGISTERNOW=Jetzt ®istrieren! IDS_BTN_RELOAD=&Aktualisieren IDS_BTN_RENAME=Umbenennen +IDS_BTN_RESET=Zurücksetzen IDS_BTN_RESETCONFIG=Konfiguration zurücksetzen IDS_BTN_RESETKEYBOARD=Alle zurücksetzen IDS_BTN_RESTART=Neu &Starten IDS_BTN_RETRY=Wiederholen -IDS_BTN_SIMPLE=<- Einfach IDS_BTN_START=Starten IDS_BTN_STARTGAME=&Start -IDS_BTN_UNPACK=Entpacken -IDS_BTN_USEACTIVATED=Aktuelle Auswahl als Vorgabe IDS_BTN_VOLUME=Lautstärkeregelung IDS_BTN_YES=Ja IDS_CHAT_NOTCONNECTED=nicht verbunden @@ -58,10 +41,7 @@ IDS_CNS_EXACTTOSTATIC=Beim Wechsel von einer exakten zur statischen Landschaft g IDS_CNS_FILLNOHALT=Das Füllwerkzeug kann nicht im Haltemodus eingesetzt werden. IDS_CNS_GAMECLOSED=Spiel deinitialisiert. IDS_CNS_GAMESAVED=Spiel gespeichert. -IDS_CNS_INFO=Info -IDS_CNS_LOCALS=Lokale Variablen: IDS_CNS_MULTIPLEOBJECTS=%i Objekte ausgewählt. -IDS_CNS_NAMES=Namen IDS_CNS_NEWPLRVIEWPORT=Neu für %s IDS_CNS_NOCHILDSAVE=%s befindet sich in einem Rundenordner.\nSzenarien können nicht in geschlossenen Gruppendateien gespeichert werden. IDS_CNS_NOFULLSCREENPLRS=Im Vollbildmodus kann nur gestartet werden, wenn Spieler am Spiel teilnehmen. @@ -73,27 +53,21 @@ IDS_CNS_OWNER=Besitzer: %s IDS_CNS_PLRQUIT=%s löschen IDS_CNS_PLRQUITNET=%s (%s) löschen IDS_CNS_PROPERTIES=Eigenschaften -IDS_CNS_REGONLY=Der Konsolenmodus kann nur in der registrierten Version gestartet werden. IDS_CNS_SAVEASERROR=Fehler beim Speichern des Szenarios nach %s. IDS_CNS_SAVERROR=Fehler beim Speichern des Szenarios. IDS_CNS_SCENARIOSAVED=Szenario gespeichert. IDS_CNS_SCRIPT=Script IDS_CNS_SCRIPTCREATEDOBJECTS=Das Script dieses Szenarios hat beim Start der Runde Objekte erschaffen. -IDS_CNS_TITLE=Titel -IDS_CNS_TOOLS=Werkzeuge IDS_CNS_TYPE=Typ: %s (%s) IDS_CNS_VIEWPORT=Sichtfenster IDS_CNS_WARNDOUBLE=Um Verdoppelungen der abgespeicherten Objekte beim nächsten Start zu vermeiden, sollte die Initialize-Funktion des Scripts entsprechend angepasst werden. IDS_COMM_ACQUIRE=Beschaffung IDS_COMM_ACTIVATE=Aktivieren IDS_COMM_ATTACK=Angreifen -IDS_COMM_BUILD=Bauen IDS_COMM_BUY=Kaufen IDS_COMM_CALL=Objektaufruf -IDS_COMM_CONSTRUCT=Konstruktion IDS_COMM_DIG=Graben IDS_COMM_DROP=Ablegen -IDS_COMM_ENERGY=Energieversorgung IDS_COMM_ENTER=Betreten IDS_COMM_EXIT=Verlassen IDS_COMM_FOLLOW=Folgen @@ -112,244 +86,93 @@ IDS_COMM_THROW=Werfen IDS_COMM_TRANSFER=Bewegung IDS_COMM_UNGRAB=Loslassen IDS_COMM_WAIT=Warten -IDS_CON_ACTIVATEFROM=Objekt in %s aktivieren -IDS_CON_ATTACK=%s angreifen. IDS_CON_BUILD=%s bauen. -IDS_CON_BUILDINFO=Baumaterial IDS_CON_BUILDMATNEED=%s|braucht noch IDS_CON_BUILDMATNONE=%s braucht kein|weiteres Baumaterial. -IDS_CON_BUY=Kaufen -IDS_CON_COLLECT=%s einsammeln. -IDS_CON_CONTENTS=Inhalt -IDS_CON_DIGOUT=%s ausgraben. -IDS_CON_DOUBLECLICK=(Doppelklick) -IDS_CON_ENTER=%s betreten. -IDS_CON_EXIT=Gebäude verlassen IDS_CON_FAILURE=%s|nicht möglich! IDS_CON_FAILUREOF=%s von %s|nicht möglich! -IDS_CON_GET=Objekt aus %s herausnehmen. -IDS_CON_GRAB=%s anfassen. IDS_CON_HELP=Hilfe IDS_CON_HOME=Zurück zur Basis -IDS_CON_INFO=Info -IDS_CON_ITEMS=Gegenstände -IDS_CON_JUMP=Springen. -IDS_CON_NAME=%s -IDS_CON_PLAYERMENU=Spielermenü -IDS_CON_PUT2=Ablegen -IDS_CON_PUT=%s in %s ablegen -IDS_CON_SELECT=%s -IDS_CON_SELL=Verkaufen -IDS_CON_UNGRAB=%s loslassen. -IDS_CON_VEHICLEPUT=%s in %s schieben -IDS_CON_VEHICLES=Fahrzeuge -IDS_CTL_ACCESS=Zugang: IDS_CTL_ACTIVE=Aktivieren -IDS_CTL_ALL=Alle -IDS_CTL_AMPLITUDE=Amplitude: -IDS_CTL_ANIMALS=Tiere IDS_CTL_ANTIALIASING=Antialiasing: IDS_CTL_AUTHOR=Autor: %s -IDS_CTL_AUTOEDITSCAN=Bearbeitete Objekte im Hintergrund aktualisieren IDS_CTL_AUTOMATICUPDATES=automatische Updates aktivieren IDS_CTL_BITDEPTH=Farbtiefe -IDS_CTL_BITMAP=Grafik (BMP) -IDS_CTL_BITMAP_PNG=Grafik (PNG) -IDS_CTL_BUILDINGS=Gebäude: IDS_CTL_CHANNEL=Chat-Raum (Kanal): IDS_CTL_CHAT=Cha&t: -IDS_CTL_CLIMATE2=heiß -IDS_CTL_CLIMATE3=kalt -IDS_CTL_CLIMATE=Klima IDS_CTL_CLONKSKIN=Clonk-Stil: IDS_CTL_COLOR=Farbe IDS_CTL_COMMENT=Kommentar IDS_CTL_CONTROL=Steuerung IDS_CTL_CONTROLRATE=Kontrollrate IDS_CTL_CONTROLRATE_DESC=Gibt in Frames an, wie oft Kontrolldaten im Netzwerk ausgetauscht werden -IDS_CTL_CREATEDMAP=Generierte Karte IDS_CTL_CREW=Mannschaft: -IDS_CTL_CUID=User-Id: IDS_CTL_DEBUGMODE=Debug-Modus -IDS_CTL_DEFBYCHOICE=lokale und aktivierte Objektdefinitionen -IDS_CTL_DESCRIPTION=Beschreibung -IDS_CTL_DETAILS=Details -IDS_CTL_DIG=Graben IDS_CTL_DL_PROGRESS=Fortschritt: IDS_CTL_DL_TITLE=Download -IDS_CTL_DOWNSTOP=Runter / Stop -IDS_CTL_DYNAMICMAP=Dynamische Karte -IDS_CTL_EARTHQUAKES2=keine -IDS_CTL_EARTHQUAKES3=viele -IDS_CTL_EARTHQUAKES=Erdbeben -IDS_CTL_ENABLEROUNDOPTIONS=Szenarioeigenschaften zulassen -IDS_CTL_ENGINE=Engine IDS_CTL_ENTERCOMMENT=Bitte gewünschten Kommentar eingeben: -IDS_CTL_ENVIRONMENTOBJECTS=Umweltobjekte -IDS_CTL_EXACTMAP=Exakte Karte IDS_CTL_FONT=Schriftart IDS_CTL_FRONTEND=Menüsystem -IDS_CTL_FULLNAME=Spielername: IDS_CTL_GAME=Spiel IDS_CTL_GAMEFUNCTIONS=Spielfunktionen IDS_CTL_GAMEPADFORMENU=Gamepad zur Menüsteuerung verwenden. IDS_CTL_GAMESPEEDUP=Spielgeschwindigkeit erhöhen IDS_CTL_GAMESPEEDDOWN=Spielgeschwindigkeit verringern IDS_CTL_GFXENGINE=Grafiktreiber -IDS_CTL_GOALS=Ziele: -IDS_CTL_GRAVITY2=schwach -IDS_CTL_GRAVITY3=stark -IDS_CTL_GRAVITY=Schwerkraft -IDS_CTL_HEIGHT=Höhe: -IDS_CTL_HOMEBASE=Kaufbare Objekte: -IDS_CTL_ICON=Icon: -IDS_CTL_IMPORTIMAGEAS=Bild importieren als: -IDS_CTL_INEARTHAMOUNTS=Objekte im Erdreich Menge -IDS_CTL_INEARTHTYPES=Objekte im Erdreich Anteile IDS_CTL_INETSERVER=&Internet IDS_CTL_IRCCHAT=IRC-Chat -IDS_CTL_KEYFILE=Registrierungsschlüssel: -IDS_CTL_KNOWLEDGE=Baupläne: IDS_CTL_LANGUAGE=Sprache IDS_CTL_LEAGUE_ACCOUNT=Liga-Benutzername: IDS_CTL_LEAGUE_CHK_PLRPW=Liga-Passwort eingeben IDS_CTL_LEAGUE_PLRPW2=Liga-Passwort (Wiederholung): IDS_CTL_LEAGUE_PLRPW=Liga-Passwort: -IDS_CTL_LEFT=Links -IDS_CTL_LOCALMATS= mit lokalen Materialdefinitionen -IDS_CTL_LOCALONLY=nur lokale Objektdefinitionen -IDS_CTL_LOCATION=in %s IDS_CTL_LOST=verloren IDS_CTL_LOUD=laut -IDS_CTL_MANUALCLIP=Manuelles Clipping -IDS_CTL_MAPPLAYEREXTEND=Breite nach Spielerzahl IDS_CTL_MATERIAL=Material -IDS_CTL_MAXPLAYERS=Max. Spieler: -IDS_CTL_MENUSYSTEM=Menüsystem IDS_CTL_MESSAGEBOARDBACK=Nachrichten zurück IDS_CTL_MESSAGEBOARDFORWARD=Nachrichten vor -IDS_CTL_METEORITES2=keine -IDS_CTL_METEORITES3=viele -IDS_CTL_METEORITES=Meteoriten IDS_CTL_MMTIMER=Multimedia-Timer abschalten IDS_CTL_MUSIC=Musik IDS_CTL_NAME2=Name: IDS_CTL_NAME=Name -IDS_CTL_NESTS=Nester IDS_CTL_NICK=Kurzname: -IDS_CTL_NOADDBLT=Kein additives Zeichnen -IDS_CTL_NOALPHAADD=Keine Alpha-Addition -IDS_CTL_NOCLRFADE=Keine Farbverläufe IDS_CTL_NOGOAL=Kein Spielziel IDS_CTL_NOLANGINFO=Sprachpaket nicht verfügbar. IDS_CTL_NONE=keine -IDS_CTL_NORMALCREW_DESC=Trainierte Clonks: Clonks sind je nach Rang unterschiedlich stark. IDS_CTL_OFF=aus IDS_CTL_ON=an -IDS_CTL_OPENBOTTOM=Unten offen -IDS_CTL_OPENDIRECTORY=Offenes Verzeichnis -IDS_CTL_OPENTOP=Oben offen IDS_CTL_PASSWORDOPTIONAL=Passwort (optional): -IDS_CTL_PERIOD=Periode: -IDS_CTL_PHASE=Phase: IDS_CTL_PICTURE=Bild: IDS_CTL_PLAYER1=Spieler 1 IDS_CTL_PLAYER2=Spieler 2 IDS_CTL_PLAYER3=Spieler 3 IDS_CTL_PLAYER4=Spieler 4 IDS_CTL_PLAYER=Spieler -IDS_CTL_PLAYERMENU=Spielermenü -IDS_CTL_PLAYERS1=1 Spieler -IDS_CTL_PLAYERS2=2 Spieler -IDS_CTL_PLAYERS3=3 Spieler -IDS_CTL_PLAYERS4=4 Spieler -IDS_CTL_PLEASEWAIT=Bitte warten... -IDS_CTL_POINTFILTERING=Nicht interpolieren -IDS_CTL_PREVIEWFOR=Vorschau für -IDS_CTL_PRODUCTION=Nachlieferung kaufbarer Objekte: -IDS_CTL_RAIN2=kein -IDS_CTL_RAIN3=viel -IDS_CTL_RAIN=Niederschlag -IDS_CTL_RANDOM=Zufall: IDS_CTL_REALNAME=Realname: IDS_CTL_RECORD=Au&fnehmen -IDS_CTL_REGISTERED=Vielen Dank für Ihre Registrierung! -IDS_CTL_REGISTEREDONLY=Nur in der registrierten Version möglich. IDS_CTL_RESOLUTION=Auflösung -IDS_CTL_RICHTEXT=Beschreibungstext -IDS_CTL_RIGHT=Rechts -IDS_CTL_RULES=Regeln: -IDS_CTL_SCENARIOUSES=Szenario benutzt IDS_CTL_SCOREBOARD=Scoreboard (wenn verfügbar) IDS_CTL_SCREENSHOT=Screenshot IDS_CTL_SCREENSHOTEX=Screenshot Gesamtspielfläche IDS_CTL_SCRIPT=Script IDS_CTL_SCRIPTPLAYERS=Script-Spieler -IDS_CTL_SEASON2=Frühling -IDS_CTL_SEASON3=Winter -IDS_CTL_SEASON=Jahreszeit zu Spielbeginn -IDS_CTL_SELECTLEFT=Auswahl links -IDS_CTL_SELECTRIGHT=Auswahl rechts -IDS_CTL_SELECTTOGGLE=Auswahl -IDS_CTL_SENDDEFRELOAD=Objektdefinitionsupdates bei laufender Engine IDS_CTL_SENDMESSAGE=Nachricht senden IDS_CTL_SHOW=Anzeigen IDS_CTL_SHOWALLRESOLUTIONS=alle Auflösungen anzeigen -IDS_CTL_SHOWLAYERS=Erdreich -IDS_CTL_SHOWSCREEN=Bildschirmgröße IDS_CTL_SILENT=leise -IDS_CTL_SKIPDEFS=Nicht zu ladende Definitionen: IDS_CTL_SMOKE=Effekte IDS_CTL_SMOKEHI=hoch IDS_CTL_SMOKELOW=niedrig IDS_CTL_SOUND=Sound IDS_CTL_SOUNDFX=Soundeffekte -IDS_CTL_SPECIAL1=Spezial 1 -IDS_CTL_SPECIAL2=Spezial 2 -IDS_CTL_SPECIFIEDDEFS=lokale und vorgegebene Objektdefinitionen: -IDS_CTL_STATICMAP=Statische Karte -IDS_CTL_SYMBOLS=Symbole IDS_CTL_TEXT=Text IDS_CTL_TEXTURE=Textur -IDS_CTL_THROW=Werfen -IDS_CTL_THUNDERSTORMS2=keine -IDS_CTL_THUNDERSTORMS3=viele -IDS_CTL_THUNDERSTORMS=Gewitter -IDS_CTL_TIMEADVANCE2=langsam -IDS_CTL_TIMEADVANCE3=schnell -IDS_CTL_TIMEADVANCE=Zeitverlauf IDS_CTL_TOTALPLAYINGTIME=Gesamtspielzeit: %02d:%02d:%02d IDS_CTL_TROUBLE=Problembehebung -IDS_CTL_UNREGISTERED=NICHT REGISTRIERT IDS_CTL_UPDATE=&Update -IDS_CTL_UPJUMP=Rauf / Springen IDS_CTL_USEOTHERSERVER=anderen Internetserver verwenden -IDS_CTL_USESHELL=Windows-Shell zum Bearbeiten benutzen -IDS_CTL_VALUE=Wert -IDS_CTL_VALUESFOR=Werte für -IDS_CTL_VEGETATIONAMOUNTS=Vegetation Menge -IDS_CTL_VEGETATIONTYPES=Vegetation Anteile -IDS_CTL_VEHICLES=Fahrzeuge: -IDS_CTL_VERBOSEOBJECTS=Ãœberladene Objekte melden -IDS_CTL_VIEW=Ansicht: -IDS_CTL_VOLCANOES2=keine -IDS_CTL_VOLCANOES3=viele -IDS_CTL_VOLCANOES=Vulkane -IDS_CTL_VOLUME=Lautstärke -IDS_CTL_WATERLEVEL=Wasserstand: -IDS_CTL_WEALTH=Vermögen: -IDS_CTL_WEBCODE=WebCode: -IDS_CTL_WIDTH=Breite: -IDS_CTL_WIND2=links -IDS_CTL_WIND3=rechts -IDS_CTL_WIND=Wind IDS_CTL_WON=gewonnen -IDS_CTL_ZIP=Zip -IDS_CTL_ZOOM=Vergrößerungsfaktor: IDS_DESC_AUTOMATICUPDATES=Prüft beim Programmstart einmal pro Tag, ob Updates für die installierte Version verfügbar sind. -IDS_DESC_BREATH=Atem: -IDS_DESC_CHANGESTHEIMAGEYOUSEEINTH2=Bild, welches in der Netzwerk-Lobby und im Auswertungsdialog angezeigt wird. -IDS_DESC_CHANGESTHEIMAGEYOUSEEINTH=Bild, welches im Spielerauswahldialog angezeigt wird. IDS_DESC_CHANGESTHEWAYCONTROLDATAI=Legt fest, wie Steuerungsdaten in Netzwerkspielen zwischen Client-Rechnern ausgetauscht werden. IDS_DESC_CHECKONLINEFORNEWVERSIONS=Sucht online nach Updates für diese Version. IDS_DESC_CLIENTS=Clients: @@ -362,24 +185,17 @@ IDS_DESC_DATE=Spiel vom %i.%i.%i %02d:%02d Uhr. IDS_DESC_DATENET=Netzwerkspiel vom %i.%i.%i %02d:%02d Uhr. IDS_DESC_DATEREC=Aufnahme vom %i.%i.%i %02d:%02d Uhr. IDS_DESC_DEFSPECS=Objektdefinitionen: -IDS_DESC_DIG=Graben: IDS_DESC_DURATION=Spieldauer: %02d:%02d:%02d. IDS_DESC_ENDTHEROUND=Die Runde beenden. -IDS_DESC_ENERGY=Energie: -IDS_DESC_ENGINE=Dieses Zusatzprogramm ist für die Ausführung von Spielrunden verantwortlich.\n\nBei Auswahl eines Szenarios zeigt die rote Markierung an, welche Engine für die Ausführung des jeweiligen Szenarios verwendet wird.\n\nDurch Aktivierung oder Deaktivierung einer Engine (Kästchen wird grün) kann bestimmt werden, welche Engine eingesetzt werden soll, falls mehrere gleichermaßen geeignete Engines vorhanden sind. IDS_DESC_EXPECTING=Teilnehmer werden erwartet. -IDS_DESC_FAIRCREWSTRENGTH=Bestimmt die Stärke der Clonks in einem Spiel mit "Fairen Clonks". IDS_DESC_FONTSIZE=Schriftgröße auswählen. Bei Wechsel der Bildschirmauflösung wird die Schriftgröße automatisch angepasst. IDS_DESC_GAMEMUSIC=Steuert Hintergrundmusik im Spiel. IDS_DESC_GAMEPADFORMENU=Mit dieser Option kann das Gamepad für die Steuerung des Menüsystems verwendet werden. IDS_DESC_GAMEPAUSED=Spiel ist pausiert IDS_DESC_GAMERUNNING=Spiel läuft IDS_DESC_GAMESOUND=Steuert Geräuscheffekte im Spiel. -IDS_DESC_GOALFULFILLED=Spielziel %s erfüllt: %s -IDS_DESC_GOALNOTFULFILLED=Spielziel %s nicht erfüllt: %s -IDS_DESC_GOTOTHEONLINEREGISTRATION=Öffnet das Online-Bestellformular. -IDS_DESC_HANGLE=Hangeln: -IDS_DESC_JUMP=Springen: +IDS_DESC_GOALFULFILLED=Spielziel %s erfüllt +IDS_DESC_GOALNOTFULFILLED=Spielziel %s nicht erfüllt IDS_DESC_LASTGAME=\nLetzte Runde: %s\nDatum: %s\nDauer: %s\nPunkte: %i\n IDS_DESC_LEAGUECHECKPASSWORD=Aktivieren, um ein eigenes Passwort einzugeben. Wird kein eigenes Passwort eingegeben, wird stattdessen der persönliche WebCode verwendet, der bereits auf diesem System gespeichert ist. IDS_DESC_LEAGUESCOREANDPROJECTEDGA=Ligapunkte und möglicher Gewinn, wenn das Team dieses Spielers die Runde gewinnt. @@ -395,27 +211,23 @@ IDS_DESC_PLAYER=Punkte: %i\nRunden: %i (%i gew. %i verl.)\nSpielzeit: %s\nKommen IDS_DESC_PLAYERSCONTROLLEDBYCOMPUT=Computergesteuerte Spieler. IDS_DESC_PLRS=Spieler: IDS_DESC_PROMO=Beförderung zum %s\nbei: %i -IDS_DESC_PUSH=Schieben: IDS_DESC_RESETCONFIG=Alle Konfigurationswerte auf ihren Ursprungswert zurücksetzen. IDS_DESC_RESOURCE=Die hier angezeigten Dateien werden in dieser Runde verwendet. Ressourcen, die dynamisch über das Netzwerk geladen wurden, können über das entsprechende Symbol dauerhaft auf diesem Computer gespeichert und später wieder verwendet werden. -IDS_DESC_SCALE=Klettern: IDS_DESC_SELECTAPICTUREANDORLOBBYI=Spielerbild oder Lobby-Icon auswählen. IDS_DESC_SELECTFONT=Schriftart auswählen. Manche Schriftarten enthalten nicht alle benötigten Zeichen für bestimmte Sprachen. In diesem Fall sollte eine andere Schriftart ausgewählt werden. IDS_DESC_SHOWALLRESOLUTIONS=Erlaubt auch die Auswahl von sehr großen und sehr kleinen Auflösungen. IDS_DESC_SHOWSAVAILABLENETWORKGAME=Zeigt laufende Netzwerkspiele. -IDS_DESC_SWIM=Schwimmen: IDS_DESC_TEAM=Team %s -IDS_DESC_THROW=Werfen: IDS_DESC_UNASSOCIATEDSAVEGAMEPLAYE=Nicht zugewiesene Spielstand-Spieler. IDS_DESC_UNKNOWNGAMESTATE=Spiel ist in einem unbekannten Zustand IDS_DESC_VERSION=Engine-Version: %s IDS_DESC_VOLUMEMUSIC=Lautstärke der Hintergrundmusik. IDS_DESC_VOLUMESOUND=Lautstärke der Geräuscheffekte. IDS_DESC_WAITFORHOST=Warte auf Host-Verbindung -IDS_DESC_WALK=Laufen: -IDS_DLGTIP_ABOUT=Zeigt Programminformationen an. +IDS_DLGTIP_ABOUT=Zeigt die Credits und Programminfos an. IDS_DLGTIP_BACKMAIN=Zurück zum Hauptmenü. IDS_DLGTIP_CANCEL=Aktion abbrechen. +IDS_DLGTIP_CHANGECTRL=Wähle eine Steuerung aus um sie anzusehen und zu ändern IDS_DLGTIP_CHAT=Hier Chat-Nachrichten eintippen und mit Enter bestätigen IDS_DLGTIP_CHATWIN=Nachrichten IDS_DLGTIP_CLASSIC=Clonks laufen weiter, bis sie mit 'Stop' angehalten werden. @@ -433,9 +245,7 @@ IDS_DLGTIP_OPTIONS=Ändert die Programmeinstellungen. IDS_DLGTIP_PASTE=Fügt den Inhalt der Zwischenablage an der Einfügemarke ein IDS_DLGTIP_PING=Ping IDS_DLGTIP_PLAYERCOLORS=Wählt eine Standardfarbe aus. -IDS_DLGTIP_PLAYERCOLORSTGB=Mischt eine eigene Spielerfarbe aus Rot, Grün und Blau. IDS_DLGTIP_PLAYERCONTROL=Wählt eine Steuerungsmethode aus. -IDS_DLGTIP_PLAYERCONTROLMOUSE=Schaltet zur ausgewählten Steuerungsmethode zusätzlich Maussteurung ein. IDS_DLGTIP_PLAYERCREW=Zeigt die Stammcrew des Spielers an. IDS_DLGTIP_PLAYERCREWSKIN=Wählt das Aussehen der Clonks aus. IDS_DLGTIP_PLAYERDELETE=Löscht den ausgewählten Spieler. @@ -454,46 +264,37 @@ IDS_DLGTIP_STARTINTERNETGAME=Internetspiel: andere Spieler können diese Runde i IDS_DLGTIP_STARTLEAGUEGAME=Ligaspiel: die Runde soll in der Liga ausgewertet werden. IDS_DLGTIP_UPDATE=Update verfügbar: hier klicken, um die neue Version des Spiels herunterzuladen und zu installieren. IDS_DLG_ABORT=Abbruch -IDS_DLG_ABOUT=&Info +IDS_DLG_ABOUT=&Credits IDS_DLG_CANCEL=&Abbrechen IDS_DLG_CHAT=Chat IDS_DLG_CLASSIC=Klassisch IDS_DLG_CLEAR=Löschen IDS_DLG_CLOSE=&Schließen +IDS_DLG_CONTROLS=Steuerung IDS_DLG_COPY=Kopieren IDS_DLG_CUT=Ausschneiden IDS_DLG_DEFINITION=Objektdefinition IDS_DLG_DEFINITIONS=Objektdefinitionen -IDS_DLG_DEVELOPER=Entwickler IDS_DLG_DYNAMIC=Dynamische Landschaft -IDS_DLG_EDITOR=Extern -IDS_DLG_EDITORSWITCH=Taste F6 wechselt zum Spiel. -IDS_DLG_ENVIRONMENT=Umwelt IDS_DLG_ERROR=Fehler IDS_DLG_EXACT=Exakte Landschaft IDS_DLG_EXIT=&Beenden -IDS_DLG_EXPLORER=Editor IDS_DLG_GAME=Spiel IDS_DLG_GAMEGO=&Starten IDS_DLG_GAMEPAD=Gamepad IDS_DLG_GRAPHICS=Grafik -IDS_DLG_IDSELECT=Objektauswahl IDS_DLG_INVALIDENTRY=Ungültige Angaben IDS_DLG_JUMPANDRUN=Jump'n'Run -IDS_DLG_KEYBOARD=Tastatur -IDS_DLG_LANDSCAPE=Landschaft IDS_DLG_LEAGUESIGNUP=Liga-Anmeldung IDS_DLG_LEAGUESIGNUPCONFIRM=Bestätigung der Liga-Anmeldung IDS_DLG_LEAGUESIGNUPFAILED=Liga-Anmeldung fehlgeschlagen IDS_DLG_LEAGUESIGNUPON=Liga-Anmeldung auf %s -IDS_DLG_LICENSE=Entwicklermodus Nutzungsbedingungen IDS_DLG_LOBBY=Lobby IDS_DLG_LOG=Fehlermeldungen IDS_DLG_MISSIONACCESS=Missionszugang IDS_DLG_MOVEMENT=Bewegung IDS_DLG_NETSTART=Netzwerkspiel starten IDS_DLG_NETWORK=Netzwerk -IDS_DLG_NEW=Neu IDS_DLG_NO=&Nein IDS_DLG_NOPLAYERSSELECTED=keine ausgewählt IDS_DLG_OK=&OK @@ -504,13 +305,10 @@ IDS_DLG_PLAYER2=Spielereigenschaften IDS_DLG_PLAYERCOLORSELECTION=Farbwahl IDS_DLG_PLAYERS=S&pieler IDS_DLG_PLAYERSELECTION=S&pielerauswahl -IDS_DLG_PLAYERSTART=Ausrüstung IDS_DLG_PROGRAM=Programm IDS_DLG_PROPERTIES=Eigenschaften -IDS_DLG_REGISTRATION=Registrierung IDS_DLG_RESOURCES=Ressourcen IDS_DLG_SCENARIO=Szenario -IDS_DLG_SCENARIOPROPERTIES=Szenarioeigenschaften IDS_DLG_SCENARIOS=Szenarien IDS_DLG_SCENARIOTITLE=Geladenes Szenario IDS_DLG_SELALL=Alles markieren @@ -520,22 +318,9 @@ IDS_DLG_STATIC=Statische Landschaft IDS_DLG_TOOLS=Landschaftswerkzeuge IDS_DLG_VERSION=Version %s IDS_DLG_VOTING=Abstimmung -IDS_DLG_WEATHER=Wetter IDS_DLG_YES=&Ja -IDS_DL_ACTIVEDOWNLOADS=Aktive Downloads: IDS_DL_CANCEL=Download abbrechen -IDS_DL_CAPTION=Downloads -IDS_DL_CLOSE=Schließen -IDS_DL_FILENAME=Dateiname -IDS_DL_FILEPROGRESS=Fortschritt -IDS_DL_FILESIZE=Größe -IDS_DL_STATUSCANCELLED=abgebrochen IDS_DL_STATUSCONNECTING=verbinden... -IDS_DL_STATUSDONE=beendet -IDS_DL_STATUSERROR=Fehler -IDS_DL_STATUSWAITING=warten... -IDS_DL_TARGET=Ziel -IDS_EDITOR_WELCOME=Benutzung des Editors auf eigene Gefahr. IDS_ERR_CLONKCOLLISION=Ein Clonk mit Dateinamen "%s" existiert bereits. IDS_ERR_CONFIG=Konfigurationsfehler IDS_ERR_CONFREAD=Einstellungen konnten nicht gelesen werden: %s @@ -550,7 +335,6 @@ IDS_ERR_ERRORWHILECREATINGJOINDAT=Fehler beim Erstellen der Beitrittsdaten IDS_ERR_FAILURE=...fehlgeschlagen. IDS_ERR_FATAL=FATALER FEHLER: %s IDS_ERR_FILEEXISTS=Datei mit Namen "%s" existiert bereits. -IDS_ERR_FONTDEFS=Fehler bei den Schriftdefinitionen IDS_ERR_GAMELEFTVIAPLAYERMENU=Spiel per Spielermenü verlassen. IDS_ERR_GBACK=Fehler beim Landschaftsgenerator. IDS_ERR_GFX_REGISTERMAIN=Fehler beim Laden der Grafikdatei @@ -558,18 +342,15 @@ IDS_ERR_INITFONTS=Fehler bei der Schriftinitialisierung IDS_ERR_INSUFFICIENTPARAMETERS=/%s: fehlende Parameter IDS_ERR_INVALIDCHANNELNAME=Kein gültiger Chat-Kanal. IDS_ERR_CHANNELNOTALLOWED=Kann nur Chat-Kanäle mit "clonk" im Namen und einem # am Anfang betreten. -IDS_ERR_INVALIDID= Definition %s nicht geladen: Ungültige ID IDS_ERR_INVALIDNICKNAME2=/%s: unzulässiger Kurzname IDS_ERR_INVALIDNICKNAME=Unzulässiger Kurzname. IDS_ERR_INVALIDPASSWORDMAX31CHARA=Nicht zulässiges Passwort: maximal 31 Zeichen, keine Leerzeichen. -IDS_ERR_INVALIDREPLYFROMSERVER=Ungültige Antwort vom Server. IDS_ERR_INVALIDSYSGRP=System.c4g nicht vorhanden oder ungültig. IDS_ERR_IRCCONNECTIONFAILED=IRC-Verbindung fehlgeschlagen: %s IDS_ERR_JOINPLR_NOFILE=Kann Spieler %s nicht beitreten lassen: Datei nicht gefunden! IDS_ERR_JOINPLR_NOLOCALCLIENT=Kann Spieler %s nicht bei Client %d beitreten lassen: Fremdclient! IDS_ERR_JOINQUEUEPLRS=C4PlayerInfoList::LocalJoinUnjoinedPlayersInQueue konnte Spieler %s nicht beitreten lassen! IDS_ERR_LEAGUEERRORREPORTINGUNEXP=Liga: Fehler beim Melden des unerwarteten Verbindungsabbruchs: %s -IDS_ERR_LOAD_PLRINFO=Fehler beim Wiederherstellen der Spielinformationen für Spieler %s! IDS_ERR_LOAD_RECR_NOEXTRACT=Fehler beim Wiederherstellen von Spieler %s aus %s: Entpacken fehlgeschlagen! IDS_ERR_LOAD_RECR_NOFILE=Fehler beim Wiederherstellen von Spieler %s: Datei nicht gefunden! IDS_ERR_LOAD_RECR_NOFILEFROMNET=C4PlayerInfoList::RecreatePlayers konnte Spieler %s nicht beitreten lassen: Datei nicht gefunden! @@ -596,21 +377,14 @@ IDS_ERR_REPLAYREAD=Aufnahmedaten konnten nicht gelesen werden! IDS_ERR_SAVE_CORE=Spiel speichern: Fehler beim Speichern der Kerndaten des Szenarios IDS_ERR_SAVE_DESC=Spiel speichern: Fehler beim Speichern der Beschreibung IDS_ERR_SAVE_GAMETITLE=Spiel speichern: Fehler beim Speichern des Titelbilds -IDS_ERR_SAVE_INFO=Spiel speichern: Fehler beim Speichern der Info.txt IDS_ERR_SAVE_LANDSCAPE=Spiel speichern: Fehler beim Speichern der Landkarte -IDS_ERR_SAVE_OBJECTS=Spiel speichern: Fehler beim Speichern der Objekte IDS_ERR_SAVE_PLAYERS=Spiel speichern: Fehler beim Speichern der Spieler IDS_ERR_SAVE_RESTOREPLAYERINFOS=Spiel speichern: Fehler beim Speichern von Spielerinfos zum Wiederherstellen IDS_ERR_SAVE_RUNTIMEDATA=Spiel speichern: Fehler beim Speichern von Laufzeitspieldaten IDS_ERR_SAVE_SCENSECTIONS=Spiel speichern: Fehler beim Speichern der Szenariensektionen -IDS_ERR_SAVE_SCRIPT=Spiel speichern: Fehler beim Speichern des Scripts -IDS_ERR_SAVE_SCRIPTSTRINGS=Spiel speichern: Fehler beim Speichern der Script-Zeichenketten IDS_ERR_SAVE_TARGETGRP=Spiel speichern: Zielgruppe kann nicht als %s erzeugt werden. -IDS_ERR_SAVE_TITLE=Spiel speichern: Fehler beim Speichern des Titels IDS_ERR_SCENSECTION=Fehler beim Laden des Szenarienteils "%s" -IDS_ERR_STRINGS=Fehler beim Laden der Stringtabelle IDS_ERR_SWITCHRES=Fehler beim Ändern der Bildschirmauflösung: %s -IDS_ERR_TIMER=Fehler beim System-Timer IDS_ERR_TITLE=Fehler IDS_ERR_UNKNOWNCMD=Unbekannter Befehl: "%s" - Befehl /help für eine Liste gültiger Befehle IDS_ERR_HELPCMD=Grundlegende Befehle im IRC-Chat:|/join [Chatraum] - Neuen Chatraum betreten|/part - Diesen Chatraum verlassen|/notice [Benutzer] [Nachricht] - Sende eine Nachricht an den Benutzer|/query [Benutzer] - Öffne ein neues Chatfenster für einen privaten Dialog mit dem Benutzer|/msg [Benutzer] [Nachricht] - Dasselbe wie /query, nur dass bereits die erste Nachrich geschickt wird|/nick [Neuer Spitzname] - Wähle einen neuen Spitznamen|/quit - Chat ganz verlassen|/raw - Raw-Kommando senden @@ -618,29 +392,15 @@ IDS_ERR_USERCANCEL=Benutzerabbruch IDS_ERR_WRITENEWTITLE=Fehler beim Speichern des neuen Titels in Datei "%s": %s IDS_ERR_YOUHAVEBEENREMOVEDBYVOTIN=Du wurdest per Abstimmung aus dem Spiel entfernt. (%s) IDS_ERR_YOUSURRENDEREDTHELEAGUEGA=Du hast das Ligaspiel aufgegeben. -IDS_FAIL_COPY=Fehler beim Kopieren. +IDS_ERR_LOAD_PLAYER=Fehler beim Laden des Spielers "%s" IDS_FAIL_DELETE=Fehler beim Löschen. -IDS_FAIL_EDIT=Fehler beim Bearbeiten. -IDS_FAIL_EXTRACT=Fehler beim Extrahieren. -IDS_FAIL_LOAD=Fehler beim Laden. IDS_FAIL_MODIFY=Fehler beim Bearbeiten der Datei. -IDS_FAIL_MOVE=Fehler beim Verschieben. -IDS_FAIL_PACK=Fehler beim Packen. -IDS_FAIL_RECURSIVE=Ein Objekt kann nicht in sich selbst kopiert werden. IDS_FAIL_RENAME=Fehler beim Umbenennen. -IDS_FAIL_RENAMEDUPLICATE=Umbenennen nicht möglich.\n\nEine Datei gleichen Namens existiert bereits. -IDS_FAIL_RICHEDDLL=RichEdit-DLL nicht vorhanden. IDS_FAIL_SAVE=Fehler beim Speichern. -IDS_FAIL_UNPACK=Fehler beim Entpacken. -IDS_FAIL_UPDATE=Fehler beim Aktualisieren. -IDS_FN_EXECUTABLES=Ausführbare Programme (.exe)|*.exe|| -IDS_FN_NEWDIR=Neues Verzeichnis -IDS_FN_ROOT=Arbeitsverzeichnis IDS_GAME_DEFRANKS=Clonk|Fähnrich|Leutnant|Hauptmann|Major|Oberst|Brigadegeneral|Generalmajor|Generalleutnant|General|Feldmarschall IDS_GAME_FAILSAVEGAME=Fehler beim Speichern des Spiels. IDS_GAME_NOCLIENTSAVE=Netzwerkspiele können nur vom Host abgespeichert werden. IDS_GAME_NOSAVEONCURR=Auf dem geladenen Spielstand|kann nicht gespeichert werden.|Bitte anderen Speicherplatz benutzen! -IDS_GAME_NOUNREGSAVE=Speichern des Spiels ist nur in der registrierten Version möglich. IDS_GAME_RECORDSTITLE=Aufnahmen IDS_GAME_SAVEGAMESTITLE=Spielstände IDS_HOLD_ABORT=Runde abbrechen? @@ -649,6 +409,30 @@ IDS_LEAGUE_LEAGUEREPORTINGUNEXPECTED=Liga: unerwarteter Verbindungsabbruch wird IDS_LEAGUE_WAITINGFORLASTLEAGUESERVE=Warten auf letzte Meldung des Ligaservers... IDS_LGA_INVALIDRESPONSE3=Ungültige Antwort des Ligaservers (kein CSID). IDS_LGA_SERVERFAILURE=Ligaserver-Fehler: %s\n +IDS_LGA_TOOMANYGAMESTARTS=Zu viele Versuche, ein Spiel zu starten +IDS_LGA_INVALIDPRODUCTID=Ungültiges Produkt oder Version +IDS_LGA_WRONGCHECKSUM=Falsche Prüfsumme +IDS_LGA_WRONGRESCHECKSUM=Falsche Ressourcen-Prüfsumme +IDS_LGA_SETTLEOFFICIALSERVER=Siedlungs-Ligaspiele können nur auf einem offiziellen Server gespielt werden +IDS_LGA_SETTLEOLDENGINE=Siedlungs-Ligaspiele können nur mit der aktuellsten Spielversion gespielt werden +IDS_LGA_CANTADDSCEN=Szenario konnte nicht zur Liga hinzugefügt werden +IDS_LGA_CANTFINDLEAGUESCEN=Kein Liga-Szenario und die offene Liga ist nicht aktiv +IDS_LGA_LEAGUESCENNOMELEE=Szenario ist in dieser Version in keiner Liga eingetragen. Nur Melees können in der offenen Liga gespielt werden +IDS_LGA_GAMEALREADYENDED=Spiel ist schon beendet +IDS_LGA_CANTFINDSCEN=Szenario nicht gefunden +IDS_LGA_NOCSID=CSID fehlt +IDS_LGA_CANTFINDGAME=Spiel nicht gefunden +IDS_LGA_WRONGHOSTIP=Falsche/geänderte Host-IP +IDS_LGA_CUIDALREADYEXISTS=Für diese CUID existiert bereits ein Account +IDS_LGA_WEBCODEAUTHFAILED=Authentifizierung fehlgeschlagen +IDS_LGA_WEBCODEAUTHNA=Authentifizierung derzeit nicht verfügbar +IDS_LGA_LOGINFAILED=Login fehlgeschlagen +IDS_LGA_AUIDNOTFOUND=Spieler wurde nicht authentifiziert +IDS_LGA_USERALREADYJOINED=Spieler ist diesem Spiel bereits beigetreten +IDS_LGA_USERBANNED=Benutzer gebannt +IDS_LGA_GAMENOLEAGUE=Kein Ligaspiel +IDS_LGA_GAMERECORDCOMPLETE=Aufnahme bereits komplett +IDS_LGA_GAMERECORDTOOLARGE=Aufnahme zu groß IDS_LOG_COMMANDNOTALLOWEDINLEAGUE=Kommando in Ligaspielen nicht erlaubt! IDS_MENU_ABORT=Runde abbrechen IDS_MENU_ABORT_DESC=Die Runde ohne Auswertung abbrechen. @@ -660,7 +444,6 @@ IDS_MENU_ATTACKHOSTILE=feindlich IDS_MENU_ATTACKINFO=%s ist uns %sgesinnt und wird zur Zeit von uns %sangegriffen. IDS_MENU_ATTACKNOT=nicht IDS_MENU_ATTACKSELF=Wir greifen uns selbst nicht an. -IDS_MENU_BUY=%s kaufen IDS_MENU_CLONKNAMES_DESC=Zeigt Clonk-Namen über gegnerischen Clonks an. IDS_MENU_CPATTACK=Angriff IDS_MENU_CPATTACKINFO=Festlegen, welche Spieler von den eigenen Clonks angegriffen werden sollen. @@ -675,41 +458,28 @@ IDS_MENU_CPSAVEGAME=Spielstand speichern IDS_MENU_CPSAVEGAMEINFO=Das Spiel speichern, so dass es später fortgesetzt werden kann. IDS_MENU_CPSURRENDER=Aufgeben IDS_MENU_CPSURRENDERINFO=Aufgeben und das Spiel verlassen (mit Auswertung). -IDS_MENU_DELETE=Löschen IDS_MENU_DISCONNECT=Verbindung trennen IDS_MENU_DISCONNECTCLIENT=Client trennen IDS_MENU_DISCONNECTFROMSERVER=Verbindung zum Host trennen? IDS_MENU_DISPLAY=Anzeige IDS_MENU_GET=%s holen -IDS_MENU_HELP=Hilfe -IDS_MENU_INSERT=Hinzufügen... -IDS_MENU_MULTIPLEITEMS=Objekte IDS_MENU_NEWPLAYER=Spielerbeitritt: %s IDS_MENU_NOATTACK=%s nicht angreifen. IDS_MENU_NOPLRFILES=Keine weiteren Spielerdateien verfügbar. IDS_MENU_OBSERVER=Zuschauermenü -IDS_MENU_ONLINEDOCS=Online-Dokumentation... -IDS_MENU_OPTION=Optionen -IDS_MENU_OPTIONS=Optionen... IDS_MENU_PLAYERNAMES_DESC=Zeigt Spielernamen über gegnerischen Clonks an. -IDS_MENU_REGISTRATION=Registrierung... -IDS_MENU_SELL=%s verkaufen -IDS_MENU_SHOWCOMMANDKEYS=Tasten -IDS_MENU_SHOWCOMMANDS=Kommandos IDS_MENU_SURRENDER=Wirklich aufgeben? -IDS_MENU_WEBSITE=Clonk im Internet... IDS_MNU_CLOCK=Uhrzeit IDS_MNU_CLONKNAMES=Clonk-Namen IDS_MNU_CLOSE=Schließen IDS_MNU_COMPONENTS=Komponenten IDS_MNU_CONTENTS=Inhalt nehmen +IDS_MNU_DEFAULTRESOLUTION=Bildschirm IDS_MNU_DELETE=Löschen IDS_MNU_DUPLICATE=Duplizieren IDS_MNU_FILE=Datei IDS_MNU_FPS=FPS-Anzeige -IDS_MNU_INFO=Info IDS_MNU_JOIN=Beitritt -IDS_MNU_MOUSECONTROL=Maussteuerung IDS_MNU_MUSIC=Musik IDS_MNU_NET=Host IDS_MNU_NETCLIENT=Client %s (%i) deaktivieren @@ -722,28 +492,22 @@ IDS_MNU_OPTIONS=Optionen IDS_MNU_OPTIONSINFO=Einstellungen ändern. IDS_MNU_PLAYER=Spieler IDS_MNU_PLAYERNAMES=Spielernamen -IDS_MNU_PORTRAITS=Portraits IDS_MNU_QUIT=Beenden IDS_MNU_RECORD=Aufnahme IDS_MNU_SAVEGAME=Spiel speichern IDS_MNU_SAVEGAMEAS=Spiel speichern unter... IDS_MNU_SAVESCENARIO=Szenario speichern IDS_MNU_SAVESCENARIOAS=Szenario speichern unter... -IDS_MNU_SCRIPT=Script IDS_MNU_SWITCHRESOLUTION=Bildschirmauflösung ändern IDS_MNU_SWITCHRESOLUTION_LIKEIT=Neue Auflösung gewählt. Zufrieden? IDS_MNU_SWITCHRESOLUTION_UNDO=Alte Einstellung wird in %d Sekunden wiederhergestellt... -IDS_MNU_TITLE=Titel IDS_MNU_UPPERBOARD=Titelleiste IDS_MNU_VIEWPORT=Sichtfenster -IDS_MSG_ACTIVE=Aktiver IDS_MSG_ALLOWSYOUTOJOINADIFFERENT=Erlaubt die Auswahl eines anderen Teams. -IDS_MSG_ALLPLAYERDATA=Sollen die aktuellen Werte für alle Spieler übernommen werden? IDS_MSG_ANTIALIASING_DESC=FSAA (MultiSampling)-Level einstellen IDS_MSG_ANUPDATETOVERSIONISAVAILA=Ein neues Update ist verfügbar. Soll das Update heruntergeladen und installiert werden? +IDS_MSG_AUTOWINDOWED=Automagisch IDS_MSG_BACKTOPLAYERDLG=Zurück zur Spielerauswahl. -IDS_MSG_BLITOFFSET=Blit offset -IDS_MSG_BLITOFFSET_DESC=Gibt das für jede Zeichenoperation benutze Offset zwecks hochgenauer Pixeloperationen an. Wert erhöhen, wenn schwarze Linien unter/rechts von Grafiken auftauchen. Verringern, wenn Linien über/links von Grafiken auftauchen. IDS_MSG_CANNOTSTARTSCENARIO=Start nicht möglich. IDS_MSG_CANTSENDTEAMMESSAGETEAMSN=Konnte Team-Nachricht nicht senden: unbekanntes Team. IDS_MSG_CHANGESTHETOPICTO=%s ändert das Thema zu: %s @@ -764,7 +528,6 @@ IDS_MSG_DEFINEKEY=Taste belegen IDS_MSG_DELETECLONK=Soll %s %s wirklich gelöscht werden? IDS_MSG_DELETECLONK_DESC=Ausgewählten Clonk aus der Mannschaft entfernen. IDS_MSG_DELETECLONK_PLAYTIME= - dieser Clonk hat eine Gesamtspielzeit von %s! -IDS_MSG_DELETEORIGINAL=%s ist eine Originaldatei. Wirklich löschen? IDS_MSG_DELETEPLR=Soll Spieler %s wirklich gelöscht werden? IDS_MSG_DELETEPLR_PLAYTIME= - dieser Spieler hat eine Gesamtspielzeit von %s! IDS_MSG_DISABLED=Deaktiviert @@ -772,7 +535,6 @@ IDS_MSG_DISCONNECTED=Verbindungsabbruch IDS_MSG_DISCONNECTEDFROMSERVER=Verbindung beendet (%s). IDS_MSG_DISCONNECTFROMSERVER=Verbindung beenden? IDS_MSG_DONTSHOW=Diese Meldung in Zukunft &nicht mehr anzeigen. -IDS_MSG_EDITORREGONLY=Der Editor kann nur in der registrierten Version gestartet werden.\n\nWeitere Informationen finden sich in der Entwickler-Sektion der Clonk Website. IDS_MSG_ENABLED=Aktiviert IDS_MSG_ENTERNEWDEATHMESSAGE=Nachruf im Falle des Todes: IDS_MSG_ENTERPASSWORD=Passwort eingeben: @@ -783,7 +545,7 @@ IDS_MSG_FREELYSCROLLAROUNDTHEMAP=Freies Scrollen der Landkarte. IDS_MSG_FREESAVEGAMEPLRS=Spielerzuweisung IDS_MSG_FREEVIEW=Freie Sicht IDS_MSG_FULLSCREEN=Vollbild -IDS_MSG_FULLSCREEN_DESC=Vollbildmodus aktivieren. +IDS_MSG_FULLSCREEN_DESC=Vollbild/Fenstermodus.|Automatisch für Fenstermodus nur im Menü. IDS_MSG_GFXENGINE_DESC=Gibt an, welcher Grafikmodus benutzt wird. Änderungen greifen erst beim nächsten Programmstart. IDS_MSG_GFXERR_RESINVAL=Ungültige Auflösung! IDS_MSG_GFXERR_RESNOTFOUND=Die gewählte Auflösung wird vom System anscheinend nicht unterstützt. @@ -795,16 +557,19 @@ IDS_MSG_HOST=Host IDS_MSG_INACTIVE=Inaktiver IDS_MSG_INTERNETGAMEEVALUATED=Internetspiel ausgewertet. IDS_MSG_ISNOWKNOWNAS=%s heißt jetzt %s -IDS_MSG_ITEMORIGINAL=%s ist Teil eines Originalpakets und kann an dieser Stelle nicht bearbeitet werden. Zum Bearbeiten kann eine Kopie des Objekts an anderer Stelle erzeugt werden. -IDS_MSG_ITEMSEDITED=Die folgenden Objekte werden noch bearbeitet:\n -IDS_MSG_ITEMSMODIFIED=Bearbeitete Objekte aktualisieren:\n IDS_MSG_JOINTEAM=Team %s beitreten IDS_MSG_KICKBYMENU=Rausgeworfen über das Hostmenü IDS_MSG_KICKFROMCLIENTLIST=Rausgeworfen über die Clientliste IDS_MSG_KICKFROMLOBBY=Rausgeworfen aus der Lobby IDS_MSG_KICKFROMMSGBOARD=Rausgeworfen über die Konsole IDS_MSG_KICKFROMSTARTUPDLG=Rausgeworfen aus dem Startwartedialog -IDS_MSG_LANGUAGEDISCLAIMER=Dies ist eine zusätzliche Sprache eines Drittanbieters. Es gibt keine Gewähr für Vollständigkeit oder Korrektheit. Benutzung auf eigene Gefahr. +IDS_MSG_LEAGUENOTSUPPORTED=Der Masterserver unterstützt keine Liga. +IDS_MSG_MASTERSERVNATERROR=Es wurde festgestellt, dass aus deinem Netzwerk höchstwahrscheinlich keine Internetspiele gehostet werden können.|Um dies zu beheben, müssen bestimmte Ports an deinem Router freigeschaltet werden. Siehe dazu unsere FAQ für weitere Informationen. +IDS_MSG_MASTERSERVSIGNUPFAIL=Anmelden der Runde am Mastererver fehlgeschlagen. +IDS_MSG_MASTERSERVUPDATEFAIL=Aktualisierung der Runde am Masterserver fehlgeschlagen. +IDS_MSG_MASTERSERVENDFAIL=Dem Masterserver konnte nicht mitgeteilt werden, dass die Runde zuende beendet wurde. +IDS_MSG_MASTERSERVNOOP=Der Masterserver unterstützt diese Operation nicht. +IDS_MSG_MASTERSERVWRONGENGINE=Falsche Engine. IDS_MSG_LEAGUEEVALUATIONSUCCESSFU=Ligaspiel erfolgreich ausgewertet. IDS_MSG_LEAGUEGAMESIGNUP=Spiel bei Ligaserver %s angemeldet:|%s IDS_MSG_LEAGUEINVALIDUSERNAME=Der Benutzername enthält ungültige Zeichen. @@ -823,56 +588,30 @@ IDS_MSG_LEAGUEUNEXPECTEDDISCONNEC=Liga: unerwarteter Verbindungsabbruch wurde ge IDS_MSG_LEAGUEUSERNAMETOOSHORT=Der Benutzername ist zu kurz. IDS_MSG_LEAGUE_REGISTRATION=Dies ist Deine erste Anmeldung bei der Liga. Du kannst hier Deinen gewünschten Liga-Benutzernamen und Dein gewünschtes Liga-Passwort eingeben. IDS_MSG_LOCAL=lokaler -IDS_MSG_LOCKACTIVATION=Dieses Objekt muss immer aktiviert bleiben. IDS_MSG_LOOKINGFORUPDATES=Suche nach Updates... -IDS_MSG_MANUALCLIP_DESC=Aktiviert manuelles Clipping. Kann gegen Grafikfehler wie lange, weit gestreckte Linien über den ganzen Bildschirm helfen. IDS_MSG_MAP_DESC=Szenario auf der Karte wählen. IDS_MSG_MAP_STARTSCEN=Szenario %s starten IDS_MSG_MMTIMER_DESC=Kann bei Problemen mit der Spielgeschwindigkeit helfen. -IDS_MSG_MOVEKEY=Soll der Registrierungsschlüssel in das persönliche Benutzerverzeichnis verschoben werden, so dass er nur für den zur Zeit angemeldeten Benutzer gilt? IDS_MSG_NEWPLRCOLOR=Neue &Farbe IDS_MSG_NEWPLRCOLOR_DESC=Zufällige neue Farbe aussuchen -IDS_MSG_NOADDBLT_DESC=Deaktiviert additive Blits. Kann helfen, wenn Spezialeffekte wie Explosionen falsch dargestellt werden. -IDS_MSG_NOALPHAADD_DESC=Deaktiviert additive Transparenzwerte. Kann helfen, wenn im Spiel Rechtecke um Grafiken auftauchen. -IDS_MSG_NOCLRFADE_DESC=Deaktiviert Vertex-Farbverläufe. Kann helfen, wenn das Spiel in Szenarien mit Himmelsfarbverläufen oder eingeschränkter Sicht extrem langsam läuft. IDS_MSG_NODEBUGMODE=Kein Debug-Modus! -IDS_MSG_NODEFS=Keine Objektdefinitionen verfügbar! -IDS_MSG_NOEDITNETREF=Netzwerkreferenzen können nicht bearbeitet werden. -IDS_MSG_NOENGINE=Zum Starten des gewählten Szenarios ist eine Engine der Version %i.%i%i.%i oder höher nötig. -IDS_MSG_NOMATS=Keine Materialdefinitionen verfügbar! -IDS_MSG_NOMODIFYORIGINAL=%s kann nicht aktualisiert werden, da es Teil eines Originalpakets ist. IDS_MSG_NOPARTICIPATE_DESC=%s von der nächsten Runde ausnehmen. IDS_MSG_NOPLAYERSELECTED=Es sind keine Spieler ausgewählt. Bitte zuerst in der Spielerauswahl die Teilnehmer für diese Runde aktivieren. IDS_MSG_NOPORTRAIT=Kein Portrait -IDS_MSG_NORUNTIMEJOIN=Der Laufzeitbeitritt ist bei diesem Spiel gesperrt. IDS_MSG_NOTALLSAVEGAMEPLAYERSHAVE=Nicht alle Spielstand-Spieler wurden lokalen Spielern zugewiesen.|Mit der rechten Maustaste können Spielstand-Spieler aus der Liste lokalen Spielern zugewiesen werden.|Nicht zugewiesene Spielstand-Spieler werden aus dem Spiel entfernt. Nicht zugewiesene lokale Spieler treten als neue Spieler bei.|Jetzt starten? -IDS_MSG_NOTAVALIDFILE=%s ist keine ausführbare Datei. IDS_MSG_NOTENOUGHPLAYERSFORTHISRO=Nicht genügend Teilnehmer für diese Runde. -IDS_MSG_NOUNREGEDIT=Objektverwaltung ist nur in der registrierten Version möglich. -IDS_MSG_NOUNREGISTERED=Dieses Szenario kann nur in der registrierten Version gestartet werden. -IDS_MSG_NOUNREGPROPSAVE=Veränderte Eigenschaften können nur in der registrierten Version gespeichert werden. IDS_MSG_NOUPDATEAVAILABLEFORTHISV=Zur Zeit kein Update für diese Version verfügbar. IDS_MSG_OBJCOUNT=Anzahl Objekte IDS_MSG_PARTICIPATE_DESC=%s für den Einsatz in der nächsten Runde auswählen. IDS_MSG_PARTICLES_DESC=Bestimmt die Stärke von Partikeleffekten wie Rauch und Feuer. IDS_MSG_PASSWORDFORPLAYER=Liga-Anmeldung für Spieler %s. -IDS_MSG_PASSWORDINCORRECT=Passwort inkorrekt. IDS_MSG_PLAYERASSIGNMENT=Teilnehmer %s übernimmt Spieler %s aus dem Spielstand. -IDS_MSG_PLRWEALTH=Spieler-Vermögen -IDS_MSG_POINTFILTERING_DESC=Deaktiviert lineares Filtering. Kann gegen verschwommene Grafiken helfen. -IDS_MSG_PRESETDEFSMISSING=Das ausgewählte Szenario benutzt vorgegebene Objektdefinitionen. Die folgenden benötigten Objektpakete sind auf diesem System nicht vorhanden: %s -IDS_MSG_PRESETUSEDDEFS=In den Szenarioeigenschaften wurden die derzeit aktivierten Objektdefinitionen verwendet. Sollen diese als Vorgabe im Szenario gespeichert werden, so dass das Szenario in Zukunft die ausgewählten Pakete automatisch nutzt? -IDS_MSG_PRESSBTN=Taste für "%s" auf Gamepad %d drücken. -IDS_MSG_PRESSKEY=Taste für "%s" auf Tastaturblock %d drücken. +IDS_MSG_PRESSBTN=Taste für "%s" auf Gamepad drücken. +IDS_MSG_PRESSKEY=Taste für "%s" auf der Tastatur drücken. IDS_MSG_PRESSORPUSHANYGAMEPADBUTT=Taste %s öffnet das Zuschauermenü. -IDS_MSG_PROMPTCOPY=%s nach %s kopieren? IDS_MSG_PROMPTDELETE=%s löschen? -IDS_MSG_PROMPTIMPORT=%s nach %s importieren als %s? -IDS_MSG_PROMPTMOVE=%s nach %s verschieben? IDS_MSG_PROMPTRESETCONFIG=Sollen alle Konfigurationswerte zurückgesetzt werden? -IDS_MSG_PROPORIGINALCOPY=%s ist Teil eines Originalpakets und kann nicht an der ursprünglichen Position gespeichert werden. Soll das veränderte Objekt im Arbeitsverzeichnis abgelegt werden? IDS_MSG_RANK=[Rang -IDS_MSG_REMOTE=entfernter IDS_MSG_REMOVEPLR=&Entfernen IDS_MSG_REMOVEPLR_DESC=Nicht mit diesem Spieler beitreten IDS_MSG_REPLAYPLRS=Schau-Spieler @@ -884,7 +623,6 @@ IDS_MSG_RNDTEAM=Zufallsteam IDS_MSG_SCENARIODESC=Szenariobeschreibung IDS_MSG_SCENARIODESC_LOADING=Lade... (%d%%) IDS_MSG_SELECT=%s auswählen -IDS_MSG_SELECTKEYSET=Wählt den Tastaturblock oder das Gamepad, das angepasst werden soll. IDS_MSG_SELECTLANG=Sprachpaket auswählen. IDS_MSG_SELECTPLR=Spieler auswählen... IDS_MSG_SELTEAM=Team auswählen @@ -896,14 +634,8 @@ IDS_MSG_SETTHEMESSAGETHATAPPEARWH=Nachricht festlegen, die angezeigt wird, wenn IDS_MSG_SHOWTEAMS=Teams IDS_MSG_SHOWTEAMS_DESC=Teams anzeigen IDS_MSG_SPEED=Geschwindigkeit: %dx -IDS_MSG_STARTDEVMODE=Dieses Szenario kann nur im Entwicklermodus gestartet werden. -IDS_MSG_STARTPLAYERMODE=Dieses Szenario kann nur im Spielermodus gestartet werden. -IDS_MSG_STARTSELECTSCENARIO=Zum Starten einer Runde muss noch das gewünschte Szenario ausgewählt werden. Dazu einen Rundenordner (Buch) mit einem Doppelklick öffnen und das gewünschte Szenario anklicken. Anschließend auf 'Starten' klicken. -IDS_MSG_STARTUPVIDEO=Video beim Spielstart anzeigen -IDS_MSG_STARTUPVIDEO_DESC=Zeigt eine Videoanimation, wenn das Spiel gestartet wird. Die Datei "Splash.c4v" kann von clonk.de heruntergeladen werden und muss im Spielverzeichnis abgelegt werden. IDS_MSG_TAKEOVERPLR=&Ãœbernehmen IDS_MSG_TAKEOVERPLR_DESC=Spieler im Spiel steuern -IDS_MSG_TARGETNOGROUP=Nach %s kann nichts kopiert werden. IDS_MSG_TEAM=Team %d IDS_MSG_TEAMCOLORS=Teamfarben IDS_MSG_TEAMCOLORS_DESC=Gibt an, ob alle Spieler eines Teams die selbe Farbe haben. @@ -914,14 +646,10 @@ IDS_MSG_TEAMDIST_HOST=Per Host IDS_MSG_TEAMDIST_NONE=Keine IDS_MSG_TEAMDIST_RND=Zufällig IDS_MSG_TEAMDIST_RNDINV=Zufällig & Unsichtbar -IDS_MSG_TEXINDENT=Texindent -IDS_MSG_TEXINDENT_DESC=Gibt die für das Zeichnen von Texturen verwendete Einrückung an. Wert erhöhen, wenn im Spiel Rahmen um Grafiken auftauchen. Verringern, wenn Rahmen von Grafiken fehlen. IDS_MSG_TOOFEWPLAYERS=Dieses Szenario ist auf mindestens %i Teilnehmer ausgelegt. Bitte in der Spielerauswahl die entsprechenden Teilnehmer auswählen und aktivieren. IDS_MSG_TOOFEWPLAYERSNET=Der Spielmodus dieses Szenarios ist auf mehr Spieler ausgelegt, als auf diesem Rechner aktiviert sind. Beim Start der Runde muss auf weitere Teilnehmer aus dem Netzwerk gewartet werden. -IDS_MSG_TOOMANYDEFS=Auf diesem Rechner sind sehr viele einzelne Objektpakete aktiviert. Es wird dringend empfohlen, mehrere Pakete in sinnvoll sortierten Objektordnern zusammenzufassen. Hierzu über die Schaltfläche 'Neu' einen Objektordner erstellen und die einzelnen Objektdateien hineinschieben. IDS_MSG_TOOMANYPLAYERS=Dieses Szenario ist auf maximal %i Teilnehmer ausgelegt. IDS_MSG_TOPICIN=Thema in %s: %s -IDS_MSG_TRANSFERNOTYPE=Ein %s kann nicht in einem %s abgelegt werden. IDS_MSG_TRYLEAGUESIGNUP=Liga-Anmeldung für Spieler %s... IDS_MSG_UPDATEFAILED=Update fehlgeschlagen. IDS_MSG_UPDATEINPROGRESS=Update-Vorgang läuft noch. Bitte warten. @@ -930,6 +658,7 @@ IDS_MSG_NEWRELEASEAVAILABLE=Für die neue Version ist kein Update-Paket verfügb IDS_MSG_USINGPLR=Mit %s spielen IDS_MSG_USINGPLR_DESC=Diesen Spieler benutzen um das Spiel fortzusetzen IDS_MSG_WASKICKEDFROMTHECHANNEL=%s wurde aus dem Chat-Kanal geworfen (%s). +IDS_MSG_WINDOWED=Fenstermodus IDS_MSG_YOUAREABOUTTOCONNECTTOAPU=Hiermit wird die Verbindung zu einem öffentlichen Chat-Server (%s) erstellt. Fortfahren? IDS_MSG_YOUHAVEJOINEDCHANNEL=Du bist Chat-Kanal %s beigetreten. IDS_MSG_YOUHAVELEFTCHANNEL=Du hast Chat-Kanal %s verlassen (%s). @@ -949,7 +678,6 @@ IDS_NET_CLIENT_INFO=Client-Informationen IDS_NET_CLIENT_INFO_ADDRESSES=Adressen: IDS_NET_CLIENT_INFO_CONNDATA= Daten: %s (%s:%d, %d ms) IDS_NET_CLIENT_INFO_CONNECTIONS=Verbindungen: %s: %s (%s:%d, %d ms) -IDS_NET_CLIENT_INFO_FORMAT=%s %s %s %s (ID #%d):%s IDS_NET_CLIENT_INFO_NOADDRESSES=Addressen: Keine IDS_NET_CLIENT_INFO_NOCONNECTIONS=Verbindungen: Nicht verbunden IDS_NET_CLIENT_INFO_UNKNOWNID=Unbekannte client ID #%d. @@ -957,8 +685,6 @@ IDS_NET_CLIENT_JOIN=Client %s verbunden. IDS_NET_CLIENT_OBSERVE=%s %s muss zuschauen. IDS_NET_CLIENT_REMOVED=%s %s entfernt (%s). IDS_NET_COMMENTCHANGED=Neuer Netzwerkspiel-Kommentar gesetzt. -IDS_NET_COMPUTERNAME=Computername: -IDS_NET_COMPUTERNAME_DESC=Computername, der benutzt wird, um diesen Computer in Netzwerkspielen zu identifizieren. IDS_NET_CONNECTHOST=Verbinde mit Host auf %s... IDS_NET_CONNECTING=Verbinde mit %s (%s) IDS_NET_CONTROL=Steuerdaten @@ -1013,7 +739,7 @@ IDS_NET_LEAGUE_SENDRESULT=Spielergebnis wird an %s gesendet... IDS_NET_LEAGUE_STARTGAME=Spiel wird gestartet... IDS_NET_LOBBYWAITING=Teilnehmer werden erwartet... IDS_NET_LOCAL_CLIENT=Lokaler Client -IDS_NET_MASTERSRV_DESC=Hier kann eine abweichende Internetserver-Adresse eingegeben werden. Ist diese Option abgeschaltet, wird der offizielle Internetserver auf clonk.de genutzt. +IDS_NET_MASTERSRV_DESC=Hier kann eine abweichende Internetserver-Adresse eingegeben werden. Ist diese Option abgeschaltet, wird der offizielle Internetserver auf openclonkclonk.org genutzt. IDS_NET_NEWGAME=&Neues Spiel IDS_NET_NEWGAME_DESC=Startet ein neues Netzwerk- oder Internetspiel. IDS_NET_NODIRECTSTART=Netzwerkspieldaten können nicht direkt gestartet werden. @@ -1075,8 +801,6 @@ IDS_NET_USERNAME_DESC=Name, der für Chat-Nachrichten in Netzwerkspielen verwend IDS_NET_WAITFORRES=Warte auf %s... IDS_NET_WAITFORSTART=Warte auf Spielstart IDS_OBJ_BIRTHDAY=%s wird %d!|Herzlichen Glückwunsch! -IDS_OBJ_BURNS={{FLAM}} Das Objekt brennt. -IDS_OBJ_CONNECT=%s an|%s angeschlossen IDS_OBJ_DEATH1=%s ist tot. IDS_OBJ_DEATH2=%s ist|von uns gegangen. IDS_OBJ_DEATH3=%s|ruht in Frieden. @@ -1084,20 +808,10 @@ IDS_OBJ_DEATH4=%s war einmal... IDS_OBJ_DEATH5=%s|hat's erwischt. IDS_OBJ_DEATH6=%s|ist verstorben. IDS_OBJ_DEATH7=%s|hat uns verlassen. -IDS_OBJ_DISCONNECT=%s von|%s getrennt. IDS_OBJ_EMPTY=%s ist leer. -IDS_OBJ_HOSTILENOENTRANCE=%s verfeindet.|Eingang versperrt! -IDS_OBJ_LINEREMOVAL=%s abgenommen. -IDS_OBJ_NEWLINE=Konstruktion|%s. IDS_OBJ_NOCON=%s kann nicht|gebaut werden! -IDS_OBJ_NOCONACTIV=%s ist noch nicht fertig|und kann noch nicht|aktiviert werden. -IDS_OBJ_NOCONNECT=Verbindung hier|nicht möglich. -IDS_OBJ_NOCONNECTTYPE=%s kann nicht an|%s angeschlossen werden. IDS_OBJ_NODIG=%s kann|nicht graben. -IDS_OBJ_NODOUBLEKIT=%s wird bereits|am anderen Ende verlegt. IDS_OBJ_NOLEVEL=Untergrund|zu uneben! -IDS_OBJ_NOLINECONSTRUCT=%s kann|keine Leitungen verlegen. -IDS_OBJ_NONEWLINE=Neue Leitung hier|nicht möglich. IDS_OBJ_NOOTHER=%s ist im Weg! IDS_OBJ_NOROOM=Nicht genug Platz! IDS_OBJ_PROMOTION=%s wird zum|%s befördert! @@ -1105,15 +819,11 @@ IDS_OBJ_STUCK=%s|hängt fest! IDS_OBJ_UNDEF=Gebäude %s|gibt's hier nicht! IDS_OBJ_UNKNOWN=unbekannt IDS_PLR_ELIMINATED=Spieler %s|eliminiert! -IDS_PLR_HOSTILE=Spieler %s|verfeindet! IDS_PLR_HOSTILITY=%s greift %s an. IDS_PLR_NEWCOMMENT=Ich bin neu hier. IDS_PLR_NEWPLAYER=Neuer Spieler -IDS_PLR_NOBKNOW=Spieler %s|hat keine Baupläne. IDS_PLR_NOBUY=Es gibt nichts zu kaufen. IDS_PLR_NOHOSTILITY=%s greift %s nicht an. -IDS_PLR_NOTAVAIL=%s nicht verfügbar! -IDS_PLR_NOWEALTH=Nicht genug Geld! IDS_PLR_SURRENDERED=Spieler %s|hat aufgegeben. IDS_PRC_CONNECTED=Verbunden. IDS_PRC_COUNTDOWN=Das Spiel beginnt in %d Sekunden! @@ -1138,9 +848,7 @@ IDS_PRC_GAMEOVER=Runde beendet. IDS_PRC_GFXRES=Grafik wird geladen... IDS_PRC_INITDEFS=Objektdefinitionen werden geladen: IDS_PRC_INITEXTRA=Extras werden geladen... -IDS_PRC_INITFONTS=Schriften werden initialisiert... IDS_PRC_INITIALIZE=Laden... -IDS_PRC_INITLOADER=Initialisierung des Loaders... IDS_PRC_JOIN=Spiel beigetreten. IDS_PRC_JOINFAIL=Fehler bei Spielerdatei. IDS_PRC_JOINPLR=Spielerbeitritt: %s @@ -1159,26 +867,22 @@ IDS_PRC_NETPREPARING=Datei %s wird vorbereitet für Netzwerk... IDS_PRC_NEWTEAM=Neues Team IDS_PRC_NOC4S=Keine Szenariodatei angegeben. IDS_PRC_NODEFS=Keine gültigen Definitionen vorhanden. -IDS_PRC_NOEXACTC4X=Zum Starten des gewählten Szenarios wird die Engine der Version %i.%i%i.%i benötigt. IDS_PRC_NOGFXFILE=Fehler bei Grafikdatei %s: %s IDS_PRC_NOMATENUM=Fehler bei Materialanordnung. IDS_PRC_NOMISSIONACCESS=Noch kein Zugang zu dieser Mission. IDS_PRC_NOMUSIC=Musik nicht verfügbar. IDS_PRC_NONETREPLAY=Aufnahmen können nicht im Netzwerkmodus wiedergegeben werden. IDS_PRC_NOREPLPLRCLR=Keine passende Ersatzfarbe für Spieler %s gefunden. Benutze Standardfarbe. -IDS_PRC_NOREQC4X=Dieses Szenario benötigt die Clonk Engine Version %d.%d%d.%d oder höher. +IDS_PRC_NOREQC4X=Dieses Szenario benötigt die Clonk Engine Version %d.%d.%d oder höher. IDS_PRC_NOSND=Fehler bei Sound-Datei. -IDS_PRC_NOSWSCENARIO=Nicht registriert. Kein Shareware-Szenario. IDS_PRC_NOSYSMATS=System-Materialien nicht vorhanden. IDS_PRC_OBJECTSLOADED=%d Objekte platziert. IDS_PRC_PLAYMUSIC=Musik: %s IDS_PRC_PLRELIMINATED=Spieler %s eliminiert. IDS_PRC_PLRFILEINUSE=Spielerdatei wird bereits benutzt. IDS_PRC_PLRSURRENDERED=Spieler %s hat aufgegeben. -IDS_PRC_PRELOADVIDEOS=Lade Videos aus %s voraus... IDS_PRC_RECORDINGTO=Aufnahme nach %s... IDS_PRC_RECREATE=Wiederherstellung: %s -IDS_PRC_REG=Registriert für: %s IDS_PRC_REMOVEPLR=Spieler %s gelöscht. IDS_PRC_RESUME=Spiel wiederaufgenommen. IDS_PRC_RESUMENOCLIENT=Unidentifizierbare Spielerbeitrittsinformationen für Client %d (%d Spieler) ignoriert. @@ -1199,40 +903,9 @@ IDS_PRC_UNDEFINEDOBJECT=Objekt vom Typ %s nicht platziert. IDS_PRC_UNKOWNERROR=Unbekannter Fehler IDS_PRC_UNREGUSER=Nicht registrierter Nutzer IDS_PRC_UPDATEFONT=Schrift %s(%d,%d) wird aktualisiert... -IDS_RANKS_CLONK=Clonk|Fähnrich|Leutnant|Hauptmann|Major|Oberst|Brigadegeneral|Generalmajor|Generalleutnant|General|Feldmarschall -IDS_RANKS_PLAYER=Neuling|Anfänger|Tunichtgut|Geselle|Meister|Haudegen|Held|Junker|Ritter|Baron|Graf|Herzog|König|Kaiser -IDS_SEC_UNREGUSER=Nicht registrierter Nutzer -IDS_SELECT_ANIMALS=Tiere IDS_SELECT_CREW=Mannschaft -IDS_SELECT_ENVIRONMENT=Umweltobjekte -IDS_SELECT_GOALS=Spielziele -IDS_SELECT_HOMEBASE=Heimatbasismaterial -IDS_SELECT_INEARTH=Erdreich -IDS_SELECT_KNOWLEDGE=Baupläne -IDS_SELECT_MATERIAL=Material -IDS_SELECT_NESTS=Nester -IDS_SELECT_PRODUCTION=Heimatbasisproduktion -IDS_SELECT_RULES=Spielregeln -IDS_SELECT_SKIPDEFS=Nicht zu ladende Definitionen -IDS_SELECT_STRUCTURES=Gebäude -IDS_SELECT_VEGETATION=Vegetation -IDS_SELECT_VEHICLES=Fahrzeuge -IDS_STATUS_COPYING=%s kopieren nach %s... -IDS_STATUS_DELETING=%s löschen... -IDS_STATUS_INITEDIT=Bearbeitung wird vorbereitet... -IDS_STATUS_LOADING=%s laden... -IDS_STATUS_LOADINGDEFS=Objektdefinitionen werden geladen... -IDS_STATUS_LOADINGMAP=Landkarte wird geladen... -IDS_STATUS_MOVING=%s verschieben nach %s... -IDS_STATUS_PACK=%s packen... -IDS_STATUS_RELOADING=Arbeitsverzeichnis laden... -IDS_STATUS_RENAMING=%s umbenennen... -IDS_STATUS_UNPACK=%s entpacken... -IDS_STATUS_UPDATESCENARIO=Szenario wird aktualisiert... -IDS_STATUS_UPDATINGITEMS=Bearbeitete Objekte werden aktualisiert... IDS_TEXT_ABORTSTARTCOUNTDOWN=Rundenstart abbrechen. IDS_TEXT_ALERTTHEHOSTIFTHEHOSTISAW=Den Host aufwecken (wenn er nicht da ist). -IDS_TEXT_CANTBUILD=%s kann nicht bauen. IDS_TEXT_CHANGETHECOLOROFTHESPECIF=Farbe des angegebenen Spielers ändern. IDS_TEXT_CHANGEYOUROWNPLAYERCOLOR=Eigene Farbe ändern. IDS_TEXT_COMMANDSAVAILABLEDURINGLO=Verfügbare Befehle in der Lobby: @@ -1256,16 +929,15 @@ IDS_TEXT_JOININCONSOLEMODENOTALLOW=Beitritt im Konsolenmodus nicht erlaubt! IDS_TEXT_KICKCERTAINCLIENTSFROMTHE=Bestimmte Clients aus dem Spiel entfernen. IDS_TEXT_KICKTHESPECIFIEDCLIENT=Den entsprechenden Client entfernen. IDS_TEXT_LEAGUEWAITINGFOREVALUATIO=Warte auf Liga-Auswertung... -IDS_TEXT_LOBBYICON=Lobby-Icon IDS_TEXT_LOCATION=Suchen in: IDS_TEXT_MYDOCUMENTS=Eigene Dateien IDS_TEXT_MYPICTURES=Eigene Bilder IDS_TEXT_PAUSETHEGAME=anhalten IDS_TEXT_PERFORMANACTIONINYOURNAME=Aktion im eigenen Namen ausführen. IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO=Geräusch aus der globalen Sound-Gruppe abspielen. -IDS_TEXT_PLAYERIMAGE=Spielerbild IDS_TEXT_PREVENTDEBUGMODEINTHISROU=Debug-Modus in dieser Runde unterbinden. IDS_TEXT_PROGRAMDIRECTORY=Programmverzeichnis +IDS_TEXT_SAFEZOOMEDFULLSCREENSHOT=Screenshot der gesammten Spielfläche mit Vergrößerung anfertigen. IDS_TEXT_SCORE=Punkte IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA=Maximale Spielerzahl für diese Runde festlegen. IDS_TEXT_SETANEWNETWORKCOMMENT=Neuen Netzwerk-Kommentar setzen. @@ -1280,36 +952,11 @@ IDS_TEXT_VIEW=Sicht IDS_TEXT_WARNINGIFTHEGAMEISCANCELL=Hinweis: wenn das Spiel abgebrochen wird, werden keine Ligapunkte vergeben. IDS_TEXT_WARNINGNOLEAGUEPOINTSWILL=Hinweis: der Spieler gilt dadurch nicht als besiegt und seine Gegner erhalten für einen Sieg weniger Ligapunkte. IDS_TEXT_YOUCANONLYSTARTONEVOTINGE=Voting-Timeout: eine neue Vote-Anfrage ist nur alle zwei Minuten möglich. -IDS_TYPE_ANIMATION=Animation -IDS_TYPE_BACKUP=Backup -IDS_TYPE_BINARY=Binärelement -IDS_TYPE_BITMAP=Grafikelement -IDS_TYPE_DEFFOLDER=Objektordner -IDS_TYPE_DEFINITION=Objekt IDS_TYPE_DIRECTORY=Verzeichnis -IDS_TYPE_ENGINE=Engine -IDS_TYPE_EXECUTABLE=ausführbares Programm IDS_TYPE_FOLDER=Rundenordner -IDS_TYPE_GROUP=Gruppendatei -IDS_TYPE_HELP=Hilfedatei -IDS_TYPE_HTML=Hypertext -IDS_TYPE_KEYFILE=Registrierungsschlüssel -IDS_TYPE_LINK=Internetlink -IDS_TYPE_LOG=Log -IDS_TYPE_MATERIAL=Material -IDS_TYPE_MUSIC=Musikstück -IDS_TYPE_NONE=Unbekanntes Objekt -IDS_TYPE_OBJECTINFO=Mannschaftsmitglied -IDS_TYPE_PLAYER=Spieler IDS_TYPE_PORTRAIT=Portrait -IDS_TYPE_RICHTEXT=Beschreibungstext IDS_TYPE_SCENARIO=Szenario -IDS_TYPE_SCRIPT=Script -IDS_TYPE_SOUND=Sound -IDS_TYPE_TEXT=Text IDS_TYPE_UPDATE=Update -IDS_TYPE_VIDEO=Video -IDS_TYPE_ZIP=Zip-Archiv IDS_VOTE_CANCELTHEROUND=die Runde abbrechen IDS_VOTE_DOESNOTWANTTO=%s will nicht %s IDS_VOTE_KICKCLIENT=Client %s entfernen @@ -1322,7 +969,7 @@ IDS_NET_CLIENT_IGNORE_DESC=%s ignorieren. Du kannst Nachrichten von diesem Clien IDS_NET_CLIENT_IGNORE=Ignorieren IDS_NET_CLIENT_UNIGNORE=Nicht mehr ignorieren IDS_MSG_HIGHRESLANDSCAPE=Hochauflösende Landschaft -IDS_MSG_HIGHRESLANDSCAPE_DESC=Experimenteller Effekt für hochauflösende Texturen auf der Landschaft. +IDS_MSG_HIGHRESLANDSCAPE_DESC=Effekt für hochauflösende Texturen auf der Landschaft. IDS_ADDON_INSTALLSUCCESS=Installation von '%s' erfolgreich. IDS_ADDON_INSTALLFAILURE=Installation von '%s' fehlgeschlagen. IDS_ADDON_INSTALLTITLE=Addon-Installation diff --git a/planet/System.ocg/LanguageUS.txt b/planet/System.ocg/LanguageUS.txt index 0b1d6825e..d7304d04b 100644 --- a/planet/System.ocg/LanguageUS.txt +++ b/planet/System.ocg/LanguageUS.txt @@ -1,50 +1,33 @@ IDS_LANG_NAME=English -IDS_LANG_INFO=Original language pack by RedWolf Design. +IDS_LANG_INFO=Original language pack. IDS_LANG_FALLBACK= -IDS_BTN_ACCEPT=Accept IDS_BTN_ACTIVATE=Activate IDS_BTN_BACK=Back -IDS_BTN_BROWSE=Browse... -IDS_BTN_CANCEL=Cancel IDS_BTN_CHAT=&Chat IDS_BTN_CHECKFORUPDATES=Check for &updates IDS_BTN_CONNECT=Connect IDS_BTN_CONTINUEGAME=&Continue this round -IDS_BTN_NEXTSCENARIO=&Next scenario -IDS_DESC_NEXTSCENARIO=Continue with the next scenario. IDS_BTN_DEACTIVATE=Deactivate IDS_BTN_DELETE=Delete -IDS_BTN_DL=Download -IDS_BTN_DUPLICATE=Duplicate IDS_BTN_ENDROUND=&End game -IDS_BTN_EXPLODE=Explode -IDS_BTN_EXTENDED=Extended -> IDS_BTN_GAMES=&Games -IDS_BTN_JOIN=Join IDS_BTN_LOCALGAME=&Start Game -IDS_BTN_MESSAGE=Message IDS_BTN_NETWORKGAME=Start &Network Game IDS_BTN_NEW=New IDS_BTN_NEXTMISSION=&Next mission IDS_BTN_NO=No IDS_BTN_OBJECTS=Objects -IDS_BTN_OK=OK IDS_BTN_OPEN=Open -IDS_BTN_PACK=Pack -IDS_BTN_PRESETS=Presets IDS_BTN_PROPERTIES=Properties -IDS_BTN_REGISTERNOW=&Register now! IDS_BTN_RELOAD=Reloa&d IDS_BTN_RENAME=Rename +IDS_BTN_RESET=Reset IDS_BTN_RESETCONFIG=Reset configuration IDS_BTN_RESETKEYBOARD=Reset all IDS_BTN_RESTART=Restart IDS_BTN_RETRY=Retry -IDS_BTN_SIMPLE=<- Basic IDS_BTN_START=Start IDS_BTN_STARTGAME=&Start -IDS_BTN_UNPACK=Unpack -IDS_BTN_USEACTIVATED=Use current selection as preset IDS_BTN_VOLUME=Volume control IDS_BTN_YES=Yes IDS_CHAT_NOTCONNECTED=not connected @@ -58,10 +41,7 @@ IDS_CNS_EXACTTOSTATIC=When switching from exact to dynamic mode\nall changes mad IDS_CNS_FILLNOHALT=The fill tool cannot be used in halt mode. IDS_CNS_GAMECLOSED=Game cleared. IDS_CNS_GAMESAVED=Game saved. -IDS_CNS_INFO=Info -IDS_CNS_LOCALS=Local variables: IDS_CNS_MULTIPLEOBJECTS=%i selected objects. -IDS_CNS_NAMES=Names IDS_CNS_NEWPLRVIEWPORT=New for %s IDS_CNS_NOCHILDSAVE=%s is located in a group folder.\nScenarios cannot be saved in closed group folders. IDS_CNS_NOFULLSCREENPLRS=Fullscreen mode requires at least one participating player. @@ -73,27 +53,21 @@ IDS_CNS_OWNER=Owner: %s IDS_CNS_PLRQUIT=Remove %s IDS_CNS_PLRQUITNET=Remove %s (%s) IDS_CNS_PROPERTIES=Properties -IDS_CNS_REGONLY=Console mode is available in the registered version only. IDS_CNS_SAVEASERROR=Error while saving the scenario to %s. IDS_CNS_SAVERROR=Error while saving the scenario. IDS_CNS_SCENARIOSAVED=Scenario saved. IDS_CNS_SCRIPT=Script IDS_CNS_SCRIPTCREATEDOBJECTS=This scenario's script has created objects on initialization. -IDS_CNS_TITLE=Title -IDS_CNS_TOOLS=Tools IDS_CNS_TYPE=Type: %s (%s) IDS_CNS_VIEWPORT=Viewport IDS_CNS_WARNDOUBLE=In order to avoid double creation, the script's 'Initialize' function should be modified. IDS_COMM_ACQUIRE=Acquisition IDS_COMM_ACTIVATE=Activation IDS_COMM_ATTACK=Attack -IDS_COMM_BUILD=Build IDS_COMM_BUY=Buy IDS_COMM_CALL=Object call -IDS_COMM_CONSTRUCT=Construction IDS_COMM_DIG=Digging IDS_COMM_DROP=Drop -IDS_COMM_ENERGY=Power supply IDS_COMM_ENTER=Enter IDS_COMM_EXIT=Exit IDS_COMM_FOLLOW=Follow @@ -112,244 +86,93 @@ IDS_COMM_THROW=Throw IDS_COMM_TRANSFER=Movement IDS_COMM_UNGRAB=Let go IDS_COMM_WAIT=Wait -IDS_CON_ACTIVATEFROM=Activate object in %s -IDS_CON_ATTACK=Attack %s. IDS_CON_BUILD=Build %s. -IDS_CON_BUILDINFO=Construction material IDS_CON_BUILDMATNEED=%s|needs IDS_CON_BUILDMATNONE=%s needs|no more material. -IDS_CON_BUY=Buy -IDS_CON_COLLECT=Collect %s. -IDS_CON_CONTENTS=Contents -IDS_CON_DIGOUT=Dig out %s. -IDS_CON_DOUBLECLICK=(Double click) -IDS_CON_ENTER=Enter %s. -IDS_CON_EXIT=Exit building IDS_CON_FAILURE=%s failed! IDS_CON_FAILUREOF=%s of %s failed! -IDS_CON_GET=Take object from %s. -IDS_CON_GRAB=Grab %s. IDS_CON_HELP=Help IDS_CON_HOME=Back to base -IDS_CON_INFO=Info -IDS_CON_ITEMS=items -IDS_CON_JUMP=Jump. -IDS_CON_NAME=%s -IDS_CON_PLAYERMENU=Player menu -IDS_CON_PUT2=Drop -IDS_CON_PUT=Drop %s in %s -IDS_CON_SELECT=%s -IDS_CON_SELL=Sell -IDS_CON_UNGRAB=Let go of %s. -IDS_CON_VEHICLEPUT=Push %s into %s. -IDS_CON_VEHICLES=Vehicles -IDS_CTL_ACCESS=Access: IDS_CTL_ACTIVE=Active -IDS_CTL_ALL=All -IDS_CTL_AMPLITUDE=Amplitude: -IDS_CTL_ANIMALS=Animals IDS_CTL_ANTIALIASING=Antialiasing: IDS_CTL_AUTHOR=Author: %s -IDS_CTL_AUTOEDITSCAN=Background update edited objects IDS_CTL_AUTOMATICUPDATES=Enable automatic updates IDS_CTL_BITDEPTH=Color Depth -IDS_CTL_BITMAP=Bitmap (BMP) -IDS_CTL_BITMAP_PNG=Bitmap (PNG) -IDS_CTL_BUILDINGS=Startup buildings: IDS_CTL_CHANNEL=Channel: IDS_CTL_CHAT=Cha&t: -IDS_CTL_CLIMATE2=hot -IDS_CTL_CLIMATE3=cold -IDS_CTL_CLIMATE=Climate IDS_CTL_CLONKSKIN=Clonk style: IDS_CTL_COLOR=Color IDS_CTL_COMMENT=Comment IDS_CTL_CONTROL=Control IDS_CTL_CONTROLRATE=Control rate IDS_CTL_CONTROLRATE_DESC=Specifies the time interval in frames, at which control data is being exchanged via network -IDS_CTL_CREATEDMAP=Generated map IDS_CTL_CREW=Crew: -IDS_CTL_CUID=User-Id: IDS_CTL_DEBUGMODE=Debug mode -IDS_CTL_DEFBYCHOICE=local and activated object definitions -IDS_CTL_DESCRIPTION=Description -IDS_CTL_DETAILS=Details -IDS_CTL_DIG=Dig IDS_CTL_DL_PROGRESS=Progress: IDS_CTL_DL_TITLE=Download -IDS_CTL_DOWNSTOP=Down / Stop -IDS_CTL_DYNAMICMAP=Dynamic map -IDS_CTL_EARTHQUAKES2=none -IDS_CTL_EARTHQUAKES3=plenty -IDS_CTL_EARTHQUAKES=Earthquakes -IDS_CTL_ENABLEROUNDOPTIONS=Allow scenario properties -IDS_CTL_ENGINE=Engine IDS_CTL_ENTERCOMMENT=Please enter the desired comment for this game: -IDS_CTL_ENVIRONMENTOBJECTS=Environment objects -IDS_CTL_EXACTMAP=Exact map IDS_CTL_FONT=Font IDS_CTL_FRONTEND=Frontend -IDS_CTL_FULLNAME=Player name: IDS_CTL_GAME=Game IDS_CTL_GAMEFUNCTIONS=Game Functions IDS_CTL_GAMEPADFORMENU=Use gamepad for menu control. IDS_CTL_GAMESPEEDUP=Increase game speed IDS_CTL_GAMESPEEDDOWN=Decrease game speed IDS_CTL_GFXENGINE=Renderer -IDS_CTL_GOALS=Goals: -IDS_CTL_GRAVITY2=weak -IDS_CTL_GRAVITY3=strong -IDS_CTL_GRAVITY=Gravity -IDS_CTL_HEIGHT=Height: -IDS_CTL_HOMEBASE=Objects available at home base: -IDS_CTL_ICON=Icon: -IDS_CTL_IMPORTIMAGEAS=Import image as: -IDS_CTL_INEARTHAMOUNTS=Objects in earth amount -IDS_CTL_INEARTHTYPES=Objects in earth types IDS_CTL_INETSERVER=&Internet IDS_CTL_IRCCHAT=IRC-Chat -IDS_CTL_KEYFILE=Registration key: -IDS_CTL_KNOWLEDGE=Constructable objects: IDS_CTL_LANGUAGE=Language IDS_CTL_LEAGUE_ACCOUNT=League user name: IDS_CTL_LEAGUE_CHK_PLRPW=Specify league password IDS_CTL_LEAGUE_PLRPW2=League password (repeat): IDS_CTL_LEAGUE_PLRPW=League password: -IDS_CTL_LEFT=Left -IDS_CTL_LOCALMATS= with local material definitions -IDS_CTL_LOCALONLY=local objects definitions only -IDS_CTL_LOCATION=in %s IDS_CTL_LOST=lost IDS_CTL_LOUD=loud -IDS_CTL_MANUALCLIP=Manual clipping -IDS_CTL_MAPPLAYEREXTEND=Width according to player number IDS_CTL_MATERIAL=Material -IDS_CTL_MAXPLAYERS=Max. players: -IDS_CTL_MENUSYSTEM=Frontend IDS_CTL_MESSAGEBOARDBACK=Scroll messages back IDS_CTL_MESSAGEBOARDFORWARD=Scroll messages forward -IDS_CTL_METEORITES2=none -IDS_CTL_METEORITES3=plenty -IDS_CTL_METEORITES=Meteorites IDS_CTL_MMTIMER=Disable multimedia timer IDS_CTL_MUSIC=Music IDS_CTL_NAME2=Name: IDS_CTL_NAME=Name -IDS_CTL_NESTS=Nests IDS_CTL_NICK=Nickname: -IDS_CTL_NOADDBLT=Disable additive blits -IDS_CTL_NOALPHAADD=Disable additive alpha -IDS_CTL_NOCLRFADE=Disable color fades IDS_CTL_NOGOAL=No game goal IDS_CTL_NOLANGINFO=Language pack not available. IDS_CTL_NONE=none -IDS_CTL_NORMALCREW_DESC=Trained Clonks: Clonks have different strength according to their rank. IDS_CTL_OFF=off IDS_CTL_ON=on -IDS_CTL_OPENBOTTOM=Bottom open -IDS_CTL_OPENDIRECTORY=Open directory -IDS_CTL_OPENTOP=Top open IDS_CTL_PASSWORDOPTIONAL=Password (optional): -IDS_CTL_PERIOD=Period: -IDS_CTL_PHASE=Phase: IDS_CTL_PICTURE=Picture: IDS_CTL_PLAYER1=Player 1 IDS_CTL_PLAYER2=Player 2 IDS_CTL_PLAYER3=Player 3 IDS_CTL_PLAYER4=Player 4 IDS_CTL_PLAYER=Player -IDS_CTL_PLAYERMENU=Player menu -IDS_CTL_PLAYERS1=1 player -IDS_CTL_PLAYERS2=2 players -IDS_CTL_PLAYERS3=3 players -IDS_CTL_PLAYERS4=4 players -IDS_CTL_PLEASEWAIT=Please wait... -IDS_CTL_POINTFILTERING=Disable interpolation -IDS_CTL_PREVIEWFOR=Preview for -IDS_CTL_PRODUCTION=Resupply of objects available at home base: -IDS_CTL_RAIN2=none -IDS_CTL_RAIN3=plenty -IDS_CTL_RAIN=Rain -IDS_CTL_RANDOM=Random: IDS_CTL_REALNAME=Real name: IDS_CTL_RECORD=&Record -IDS_CTL_REGISTERED=Thank you for your registration! -IDS_CTL_REGISTEREDONLY=Available in the registered version only. IDS_CTL_RESOLUTION=Resolution -IDS_CTL_RICHTEXT=Description -IDS_CTL_RIGHT=Right -IDS_CTL_RULES=Rules: -IDS_CTL_SCENARIOUSES=Scenario uses IDS_CTL_SCOREBOARD=Scoreboard (if available) IDS_CTL_SCREENSHOT=Screenshot IDS_CTL_SCREENSHOTEX=Screenshot (full game area) IDS_CTL_SCRIPT=Script IDS_CTL_SCRIPTPLAYERS=Script players -IDS_CTL_SEASON2=spring -IDS_CTL_SEASON3=winter -IDS_CTL_SEASON=Season -IDS_CTL_SELECTLEFT=Select left -IDS_CTL_SELECTRIGHT=Select right -IDS_CTL_SELECTTOGGLE=Select toggle -IDS_CTL_SENDDEFRELOAD=Send runtime object updates to engine IDS_CTL_SENDMESSAGE=Send message IDS_CTL_SHOW=Display IDS_CTL_SHOWALLRESOLUTIONS=Show all resolutions -IDS_CTL_SHOWLAYERS=Layers -IDS_CTL_SHOWSCREEN=Screen size IDS_CTL_SILENT=quiet -IDS_CTL_SKIPDEFS=Definitions *not* to load: IDS_CTL_SMOKE=Effects Level IDS_CTL_SMOKEHI=High IDS_CTL_SMOKELOW=Low IDS_CTL_SOUND=Sound IDS_CTL_SOUNDFX=Sound effects -IDS_CTL_SPECIAL1=Special 1 -IDS_CTL_SPECIAL2=Special 2 -IDS_CTL_SPECIFIEDDEFS=local and preset object definitions: -IDS_CTL_STATICMAP=Static map -IDS_CTL_SYMBOLS=Symbols IDS_CTL_TEXT=Text IDS_CTL_TEXTURE=Texture -IDS_CTL_THROW=Throw -IDS_CTL_THUNDERSTORMS2=none -IDS_CTL_THUNDERSTORMS3=plenty -IDS_CTL_THUNDERSTORMS=Thunderstorms -IDS_CTL_TIMEADVANCE2=slow -IDS_CTL_TIMEADVANCE3=fast -IDS_CTL_TIMEADVANCE=Time advance IDS_CTL_TOTALPLAYINGTIME=Total playing time: %02d:%02d:%02d IDS_CTL_TROUBLE=Troubleshooting -IDS_CTL_UNREGISTERED=NOT REGISTERED IDS_CTL_UPDATE=&Update -IDS_CTL_UPJUMP=Up / Jump IDS_CTL_USEOTHERSERVER=Use alternate internet server -IDS_CTL_USESHELL=Use Windows Shell to edit files -IDS_CTL_VALUE=Value -IDS_CTL_VALUESFOR=Values for -IDS_CTL_VEGETATIONAMOUNTS=Vegetation amount -IDS_CTL_VEGETATIONTYPES=Vegetation types -IDS_CTL_VEHICLES=Startup vehicles: -IDS_CTL_VERBOSEOBJECTS=Show object definition overload -IDS_CTL_VIEW=View: -IDS_CTL_VOLCANOES2=none -IDS_CTL_VOLCANOES3=plenty -IDS_CTL_VOLCANOES=Volcanoes -IDS_CTL_VOLUME=Volume -IDS_CTL_WATERLEVEL=Water level: -IDS_CTL_WEALTH=Wealth: -IDS_CTL_WEBCODE=WebCode: -IDS_CTL_WIDTH=Width: -IDS_CTL_WIND2=left -IDS_CTL_WIND3=right -IDS_CTL_WIND=Wind IDS_CTL_WON=won -IDS_CTL_ZIP=Zip -IDS_CTL_ZOOM=Zoom factor: IDS_DESC_AUTOMATICUPDATES=With this option enabled, the program will automatically check for updates once a day at program start. -IDS_DESC_BREATH=Breath: -IDS_DESC_CHANGESTHEIMAGEYOUSEEINTH2=Changes the image you see in the multiplayer lobby and in the game evaluation dialog. -IDS_DESC_CHANGESTHEIMAGEYOUSEEINTH=Changes the image you see in the player selection dialog. IDS_DESC_CHANGESTHEWAYCONTROLDATAI=Changes the way control data is exchanged between network clients. IDS_DESC_CHECKONLINEFORNEWVERSIONS=Check online for new versions. IDS_DESC_CLIENTS=Clients: @@ -362,11 +185,8 @@ IDS_DESC_DATE=Game saved %i.%i.%i %02d:%02d. IDS_DESC_DATENET=Network game from %i.%i.%i %02d:%02d. IDS_DESC_DATEREC=Recording from %i.%i.%i %02d:%02d. IDS_DESC_DEFSPECS=Object definitions: -IDS_DESC_DIG=Dig: IDS_DESC_DURATION=Playing time: %02d:%02d:%02d. IDS_DESC_ENDTHEROUND=End the round. -IDS_DESC_ENERGY=Energy: -IDS_DESC_ENGINE=Engine modules are used to run the game.\n\nWhen selecting a scenario, the red check mark will indicate which engine is going to be used to run that scenario.\n\nBy activating or deactivating an engine (check box will turn green) you can determine which engine will be used if there are multiple, equally well suited engines present. IDS_DESC_EXPECTING=Awaiting participants. IDS_DESC_FONTSIZE=Select font size. When you change the screen resolution, the font size will be automatically adjusted. IDS_DESC_GAMEMUSIC=Enable background music in the game. @@ -374,11 +194,8 @@ IDS_DESC_GAMEPADFORMENU=If enabled, you can control the startup menu system with IDS_DESC_GAMEPAUSED=Game is paused IDS_DESC_GAMERUNNING=Game is running IDS_DESC_GAMESOUND=Enable sound effects in the game. -IDS_DESC_GOALFULFILLED=Goal %s fulfilled: %s -IDS_DESC_GOALNOTFULFILLED=Goal %s not fulfilled: %s -IDS_DESC_GOTOTHEONLINEREGISTRATION=Go to the online registration form. -IDS_DESC_HANGLE=Hangle: -IDS_DESC_JUMP=Jump: +IDS_DESC_GOALFULFILLED=Goal %s fulfilled +IDS_DESC_GOALNOTFULFILLED=Goal %s not fulfilled IDS_DESC_LASTGAME=\nLast round: %s\nDate: %s\nDuration: %s\nScore: %i\n IDS_DESC_LEAGUECHECKPASSWORD=Enable to enter your own password. If you do not enter a password of your own, the personal WebCode will be used which is already stored on this system. IDS_DESC_LEAGUESCOREANDPROJECTEDGA=League score and projected gain if this player's team wins the round. @@ -394,27 +211,23 @@ IDS_DESC_PLAYER=Score: %i\nRounds: %i (%i won %i lost)\nPlaying time: %s\nCommen IDS_DESC_PLAYERSCONTROLLEDBYCOMPUT=Players controlled by computer. IDS_DESC_PLRS=Players: IDS_DESC_PROMO=Promotion to %s\nat: %i -IDS_DESC_PUSH=Push: IDS_DESC_RESETCONFIG=Reset all configuration values to factory default. IDS_DESC_RESOURCE=The files shown here are used during this round. Resources which were dynamically loaded via the network can be permanently stored on this computer for later use by clicking the save symbol. -IDS_DESC_SCALE=Scale: IDS_DESC_SELECTAPICTUREANDORLOBBYI=Select a picture and/or lobby icon for your player. IDS_DESC_SELECTFONT=Select text font. Some fonts may not contain all characters necessary to display some languages. In this case, select a different font. IDS_DESC_SHOWALLRESOLUTIONS=Allow selection of very large and very small resolutions. IDS_DESC_SHOWSAVAILABLENETWORKGAME=Shows running network games. -IDS_DESC_SWIM=Swim: IDS_DESC_TEAM=Team %s -IDS_DESC_THROW=Throw: IDS_DESC_UNASSOCIATEDSAVEGAMEPLAYE=Unassociated savegame players. IDS_DESC_UNKNOWNGAMESTATE=Game is in an unknown state IDS_DESC_VERSION=Engine version: %s IDS_DESC_VOLUMEMUSIC=Volume of background music. IDS_DESC_VOLUMESOUND=Volume of sound effects. IDS_DESC_WAITFORHOST=Waiting for host connection -IDS_DESC_WALK=Run: -IDS_DLGTIP_ABOUT=Display program info and credits. +IDS_DLGTIP_ABOUT=Display credits and program info. IDS_DLGTIP_BACKMAIN=Back to main menu. IDS_DLGTIP_CANCEL=Cancel. +IDS_DLGTIP_CHANGECTRL=Choose a control set to view and modify it IDS_DLGTIP_CHAT=Enter chat messages here and send them with enter. IDS_DLGTIP_CHATWIN=Messages IDS_DLGTIP_CLASSIC=Clonks run until they are stopped using the 'stop' key. @@ -432,9 +245,7 @@ IDS_DLGTIP_OPTIONS=Change program options. IDS_DLGTIP_PASTE=Inserts the contents of the clipboard. IDS_DLGTIP_PING=Ping IDS_DLGTIP_PLAYERCOLORS=Selects a standard color. -IDS_DLGTIP_PLAYERCOLORSTGB=Composes a custom player color from red, green, and blue. IDS_DLGTIP_PLAYERCONTROL=Selects a control method. -IDS_DLGTIP_PLAYERCONTROLMOUSE=Activates mouse control in addition to the selected control method. IDS_DLGTIP_PLAYERCREW=Display the permanent crew of the selected player. IDS_DLGTIP_PLAYERCREWSKIN=Selects the appearance of the player's clonks. IDS_DLGTIP_PLAYERDELETE=Delete the selected player file. @@ -453,46 +264,37 @@ IDS_DLGTIP_STARTINTERNETGAME=Internet game: other players can see this round on IDS_DLGTIP_STARTLEAGUEGAME=League game: this round will be evaluated in the league. IDS_DLGTIP_UPDATE=Update available: click here to download and install the new version of the game. IDS_DLG_ABORT=Abort -IDS_DLG_ABOUT=&About +IDS_DLG_ABOUT=&Credits IDS_DLG_CANCEL=Cancel IDS_DLG_CHAT=Chat IDS_DLG_CLASSIC=Classic IDS_DLG_CLEAR=Clear IDS_DLG_CLOSE=&Close +IDS_DLG_CONTROLS=Controls IDS_DLG_COPY=Copy IDS_DLG_CUT=Cut IDS_DLG_DEFINITION=Object Definition IDS_DLG_DEFINITIONS=Object Definitions -IDS_DLG_DEVELOPER=Developer IDS_DLG_DYNAMIC=Dynamic landscape -IDS_DLG_EDITOR=Extern -IDS_DLG_EDITORSWITCH=Press F6 to switch to the game. -IDS_DLG_ENVIRONMENT=Environment IDS_DLG_ERROR=Error IDS_DLG_EXACT=Exact landscape IDS_DLG_EXIT=E&xit -IDS_DLG_EXPLORER=Editor IDS_DLG_GAME=Game IDS_DLG_GAMEGO=&Start IDS_DLG_GAMEPAD=Gamepad IDS_DLG_GRAPHICS=Graphics -IDS_DLG_IDSELECT=Object selection IDS_DLG_INVALIDENTRY=Invalid Entry IDS_DLG_JUMPANDRUN=Jump'n'Run -IDS_DLG_KEYBOARD=Keyboard -IDS_DLG_LANDSCAPE=Landscape IDS_DLG_LEAGUESIGNUP=League Login IDS_DLG_LEAGUESIGNUPCONFIRM=Confirm League Login IDS_DLG_LEAGUESIGNUPFAILED=League Login Failed IDS_DLG_LEAGUESIGNUPON=League Login on %s -IDS_DLG_LICENSE=Developer Mode License Agreement IDS_DLG_LOBBY=Lobby IDS_DLG_LOG=Error Log IDS_DLG_MISSIONACCESS=Mission Access IDS_DLG_MOVEMENT=Movement IDS_DLG_NETSTART=Start Network Game IDS_DLG_NETWORK=Network -IDS_DLG_NEW=New IDS_DLG_NO=&No IDS_DLG_NOPLAYERSSELECTED=none selected IDS_DLG_OK=&OK @@ -503,13 +305,10 @@ IDS_DLG_PLAYER2=Player Properties IDS_DLG_PLAYERCOLORSELECTION=Choose a color IDS_DLG_PLAYERS=&Players IDS_DLG_PLAYERSELECTION=&Player Selection -IDS_DLG_PLAYERSTART=Equipment IDS_DLG_PROGRAM=Program IDS_DLG_PROPERTIES=Properties -IDS_DLG_REGISTRATION=Registration IDS_DLG_RESOURCES=Resources IDS_DLG_SCENARIO=Scenario -IDS_DLG_SCENARIOPROPERTIES=Scenario Properties IDS_DLG_SCENARIOS=Scenarios IDS_DLG_SCENARIOTITLE=Loaded scenario IDS_DLG_SELALL=Select all @@ -519,22 +318,9 @@ IDS_DLG_STATIC=Static landscape IDS_DLG_TOOLS=Landscape tools IDS_DLG_VERSION=Version %s IDS_DLG_VOTING=Voting -IDS_DLG_WEATHER=Weather IDS_DLG_YES=&Yes -IDS_DL_ACTIVEDOWNLOADS=Active downloads: IDS_DL_CANCEL=Cancel download -IDS_DL_CAPTION=Downloads -IDS_DL_CLOSE=Close -IDS_DL_FILENAME=Filename -IDS_DL_FILEPROGRESS=Progress -IDS_DL_FILESIZE=Size -IDS_DL_STATUSCANCELLED=cancelled IDS_DL_STATUSCONNECTING=connecting... -IDS_DL_STATUSDONE=done -IDS_DL_STATUSERROR=failed -IDS_DL_STATUSWAITING=waiting... -IDS_DL_TARGET=Target -IDS_EDITOR_WELCOME=Use at your own risk. IDS_ERR_CLONKCOLLISION=A Clonk with the file name "%s" exists already. IDS_ERR_CONFIG=Configuration error IDS_ERR_CONFREAD=Could not read configuration: %s @@ -549,7 +335,6 @@ IDS_ERR_ERRORWHILECREATINGJOINDAT=Error while creating join data IDS_ERR_FAILURE=...failed. IDS_ERR_FATAL=FATAL ERROR: %s IDS_ERR_FILEEXISTS=A file with the name "%s" exists already. -IDS_ERR_FONTDEFS=Error loading font definitions IDS_ERR_GAMELEFTVIAPLAYERMENU=Game left via player menu. IDS_ERR_GBACK=Landscape error. IDS_ERR_GFX_REGISTERMAIN=Could not register main graphic groups @@ -557,18 +342,15 @@ IDS_ERR_INITFONTS=Error initializing fonts IDS_ERR_INSUFFICIENTPARAMETERS=/%s: insufficient parameters IDS_ERR_INVALIDCHANNELNAME=Invalid channel name. IDS_ERR_CHANNELNOTALLOWED=Can only join channels with "clonk" in it's name and a # in front. -IDS_ERR_INVALIDID= Definition %s not loaded: Invalid ID IDS_ERR_INVALIDNICKNAME2=/%s: invalid nick name IDS_ERR_INVALIDNICKNAME=Invalid nickname. IDS_ERR_INVALIDPASSWORDMAX31CHARA=Invalid password. Maximum 31 characters. No spaces allowed. -IDS_ERR_INVALIDREPLYFROMSERVER=Invalid reply from server. IDS_ERR_INVALIDSYSGRP=System.c4g not found or invalid. IDS_ERR_IRCCONNECTIONFAILED=IRC connection failed: %s IDS_ERR_JOINPLR_NOFILE=Cannot join player %s: File not found! IDS_ERR_JOINPLR_NOLOCALCLIENT=Cannot join player %s to client %d: Client not local! IDS_ERR_JOINQUEUEPLRS=C4PlayerInfoList::LocalJoinUnjoinedPlayersInQueue failed to join player %s! IDS_ERR_LEAGUEERRORREPORTINGUNEXP=League: Error reporting unexpected disconnect: %s -IDS_ERR_LOAD_PLRINFO=Error restoring savegame information for player %s! IDS_ERR_LOAD_RECR_NOEXTRACT=Error recreating player %s from %s: Extract failed! IDS_ERR_LOAD_RECR_NOFILE=Error recreating player %s: No file! IDS_ERR_LOAD_RECR_NOFILEFROMNET=C4PlayerInfoList::RecreatePlayers couldn't join player %s: No file. @@ -595,21 +377,14 @@ IDS_ERR_REPLAYREAD=Could not read playback data! IDS_ERR_SAVE_CORE=SaveGame: Error saving core IDS_ERR_SAVE_DESC=SaveGame: Error saving desc IDS_ERR_SAVE_GAMETITLE=SaveGame: Error saving game title -IDS_ERR_SAVE_INFO=SaveGame: Error saving info IDS_ERR_SAVE_LANDSCAPE=SaveGame: Error saving landscape -IDS_ERR_SAVE_OBJECTS=SaveGame: Error saving objects IDS_ERR_SAVE_PLAYERS=SaveGame: Error saving players IDS_ERR_SAVE_RESTOREPLAYERINFOS=SaveGame: Error saving restore player infos IDS_ERR_SAVE_RUNTIMEDATA=SaveGame: Error saving game data IDS_ERR_SAVE_SCENSECTIONS=SaveGame: Error saving scenario sections -IDS_ERR_SAVE_SCRIPT=SaveGame: Error saving script -IDS_ERR_SAVE_SCRIPTSTRINGS=SaveGame: Error saving strings IDS_ERR_SAVE_TARGETGRP=SaveGame: Unable to create target group at %s. -IDS_ERR_SAVE_TITLE=SaveGame: Error saving title IDS_ERR_SCENSECTION=Error loading scenario section "%s" -IDS_ERR_STRINGS=String table error IDS_ERR_SWITCHRES=Error switching resolution: %s -IDS_ERR_TIMER=System timer error. IDS_ERR_TITLE=Error IDS_ERR_UNKNOWNCMD=Unknown command: "%s" - type /help to get a list of valid commands IDS_ERR_HELPCMD=Basic commands in the IRC-chat:|/join [channel] - Enter a new chat room|/part - Leave this chat room|/notice [user] [message] - Send a message to the user|/query [user] - Open a new chat window to chat for chatting with the user|/msg [user] [message] - The same as /query, only that the first message is already sent|/nick [new nick name] - Choose a new nick name|/quit - Exit the chat|/raw - Send a raw command @@ -617,29 +392,15 @@ IDS_ERR_USERCANCEL=User abort IDS_ERR_WRITENEWTITLE=Error writing new title for file "%s": %s IDS_ERR_YOUHAVEBEENREMOVEDBYVOTIN=You have been removed by vote. (%s) IDS_ERR_YOUSURRENDEREDTHELEAGUEGA=You have surrendered the league game. -IDS_FAIL_COPY=Copy failure. +IDS_ERR_LOAD_PLAYER=Error loading player "%s" IDS_FAIL_DELETE=Delete failure. -IDS_FAIL_EDIT=Edit failure. -IDS_FAIL_EXTRACT=Extract failure. -IDS_FAIL_LOAD=Load failure. IDS_FAIL_MODIFY=File modification failure. -IDS_FAIL_MOVE=Move failure. -IDS_FAIL_PACK=Pack failure. -IDS_FAIL_RECURSIVE=An object cannot be copied onto itself. IDS_FAIL_RENAME=Rename failure. -IDS_FAIL_RENAMEDUPLICATE=Cannot rename.\n\nA file of that name already exists. -IDS_FAIL_RICHEDDLL=RichEdit DLL missing. IDS_FAIL_SAVE=Save failure. -IDS_FAIL_UNPACK=Unpack failure. -IDS_FAIL_UPDATE=Update failure. -IDS_FN_EXECUTABLES=Executable programs (.exe)|*.exe|| -IDS_FN_NEWDIR=New directory -IDS_FN_ROOT=Working directory IDS_GAME_DEFRANKS=Clonk|Ensign|Lieutenant|Captain|Major|Lieutenant Colonel|Colonel|Brigade General|Major General|Lieutenant General|General IDS_GAME_FAILSAVEGAME=Error while saving the game. IDS_GAME_NOCLIENTSAVE=Network games may be saved by the host only. IDS_GAME_NOSAVEONCURR=Can't overwrite loaded game.|Please save on another slot! -IDS_GAME_NOUNREGSAVE=Saving games is available in the registered version only. IDS_GAME_RECORDSTITLE=Records IDS_GAME_SAVEGAMESTITLE=Savegames IDS_HOLD_ABORT=Abort round? @@ -648,6 +409,30 @@ IDS_LEAGUE_LEAGUEREPORTINGUNEXPECTED=League: Reporting unexpected disconnect (re IDS_LEAGUE_WAITINGFORLASTLEAGUESERVE=Waiting for last league server reply... IDS_LGA_INVALIDRESPONSE3=Invalid reply from internet server (no CSID). IDS_LGA_SERVERFAILURE=internet server error: %s\n +IDS_LGA_TOOMANYGAMESTARTS=Too many attempts to start a game +IDS_LGA_INVALIDPRODUCTID=Invalid product or version +IDS_LGA_WRONGCHECKSUM=Wrong checksum +IDS_LGA_WRONGRESCHECKSUM=Wrong resource checksum +IDS_LGA_SETTLEOFFICIALSERVER=Settle league games can only be played on official a server +IDS_LGA_SETTLEOLDENGINE=Settle league games can only be played using the latest game version +IDS_LGA_CANTADDSCEN=Scenario could not be added +IDS_LGA_CANTFINDLEAGUESCEN=Scenario not found and no open league active +IDS_LGA_LEAGUESCENNOMELEE=This scenario version is not registered in any league. Only melees can be played in the open league +IDS_LGA_GAMEALREADYENDED=Game already ended +IDS_LGA_CANTFINDSCEN=Scenario not found +IDS_LGA_NOCSID=CSID is missing +IDS_LGA_CANTFINDGAME=Game not found +IDS_LGA_WRONGHOSTIP=Wrong/changed host ip +IDS_LGA_CUIDALREADYEXISTS=There is already an account with this cuid +IDS_LGA_WEBCODEAUTHFAILED=Authentification failed +IDS_LGA_WEBCODEAUTHNA=Authentification not available at the moment +IDS_LGA_LOGINFAILED=Login failed +IDS_LGA_AUIDNOTFOUND=Player is not authentificated +IDS_LGA_USERALREADYJOINED=Player already joined this game +IDS_LGA_USERBANNED=User banned +IDS_LGA_GAMENOLEAGUE=Not a league game +IDS_LGA_GAMERECORDCOMPLETE=Record is already complete +IDS_LGA_GAMERECORDTOOLARGE=Record is too large IDS_LOG_COMMANDNOTALLOWEDINLEAGUE=Command not allowed in league games! IDS_MENU_ABORT=Abort round IDS_MENU_ABORT_DESC=Abort the round without evaluation. @@ -659,7 +444,6 @@ IDS_MENU_ATTACKHOSTILE=hostile IDS_MENU_ATTACKINFO=%s is currently %sand will %sbe attacked. IDS_MENU_ATTACKNOT=not IDS_MENU_ATTACKSELF=We don't attack ourselves. -IDS_MENU_BUY=Buy %s IDS_MENU_CLONKNAMES_DESC=Displays clonk names above enemy clonks. IDS_MENU_CPATTACK=Attack IDS_MENU_CPATTACKINFO=Order your clonks to attack other players. @@ -674,41 +458,28 @@ IDS_MENU_CPSAVEGAME=Save game IDS_MENU_CPSAVEGAMEINFO=Save this game so it can be resumed later. IDS_MENU_CPSURRENDER=Surrender IDS_MENU_CPSURRENDERINFO=Leave the game with evaluation. -IDS_MENU_DELETE=Delete IDS_MENU_DISCONNECT=Disconnect IDS_MENU_DISCONNECTCLIENT=Disconnect client IDS_MENU_DISCONNECTFROMSERVER=Disconnect from host? IDS_MENU_DISPLAY=Display IDS_MENU_GET=Get %s -IDS_MENU_HELP=Help -IDS_MENU_INSERT=Add... -IDS_MENU_MULTIPLEITEMS=Objects IDS_MENU_NEWPLAYER=Join player: %s IDS_MENU_NOATTACK=Don't attack %s IDS_MENU_NOPLRFILES=No additional player files available. IDS_MENU_OBSERVER=Observer Menu -IDS_MENU_ONLINEDOCS=Online documentation... -IDS_MENU_OPTION=Options -IDS_MENU_OPTIONS=Options... IDS_MENU_PLAYERNAMES_DESC=Displays player names above enemy clonks. -IDS_MENU_REGISTRATION=Registration... -IDS_MENU_SELL=Sell %s -IDS_MENU_SHOWCOMMANDKEYS=Keys -IDS_MENU_SHOWCOMMANDS=Commands IDS_MENU_SURRENDER=Are you sure? -IDS_MENU_WEBSITE=Clonk on the web... IDS_MNU_CLOCK=Clock IDS_MNU_CLONKNAMES=Clonk names IDS_MNU_CLOSE=Close IDS_MNU_COMPONENTS=Components IDS_MNU_CONTENTS=Grab contents +IDS_MNU_DEFAULTRESOLUTION=Screen IDS_MNU_DELETE=Delete IDS_MNU_DUPLICATE=Duplicate IDS_MNU_FILE=File IDS_MNU_FPS=FPS Display -IDS_MNU_INFO=Info IDS_MNU_JOIN=Join -IDS_MNU_MOUSECONTROL=Mouse control IDS_MNU_MUSIC=Music IDS_MNU_NET=Host IDS_MNU_NETCLIENT=Client %s (%i) @@ -721,28 +492,22 @@ IDS_MNU_OPTIONS=Options IDS_MNU_OPTIONSINFO=Change program options. IDS_MNU_PLAYER=Player IDS_MNU_PLAYERNAMES=Player names -IDS_MNU_PORTRAITS=Portraits IDS_MNU_QUIT=Quit IDS_MNU_RECORD=Record IDS_MNU_SAVEGAME=Save game IDS_MNU_SAVEGAMEAS=Save game as... IDS_MNU_SAVESCENARIO=Save scenario IDS_MNU_SAVESCENARIOAS=Save scenario as... -IDS_MNU_SCRIPT=Script IDS_MNU_SWITCHRESOLUTION=Switch resolution IDS_MNU_SWITCHRESOLUTION_LIKEIT=This is your new resolution. Do you like it? IDS_MNU_SWITCHRESOLUTION_UNDO=Original resolution will be restored in %d seconds... -IDS_MNU_TITLE=Title IDS_MNU_UPPERBOARD=Title board IDS_MNU_VIEWPORT=Viewport -IDS_MSG_ACTIVE=Active IDS_MSG_ALLOWSYOUTOJOINADIFFERENT=Allows you to join a different team. -IDS_MSG_ALLPLAYERDATA=Use current values for all players? IDS_MSG_ANTIALIASING_DESC=Set FSAA (MultiSampling) level IDS_MSG_ANUPDATETOVERSIONISAVAILA=A new update is available. Do you want to download and install this update? +IDS_MSG_AUTOWINDOWED=Automatic IDS_MSG_BACKTOPLAYERDLG=Back to player selection. -IDS_MSG_BLITOFFSET=Blit offset -IDS_MSG_BLITOFFSET_DESC=Determines the offset used for every drawing operation to ensure exact pixels are drawn. Increase this value if you see black borders below/to the right of some graphics. Deacrease it if you see borders above/to the left of some graphics. IDS_MSG_CANNOTSTARTSCENARIO=Cannot start scenario. IDS_MSG_CANTSENDTEAMMESSAGETEAMSN=Can't send team message: Teams not known. IDS_MSG_CHANGESTHETOPICTO=%s changes the topic to: %s @@ -763,7 +528,6 @@ IDS_MSG_DEFINEKEY=Assign key IDS_MSG_DELETECLONK=Do you really want to delete %s %s? IDS_MSG_DELETECLONK_DESC=Delete the selected crew member. IDS_MSG_DELETECLONK_PLAYTIME= - this Clonk has a total playing time of %s! -IDS_MSG_DELETEORIGINAL=%s is an original file. Are your sure you want to delete it? IDS_MSG_DELETEPLR=Do you really want to delete player %s? IDS_MSG_DELETEPLR_PLAYTIME= - this player has a total playing time of %s! IDS_MSG_DISABLED=disabled @@ -771,7 +535,6 @@ IDS_MSG_DISCONNECTED=disconnected IDS_MSG_DISCONNECTEDFROMSERVER=Disconnected from server (%s). IDS_MSG_DISCONNECTFROMSERVER=Disconnect from server? IDS_MSG_DONTSHOW=&Don't display this message in the future. -IDS_MSG_EDITORREGONLY=The editor can only be started in the registered version.\n\nPlease see the Developers section of the Clonk website for more information. IDS_MSG_ENABLED=enabled IDS_MSG_ENTERNEWDEATHMESSAGE=Enter new death message: IDS_MSG_ENTERPASSWORD=Enter password: @@ -782,7 +545,7 @@ IDS_MSG_FREELYSCROLLAROUNDTHEMAP=Freely scroll around the map. IDS_MSG_FREESAVEGAMEPLRS=Player assignment IDS_MSG_FREEVIEW=free view IDS_MSG_FULLSCREEN=Fullscreen -IDS_MSG_FULLSCREEN_DESC=Use fullscreen mode. +IDS_MSG_FULLSCREEN_DESC=Fullscreen/Windowed mode.|Automatic for windowed mode in menus only. IDS_MSG_GFXENGINE_DESC=Determines the rendering engine. Changes take effect when the game is restarted. IDS_MSG_GFXERR_RESINVAL=Invalid resolution! IDS_MSG_GFXERR_RESNOTFOUND=This resolution is probably not supportet by your system. @@ -794,16 +557,19 @@ IDS_MSG_HOST=host IDS_MSG_INACTIVE=Inactive IDS_MSG_INTERNETGAMEEVALUATED=Internet game evaluated. IDS_MSG_ISNOWKNOWNAS=%s is now known as %s -IDS_MSG_ITEMORIGINAL=%s is part of an original packet and my not be modified at this location. To modify, create a copy of this object at a different location. -IDS_MSG_ITEMSEDITED=The following objects are still being edited:\n -IDS_MSG_ITEMSMODIFIED=Update edited objects:\n IDS_MSG_JOINTEAM=Join team %s IDS_MSG_KICKBYMENU=kicked from host menu IDS_MSG_KICKFROMCLIENTLIST=kicked from client list IDS_MSG_KICKFROMLOBBY=kicked from lobby IDS_MSG_KICKFROMMSGBOARD=kicked from messageboard IDS_MSG_KICKFROMSTARTUPDLG=kicked from startup waiting dialog -IDS_MSG_LANGUAGEDISCLAIMER=This is a third party language. There is no warranty for completeness or accuracy. Use at your own risk. +IDS_MSG_LEAGUENOTSUPPORTED=League not supported by masterserver. +IDS_MSG_MASTERSERVNATERROR=Your network failed to pass certain tests. It is unlikely that you are able to host games in the internet.|To fix that, you need to forward the certain ports on your router. Refer to the FAQ on our website for more information. +IDS_MSG_MASTERSERVSIGNUPFAIL=Round signup at the masterserver failed. +IDS_MSG_MASTERSERVUPDATEFAIL=Round update at the masterserver failed. +IDS_MSG_MASTERSERVENDFAIL=Round end notification at the masterserver failed. +IDS_MSG_MASTERSERVNOOP=Operation not supported by the masterserver. +IDS_MSG_MASTERSERVWRONGENGINE=Wrong engine. IDS_MSG_LEAGUEEVALUATIONSUCCESSFU=League: evaluation successful. IDS_MSG_LEAGUEGAMESIGNUP=Game signed up at league server %s:|%s IDS_MSG_LEAGUEINVALIDUSERNAME=The user name contains invalid characters. @@ -822,56 +588,30 @@ IDS_MSG_LEAGUEUNEXPECTEDDISCONNEC=League: Unexpected disconnect reported: %s IDS_MSG_LEAGUEUSERNAMETOOSHORT=The user name is too short. IDS_MSG_LEAGUE_REGISTRATION=This is your first login at the league. Your can specify your desired league user name and league password below. IDS_MSG_LOCAL=local -IDS_MSG_LOCKACTIVATION=This object must be activated at all times. IDS_MSG_LOOKINGFORUPDATES=Looking for updates... -IDS_MSG_MANUALCLIP_DESC=Enable manual clipping. Try this if you encounter graphics errors like long, stretched lines across your screen. IDS_MSG_MAP_DESC=Select scenario from the map. IDS_MSG_MAP_STARTSCEN=Start scenario %s IDS_MSG_MMTIMER_DESC=Try this option if you experience timing problems during the game, e.g. very slow game even in small scenarios on decent hardware. -IDS_MSG_MOVEKEY=Shall the registration key be moved to the personal user directory so it will only be available to the currently logged on user on this computer? IDS_MSG_NEWPLRCOLOR=New &color IDS_MSG_NEWPLRCOLOR_DESC=Generate a new random player color -IDS_MSG_NOADDBLT_DESC=Disable additive blittings. Try this if some special effects like explosions are screwed up. -IDS_MSG_NOALPHAADD_DESC=Disable additive transparency values. Try this if you see boxes around some graphics. -IDS_MSG_NOCLRFADE_DESC=Disable vertex color fading. Try this if you encounter serious slowdowns in scenarios with a faded sky or enabled fog of war. IDS_MSG_NODEBUGMODE=No debug mode! -IDS_MSG_NODEFS=No object definitions available! -IDS_MSG_NOEDITNETREF=Network reference items may not be edited. -IDS_MSG_NOENGINE=The selected scenario requires an engine version %i.%i%i.%i or higher. -IDS_MSG_NOMATS=No material definitions available! -IDS_MSG_NOMODIFYORIGINAL=%s cannot be updated because it is part of an original packet. IDS_MSG_NOPARTICIPATE_DESC=Exclude %s from participation in the next round. IDS_MSG_NOPLAYERSELECTED=No players are selected. Please go to player selection and activate the participants for this round. IDS_MSG_NOPORTRAIT=No Portrait -IDS_MSG_NORUNTIMEJOIN=Runtime join for this game denied. IDS_MSG_NOTALLSAVEGAMEPLAYERSHAVE=Not all savegame players have been associated with a local player! To associate, right-click the savegame player in the player list and then select a local player to take over this player.|Any unassociated savegame players will be removed from the game. Unassociated local players will join as new players.|Start anyway? -IDS_MSG_NOTAVALIDFILE=%s is not an executable file. IDS_MSG_NOTENOUGHPLAYERSFORTHISRO=Not enough players for this round. -IDS_MSG_NOUNREGEDIT=Object organization is available in the registered version only. -IDS_MSG_NOUNREGISTERED=This scenario can only be started in the registered version. -IDS_MSG_NOUNREGPROPSAVE=Saving scenario properties is available in the registered version only. IDS_MSG_NOUPDATEAVAILABLEFORTHISV=No update available for this version. IDS_MSG_OBJCOUNT=Object count IDS_MSG_PARTICIPATE_DESC=Enable %s for participation in the next round. IDS_MSG_PARTICLES_DESC=Controls the amount of particles emitted by effects like smoke and fire. IDS_MSG_PASSWORDFORPLAYER=League login for player %s: -IDS_MSG_PASSWORDINCORRECT=Password incorrect. IDS_MSG_PLAYERASSIGNMENT=Participant %s will continue for player %s from the savegame. -IDS_MSG_PLRWEALTH=Player Wealth -IDS_MSG_POINTFILTERING_DESC=Disable linear filtering. Try this if you encounter blurry graphics. -IDS_MSG_PRESETDEFSMISSING=The selected scenario requires specified object definitions. The following required object packs were not found on this computer: %s -IDS_MSG_PRESETUSEDDEFS=You have used the currently activated object definitions in the scenario properties. Do you want these to be set in the scenario's presets so the scenario will automatically make use of these packs in the future? -IDS_MSG_PRESSBTN=Press the button for "%s" on gamepad %d. -IDS_MSG_PRESSKEY=Press the key for "%s" on keyboard block %d. +IDS_MSG_PRESSBTN=Press the button for "%s" on the gamepad. +IDS_MSG_PRESSKEY=Press the key for "%s" on the keyboard. IDS_MSG_PRESSORPUSHANYGAMEPADBUTT=Press %s or any gamepad button to open observer menu. -IDS_MSG_PROMPTCOPY=Copy %s to %s? IDS_MSG_PROMPTDELETE=Delete %s? -IDS_MSG_PROMPTIMPORT=Import %s to %s as %s? -IDS_MSG_PROMPTMOVE=Move %s to %s? IDS_MSG_PROMPTRESETCONFIG=Are you sure you want to reset all configuration values? -IDS_MSG_PROPORIGINALCOPY=%s is part of an original packet and may not be saved at its former location. Save modification to working directory? IDS_MSG_RANK=Rank -IDS_MSG_REMOTE=remote IDS_MSG_REMOVEPLR=&Remove IDS_MSG_REMOVEPLR_DESC=Do not join with this player IDS_MSG_REPLAYPLRS=Replay players @@ -883,7 +623,6 @@ IDS_MSG_RNDTEAM=Random team IDS_MSG_SCENARIODESC=Scenario description IDS_MSG_SCENARIODESC_LOADING=Loading... (%d%%) IDS_MSG_SELECT=Select %s -IDS_MSG_SELECTKEYSET=Select keyboard block or gamepad to be modified. IDS_MSG_SELECTLANG=Select program language. IDS_MSG_SELECTPLR=Select player... IDS_MSG_SELTEAM=Select team @@ -895,14 +634,8 @@ IDS_MSG_SETTHEMESSAGETHATAPPEARWH=Set the message that appear when this clonk di IDS_MSG_SHOWTEAMS=Teams IDS_MSG_SHOWTEAMS_DESC=Show teams IDS_MSG_SPEED=Speed: %dx -IDS_MSG_STARTDEVMODE=This scenario can only be started in developer mode. -IDS_MSG_STARTPLAYERMODE=This scenario can only be started in player mode. -IDS_MSG_STARTSELECTSCENARIO=To start a round you need to select a scenario first. To do this, open a scenario folder (book) by double clicking on it and select the desired scenario. Then click 'start'. -IDS_MSG_STARTUPVIDEO=Show startup video -IDS_MSG_STARTUPVIDEO_DESC=Shows a startup video when you start the game. The file called "Splash.c4v" can be downloaded from clonk.de and should be placed in the program directory. IDS_MSG_TAKEOVERPLR=&Take over IDS_MSG_TAKEOVERPLR_DESC=Control the player in the game -IDS_MSG_TARGETNOGROUP=Cannot copy any item to %s. IDS_MSG_TEAM=Team %d IDS_MSG_TEAMCOLORS=Team colors IDS_MSG_TEAMCOLORS_DESC=Specifies whether all players of a team have the same color, or individual colors are assigned for each team-member. @@ -913,14 +646,10 @@ IDS_MSG_TEAMDIST_HOST=by Host IDS_MSG_TEAMDIST_NONE=none IDS_MSG_TEAMDIST_RND=random IDS_MSG_TEAMDIST_RNDINV=surprise random! -IDS_MSG_TEXINDENT=Texindent -IDS_MSG_TEXINDENT_DESC=Determines the indent used when blitting from textures. Increase this value if you experience borders around some graphics; decrease it if borders of graphics are missing. IDS_MSG_TOOFEWPLAYERS=This scenario is designed for a minimum of %i players. Please go to the Player Selection dialog and activate the participants for this round. IDS_MSG_TOOFEWPLAYERSNET=This scenario is set for more participants than are activated on this computer. On start, you will have to wait for additional players to join from the network. -IDS_MSG_TOOMANYDEFS=You have activated a large number of separate object packs. It is strongly reommended that you combine several of those packs into object folders. To do this, create a new object folder using the 'new' button and move the object files into that folder. IDS_MSG_TOOMANYPLAYERS=This scenario is designed for a maximum of %i players. IDS_MSG_TOPICIN=Topic in %s: %s -IDS_MSG_TRANSFERNOTYPE=Cannot drop a %s into %s. IDS_MSG_TRYLEAGUESIGNUP=League login for player %s... IDS_MSG_UPDATEFAILED=Update failed. IDS_MSG_UPDATEINPROGRESS=Update still in progress. Please wait. @@ -929,6 +658,7 @@ IDS_MSG_NEWRELEASEAVAILABLE=For the new version there is no update package avail IDS_MSG_USINGPLR=Using %s IDS_MSG_USINGPLR_DESC=Use this player to continue the savegame IDS_MSG_WASKICKEDFROMTHECHANNEL=%s was kicked from the channel (%s). +IDS_MSG_WINDOWED=Window mode IDS_MSG_YOUAREABOUTTOCONNECTTOAPU=You are about to connect to a public chat server (%s). Proceed? IDS_MSG_YOUHAVEJOINEDCHANNEL=You have joined channel %s. IDS_MSG_YOUHAVELEFTCHANNEL=You have left channel %s (%s). @@ -948,7 +678,6 @@ IDS_NET_CLIENT_INFO=Client info IDS_NET_CLIENT_INFO_ADDRESSES=Addresses: IDS_NET_CLIENT_INFO_CONNDATA= Data: %s (%s:%d, %d ms) IDS_NET_CLIENT_INFO_CONNECTIONS=Connections: %s: %s (%s:%d, %d ms) -IDS_NET_CLIENT_INFO_FORMAT=%s %s %s %s (ID #%d):%s IDS_NET_CLIENT_INFO_NOADDRESSES=Addresses: none IDS_NET_CLIENT_INFO_NOCONNECTIONS=Connections: Not connected IDS_NET_CLIENT_INFO_UNKNOWNID=Unknown client ID #%d. @@ -956,8 +685,6 @@ IDS_NET_CLIENT_JOIN=Client %s connected. IDS_NET_CLIENT_OBSERVE=%s %s forced to observe. IDS_NET_CLIENT_REMOVED=%s %s removed (%s). IDS_NET_COMMENTCHANGED=Network game comment adjusted. -IDS_NET_COMPUTERNAME=Computer name: -IDS_NET_COMPUTERNAME_DESC=Name used to identify this computer in network games. IDS_NET_CONNECTHOST=Connecting to host on %s... IDS_NET_CONNECTING=Connecting to %s at %s IDS_NET_CONTROL=Control @@ -1012,7 +739,7 @@ IDS_NET_LEAGUE_SENDRESULT=Sending game result to %s... IDS_NET_LEAGUE_STARTGAME=Starting game... IDS_NET_LOBBYWAITING=Awaiting participants... IDS_NET_LOCAL_CLIENT=Local client -IDS_NET_MASTERSRV_DESC=Here you can enter the address of an alternate internet server you wish to use. If this option is disabled, the official server on clonk.de is used. +IDS_NET_MASTERSRV_DESC=Here you can enter the address of an alternate internet server you wish to use. If this option is disabled, the official server on openclonk.org is used. IDS_NET_NEWGAME=&New game IDS_NET_NEWGAME_DESC=Create a new network or internet game. IDS_NET_NODIRECTSTART=Cannot start network game data directly. @@ -1074,8 +801,6 @@ IDS_NET_USERNAME_DESC=Name used when sending chat messages from this computer in IDS_NET_WAITFORRES=Waiting for %s... IDS_NET_WAITFORSTART=Waiting for start... IDS_OBJ_BIRTHDAY=%s becomes %d!|Happy birthday! -IDS_OBJ_BURNS={{FLAM}} The object burns. -IDS_OBJ_CONNECT=%s conntected|to %s IDS_OBJ_DEATH1=%s is dead. IDS_OBJ_DEATH2=%s has|deceased. IDS_OBJ_DEATH3=%s|rests in peace. @@ -1083,20 +808,10 @@ IDS_OBJ_DEATH4=%s is dead. IDS_OBJ_DEATH5=%s has|deceased. IDS_OBJ_DEATH6=%s|rests in peace. IDS_OBJ_DEATH7=%s is dead. -IDS_OBJ_DISCONNECT=%s disconnected|from %s. IDS_OBJ_EMPTY=%s is empty. -IDS_OBJ_HOSTILENOENTRANCE=%s hostile.|No entrance! -IDS_OBJ_LINEREMOVAL=%s disconnected. -IDS_OBJ_NEWLINE=New|%s. IDS_OBJ_NOCON=%s cannot|be built. -IDS_OBJ_NOCONACTIV=%s not completed.|Activation denied. -IDS_OBJ_NOCONNECT=Connection not possible. -IDS_OBJ_NOCONNECTTYPE=%s cannot be connected|to %s. IDS_OBJ_NODIG=%s cannot dig. -IDS_OBJ_NODOUBLEKIT=%s is not fixed at the other end. IDS_OBJ_NOLEVEL=No level ground! -IDS_OBJ_NOLINECONSTRUCT=%s cannot create lines. -IDS_OBJ_NONEWLINE=Cannot create a new line here. IDS_OBJ_NOOTHER=%s is in the way. IDS_OBJ_NOROOM=Not enough room! IDS_OBJ_PROMOTION=%s is promoted|to %s! @@ -1104,15 +819,11 @@ IDS_OBJ_STUCK=%s is stuck! IDS_OBJ_UNDEF=Structure %s undefined. IDS_OBJ_UNKNOWN=unknown IDS_PLR_ELIMINATED=Player %s|eliminated. -IDS_PLR_HOSTILE=Player %s|hostile! IDS_PLR_HOSTILITY=%s attacks %s. IDS_PLR_NEWCOMMENT=I'm new. IDS_PLR_NEWPLAYER=New player -IDS_PLR_NOBKNOW=Player %s|has no construction plans. IDS_PLR_NOBUY=There is nothing to buy. IDS_PLR_NOHOSTILITY=%s does not attack %s. -IDS_PLR_NOTAVAIL=%s not available. -IDS_PLR_NOWEALTH=Not enough money! IDS_PLR_SURRENDERED=Player %s|has surrendered. IDS_PRC_CONNECTED=Connected. IDS_PRC_COUNTDOWN=The game will start in %d seconds. @@ -1137,9 +848,7 @@ IDS_PRC_GAMEOVER=Game over. IDS_PRC_GFXRES=Loading graphics... IDS_PRC_INITDEFS=Loading object definitions: IDS_PRC_INITEXTRA=Loading extras... -IDS_PRC_INITFONTS=Initializing fonts... IDS_PRC_INITIALIZE=Loading... -IDS_PRC_INITLOADER=Init loader... IDS_PRC_JOIN=Game joined. IDS_PRC_JOINFAIL=Error at player file. IDS_PRC_JOINPLR=Player join: %s @@ -1158,26 +867,22 @@ IDS_PRC_NETPREPARING=Preparing file %s for network... IDS_PRC_NEWTEAM=New Team IDS_PRC_NOC4S=No scenario file specified. IDS_PRC_NODEFS=No valid object definitions found. -IDS_PRC_NOEXACTC4X=This scenario can only be played with engine version %i.%i%i.%i. IDS_PRC_NOGFXFILE=Error at graphics file %s: %s IDS_PRC_NOMATENUM=Error at material enumeration. IDS_PRC_NOMISSIONACCESS=Access to this mission not yet granted. IDS_PRC_NOMUSIC=Music not available. IDS_PRC_NONETREPLAY=Cannot play back records while in network mode. IDS_PRC_NOREPLPLRCLR=Couldn't find a suitable replacement player color for player %s. Using default. -IDS_PRC_NOREQC4X=This scenario can only be played with engine version %d.%d%d.%d or higher. +IDS_PRC_NOREQC4X=This scenario can only be played with engine version %d.%d.%d or higher. IDS_PRC_NOSND=Error at sound file. -IDS_PRC_NOSWSCENARIO=Not registered. No shareware scenario. IDS_PRC_NOSYSMATS=System materials missing. IDS_PRC_OBJECTSLOADED=%d objects positioned. IDS_PRC_PLAYMUSIC=Music: %s IDS_PRC_PLRELIMINATED=Player %s eliminated. IDS_PRC_PLRFILEINUSE=Player file already in use. IDS_PRC_PLRSURRENDERED=Player %s surrendered. -IDS_PRC_PRELOADVIDEOS=Preloading videos from %s... IDS_PRC_RECORDINGTO=Recording %s... IDS_PRC_RECREATE=Recreating: %s -IDS_PRC_REG=Registered for: %s IDS_PRC_REMOVEPLR=Player %s removed. IDS_PRC_RESUME=Game resumed. IDS_PRC_RESUMENOCLIENT=Found unidentifiable join info for client %d (%d players) - discarded. @@ -1198,40 +903,9 @@ IDS_PRC_UNDEFINEDOBJECT=Object type %s not placed. IDS_PRC_UNKOWNERROR=Unknown error IDS_PRC_UNREGUSER=Unregistered user IDS_PRC_UPDATEFONT=Updating font %s(%d,%d)... -IDS_RANKS_CLONK=Clonk|Ensign|Lieutenant|Captain|Major|Lieutenant Colonel|Colonel|Brigade General|Major General|Lieutenant General|General -IDS_RANKS_PLAYER=Novice|Beginner|Adept|Ensign|Lieutenant|Captain|Major|Lieutenant Colonel|Colonel|Brigade General|Major General|Lieutenant General|General -IDS_SEC_UNREGUSER=Unregistered user -IDS_SELECT_ANIMALS=Animals IDS_SELECT_CREW=Crew -IDS_SELECT_ENVIRONMENT=Environment -IDS_SELECT_GOALS=Goals -IDS_SELECT_HOMEBASE=Home base material -IDS_SELECT_INEARTH=In earth -IDS_SELECT_KNOWLEDGE=Construction plans -IDS_SELECT_MATERIAL=Material -IDS_SELECT_NESTS=Nests -IDS_SELECT_PRODUCTION=Home base production -IDS_SELECT_RULES=Rules -IDS_SELECT_SKIPDEFS=Definitions not to load -IDS_SELECT_STRUCTURES=Buildings -IDS_SELECT_VEGETATION=Vegetation -IDS_SELECT_VEHICLES=Vehicles -IDS_STATUS_COPYING=Copying %s to %s... -IDS_STATUS_DELETING=Deleting %s... -IDS_STATUS_INITEDIT=Preparing edit... -IDS_STATUS_LOADING=Loading %s... -IDS_STATUS_LOADINGDEFS=Loading objects definitions... -IDS_STATUS_LOADINGMAP=Loading map... -IDS_STATUS_MOVING=Moving %s to %s... -IDS_STATUS_PACK=Packing %s... -IDS_STATUS_RELOADING=Loading working directory... -IDS_STATUS_RENAMING=Renaming %s... -IDS_STATUS_UNPACK=Unpacking %s... -IDS_STATUS_UPDATESCENARIO=Updating scenario... -IDS_STATUS_UPDATINGITEMS=Updating edited objects... IDS_TEXT_ABORTSTARTCOUNTDOWN=Abort start countdown. IDS_TEXT_ALERTTHEHOSTIFTHEHOSTISAW=Alert the host (if the host is away). -IDS_TEXT_CANTBUILD=%s can't build. IDS_TEXT_CHANGETHECOLOROFTHESPECIF=Change the color of the specified player. IDS_TEXT_CHANGEYOUROWNPLAYERCOLOR=Change your own player color. IDS_TEXT_COMMANDSAVAILABLEDURINGLO=Commands available during lobby: @@ -1255,16 +929,15 @@ IDS_TEXT_JOININCONSOLEMODENOTALLOW=Join in console mode not allowed! IDS_TEXT_KICKCERTAINCLIENTSFROMTHE=Kick certain clients from the game. IDS_TEXT_KICKTHESPECIFIEDCLIENT=Kick the specified client. IDS_TEXT_LEAGUEWAITINGFOREVALUATIO=League: waiting for evaluation... -IDS_TEXT_LOBBYICON=Lobby-Icon IDS_TEXT_LOCATION=Location: IDS_TEXT_MYDOCUMENTS=My Documents IDS_TEXT_MYPICTURES=My Pictures IDS_TEXT_PAUSETHEGAME=pause the game IDS_TEXT_PERFORMANACTIONINYOURNAME=Perform an action in your name. IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO=Play a sound from the global sound group. -IDS_TEXT_PLAYERIMAGE=Player image IDS_TEXT_PREVENTDEBUGMODEINTHISROU=Prevent debug mode in this round. IDS_TEXT_PROGRAMDIRECTORY=Program Directory +IDS_TEXT_SAFEZOOMEDFULLSCREENSHOT=Full game area screenshot with zoom. IDS_TEXT_SCORE=Score IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA=Set a new maximum number of players for this round. IDS_TEXT_SETANEWNETWORKCOMMENT=Set a new network comment. @@ -1279,36 +952,11 @@ IDS_TEXT_VIEW=View IDS_TEXT_WARNINGIFTHEGAMEISCANCELL=Notice: if the game is cancelled, no league score will be awarded. IDS_TEXT_WARNINGNOLEAGUEPOINTSWILL=Notice: if a player leaves without being defeated, the opposing players will gain less league score in case of a win. IDS_TEXT_YOUCANONLYSTARTONEVOTINGE=Voting-Timeout: you have to wait two minutes until you can request a new vote. -IDS_TYPE_ANIMATION=Animation -IDS_TYPE_BACKUP=Backup -IDS_TYPE_BINARY=Binary component -IDS_TYPE_BITMAP=Bitmap -IDS_TYPE_DEFFOLDER=Object folder -IDS_TYPE_DEFINITION=Object definition IDS_TYPE_DIRECTORY=Directory -IDS_TYPE_ENGINE=Engine -IDS_TYPE_EXECUTABLE=Executable IDS_TYPE_FOLDER=Scenario folder -IDS_TYPE_GROUP=Group file -IDS_TYPE_HELP=Help file -IDS_TYPE_HTML=Hypertext -IDS_TYPE_KEYFILE=Registration Key -IDS_TYPE_LINK=internet link -IDS_TYPE_LOG=Log file -IDS_TYPE_MATERIAL=Material definition -IDS_TYPE_MUSIC=Music file -IDS_TYPE_NONE=Unknown -IDS_TYPE_OBJECTINFO=Crew member -IDS_TYPE_PLAYER=Player IDS_TYPE_PORTRAIT=Portrait -IDS_TYPE_RICHTEXT=Description IDS_TYPE_SCENARIO=Scenario -IDS_TYPE_SCRIPT=Script -IDS_TYPE_SOUND=Sound -IDS_TYPE_TEXT=Text IDS_TYPE_UPDATE=Update -IDS_TYPE_VIDEO=Video -IDS_TYPE_ZIP=Zip archive IDS_VOTE_CANCELTHEROUND=abort the round IDS_VOTE_DOESNOTWANTTO=%s does not want to %s IDS_VOTE_KICKCLIENT=kick client %s @@ -1321,7 +969,7 @@ IDS_NET_CLIENT_IGNORE_DESC=Ignores %s. You will not be able to see messages from IDS_NET_CLIENT_IGNORE=Ignore IDS_NET_CLIENT_UNIGNORE=Unignore IDS_MSG_HIGHRESLANDSCAPE=High resolution landscape -IDS_MSG_HIGHRESLANDSCAPE_DESC=Experimental effect for high resolution textures on the landscape. +IDS_MSG_HIGHRESLANDSCAPE_DESC=Effect for high resolution textures on the landscape. IDS_ADDON_INSTALLSUCCESS=Installation of '%s' successful. IDS_ADDON_INSTALLFAILURE=Failed to install '%s'. IDS_ADDON_INSTALLTITLE=Addon Installation diff --git a/planet/System.ocg/Material.c b/planet/System.ocg/Material.c index 0f38e836e..6009c82fe 100644 --- a/planet/System.ocg/Material.c +++ b/planet/System.ocg/Material.c @@ -51,24 +51,42 @@ global func FindPosInMat(string sMat, int iXStart, int iYStart, int iWidth, int return 0; // No location found. } -// Removes a material pixel from the specified location, if the material is a liquid. -// \par x X coordinate. Offset if called in object context. -// \par y Y coordinate. Offset if called in object context. -// \returns The material index of the removed pixel, or -1 if no liquid was found. +/** Removes a material pixel from the specified location, if the material is a liquid. + @param x X coordinate + @param y Y coordinate + @return The material index of the removed pixel, or -1 if no liquid was found. */ global func ExtractLiquid(int x, int y) { - var mat = GetMaterial(x, y); - var density = GetMaterialVal("Density", "Material", mat); - if (density < C4M_Liquid || density >= C4M_Solid) - return -1; - ExtractMaterialAmount(x, y, mat, 1); - return mat; + var result = ExtractLiquidAmount(x, y, 1); + if(!result) return -1; + + return result[0]; } -// Removes a material pixel from the specified location, if the material is flammable. -// \par x X coordinate. Offset if called in object context. -// \par y Y coordinate. Offset if called in object context. -// \returns \c true if material was removed, \c false otherwise. +/** Tries to remove amount material pixels from the specified location if the material is a liquid. + @param x X coordinate + @param y Y coordinate + @param amount amount of liquid that should be extracted + @return an array with the first position being the material index being extracted and the second the + actual amount of pixels extracted OR nil if there was no liquid at all */ +global func ExtractLiquidAmount(int x, int y, int amount) +{ + var mat = GetMaterial(x, y); + if(mat == -1) + return nil; + var density = GetMaterialVal("Density", "Material", mat); + if (density < C4M_Liquid || density >= C4M_Solid) + return nil; + var amount = ExtractMaterialAmount(x, y, mat, amount); + if (amount <= 0) + return nil; + return [mat, amount]; +} + +/** Removes a material pixel from the specified location, if the material is flammable + @param x X coordinate. Offset if called in object context. + @param y Y coordinate. Offset if called in object context. + @return true if material was removed, false otherwise. */ global func FlameConsumeMaterial(int x, int y) { var mat = GetMaterial(x, y); diff --git a/planet/System.ocg/Math.c b/planet/System.ocg/Math.c index acd2a47ac..c38a1b108 100644 --- a/planet/System.ocg/Math.c +++ b/planet/System.ocg/Math.c @@ -32,6 +32,12 @@ global func RandomX(int start, int end) return Random(end - start + 1) + start; } +// Returns the sign of x. +global func Sign(int x) +{ + return (x>0)-(x<0); +} + // Tangens. global func Tan(int angle, int radius, int prec) { @@ -69,8 +75,16 @@ global func ComDirLike(int comdir1, int comdir2) // the shortest direction (left/right) to turn from one angle to another // (for example for homing projectiles or aiming) -global func GetTurnDirection(int from, int to) +global func GetTurnDirection( + int from /* the angle at which the turning starts */ + , int to /* the angle that should be turned towards */) { +/* + // code for a homing missile + var dir = GetTurnDirection(my_angle, target_angle); + SetR(GetR() + dir / 10); + SetSpeed(Sin(GetR(), 10), -Cos(GetR(), 10)); +*/ var dir; /*if(to < from)*/dir=to-from; //else dir=from-to; @@ -99,4 +113,53 @@ global func GetBit(int value, int bit_nr) global func ToggleBit(int old_val, int bit_nr) { return old_val ^ (1 << bit_nr); +} + +// Returns -1 for DIR_Left and +1 for DIR_Right or 0 if no object context is present +global func GetCalcDir() +{ + if (!this) return 0; + return GetDir() * 2 - 1; +} + +// Ensure that the first rectangle is fully with the second one and returns an adjusted rectangle. Both rectangles can be created with Rectangle() +global func RectangleEnsureWithin(proplist first, proplist second) +{ + if (GetType(first) != C4V_PropList) return {}; + if (GetType(second) != C4V_PropList) return {}; + + var adjusted = { x = first.x, y = first.y, w = first.w, h = first.h }; + if (first.x < second.x) adjusted.x = second.x; + if (first.w > second.w) adjusted.w = second.w - (adjusted.x - second.x); + if (adjusted.x + adjusted.w > second.x + second.w) adjusted.w = second.w - (adjusted.x - second.x); + if (first.y < second.y) adjusted.y = second.y; + if (first.h > second.h) adjusted.h = second.h - (adjusted.y - second.y); + if (adjusted.y + adjusted.h > second.y + second.h) adjusted.h = second.h - (adjusted.y - second.y); + + return adjusted; +} + +// checks whether a point {x, y} is in a normalized rectangle {x, y, w, h} +global func IsPointInRectangle(proplist point, proplist rectangle) +{ + return (point.x >= rectangle.x && point.x <= rectangle.x + rectangle.w) && (point.y >= rectangle.y && point.y <= rectangle.w + rectangle.h); +} + +//Moves param 'a' towards param 'b' by 'max' amount per frame +global func MoveTowards(int a, int b, int max) +{ + if(b == nil) return false; + if(max == nil) max = 1; + if(a < b) return BoundBy(a + max,a,b); + if(a > b) return BoundBy(a - max,b,a); +} + +global func FindHeight(int x) +{ + var y = 0; + while (!GBackSemiSolid(x, y) && y < LandscapeHeight()) + y += 10; + while (GBackSemiSolid(x, y) && y) + y--; + return y; } \ No newline at end of file diff --git a/planet/System.ocg/MeshAnimation.c b/planet/System.ocg/MeshAnimation.c index 8dd801859..9b37cfaeb 100644 --- a/planet/System.ocg/MeshAnimation.c +++ b/planet/System.ocg/MeshAnimation.c @@ -26,6 +26,11 @@ global func Anim_Y(int position, int begin, int end, int length) return [C4AVP_Y, position, begin, end, length]; } +global func Anim_R(int begin, int end) +{ + return [C4AVP_R, begin, end, this]; +} + global func Anim_AbsX(int position, int begin, int end, int length) { return [C4AVP_AbsX, position, begin, end, length]; diff --git a/planet/System.ocg/Object.c b/planet/System.ocg/Object.c index 1c35845a4..b0956e4e4 100644 --- a/planet/System.ocg/Object.c +++ b/planet/System.ocg/Object.c @@ -17,11 +17,13 @@ global func SetSpeed(int x_dir, int y_dir, int prec) // Can set either speed or angle of velocity, or both global func SetVelocity(int angle, int speed, int precAng, int precSpd) { + if(!precSpd) precSpd = 10; + if(!precAng) precAng = 1; if(!speed) speed = Distance(0,0, GetXDir(precSpd), GetYDir(precSpd)); if(!angle) angle = Angle(0,0, GetXDir(precSpd), GetYDir(precSpd), precAng); - if(!precAng) precAng = 1; + var x_dir = Sin(angle, speed, precAng); var y_dir = -Cos(angle, speed, precAng); @@ -36,6 +38,11 @@ global func SetCon(int new_con) return DoCon(new_con - GetCon()); } +global func GetObjAlpha() +{ + return (GetClrModulation() >> 24) & 0xFF; +} + // Sets the object's transparency. global func SetObjAlpha(int by_alpha) { @@ -68,16 +75,25 @@ global func MovePosition(int x, int y, int prec) SetPosition(GetX(prec) + x, GetY(prec) + y, nil, prec); } +// Returns the position as an array +global func GetPosition(int prec) +{ + return [GetX(prec), GetY(prec)]; +} + // Speed the calling object into the given direction (angle) -global func LaunchProjectile(int angle, int dist, int speed, int x, int y, bool rel_x) +global func LaunchProjectile(int angle, int dist, int speed, int x, int y, int precAng, int precSpd, bool rel_x) { // dist: Distance object travels on angle. Offset from calling object. // x: X offset from container's center // y: Y offset from container's center // rel_x: if true, makes the X offset relative to container direction. (x=+30 will become x=-30 when Clonk turns left. This way offset always stays in front of a Clonk.) - var x_offset = Sin(angle, dist); - var y_offset = -Cos(angle, dist); + var x_offset = x ?? Sin(angle, dist, precAng); + var y_offset = y ?? -Cos(angle, dist, precAng); + + if(!precAng) precAng = 1; + if(!precSpd) precSpd = 10; if (Contained() != nil && rel_x == true) if (Contained()->GetDir() == 0) @@ -85,16 +101,16 @@ global func LaunchProjectile(int angle, int dist, int speed, int x, int y, bool if (Contained() != nil) { - Exit(x_offset + x, y_offset + y, angle); - SetVelocity(angle, speed); + Exit(x_offset, y_offset, angle / precAng); + SetVelocity(angle, speed, precAng, precSpd); return true; } if (Contained() == nil) { - SetPosition(GetX() + x_offset + x, GetY() + y_offset + y); - SetR(angle); - SetVelocity(angle, speed); + SetPosition(GetX() + x_offset, GetY() + y_offset); + SetR(angle/precAng); + SetVelocity(angle, speed, precAng, precSpd); return true; } return false; @@ -142,9 +158,12 @@ global func GetMaxBreath() } // Makes an object gain Con until it is FullCon -global func StartGrowth(int value) +global func StartGrowth(int value /* the value the object grows approx. every second, in tenths of percent */) { - return AddEffect("IntGrowth", this, 1, 35, nil, nil, value); + var effect; + effect = AddEffect("IntGrowth", this, 1, 35, nil, nil, value); + effect.Time = Random(35); + return effect; } global func StopGrowth() @@ -289,4 +308,36 @@ global func GetBase () { if(!(this->~IsBase())) return NO_OWNER; return GetOwner(); -} \ No newline at end of file +} + + +/* GetXEdge returns the position of the objects top/bottom/left/right edge */ +global func GetLeftEdge() +{ + return GetX()-GetObjWidth()/2; +} + +global func GetRightEdge() +{ + return GetX()+GetObjWidth()/2; +} + +global func GetTopEdge() +{ + return GetY()-GetObjHeight()/2; +} + +global func GetBottomEdge() +{ + return GetY()+GetObjHeight()/2; +} + +// Returns if the object is standing in front of the back-object +global func InFrontOf(object back) +{ + var front = this; + if(!front) + return; + + return front->FindObject(front->Find_AtPoint(), Find_Not(Find_Exclude(back))) != nil; +} diff --git a/planet/System.ocg/Particles.c b/planet/System.ocg/Particles.c new file mode 100644 index 000000000..f382abed3 --- /dev/null +++ b/planet/System.ocg/Particles.c @@ -0,0 +1,335 @@ +/** + This file contains some default particle behavior definitions as well as helper functions. +*/ + +/* particle helper/effect functions */ + +global func CreateMuzzleFlash(int x, int y, int angle, int size) +{ + // main muzzle flash + CreateParticle("MuzzleFlash", x, y, 0, 0, 10, {Prototype = Particles_MuzzleFlash(), Size = size, Rotation = angle}); + // and some additional little sparks + var xdir = Sin(angle, size * 2); + var ydir = -Cos(angle, size * 2); + CreateParticle("StarFlash", x, y, PV_Random(xdir - size, xdir + size), PV_Random(ydir - size, ydir + size), PV_Random(20, 60), Particles_Glimmer(), size); +} + +global func Smoke(int x, int y, int level, int color) +{ + level = level ?? 10; + var particles = Particles_Smoke(); + if (color) + { + particles.Alpha = PV_Linear((color >> 24) & 0xff, 0); + particles.R = (color >> 16) & 0xff; + particles.G = (color >> 8) & 0xff; + particles.B = (color >> 0) & 0xff; + } + particles.Size = PV_Linear(PV_Random(level/2, level), PV_Random(2 * level, 3 * level)); + CreateParticle("Smoke", x, y, PV_Random(-level/3, level/3), PV_Random(-level/2, -level/3), PV_Random(level * 2, level * 10), particles, BoundBy(level/5, 3, 20)); +} + + +/* particle definitions */ +global func Particles_Dust() +{ + return + { + CollisionVertex = 500, + OnCollision = PC_Stop(), + ForceX = PV_Wind(20), + ForceY = PV_Gravity(25), + Alpha = PV_Linear(30, 0), + Rotation = PV_Random(0, 360), + Size = PV_KeyFrames(0, 0, 0, 100, 25, 1000, 15) + }; +} + +global func Particles_Cloud() +{ + return + { + Size = 200, + Attach = ATTACH_MoveRelative, + Phase = PV_Random(0, 15) + }; +} + + +global func Particles_Smoke() +{ + return + { + CollisionVertex = 500, + OnCollision = PC_Stop(), + ForceY = PV_Gravity(-100), + ForceX = PV_Wind(200), + DampingX = 900, DampingY = 900, + Alpha = PV_Linear(255, 0), + R = 100, G = 100, B = 100, + Size = PV_Linear(PV_Random(4, 10), PV_Random(20, 30)), + Phase = PV_Random(0, 15) + }; +} + +global func Particles_Fire() +{ + return + { + CollisionVertex = 0, + OnCollision = PC_Die(), + Phase = PV_Random(0, 3, 10), + ForceY = PV_Gravity(-100), + DampingY = 950, + Alpha = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0), + BlitMode = GFX_BLIT_Additive, + Size = PV_KeyFrames(0, 0, PV_Random(5, 10), 500, 5, 1000, 0), + Attach = ATTACH_Front, + Rotation = PV_Direction() + }; +} + +global func Particles_FireTrail() +{ + return + { + Prototype = Particles_Fire(), + ForceY = 0, + Attach = nil, + }; +} + +global func Particles_Flash() +{ + return + { + BlitMode = GFX_BLIT_Additive, + Alpha = PV_KeyFrames(0, 0, 128, 250, 64, 1000, 0), + Size = PV_KeyFrames(0, 0, 0, 100, 160, 1000, 0), + R = 255, G = 255, B = 64 + }; +} + +global func Particles_Magic() +{ + return + { + BlitMode = GFX_BLIT_Additive, + Alpha = PV_Linear(128, 0), + Size = PV_Linear(0, PV_Random(5, 15)), + CollisionVertex = 500, + OnCollision = PC_Die(), + Rotation = PV_Random(0, 360) + }; +} + +global func Particles_MagicRing() +{ + return + { + BlitMode = GFX_BLIT_Additive, + Alpha = PV_Linear(100, 0), + Size = PV_KeyFrames(1, 0, 0, 500, 20, 1000, 0), + Attach = ATTACH_Front | ATTACH_MoveRelative + }; +} + +global func Particles_Spark() +{ + return + { + BlitMode = GFX_BLIT_Additive, + Size = PV_Linear(PV_Random(5, 15), 0), + CollisionVertex = 500, + OnCollision = PC_Bounce(500), + Rotation = PV_Direction(), + ForceY = PV_Gravity(20) + }; +} + +global func Particles_Colored(prototype, color, color2) +{ + // Colors the given particle. If color2 is given, colors in a random fade between color and color2 + if (GetType(color2)) + { + return { + Prototype = prototype, + R = PV_Random((color >> 16) & 0xff, (color2 >> 16) & 0xff), + G = PV_Random((color >> 8) & 0xff, (color2 >> 8) & 0xff), + B = PV_Random((color >> 0) & 0xff, (color2 >> 0) & 0xff), + }; + } + else + return { + Prototype = prototype, + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff + }; +} + +global func Particles_SparkFire() +{ + return + { + Prototype = Particles_Spark(), + R = 255, G = 200, B = 10 + }; +} + +global func Particles_SmokeTrail() +{ + return + { + Prototype = Particles_Smoke(), + ForceY = PV_Gravity(-10), + ForceX = PV_Wind(20), + DampingX = 950, DampingY = 950, + Alpha = PV_Linear(128, 0), + R = 50, G = 50, B = 50, + Size = PV_KeyFrames(0, 0, 0, 200, PV_Random(10, 30), 1000, PV_Random(25, 35)) + }; +} + +global func Particles_Material(int color) +{ + return + { + Stretch = PV_Speed(2000), + CollisionVertex = 1000, + OnCollision = PC_Die(), + Size = 1, + Rotation = PV_Direction(), + ForceY = PV_Gravity(100), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff + }; +} + +global func Particles_Trajectory() +{ + return + { + BlitMode = GFX_BLIT_Additive, + Attach = ATTACH_Front | ATTACH_MoveRelative + }; +} + +global func Particles_WoodChip() +{ + return + { + Size = PV_Random(1, 3), + Phase = PV_Linear(0, 3), + Alpha = PV_KeyFrames(0, 0, 255, 900, 255, 1000, 0), + CollisionVertex = 500, + OnCollision = PC_Stop(), + ForceX = PV_Wind(50), + ForceY = PV_Gravity(100), + DampingX = 975, DampingY = 975, + Rotation = PV_Direction(PV_Random(750, 1250)), + Attach = ATTACH_Front + }; +} + +global func Particles_Straw() +{ + return + { + Prototype = Particles_WoodChip(), + Phase = PV_Random(0, 3), + Size = PV_Random(3, 5), + Attach = nil + }; +} + +global func Particles_Air() +{ + return + { + Stretch = PV_Speed(500, 1000), + Alpha = PV_Linear(255, 0), + Phase = PV_Random(0, 3), + DampingX = 990, DampingY = 990, + ForceX = PV_Random(-5, 5, 30), + ForceY = PV_Gravity(10, PV_Random(-5, 5)), + Size = PV_KeyFrames(0, 0, 0, 100, PV_Random(20, 30), 1000, 0), + Rotation = PV_Direction(), + CollisionVertex = 1000, + OnCollision = PC_Bounce(500) + }; +} + + +global func Particles_Thrust(int size) +{ + size = size ?? 10; + return + { + Size = PV_KeyFrames(0, 0, 0, 50, size, 1000, size * 2), + Alpha = PV_Linear(255, 0), + R = PV_KeyFrames(0, 0, 255, 500, 0, 1000, 0), + G = PV_KeyFrames(0, 0, 255, 500, 0, 1000, 0), + B = PV_KeyFrames(0, 0, 255, 500, 0, 1000, 0), + Phase = PV_Random(0, 3, 10), + Rotation = PV_Random(0, 360), + DampingX = 950, DampingY = 950, + ForceY = PV_KeyFrames(0, 0, 0, 500, 0, 1000, PV_Gravity(20)), + ForceX = PV_KeyFrames(0, 0, 0, 500, 0, 1000, PV_Wind(50)), + CollisionVertex = 750 + }; +} + +global func Particles_MuzzleFlash() +{ + return + { + Attach = ATTACH_Front | ATTACH_MoveRelative, + Size = 20, + Phase = PV_Linear(0, 5), + BlitMode = GFX_BLIT_Additive + }; +} + +global func Particles_Glimmer() +{ + return + { + Size = PV_Linear(2, 0), + ForceY = GetGravity(), + DampingY = PV_Linear(1000,700), + DampingX = PV_Linear(1000,700), + Stretch = PV_Speed(1000, 500), + Rotation = PV_Direction(), + OnCollision = PC_Die(), + CollisionVertex = 500, + R = 255, + G = PV_Linear(128,32), + B = PV_Random(0, 128, 2), + Alpha = PV_Random(255,0,3), + BlitMode = GFX_BLIT_Additive, + }; +} + +global func Particles_ElectroSpark1() +{ + return + { + Size = PV_Random(5, 9), + Phase = PV_Linear(0, 5), + BlitMode = GFX_BLIT_Additive, + CollisionVertex = 750, + OnCollision = PC_Die(), + Rotation = PV_Direction() + }; +} + +global func Particles_ElectroSpark2() +{ + return + { + Prototype = Particles_ElectroSpark1(), + Phase = PV_Linear(6, 11), + }; +} \ No newline at end of file diff --git a/planet/System.ocg/Player.c b/planet/System.ocg/Player.c index f1073e2bb..03318033f 100644 --- a/planet/System.ocg/Player.c +++ b/planet/System.ocg/Player.c @@ -85,7 +85,8 @@ global func DoWealth(int plr, int value) return SetWealth(plr, value + GetWealth(plr)); } -global func IsAllied(int plr1, int plr2, bool check_one_way_only) +// checks whether two players are allied - that means they are not hostile and neither of them is NO_OWNER +global func IsAllied(int plr1, int plr2, bool check_one_way_only /* whether to check the hostility only in one direction */) { if(plr1 == NO_OWNER) return false; if(plr2 == NO_OWNER) return false; @@ -113,4 +114,4 @@ global func MessageWindow(string msg, int for_plr, id icon, string caption) global func FindBase (int iPlr, int iIndex) { return FindObjects(Find_Owner(iPlr), Find_Func("IsBase"))[iIndex]; -} \ No newline at end of file +} diff --git a/planet/System.ocg/PlayerControl.c b/planet/System.ocg/PlayerControl.c index 15006026f..545c16722 100644 --- a/planet/System.ocg/PlayerControl.c +++ b/planet/System.ocg/PlayerControl.c @@ -26,6 +26,7 @@ global func PlayerControl(int plr, int ctrl, id spec_id, int x, int y, int stren // Forward control to cursor var cursor = GetCursor(plr); if (cursor) + if (cursor->GetCrewEnabled()) { // Object controlled by plr cursor->SetController(plr); diff --git a/planet/System.ocg/PlayerControls.txt b/planet/System.ocg/PlayerControls.txt index d4c02fb3c..a0ffc16a2 100644 --- a/planet/System.ocg/PlayerControls.txt +++ b/planet/System.ocg/PlayerControls.txt @@ -1,4 +1,3 @@ - ############################################################################### # # # ControlDefs # @@ -11,8 +10,8 @@ # Summary # -------- # Left Right Up Down Jump - # Throw Drop Use Collect - # ThrowAlt DropAlt UseAlt + # Throw Drop Use Collect ForcedThrow + # ThrowAlt DropAlt UseAlt ForcedThrowAlt # # CancelUse CancelMenu # @@ -29,11 +28,13 @@ # # CursorPos # - # Backpack, Contents + # Contents + # + # ZoomIn ZoomOut # # with Mouse # --------------- - # Aim GUICursor GUIClick1 GUIClick2 + # Aim GUICursor GUIClick1 GUIClick2 WheelZoomIn WheelZoomOut # # Gamepad controls # ------------------------------------- @@ -44,12 +45,12 @@ # # with Keyboard # ------------------ - # Hotkey1 Hotkey2 Hotkey3 Hotkey4 Hotkey5 Hotkey6 Hotkey7 Hotkey8 Hotkey9 - # Hotkey0 - # - # PlayerHotkey1 PlayerHotkey2 PlayerHotkey3 PlayerHotkey4 PlayerHotkey5 - # PlayerHotkey6 PlayerHotkey7 PlayerHotkey8 PlayerHotkey9 PlayerHotkey0 - # + # Hotkey0-9 + # PlayerHotkey0-9 + # DropHotkey0-9 + # Hotkey0-9Select + # Hotkey0-9SelectAlt + # InteractionHotkey0-9 [ControlDef] Identifier=Aim @@ -82,165 +83,146 @@ [ControlDef] Identifier=AimAxisUp - GUIName=Aim up + GUIName=$CON_AimAxisUp$ Hold=1 [ControlDef] Identifier=AimAxisDown - GUIName=Aim down + GUIName=$CON_AimAxisDown$ Hold=1 [ControlDef] Identifier=AimAxisLeft - GUIName=Aim left + GUIName=$CON_AimAxisLeft$ Hold=1 [ControlDef] Identifier=AimAxisRight - GUIName=Aim right + GUIName=$CON_AimAxisRight$ Hold=1 # Movement [ControlDef] Identifier=Left - GUIName=Left Hold=1 [ControlDef] Identifier=Right - GUIName=Right Hold=1 [ControlDef] Identifier=Up - GUIName=Up Hold=1 [ControlDef] Identifier=Down - GUIName=Down Hold=1 [ControlDef] Identifier=Jump - GUIName=Jump - GUIDesc=Do the mario! + GUIName=$CON_Jump$ + GUIDesc=$CON_Jump_Desc$ # Inventory [ControlDef] Identifier=Throw - GUIName=Throw - GUIDesc=Throw selected inventory item + GUIName=$CON_Throw$ + GUIDesc=$CON_Throw_Desc$ Hold=1 [ControlDef] Identifier=ForcedThrow - #GUIName=Throw - GUIDesc=Force to throw selected inventory item Hold=1 [ControlDef] Identifier=ThrowDelayed - GUIName=Throw - GUIDesc=Throw selected inventory item + GUIName=$CON_Throw$ + GUIDesc=$CON_Throw_Desc$ Hold=1 [ControlDef] Identifier=Drop - #GUIName=Drop - GUIDesc=Drop selected inventory item + GUIName=$CON_Drop$ + GUIDesc=$CON_Drop_Desc$ Hold=1 [ControlDef] Identifier=Collect - GUIName=Collect [ControlDef] Identifier=ThrowAlt - GUIName=Throw 2 - GUIDesc=Throw secondary selected inventory item + GUIName=$CON_ThrowAlt$ + GUIDesc=$CON_ThrowAlt_Desc$ Hold=1 [ControlDef] Identifier=ForcedThrowAlt - #GUIName=Throw 2 - GUIDesc=Force to throw selected inventory item Hold=1 [ControlDef] Identifier=ThrowAltDelayed - GUIName=Throw 2 - GUIDesc=Throw secondary selected inventory item + GUIName=$CON_ThrowAlt$ + GUIDesc=$CON_ThrowAlt_Desc$ Hold=1 [ControlDef] Identifier=DropAlt - #GUIName=Drop 2 - GUIDesc=Drop secondary selected inventory item + GUIName=$CON_DropAlt$ + GUIDesc=$CON_DropAlt_Desc$ Hold=1 # Hotkeys (Inventory) [ControlDef] Identifier=Hotkey1 - GUIName=Hotkey 1 - GUIDesc=Selects the 1st Slot + GUIName=$CON_Hotkey1$ Hold=1 [ControlDef] Identifier=Hotkey2 - GUIName=Hotkey 2 - GUIDesc=Selects the 2nd Slot + GUIName=$CON_Hotkey2$ Hold=1 [ControlDef] Identifier=Hotkey3 - GUIName=Hotkey 3 - GUIDesc=Selects the 3rd Slot + GUIName=$CON_Hotkey3$ Hold=1 [ControlDef] Identifier=Hotkey4 - GUIName=Hotkey 4 - GUIDesc=Selects the 4th Slot + GUIName=$CON_Hotkey4$ Hold=1 [ControlDef] Identifier=Hotkey5 - GUIName=Hotkey 5 - GUIDesc=Selects the 5th Slot + GUIName=$CON_Hotkey5$ Hold=1 [ControlDef] Identifier=Hotkey6 - GUIName=Hotkey 6 - GUIDesc=Selects the 6th Slot + GUIName=$CON_Hotkey6$ Hold=1 [ControlDef] Identifier=Hotkey7 - GUIName=Hotkey 7 - GUIDesc=Selects the 7th Slot + GUIName=$CON_Hotkey7$ Hold=1 [ControlDef] Identifier=Hotkey8 - GUIName=Hotkey 8 - GUIDesc=Selects the 8th Slot + GUIName=$CON_Hotkey8$ Hold=1 [ControlDef] Identifier=Hotkey9 - GUIName=Hotkey 9 - GUIDesc=Selects the 9th Slot + GUIName=$CON_Hotkey9$ Hold=1 [ControlDef] Identifier=Hotkey0 - GUIName=Hotkey 10 - GUIDesc=Selects the 10th Slot + GUIName=$CON_Hotkey0$ Hold=1 [ControlDef] @@ -337,95 +319,76 @@ [ControlDef] Identifier=Use - GUIName=Use - GUIDesc=Use selected or controlled item + GUIName=$CON_Use$ + GUIDesc=$CON_Use_Desc$ Hold=1 SendCursorPos=1 [ControlDef] Identifier=UseDelayed - GUIName=Use - GUIDesc=Use selected or controlled item + GUIName=$CON_Use$ + GUIDesc=$CON_Use_Desc$ Hold=1 SendCursorPos=1 [ControlDef] Identifier=CancelUse - #GUIName=Cancel Use - GUIDesc=Cancel usage of selected or controlled item [ControlDef] Identifier=CancelMenu - GUIName=Close Menu - GUIDesc=Close a menu + GUIName=$CON_MenuCancel$ [ControlDef] Identifier=UseAlt - GUIName=Use 2 - GUIDesc=Use secondary selected or controlled item + GUIName=$CON_UseAlt$ + GUIDesc=$CON_UseAlt_Desc$ Hold=1 SendCursorPos=1 [ControlDef] Identifier=UseAltDelayed - GUIName=Use 2 - GUIDesc=Use secondary selected or controlled item + GUIName=$CON_UseAlt$ + GUIDesc=$CON_UseAlt_Desc$ Hold=1 SendCursorPos=1 [ControlDef] Identifier=Contents - GUIName=Contents - GUIDesc=Open/close contents menus + GUIName=$CON_Contents$ + GUIDesc=$CON_Contents_Desc$ SendCursorPos=1 [ControlDef] Identifier=Grab - #GUIName=Grab - GUIDesc=Grab vehicle SendCursorPos=1 Hold=1 [ControlDef] Identifier=Ungrab - #GUIName=Let go - GUIDesc=Let go vehicle Hold=1 [ControlDef] Identifier=GrabPrevious - GUIName=Grab previous - GUIDesc=Grab the previous vehicle on the same spot [ControlDef] Identifier=GrabNext - GUIName=Grab next - GUIDesc=Grab the next vehicle on the same spot [ControlDef] Identifier=PushEnter - #GUIName=Push into building - GUIDesc=Push the vehicle into the building Hold=1 [ControlDef] Identifier=Interact - GUIName=Interact - GUIDesc=Interact with object in landscape SendCursorPos=1 Hold=1 [ControlDef] Identifier=Enter - #GUIName=Enter - GUIDesc=Go into the building SendCursorPos=1 Hold=1 [ControlDef] Identifier=Exit - #GUIName=Exit - GUIDesc=Exit the building Hold=1 @@ -433,75 +396,55 @@ [ControlDef] Identifier=InteractionHotkey1 - GUIName=Interaction Hotkey 1 - GUIDesc=Activates the 1st item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey2 - GUIName=Interaction Hotkey 2 - GUIDesc=Activates the 2nd item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey3 - GUIName=Interaction Hotkey 3 - GUIDesc=Activates the 3rd item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey4 - GUIName=Interaction Hotkey 4 - GUIDesc=Activates the 4th item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey5 - GUIName=Interaction Hotkey 5 - GUIDesc=Activates the 5th item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey6 - GUIName=Interaction Hotkey 6 - GUIDesc=Activates the 6th item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey7 - GUIName=Interaction Hotkey 7 - GUIDesc=Activates the 7th item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey8 - GUIName=Interaction Hotkey 8 - GUIDesc=Activates the 8th item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey9 - GUIName=Interaction Hotkey 9 - GUIDesc=Activates the 9th item in the Actionbar SendCursorPos=1 [ControlDef] Identifier=InteractionHotkey0 - GUIName=Interaction Hotkey 10 - GUIDesc=Activates the 10th item in the Actionbar SendCursorPos=1 # Crew [ControlDef] Identifier=NextCrew - GUIName=Next crew member - GUIDesc=Control next crew member + GUIName=$CON_NextCrew$ + GUIDesc=$CON_NextCrew_Desc$ [ControlDef] Identifier=PreviousCrew - GUIName=Previous crew member - GUIDesc=Control previous crew member + GUIName=$CON_PreviousCrew$ + GUIDesc=$CON_PreviousCrew_Desc$ [ControlDef] Identifier=PlayerHotkey1 @@ -538,34 +481,26 @@ [ControlDef] Identifier=GUIClick1 - #GUIName=Click - GUIDesc=Click selected or controlled GUI item DefaultDisabled=1 Hold=1 CoordinateSpace=Viewport [ControlDef] Identifier=GUIClick2 - #GUIName=Right click - GUIDesc=Right click selected or controlled GUI item DefaultDisabled=1 Hold=1 CoordinateSpace=Viewport [ControlDef] Identifier=MenuOK - GUIName=Menu OK + GUIName=$CON_MenuOK$ + GUIDesc=$CON_MenuOK_Desc$ Action=MenuOK - [ControlDef] - Identifier=MenuSelect - GUIName=Menu Select - GUIDesc=Select specific item - Action=MenuSelect - [ControlDef] Identifier=MenuCancel - GUIName=Close menu + GUIName=$CON_MenuCancel$ + GUIDesc=$CON_MenuCancel_Desc$ Action=MenuCancel [ControlDef] @@ -588,18 +523,24 @@ [ControlDef] Identifier=ObjectMenuOK + GUIName=$CON_MenuOK$ Action=ObjectMenuOK [ControlDef] Identifier=ObjectMenuOKAll + GUIName=$CON_MenuOKAll$ Action=ObjectMenuOKAll [ControlDef] Identifier=ObjectMenuSelect + GUIName=$CON_MenuSelect$ + GUIDesc=$CON_MenuSelect_Desc$ Action=ObjectMenuSelect [ControlDef] Identifier=ObjectMenuCancel + GUIName=$CON_MenuCancel$ + GUIDesc=$CON_MenuCancel_Desc$ Action=ObjectMenuCancel [ControlDef] @@ -627,38 +568,38 @@ [ControlDef] Identifier=PlayerMenu - GUIName=Player menu - GUIDesc=Open/close player menu + GUIName=$CON_PlayerMenu$ + GUIDesc=$CON_PlayerMenu_Desc$ Action=Menu # Viewport Zoom [ControlDef] Identifier=ZoomIn - GUIName=Zoom in - GUIDesc=Increase viewport zoom + GUIName=$CON_ZoomIn$ + GUIDesc=$CON_ZoomIn_Desc$ Action=ZoomIn Hold=1 RepeatDelay=3 [ControlDef] Identifier=ZoomOut - GUIName=Zoom out - GUIDesc=Decrease viewport zoom + GUIName=$CON_ZoomOut$ + GUIDesc=$CON_ZoomOut_Desc$ Action=ZoomOut Hold=1 RepeatDelay=3 [ControlDef] Identifier=WheelZoomIn - GUIName=Zoom in - GUIDesc=Increase viewport zoom + GUIName=$CON_ZoomIn$ + GUIDesc=$CON_ZoomIn_Desc$ Action=ZoomIn [ControlDef] Identifier=WheelZoomOut - GUIName=Zoom out - GUIDesc=Decrease viewport zoom + GUIName=$CON_ZoomOut$ + GUIDesc=$CON_ZoomOut_Desc$ Action=ZoomOut @@ -681,46 +622,12 @@ [ControlSets] # ======================================================================= # - # Mouse control with keyboard (QWERTY) # + # Mouse control with keyboard # # ======================================================================= # - # - # - # Summary - # -------- - # Left A - # Right D - # Up, Jump W - # Down S - # - # Hotkey0-9 (0-9) - # InteractionHotkey0-0 Shift+(0-9) - # - # Use, Throw Left mouse button - # Drop S+Left mouse button - # Throw Shift+Left mouse button - # - # UseAlt, ThrowAlt Right mouse button - # DropAlt S+Right mouse button - # ThrowAlt Shift+Right mouse button - # - # Interact Space - # - # Backpack Q - # Contents E - # Collect A,D,W,S - # - # NextCrew T - # PreviousCrew R - # PlayerHotkey0-9 Ctrl+(0-9) - # - # MenuOK Return - # MenuCancel Backspace - # - # PlayerMenu F [ControlSet] Name=WASD_Hotkeys_IntQueue_MouseCon_ - GUIName=Keyboard and Mouse + GUIName=$SET_WASD_QWERTZ$ Keyboard=1 Mouse=1 Gamepad=0 @@ -730,51 +637,65 @@ [Assignment] Key=E Control=Contents - Group=1 - + GUIGroup=50 + # Menu [Assignment] Key=F Control=PlayerMenu - Group=1 - + GUIGroup=50 + [Assignment] - Key=Return + Key=Space Priority=100 Control=MenuOK + GUIGroup=50 [Assignment] - Key=Backspace + Key=BackSpace Priority=100 Control=MenuCancel + GUIGroup=50 # Movement [Assignment] Key=A Priority=50 + GUIName=$KEY_Left$ + GUIDesc=$KEY_Left_Desc$ + GUIGroup=10 Control=Left - Group=1 [Assignment] Key=D Priority=50 + GUIName=$KEY_Right$ + GUIDesc=$KEY_Right_Desc$ + GUIGroup=10 Control=Right [Assignment] Key=S Priority=50 + GUIName=$KEY_Down$ + GUIDesc=$KEY_Down_Desc$ + GUIGroup=10 Control=Down [Assignment] Key=W Priority=50 + GUIName=$KEY_Up$ + GUIDesc=$KEY_Up_Desc$ + GUIGroup=10 Control=Up [Assignment] Key=W Priority=10 + GUIGroup=10 Control=Jump # Object interaction @@ -782,262 +703,57 @@ [Assignment] Key=Space Priority=35 + GUIName=$KEY_Interact$ + GUIDesc=$KEY_Interact_Desc$ + GUIGroup=40 Control=Interact - Group=1 - + # Crew - [Assignment] - Key=R - Control=PreviousCrew - Group=1 - [Assignment] Key=T - Control=NextCrew - - # Use - - [Assignment] - Key=Mouse1ButtonLeft - Priority=100 - Control=Use - Group=1 - - [Assignment] - Key=Mouse1ButtonRight - Priority=100 - Control=UseAlt - - # click in gui - - [Assignment] - Key=Mouse1ButtonLeft - Priority=300 - Control=GUIClick1 - - [Assignment] - Key=Mouse1ButtonRight - Priority=300 - Control=GUIClick2 - - # Zoom - - [Assignment] - Key=Mouse1Wheel1Up - Priority=100 - Control=WheelZoomIn - Group=1 - - [Assignment] - Key=Mouse1Wheel1Down - Priority=100 - Control=WheelZoomOut - - # Secondary Hotkeys for interacting (actionbar) - - [Assignment] - Key=Less - Control=InteractionHotkey1 - - [Assignment] - Key=Y - Control=InteractionHotkey2 - - [Assignment] - Key=X - Control=InteractionHotkey3 - - [Assignment] - Key=C - Control=InteractionHotkey4 - - [Assignment] - Key=V - Control=InteractionHotkey5 - - [Assignment] - Key=B - Control=InteractionHotkey6 - - [Assignment] - Key=N - Control=InteractionHotkey7 - - [Assignment] - Key=M - Control=InteractionHotkey8 - - [Assignment] - Key=Comma - Control=InteractionHotkey9 - - [Assignment] - Key=Period - Control=InteractionHotkey0 - - # ======================================================================= # - # Mouse control with keyboard (DVORAK) # - # ======================================================================= # - # - # - # Summary - # -------- - # - # See Keyboard_Mouse. Same but with DVORAK keyboard - # - [ControlSet] - Name=DVORAK_Hotkeys_IntQueue_MouseCon_ - GUIName=DVORAK keyboard and mouse - Keyboard=1 - Mouse=1 - Gamepad=0 - - # Contents Menu - - [Assignment] - Key=Period - Control=Contents - - # Menu - - [Assignment] - Key=U - Control=PlayerMenu - - [Assignment] - Key=Return - Priority=100 - Control=MenuOK - - [Assignment] - Key=Backspace - Priority=100 - Control=MenuCancel - - # Movement - - [Assignment] - Key=A - Priority=50 - Control=Left - - [Assignment] - Key=E - Priority=50 - Control=Right - - [Assignment] - Key=O - Priority=50 - Control=Down - - [Assignment] - Key=Comma - Priority=50 - Control=Up - - [Assignment] - Key=Comma - Priority=10 - Control=Jump - - # Object interaction - - [Assignment] - Key=Space - Priority=35 - Control=Interact - - # Crew - - [Assignment] - Key=P + GUIGroup=70 Control=PreviousCrew - + [Assignment] - Key=Y + Key=R + GUIGroup=70 Control=NextCrew - + # Use [Assignment] Key=Mouse1ButtonLeft Priority=100 + GUIName=$KEY_MouseUse$ + GUIDesc=$KEY_MouseUse_Desc$ + GUIDisabled=1 + GUIGroup=20 Control=Use - + [Assignment] Key=Mouse1ButtonRight Priority=100 + GUIName=$KEY_MouseUseAlt$ + GUIDesc=$KEY_MouseUseAlt_Desc$ + GUIDisabled=1 + GUIGroup=20 Control=UseAlt - - # click in gui - - [Assignment] - Key=Mouse1ButtonLeft - Priority=300 - Control=GUIClick1 - - [Assignment] - Key=Mouse1ButtonRight - Priority=300 - Control=GUIClick2 - # Zoom [Assignment] Key=Mouse1Wheel1Up + GUIGroup=60 Priority=100 Control=WheelZoomIn - + [Assignment] Key=Mouse1Wheel1Down + GUIGroup=60 Priority=100 Control=WheelZoomOut - - # Secondary Hotkeys for interacting (actionbar) - - [Assignment] - Key=Backslash - Control=InteractionHotkey1 - - [Assignment] - Key=Comma_US - Control=InteractionHotkey2 - - [Assignment] - Key=Q - Control=InteractionHotkey3 - - [Assignment] - Key=J - Control=InteractionHotkey4 - - [Assignment] - Key=K - Control=InteractionHotkey5 - - [Assignment] - Key=X - Control=InteractionHotkey6 - - [Assignment] - Key=B - Control=InteractionHotkey7 - - [Assignment] - Key=M - Control=InteractionHotkey8 - - [Assignment] - Key=W - Control=InteractionHotkey9 - - [Assignment] - Key=V - Control=InteractionHotkey0 - + # ======================================================================= # # Dualshock-like gamepad (10-12 buttons, 1 D-Pad, 2 analog stick) # # ======================================================================= # @@ -1050,44 +766,11 @@ # but otherwise no analog stick and only 2 shoulder buttons). It would be # he found out a way how to distinguish shoulder buttons from main buttons # :P - # - # Summary - # -------- - # Left Joy1Left - # Right Joy1Right - # Up Joy1Up - # Down Joy1Down - # - # AimAxisLeft, Left Joy1Axis1Min - # AimAxisRight, Right Joy1Axis1Max - # AimAxisUp, Up Joy1Axis2Min - # AimAxisDown, Down Joy1Axis2Max - # - # Jump Joy1C - # - # Backpack Joy1E - # Contents Joy1F - # - # Use, Throw Joy1A - # Drop Joy1Down+Joy1A - # - # UseAlt, ThrowAlt Joy1D - # DropAlt Joy1Down+Joy1D - # - # Interact Joy1B - # - # MenuOK Joy1C - # MenuCancel Joy1B - # - # NextCrew Joy1I - # PlayerMenu Joy1J - # - # ZoomOut Joy1G - # ZoomIn Joy1H - + + [ControlSet] Name=Gamepad_GamepadCon_IntQueue_ - GUIName=Gamepad + GUIName=$SET_Gamepad$ Keyboard=0 Mouse=0 Gamepad=1 @@ -1096,20 +779,24 @@ [Assignment] Key=Joy1F + GUIGroup=50 Control=Contents # Menu [Assignment] Key=Joy1J + GUIGroup=50 Control=PlayerMenu - + [Assignment] Key=Joy1C + GUIGroup=50 Control=MenuOK [Assignment] Key=Joy1B + GUIGroup=50 Control=MenuCancel # Movement @@ -1117,66 +804,67 @@ [Assignment] Key=Joy1Left Priority=50 + GUIName=$KEY_Left$ + GUIDesc=$KEY_Left_Desc$ + GUIGroup=10 Control=Left [Assignment] Key=Joy1Right Priority=50 + GUIName=$KEY_Right$ + GUIDesc=$KEY_Right_Desc$ + GUIGroup=10 Control=Right [Assignment] Key=Joy1Down Priority=50 + GUIName=$KEY_Down$ + GUIDesc=$KEY_Down_Desc$ + GUIGroup=10 Control=Down [Assignment] Key=Joy1Up Priority=50 + GUIName=$KEY_Up$ + GUIDesc=$KEY_Up_Desc$ + GUIGroup=10 Control=Up [Assignment] Key=Joy1C Priority=10 + GUIGroup=10 Control=Jump - - [Assignment] - Key=Joy1Axis1Min - Priority=50 - Control=Left - - [Assignment] - Key=Joy1Axis1Max - Priority=50 - Control=Right - - [Assignment] - Key=Joy1Axis2Max - Priority=50 - Control=Down - - [Assignment] - Key=Joy1Axis2Min - Priority=50 - Control=Up [Assignment] Key=Joy1Axis1Min + GUIDesc=$KEY_AimAxis_Desc$ Priority=80 + GUIGroup=30 Control=AimAxisLeft [Assignment] Key=Joy1Axis1Max + GUIDesc=$KEY_AimAxis_Desc$ Priority=80 + GUIGroup=30 Control=AimAxisRight [Assignment] Key=Joy1Axis2Max + GUIDesc=$KEY_AimAxis_Desc$ Priority=80 + GUIGroup=30 Control=AimAxisDown [Assignment] Key=Joy1Axis2Min + GUIDesc=$KEY_AimAxis_Desc$ Priority=80 + GUIGroup=30 Control=AimAxisUp # Object interaction @@ -1184,51 +872,79 @@ [Assignment] Key=Joy1B Priority=35 + GUIName=$KEY_Interact$ + GUIDesc=$KEY_Interact_Desc$ + GUIGroup=40 Control=Interact - + # Crew [Assignment] Key=Joy1I Control=NextCrew - + GUIGroup=70 + # Use, Throw, Drop [Assignment] Key=Joy1A + GUIName=$KEY_GamepadUse$ + GUIDesc=$KEY_GamepadUse_Desc$ + GUIGroup=20 Priority=100 Control=UseDelayed - + [Assignment] Key=Joy1D + GUIName=$KEY_GamepadUseAlt$ + GUIDesc=$KEY_GamepadUseAlt_Desc$ + GUIGroup=20 Priority=100 Control=UseAltDelayed - - [Assignment] - Key=Joy1K - Control=CancelUse # Zoom [Assignment] Key=Joy1H Priority=100 + GUIGroup=60 Control=ZoomIn - + [Assignment] Key=Joy1G Priority=100 + GUIGroup=60 Control=ZoomOut # ======================================================================= # # Default gamepad control # - # ======================================================================= # + # ======================================================================= # [ControlSet] Name=*_GamepadCon_* + [Assignment] + Key=CON_AimAxisLeft + Priority=50 + Control=Left + + [Assignment] + Key=CON_AimAxisRight + Priority=50 + Control=Right + + [Assignment] + Key=CON_AimAxisDown + Priority=50 + Control=Down + + [Assignment] + Key=CON_AimAxisUp + Priority=50 + Control=Up + [Assignment] Key=CON_Left Priority=70 @@ -1249,33 +965,51 @@ Priority=70 Control=AimUp + [Assignment] + Key=CON_Down,CON_UseDelayed + GUIDisabled=1 + GUIGroup=20 + Priority=150 + Control=Drop + [Assignment] Key=CON_Down,CON_UseAltDelayed + GUIDisabled=1 + GUIGroup=20 Priority=150 Control=DropAlt - [Assignment] - Key=CON_UseAltDelayed - Priority=50 - Control=ThrowAltDelayed - - [Assignment] - Key=CON_Down,CON_UseDelayed - Priority=150 - Control=Drop - [Assignment] Key=CON_UseDelayed + GUIName=None Priority=50 Control=ThrowDelayed + [Assignment] + Key=CON_UseAltDelayed + GUIName=None + Priority=50 + Control=ThrowAltDelayed + # ======================================================================= # # Default mouse control # - # ======================================================================= # + # ======================================================================= # [ControlSet] Name=*_MouseCon_* + # click in gui + + [Assignment] + Key=Mouse1ButtonLeft + Priority=300 + Control=GUIClick1 + + [Assignment] + Key=Mouse1ButtonRight + Priority=300 + Control=GUIClick2 + # Aiming [Assignment] @@ -1292,21 +1026,29 @@ [Assignment] Key=Shift+CON_Use + GUIDisabled=1 + GUIGroup=20 Priority=150 Control=Throw [Assignment] Key=Shift+CON_Use + GUIDisabled=1 + GUIGroup=20 Priority=151 Control=ForcedThrow [Assignment] Key=Shift+CON_UseAlt + GUIDisabled=1 + GUIGroup=20 Priority=150 Control=ThrowAlt [Assignment] Key=Shift+CON_UseAlt + GUIDisabled=1 + GUIGroup=20 Priority=151 Control=ForcedThrowAlt @@ -1314,11 +1056,13 @@ [Assignment] Key=CON_Use + GUIName=None Priority=50 Control=Throw [Assignment] Key=CON_UseAlt + GUIName=None Priority=50 Control=ThrowAlt @@ -1335,10 +1079,10 @@ Priority=50 Control=PushEnter - #[Assignment] - #Key=CON_Interact - #Priority=45 - #Control=GrabNext + [Assignment] + Key=CON_Interact + Priority=45 + Control=GrabNext [Assignment] Key=CON_Interact @@ -1362,7 +1106,7 @@ # ======================================================================= # # Default hotkey controls # - # ======================================================================= # + # ======================================================================= # [ControlSet] Name=*_Hotkeys_* @@ -1372,319 +1116,297 @@ [Assignment] Key=1 Control=Hotkey1 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=2 Control=Hotkey2 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=3 Control=Hotkey3 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=4 Control=Hotkey4 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=5 Control=Hotkey5 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=6 Control=Hotkey6 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=7 Control=Hotkey7 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=8 Control=Hotkey8 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=9 Control=Hotkey9 + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 [Assignment] Key=0 Control=Hotkey0 - - # 2nd hand Hotkeys - - [Assignment] - Key=Alt+Hotkey1 - Control=Hotkey1SelectAlt - - [Assignment] - Key=Alt+Hotkey2 - Control=Hotkey2SelectAlt - - [Assignment] - Key=Alt+Hotkey3 - Control=Hotkey3SelectAlt - - [Assignment] - Key=Alt+Hotkey4 - Control=Hotkey4SelectAlt - - [Assignment] - Key=Alt+Hotkey5 - Control=Hotkey5SelectAlt - - [Assignment] - Key=Alt+Hotkey6 - Control=Hotkey6SelectAlt - - [Assignment] - Key=Alt+Hotkey7 - Control=Hotkey7SelectAlt - - [Assignment] - Key=Alt+Hotkey8 - Control=Hotkey8SelectAlt - - [Assignment] - Key=Alt+Hotkey9 - Control=Hotkey9SelectAlt - - [Assignment] - Key=Alt+Hotkey0 - Control=Hotkey0SelectAlt + GUIDesc=$KEY_Hotkey_Desc$ + GUIGroup=80 # Hotkey + Mousebutton Select [Assignment] - Key=Hotkey1,Mouse1ButtonLeft + Key=CON_Hotkey1,Mouse1ButtonLeft Control=Hotkey1Select Priority=200 [Assignment] - Key=Hotkey1,Mouse1ButtonRight + Key=CON_Hotkey1,Mouse1ButtonRight Control=Hotkey1SelectAlt Priority=200 [Assignment] - Key=Hotkey2,Mouse1ButtonLeft + Key=CON_Hotkey2,Mouse1ButtonLeft Control=Hotkey2Select Priority=200 [Assignment] - Key=Hotkey2,Mouse1ButtonRight + Key=CON_Hotkey2,Mouse1ButtonRight Control=Hotkey2SelectAlt Priority=200 [Assignment] - Key=Hotkey3,Mouse1ButtonLeft + Key=CON_Hotkey3,Mouse1ButtonLeft Control=Hotkey3Select Priority=200 [Assignment] - Key=Hotkey3,Mouse1ButtonRight + Key=CON_Hotkey3,Mouse1ButtonRight Control=Hotkey3SelectAlt Priority=200 [Assignment] - Key=Hotkey4,Mouse1ButtonLeft + Key=CON_Hotkey4,Mouse1ButtonLeft Control=Hotkey4Select Priority=200 [Assignment] - Key=Hotkey4,Mouse1ButtonRight + Key=CON_Hotkey4,Mouse1ButtonRight Control=Hotkey4SelectAlt Priority=200 [Assignment] - Key=Hotkey5,Mouse1ButtonLeft + Key=CON_Hotkey5,Mouse1ButtonLeft Control=Hotkey5Select Priority=200 [Assignment] - Key=Hotkey5,Mouse1ButtonRight + Key=CON_Hotkey5,Mouse1ButtonRight Control=Hotkey5SelectAlt Priority=200 [Assignment] - Key=Hotkey6,Mouse1ButtonLeft + Key=CON_Hotkey6,Mouse1ButtonLeft Control=Hotkey6Select Priority=200 [Assignment] - Key=Hotkey6,Mouse1ButtonRight + Key=CON_Hotkey6,Mouse1ButtonRight Control=Hotkey6SelectAlt Priority=200 [Assignment] - Key=Hotkey7,Mouse1ButtonLeft + Key=CON_Hotkey7,Mouse1ButtonLeft Control=Hotkey7Select Priority=200 [Assignment] - Key=Hotkey7,Mouse1ButtonRight + Key=CON_Hotkey7,Mouse1ButtonRight Control=Hotkey7SelectAlt Priority=200 [Assignment] - Key=Hotkey8,Mouse1ButtonLeft + Key=CON_Hotkey8,Mouse1ButtonLeft Control=Hotkey8Select Priority=200 [Assignment] - Key=Hotkey8,Mouse1ButtonRight + Key=CON_Hotkey8,Mouse1ButtonRight Control=Hotkey8SelectAlt Priority=200 [Assignment] - Key=Hotkey9,Mouse1ButtonLeft + Key=CON_Hotkey9,Mouse1ButtonLeft Control=Hotkey9Select Priority=200 [Assignment] - Key=Hotkey9,Mouse1ButtonRight + Key=CON_Hotkey9,Mouse1ButtonRight Control=Hotkey9SelectAlt Priority=200 [Assignment] - Key=Hotkey0,Mouse1ButtonLeft + Key=CON_Hotkey0,Mouse1ButtonLeft Control=Hotkey0Select Priority=200 [Assignment] - Key=Hotkey0,Mouse1ButtonRight + Key=CON_Hotkey0,Mouse1ButtonRight Control=Hotkey0SelectAlt Priority=200 [Assignment] - Key=Shift+Hotkey1 + Key=Shift+CON_Hotkey1 Control=DropHotkey1 [Assignment] - Key=Shift+Hotkey2 + Key=Shift+CON_Hotkey2 Control=DropHotkey2 [Assignment] - Key=Shift+Hotkey3 + Key=Shift+CON_Hotkey3 Control=DropHotkey3 [Assignment] - Key=Shift+Hotkey4 + Key=Shift+CON_Hotkey4 Control=DropHotkey4 [Assignment] - Key=Shift+Hotkey5 + Key=Shift+CON_Hotkey5 Control=DropHotkey5 [Assignment] - Key=Shift+Hotkey6 + Key=Shift+CON_Hotkey6 Control=DropHotkey6 [Assignment] - Key=Shift+Hotkey7 + Key=Shift+CON_Hotkey7 Control=DropHotkey7 [Assignment] - Key=Shift+Hotkey8 + Key=Shift+CON_Hotkey8 Control=DropHotkey8 [Assignment] - Key=Shift+Hotkey9 + Key=Shift+CON_Hotkey9 Control=DropHotkey9 [Assignment] - Key=Shift+Hotkey0 + Key=Shift+CON_Hotkey0 Control=DropHotkey0 # Hotkeys for interacting (actionbar) [Assignment] - Key=Interact,Hotkey1 + Key=CON_Interact,CON_Hotkey1 Control=InteractionHotkey1 Priority=101 [Assignment] - Key=Interact,Hotkey2 + Key=CON_Interact,CON_Hotkey2 Control=InteractionHotkey2 Priority=101 [Assignment] - Key=Interact,Hotkey3 + Key=CON_Interact,CON_Hotkey3 Control=InteractionHotkey3 Priority=101 [Assignment] - Key=Interact,Hotkey4 + Key=CON_Interact,CON_Hotkey4 Control=InteractionHotkey4 Priority=101 [Assignment] - Key=Interact,Hotkey5 + Key=CON_Interact,CON_Hotkey5 Control=InteractionHotkey5 Priority=101 [Assignment] - Key=Interact,Hotkey6 + Key=CON_Interact,CON_Hotkey6 Control=InteractionHotkey6 Priority=101 [Assignment] - Key=Interact,Hotkey7 + Key=CON_Interact,CON_Hotkey7 Control=InteractionHotkey7 Priority=101 [Assignment] - Key=Interact,Hotkey8 + Key=CON_Interact,CON_Hotkey8 Control=InteractionHotkey8 Priority=101 [Assignment] - Key=Interact,Hotkey9 + Key=CON_Interact,CON_Hotkey9 Control=InteractionHotkey9 Priority=101 [Assignment] - Key=Interact,Hotkey0 + Key=CON_Interact,CON_Hotkey0 Control=InteractionHotkey0 Priority=101 # Hotkeys for choosing clonk [Assignment] - Key=Ctrl+Hotkey1 + Key=Ctrl+CON_Hotkey1 Control=PlayerHotkey1 [Assignment] - Key=Ctrl+Hotkey2 + Key=Ctrl+CON_Hotkey2 Control=PlayerHotkey2 [Assignment] - Key=Ctrl+Hotkey3 + Key=Ctrl+CON_Hotkey3 Control=PlayerHotkey3 [Assignment] - Key=Ctrl+Hotkey4 + Key=Ctrl+CON_Hotkey4 Control=PlayerHotkey4 [Assignment] - Key=Ctrl+Hotkey5 + Key=Ctrl+CON_Hotkey5 Control=PlayerHotkey5 [Assignment] - Key=Ctrl+Hotkey6 + Key=Ctrl+CON_Hotkey6 Control=PlayerHotkey6 [Assignment] - Key=Ctrl+Hotkey7 + Key=Ctrl+CON_Hotkey7 Control=PlayerHotkey7 [Assignment] - Key=Ctrl+Hotkey8 + Key=Ctrl+CON_Hotkey8 Control=PlayerHotkey8 [Assignment] - Key=Ctrl+Hotkey9 + Key=Ctrl+CON_Hotkey9 Control=PlayerHotkey9 [Assignment] - Key=Ctrl+Hotkey0 + Key=Ctrl+CON_Hotkey0 Control=PlayerHotkey0 # ======================================================================= # @@ -1694,92 +1416,96 @@ [ControlSet] Name=* - # Interaction-Bar - [Assignment] - Key=L - Control=InteractionBar - - # Interactions - [Assignment] - Key=CON_Down,CON_Interact - Priority=46 - Control=Ungrab - # Collect [Assignment] Key=CON_Left - Priority=10 + GUIName=None + Priority=9 Control=Collect [Assignment] Key=CON_Right - Priority=10 + GUIName=None + Priority=9 Control=Collect [Assignment] Key=CON_Up - Priority=10 + GUIName=None + Priority=9 Control=Collect [Assignment] Key=CON_Down - Priority=10 + GUIName=None + Priority=9 Control=Collect # Menu control [Assignment] Key=CON_Left + GUIName=None Priority=100 Control=MenuLeft [Assignment] Key=CON_Right + GUIName=None Priority=100 Control=MenuRight [Assignment] Key=CON_Down + GUIName=None Priority=100 Control=MenuDown [Assignment] Key=CON_Up + GUIName=None Priority=100 Control=MenuUp [Assignment] Key=CON_Left + GUIName=None Priority=90 Control=ObjectMenuLeft [Assignment] Key=CON_Right + GUIName=None Priority=90 Control=ObjectMenuRight [Assignment] Key=CON_Down + GUIName=None Priority=90 Control=ObjectMenuDown [Assignment] Key=CON_Up + GUIName=None Priority=90 Control=ObjectMenuUp [Assignment] Key=CON_MenuOK + GUIName=None Priority=90 Control=ObjectMenuOK [Assignment] Key=CON_MenuCancel + GUIName=None Priority=90 Control=ObjectMenuCancel [Assignment] Key=CON_MenuCancel + GUIName=None Priority=80 Control=CancelMenu diff --git a/planet/System.ocg/Proplists.c b/planet/System.ocg/Proplists.c new file mode 100644 index 000000000..847e7fcdd --- /dev/null +++ b/planet/System.ocg/Proplists.c @@ -0,0 +1,27 @@ +/*-- + Proplists.c + + General helper functions that create or work with proplists. +--*/ + +// creates a proplists with the properties x, y, w, h that represents a rectangle +// satisfies that the resulting rectangle's x|y point is in the top-left corner and the width and height are positive +global func Rectangle(int x2, int y2, int w2, int h2) +{ +/* +// creates a rectangle representing the landscape +var rect = Rectangle(0, 0, LandscapeWidth(), LandscapeHeight()); +*/ + // normalize + if(w2 < 0) + { + x2 += w2; + w2 = -w2; + } + if(h2 < 0) + { + y2 += h2; + h2 = - h2; + } + return {x = x2, y = y2, w = w2, h = h2}; +} \ No newline at end of file diff --git a/planet/System.ocg/SaveScenario.c b/planet/System.ocg/SaveScenario.c new file mode 100644 index 000000000..2a3890361 --- /dev/null +++ b/planet/System.ocg/SaveScenario.c @@ -0,0 +1,536 @@ +/* Scenario saving functionality */ +// Defines script function SaveScenarioObjects, which is called by the +// engine to generate the Objects.c file for scenario saving + +// Temp variable used by MakeScenarioSaveName() to store dependency +static save_scenario_obj_dependencies; + +// Propert identifier of object creation +static const SAVEOBJ_Creation = "Creation"; +static const SAVEOBJ_ContentsCreation = "ContentsCreation"; + +global func SaveScenarioObjects(f) +{ + // f is a handle to the Objects.c file + // Prepare props saving object + var props_prototype = { + Add = Global.SaveScenP_Add, + AddSet = Global.SaveScenP_AddSet, + AddCall = Global.SaveScenP_AddCall, + Remove = Global.SaveScenP_Remove, + RemoveCreation = Global.SaveScenP_RemoveCreation, + Clear = Global.SaveScenP_Clear, + Buffer2File = Global.SaveScenP_Buffer2File, + HasData = Global.SaveScenP_HasData, + HasCreation = Global.SaveScenP_HasCreation, + HasProps = Global.SaveScenP_HasProps, + HasProp = Global.SaveScenP_HasProp, + TakeProps = Global.SaveScenP_TakeProps + }; + // Write all objects! + var objs = FindObjects(Find_And()), obj, i; + var n = GetLength(objs); + var obj_type, any_written, do_write_file = false; + // In reverse order (background to foreground) + for (i=0; iGetID()) + { + if (any_written) FileWrite(f, "\n"); // Extra spacing between different object types + obj_type = obj.o->GetID(); + any_written = false; + } + if (obj.o.StaticSaveVar) + { + if (obj.props->HasCreation()) FileWrite(f, Format(" %s = ", obj.o.StaticSaveVar)); + } + else if (obj.write_label) + { + FileWrite(f, Format(" var %s", obj.o->MakeScenarioSaveName())); + if (obj.props->HasCreation()) FileWrite(f, " = "); else FileWrite(f, ";\n"); + } + else if (obj.props->HasCreation()) + { + FileWrite(f, " "); + } + if (obj.props->~Buffer2File(f)) do_write_file = any_written = true; + } + // Write global effects + any_written = false; + var fx; i=0; + while (fx = GetEffect("*", nil, i++)) + { + var fx_buffer = {Prototype=props_prototype}; + EffectCall(nil, fx, "SaveScen", fx_buffer); + if (fx_buffer->HasData()) + { + if (!any_written && do_write_file) FileWrite(f, " \n"); + any_written = do_write_file = true; + fx_buffer->~Buffer2File(f); + } + } + // Write footer + FileWrite(f, " return true;\n}\n"); + // Done; success. Return true if any objects or effects were written to the file. + return do_write_file; +} + +global func SaveScen_Objects(array objs, array ignore_objs, proplist props_prototype) +{ + // Write all object data into buffers + var n = GetLength(objs); + var obj_data = CreateArray(n), obj; + for (var i=0; i=0) continue; + if (WildcardMatch(Format("%i", obj->GetID()), "GUI_*")) continue; // big bunch of objects that should not be stored. + // Generate object creation and property strings + save_scenario_obj_dependencies = []; + if (!obj->SaveScenarioObject(obj_data[i].props)) + { + obj_data[i].props->Clear(); + continue; + } + if (obj->Contained()) obj->Contained()->MakeScenarioSaveName(); // force container dependency + if (obj_data[i].props->HasProps()) obj_data[i].write_label = true; + obj_data[i].dependencies = save_scenario_obj_dependencies; + obj_data[i].n_dependencies = GetLength(save_scenario_obj_dependencies); + save_scenario_obj_dependencies = nil; + } + return obj_data; +} + +global func SaveScen_ResolveDepends(array objs, array obj_data) +{ + // Dependency pointer from obj to obj_data + var i,j,k,n=GetLength(objs),od; + for (i=0; iContained()) + { + k = GetIndexOf(objs, objs[i]->Contained()); + if (k >= 0) obj_data[i].co = obj_data[k]; + } + } + // Resolve dependencies + k = 0; + for (i=0; i i) + { + // The dependent object is behind us in the list. This is bad! + if (!od.props->HasCreation()) + { + // This is just object properties. Move them behind dependent object creation + var obj_data_new = CreateArray(n); + obj_data_new[0:i] = obj_data[0:i]; + obj_data_new[i:j] = obj_data[i+1:j+1]; + obj_data_new[j] = obj_data[i]; + if (jTakeProps() }; + od.n_dependencies = 0; od.props_detached = true; + if (jContained()) + { + // ignore if container object was not saved + if (obj.co && obj.co.props->HasCreation()) + { + // creation and props? Then turn into CreateContents + if (obj.props->HasProp(SAVEOBJ_ContentsCreation) && !obj.props_detached) + { + obj.props->Remove(SAVEOBJ_Creation); + // Adjust owner if necessery + if (obj.o->GetOwner() != obj.o->Contained()->GetOwner()) + obj.props->AddCall("Owner", obj.o, "SetOwner", obj.o->GetOwner()); + } + else if (obj.props.origin) + { + // props detached from creation. Use Enter() call to enter container + // the label must have been written because something depended on the object. + obj.props.origin->Remove(SAVEOBJ_ContentsCreation); + obj.props->AddCall("Container", obj.o, "Enter", obj.o->Contained()); + } + } + else + { + // unsaved container - just create object outside + obj.props->Remove(SAVEOBJ_ContentsCreation); + } + } + return obj_data; +} + +global func MakeScenarioSaveName() +{ + // Get name to be used to store this object in a scenario + if (!this) FatalError("MakeScenarioSaveName needs definition or object context!"); + // Definitions may just use their regular name + if (this.Prototype == Global) return Format("%i", this); + // When the name is queried while properties are built, it means that there is a dependency. Store it. + if (save_scenario_obj_dependencies && GetIndexOf(save_scenario_obj_dependencies, this)<0) save_scenario_obj_dependencies[GetLength(save_scenario_obj_dependencies)] = this; + // Build actual name using unique number (unless there's a static save variable name for us) + return this.StaticSaveVar ?? Format("%i%04d", GetID(), ObjectNumber()); +} + +global func SaveScenarioObject(props) +{ + // Called in object context: Default object writing procedure + // Overwrite this method and return false for objects that should not be saved + // Overwrite and call inherited for objects that add/remove/alter default creation/properties + var owner_string = ""; + if (GetOwner() != NO_OWNER) owner_string = Format(", %d", GetOwner()); + props->Add(SAVEOBJ_Creation, "CreateObject(%i, %d, %d%s)", GetID(), GetX(), GetDefBottom(), owner_string); + // Contained creation is added alongside regular creation because it is not yet known if CreateObject+Enter or CreateContents can be used due to dependencies. + // func SaveScen_SetContainers will take care of removing one of the two creation strings after dependencies have been resolved. + if (Contained()) props->Add(SAVEOBJ_ContentsCreation, "%s->CreateContents(%i)", Contained()->MakeScenarioSaveName(), GetID()); + // Write some default props every object should save + var v, is_static = (GetCategory() & C4D_StaticBack) || Contained(), def = GetID(); + v = GetAlive(); if (!v && (GetCategory()&C4D_Living)) props->AddCall("Alive", this, "Kill", this, true); + v = GetDir(); if (v) props->AddCall("Dir", this, "SetDir", GetConstantNameByValueSafe(v,"DIR_")); + v = GetComDir(); if (v) props->AddCall("ComDir", this, "SetComDir", GetConstantNameByValueSafe(v,"COMD_")); + v = GetCon(); if (v != 100) props->AddCall("Con", this, "SetCon", Max(v,1)); + v = GetCategory(); if (v != def->GetCategory()) props->AddCall("Category", this, "SetCategory", GetBitmaskNameByValue(v, "C4D_")); + v = GetR(); if (v) props->AddCall("R", this, "SetR", v); + v = GetXDir(); if (v && !is_static) props->AddCall("XDir", this, "SetXDir", v); + v = GetYDir(); if (v && !is_static) if (!Inside(v, 1,12) || !GetContact(-1, CNAT_Bottom)) + props->AddCall("YDir", this, "SetYDir", v); // consolidate small YDir for standing objects + v = GetRDir(); if (v && !is_static) props->AddCall("RDir", this, "SetRDir", v); + v = GetColor(); if (v && v != 0xffffffff) props->AddCall("Color", this, "SetColor", Format("0x%x", v)); + v = GetClrModulation(); if (v && v != 0xffffffff) props->AddCall("ClrModulation", this, "SetClrModulation", Format("0x%08x", v)); + v = GetObjectBlitMode();if (v) props->AddCall("BlitMode", this, "SetObjectBlitMode", GetBitmaskNameByValue(v & ~GFX_BLIT_Custom, "GFX_BLIT_")); + v = GetName(); if (v != def->GetName()) props->AddCall("Name", this, "SetName", Format("%v", v)); // TODO: Escape quotation marks, backslashes, etc. in name + v = this.MaxEnergy; if (v != def.MaxEnergy) props->AddSet ("MaxEnergy", this, "MaxEnergy", this.MaxEnergy); + v = GetEnergy(); if (v != def.MaxEnergy/1000) props->AddCall("Energy", this, "DoEnergy", v-def.MaxEnergy/1000); + v = this.Visibility; if (v != def.Visibility) props->AddSet ("Visibility", this, "Visibility", GetBitmaskNameByValue(v, "VIS_")); + v = this.Plane; if (v != def.Plane) props->AddSet ("Plane", this, "Plane", v); + v = this.StaticSaveVar; if (v) props->AddSet ("StaticSaveVar", this, "StaticSaveVar", Format("%v", v)); + // update position on objects that had a shape change through rotation because creation at def bottom would incur a vertical offset + if (GetR() && !Contained()) props->AddCall("SetPosition", this, "SetPosition", GetX(), GetY()); + // Commands: Could store the whole command stack using AppendCommand. + // However, usually there is one base command and the rest is derived + // (e.g.: A Get command may lead to multiple MoveTo commands to the + // target object). So just store the topmost command. + var command, last_command, i=0; + while (command = GetCommand(0, i++)) last_command = command; + if (last_command) + { + i-=2; + props->AddCall("Command", this, "SetCommand", Format("%v", last_command), + SaveScenarioValue2String(GetCommand(1,i)), // target + SaveScenarioValue2String(GetCommand(2,i)), // x + SaveScenarioValue2String(GetCommand(3,i)), // y + SaveScenarioValue2String(GetCommand(4,i)), // target2 + SaveScenarioValue2String(GetCommand(5,i))); // data + } + // Effects + var fx; i=0; + while (fx = GetEffect("*", this, i++)) EffectCall(this, fx, "SaveScen", props); + return true; +} + +global func SaveScenarioObjectAction(props) +{ + // Helper function to store action properties + var v; + props->AddCall("Action", this, "SetAction", Format("%v", GetAction() ?? "Idle"), GetActionTarget(), GetActionTarget(1)); + if (v = GetPhase()) props->AddCall("Phase", this, "SetPhase", v); + return true; +} + + +global func FxFireSaveScen(object obj, proplist fx, proplist props) +{ + // this is burning. Save incineration to scenario. + props->AddCall("Fire", obj, "Incinerate", fx.strength, fx.caused_by, fx.blasted, fx.incinerating_object); + return true; +} + + +/* Helper functions for value formatting */ + +// Helper function to turn values of several types into a strings to be written to Objects.c +global func SaveScenarioValue2String(v, bitmask_prefix) +{ + var rval; + if (bitmask_prefix) return GetConstantNameByValueSafe(v, bitmask_prefix); + if (GetType(v) == C4V_C4Object) return v->MakeScenarioSaveName(); + if (GetType(v) == C4V_Array) // save procedure for arrays: recurse into contents (cannot save arrays pointing into itself that way) + { + for (var el in v) + { + if (rval) rval = Format("%s,%s", rval, SaveScenarioValue2String(el)); + else rval = SaveScenarioValue2String(el); + } + if (rval) rval = Format("[%s]", rval); else rval = "[]"; + return rval; + } + if (GetType(v) == C4V_PropList || GetType(v) == C4V_Def) // custom save procedure for some prop lists or definitions + { + rval = v->~ToString(); + if (rval) return rval; + } + // Otherwise, rely on the default %v formatting + return Format("%v", v); +} + +global func GetBitmaskNameByValue(v, prefix) +{ + // Compose bitmask of names of individual bits + // e.g. GetBitmaskNameByValue(3, "C4D_") == "C4D_StaticBack|C4D_Structure" + var s, n=0; + for (var i=0; i<31 && v; ++i) + { + var v2 = 1<Remove(SAVEOBJ_ContentsCreation) + this->Remove(SAVEOBJ_Creation); +} + +global func SaveScenP_Clear() +{ + // Remove all property and creation data + this.data = nil; + return true; +} + +global func SaveScenP_AddCall(string name, proplist obj, string set_fn) +{ + // add string of style Obj123->SetFoo(bar, baz, ...) + // string parameters will not be quoted, so the caller can do some parameter formatting + // compose parameter string + var max_pars = 10, last_written = 2, set_pars = "", n_pars = 0; + for (var i=3; iAdd(name, "%s->%s(%s)", obj->MakeScenarioSaveName(), set_fn, set_pars); +} + +global func SaveScenP_AddSet(string name, object obj, string local_name, value) +{ + // add string of style Obj123->local_name = value + // string parameters will not be quoted, so the caller can do some parameter formatting + if (GetType(value) != C4V_String) value = SaveScenarioValue2String(value); + return this->Add(name, "%s.%s = %s", obj->MakeScenarioSaveName(), local_name, value); +} + +global func SaveScenP_Buffer2File(f) +{ + // buffer.data is an array of strings to be written to file f + if (!this.data) return false; + var i=0, indent = ""; + for (var creation in [true, false]) + { + for (var v in this.data) + { + var v_is_creation = ((v.name == SAVEOBJ_Creation) || (v.name == SAVEOBJ_ContentsCreation)); + if (v_is_creation != creation) continue; + if (i || !creation) indent = " "; + FileWrite(f, Format("%s%s;\n", indent, v.s)); + ++i; + } + } + return i; +} + +global func SaveScenP_HasData() +{ + // Anything added to data array? + return !!this.data; +} + +global func SaveScenP_HasCreation() +{ + // Functions to test whether any creation data has been added + if (!this.data) return false; + for (var v in this.data) if ((v.name == SAVEOBJ_Creation) || (v.name == SAVEOBJ_ContentsCreation)) return true; + return false; +} + +global func SaveScenP_HasProps() +{ + // Functions to test whether any property data has been added + if (!this.data) return false; + for (var v in this.data) if ((v.name != SAVEOBJ_Creation) && (v.name != SAVEOBJ_ContentsCreation)) return true; + return false; +} + +global func SaveScenP_HasProp(string prop) +{ + // Test if specific prop is present + if (!this.data) return false; + for (var v in this.data) if (v.name == prop) return true; + return false; +} + +global func SaveScenP_TakeProps() +{ + // Remove all props from this data and add them to a copy of this + var result = { Prototype = this.Prototype }; + if (this.data) + { + var creation = nil, props = nil; + for (var v in this.data) + if ((v.name != SAVEOBJ_Creation) && (v.name != SAVEOBJ_ContentsCreation)) + if (!props) props = [v]; else props[GetLength(props)] = v; + else + if (!creation) creation = [v]; else creation[GetLength(creation)] = v; + this.data = creation; + result.data = props; + result.origin = this; + } + return result; +} diff --git a/planet/System.ocg/Schedule.c b/planet/System.ocg/Schedule.c index cc7052a15..225e1735d 100644 --- a/planet/System.ocg/Schedule.c +++ b/planet/System.ocg/Schedule.c @@ -11,60 +11,93 @@ global func Schedule(object obj, string script, int interval, int repeats) // Defaults. if (!repeats) repeats = 1; - // in CR, it was possible to leave out obj in local calls. - // In OC, obj=nil means schedule without object context - //if (!obj) - // obj = this; // Create effect. var effect = AddEffect("IntSchedule", obj, 1, interval, obj); if (!effect) return false; // Set variables. - effect.script = script; - effect.repeats = repeats; + effect.Script = script; + effect.Repeats = repeats; return true; } -global func FxIntScheduleTimer(object obj, effect) +global func FxIntScheduleTimer(object obj, proplist effect) { // Just a specific number of repeats. - var done = --effect.repeats <= 0; + var done = --effect.Repeats <= 0; // Execute. - eval(effect.script); - return -done; + eval(effect.Script); + // Remove schedule if done. + if (done) + return FX_Execute_Kill; + return FX_OK; +} + +// Adds a timed call to an object, replacement of DefCore TimerCall. +global func AddTimer(call_function, int interval) +{ + if (!this) + return false; + // Default to one second. + if (interval == nil) + interval = 36; + // Create effect and add function and repeat infinitely. + var effect = AddEffect("IntScheduleCall", this, 1, interval, this); + effect.Function = call_function; + effect.NoStop = true; + effect.Pars = []; + return true; +} + +// removes a timer from an object that was added earlier with AddTimer. This removes exactly one timer that fits to the name and returns true on success +global func RemoveTimer(call_function /* name or pointer to the timer to remove */) +{ + if(!this) + return false; + + var effect, index = 0; + while(effect = GetEffect("IntScheduleCall", this, index++)) + { + if(effect.Function != call_function) continue; + if(effect.NoStop != true) continue; + RemoveEffect(nil, this, effect); + return true; + } + + // not found + return false; } // Executes a function repetitively with delay. -global func ScheduleCall(object obj, string function, int interval, int repeats, par0, par1, par2, par3, par4) +global func ScheduleCall(object obj, call_function, int interval, int repeats, par0, par1, par2, par3, par4) { // Defaults. if (!repeats) repeats = 1; - // in CR, it was possible to leave out obj in local calls. - // In OC, obj=nil means schedule without object context - //if (!obj) - // obj = this; // Create effect. var effect = AddEffect("IntScheduleCall", obj, 1, interval, obj); if (!effect) return false; // Set variables. - effect.function = function; - effect.repeats = repeats; - effect.par = [par0, par1, par2, par3, par4]; + effect.Function = call_function; + effect.Repeats = repeats; + effect.Pars = [par0, par1, par2, par3, par4]; return true; } -global func FxIntScheduleCallTimer(object obj, effect) +global func FxIntScheduleCallTimer(object obj, proplist effect) { // Just a specific number of repeats. - var done = --effect.repeats <= 0; + var done = --effect.Repeats <= 0; // Execute. - Call(effect.function, effect.par[0], effect.par[1], effect.par[2], effect.par[3], effect.par[4]); - return -done; + Call(effect.Function, effect.Pars[0], effect.Pars[1], effect.Pars[2], effect.Pars[3], effect.Pars[4]); + // Remove schedule call if done, take into account infinite schedules. + if (done && !effect.NoStop) + return FX_Execute_Kill; + return FX_OK; } -global func ClearScheduleCall(object obj, string function) +global func ClearScheduleCall(object obj, call_function) { var i, effect; // Count downwards from effectnumber, to remove effects. @@ -73,8 +106,8 @@ global func ClearScheduleCall(object obj, string function) // Check All ScheduleCall-Effects. if (effect = GetEffect("IntScheduleCall", obj, i)) // Found right function. - if (effect.function == function) + if (effect.Function == call_function) // Remove effect. - RemoveEffect(0, obj, effect); + RemoveEffect(nil, obj, effect); return; } diff --git a/planet/System.ocg/StringTblDE.txt b/planet/System.ocg/StringTblDE.txt new file mode 100644 index 000000000..31289c6e8 --- /dev/null +++ b/planet/System.ocg/StringTblDE.txt @@ -0,0 +1,88 @@ +SET_WASD_QWERTZ=Tastatur und Maus +SET_Gamepad=Gamepad + +CON_Jump=Springen +CON_Jump_Desc=Im Laufen abspringen, aus dem Wasser springen oder sich von einer Wand abstoßen. + +CON_AimAxisLeft=Zielen - Links (Analog Stick) +CON_AimAxisRight=Zielen - Rechts (Analog Stick) +CON_AimAxisUp=Zielen - Hoch (Analog Stick) +CON_AimAxisDown=Zielen - Runter (Analog Stick) + +CON_Throw=Werfen +CON_Throw_Desc=Werfen des Gegenstandes in der Hand in die anvisierte Richtung. +CON_ThrowAlt=Werfen (andere Hand) +CON_ThrowAlt_Desc=Werfen des Gegenstandes in der anderen Hand in die anvisierte Richtung. + +CON_Drop=Ablegen +CON_Drop_Desc=Ablegen des Gegenstandes in der Hand. +CON_DropAlt=Ablegen (andere Hand) +CON_DropAlt_Desc=Ablegen des Gegenstandes in der anderen Hand. + +CON_Use=Benutzen +CON_Use_Desc=Benutzen des Gegenstandes in der Hand. +CON_UseAlt=Benutzen (andere Hand) +CON_UseAlt_Desc=Benutzen des Gegenstandes in der anderen Hand. + +CON_Hotkey1=Hotkey 1 +CON_Hotkey2=Hotkey 2 +CON_Hotkey3=Hotkey 3 +CON_Hotkey4=Hotkey 4 +CON_Hotkey5=Hotkey 5 +CON_Hotkey6=Hotkey 6 +CON_Hotkey7=Hotkey 7 +CON_Hotkey8=Hotkey 8 +CON_Hotkey9=Hotkey 9 +CON_Hotkey0=Hotkey 10 + +CON_Contents=Inventarmenü +CON_Contents_Desc=Öffnen und schließen des Inventarmenüs. Ãœber das Inventarmenü können Gegenstände aus Truhen, Loren usw. herausgenommen und hineingetan werden sowie Dinge mit anderen Clonks getauscht werden. +CON_PlayerMenu=Spielermenü +CON_PlayerMenu_Desc=Öffnen und schließen des Spielermenüs. + +CON_MenuSelect=Menü - Auswählen +CON_MenuSelect_Desc=Bestätigen einer Auswahl im Menü. +CON_MenuCancel=Menü: Schließen +CON_MenuCancel_Desc=Schließen eines Menüs ohne eine Auswahl getroffen zu haben. +CON_MenuOKAll=Menü - okay, alle +CON_MenuOK=Menü: OK +CON_MenuOK_Desc=Im Menü bestätigen. + +CON_NextCrew=Nächster Clonk +CON_NextCrew_Desc=Auswählen des nächsten Clonks der eigenen Mannschaft. Im Spiel wird die eigene Mannschaft in der Anzeige am oberen Bildschirmrand angezeigt. +CON_PreviousCrew=Letzter Clonk +CON_PreviousCrew_Desc=Auswählen des vorherigen Clonks der eigenen Mannschaft. Im Spiel wird die eigene Mannschaft in der Anzeige am oberen Bildschirmrand angezeigt. +CON_ZoomIn=Reinzoomen +CON_ZoomIn_Desc=In die Spielwelt hineinzoomen um Details sichtbar zu machen. +CON_ZoomOut=Rauszoomen +CON_ZoomOut_Desc=Aus der Spielwelt herauszoomen um eine Ãœbersicht zu bekommen. + +# -- Assignment specific strings + +KEY_MouseUse=Benutzen / Werfen +KEY_MouseUse_Desc=Benutzen des Gegenstandes in der Hand. Falls der Gegenstand nicht benutzt werden kann, wird er stattdessen in die Richtung geworfen in die der Cursor zeigt. +KEY_MouseUseAlt=Benutzen / Werfen (andere Hand) +KEY_MouseUseAlt_Desc=Benutzen des Gegenstandes in der anderen Hand. Falls der Gegenstand nicht benutzt werden kann, wird er stattdessen in die Richtung geworfen in die der Cursor zeigt. + +KEY_GamepadUse=Benutzen / Werfen +KEY_GamepadUse_Desc=Benutzen des Gegenstandes in der Hand. Falls der Gegenstand nicht benutzt werden kann, wird er stattdessen bei Loslassen der Taste in die Richtung geworfen in die mit dem Analog Stick gezielt wird. +KEY_GamepadUseAlt=Benutzen / Werfen (andere Hand) +KEY_GamepadUseAlt_Desc=Benutzen des Gegenstandes in der anderen Hand. Falls der Gegenstand nicht benutzt werden kann, wird er stattdessen bei Loslassen der Taste in die Richtung geworfen in die mit dem Analog Stick gezielt wird. + +KEY_Left=Links +KEY_Left_Desc=Nach links laufen, schwimmen, hangeln oder sich nach links von einer Wand abstoßen. Beim Klettern links an einer Wand kann hiermit ein Gegenstand aufgenommen werden der in der Wand steckt. +KEY_Right=Rechts +KEY_Right_Desc=Nach rechts laufen, schwimmen, hangeln oder sich nach rechts von einer Wand abstoßen. Beim Klettern rechts an einer Wand kann hiermit ein Gegenstand aufgenommen werden der in der Wand steckt. +KEY_Up=Hoch +KEY_Up_Desc=Nach oben klettern oder schwimmen. Beim Hangeln wird hiermit ein Gegenstand aufgesammelt der in der Decke steckt. +KEY_Down=Runter +KEY_Down_Desc=Nach unten klettern, schwimmen oder sich beim Hangeln fallen lassen. Im Stehen wird hiermit ein herumliegender Gegenstand aufgesammelt. + +KEY_AimAxis_Desc=Mit dem Analog Stick zum Werfen oder Benutzen eines Gegenständes zielen. Kann auch statt den Richtungstasten zum Steuern des Clonks verwendet werden. + +KEY_Interact=Interagieren +KEY_Interact_Desc=Interagieren mit Fahrzeugen, Gebäuden und anderen Dingen die bei dem Clonk stehen: Gebäude betreten und verlassen, Fahrzeuge anfassen und in Gebäude schieben, Werkzeuge und Waffen in Werkstätten herstellen und vieles mehr. + +KEY_Hotkey_Desc=Hotkeys:|Nr + l/r Maustaste - Den jeweiligen Gegenstand in die eine/andere Hand nehmen|Nr + Shift - Den jeweiligen Gegenstand ablegen|Nr + Interagieren - Mit dem jeweiligen Ding interagieren|Nr + Strg - Den jeweiligen Clonk aus der Mannschaftsleiste auswählen + +KEY_Ungrab=Fahrzeug loslassen \ No newline at end of file diff --git a/planet/System.ocg/StringTblUS.txt b/planet/System.ocg/StringTblUS.txt new file mode 100644 index 000000000..4a59a8554 --- /dev/null +++ b/planet/System.ocg/StringTblUS.txt @@ -0,0 +1,88 @@ +SET_WASD_QWERTZ=Keyboard and mouse +SET_Gamepad=Gamepad + +CON_Jump=Jump +CON_Jump_Desc=Jump while running, jump out of the water or leap from a wall. + +CON_AimAxisLeft=Aim - Left (Analog Stick) +CON_AimAxisRight=Aim - Right (Analog Stick) +CON_AimAxisUp=Aim - Up (Analog Stick) +CON_AimAxisDown=Aim - Down (Analog Stick) + +CON_Throw=Throw +CON_Throw_Desc=Throw the item in the hand into the aimed direction. +CON_ThrowAlt=Throw (other hand) +CON_ThrowAlt_Desc=Throw the item in the other hand into the aimed direction. + +CON_Drop=Drop +CON_Drop_Desc=Drop the item in the hand. +CON_DropAlt=Drop (other hand) +CON_DropAlt_Desc=Drop the item in the other hand. + +CON_Use=Use +CON_Use_Desc=Use the item in the hand. +CON_UseAlt=Use (other hand) +CON_UseAlt_Desc=Use the item in the other hand. + +CON_Hotkey1=Hotkey 1 +CON_Hotkey2=Hotkey 2 +CON_Hotkey3=Hotkey 3 +CON_Hotkey4=Hotkey 4 +CON_Hotkey5=Hotkey 5 +CON_Hotkey6=Hotkey 6 +CON_Hotkey7=Hotkey 7 +CON_Hotkey8=Hotkey 8 +CON_Hotkey9=Hotkey 9 +CON_Hotkey0=Hotkey 10 + +CON_Contents=Inventory menu +CON_Contents_Desc=Open and close the inventory menu. Through the inventory menu, you can take items from and put items into chests, lorries etc. as well as exchange items with other Clonks. +CON_PlayerMenu=Player menu +CON_PlayerMenu_Desc=Open and close the player menu. + +CON_MenuSelect=Menu - Select +CON_MenuSelect_Desc=Confirm a selection in a menu. +CON_MenuCancel=Menu - Close +CON_MenuCancel_Desc=Close a menu without having selected anything. +CON_MenuOKAll=Menü: okay, alle +CON_MenuOK=Menü: OK +CON_MenuOK_Desc=Confirm in a menu. + +CON_NextCrew=Next Clonk +CON_NextCrew_Desc=Select the next clonk in your crew. Your crew is displayed at the upper edge of the screen in the game. +CON_PreviousCrew=Previous Clonk +CON_PreviousCrew_Desc=Select the previous clonk in your crew. Your crew is displayed at the upper edge of the screen in the game. +CON_ZoomIn=Zoom in +CON_ZoomIn_Desc=Zoom into the game world to make visible more details. +CON_ZoomOut=Zoom out +CON_ZoomOut_Desc=Zoom out of the game world to get an overview. + +# -- Assignment specific strings + +KEY_MouseUse=Use / Throw +KEY_MouseUse_Desc=Use the item in the hand. If the item cannot be used, it is thrown into the direction of the cursor instead. +KEY_MouseUseAlt=Use / Throw (other hand) +KEY_MouseUseAlt_Desc=Use the item in the other hand. If the item cannot be used, it is thrown into the direction of the cursor instead. + +KEY_GamepadUse=Use / Throw +KEY_GamepadUse_Desc=Use the item in the hand. If the item cannot be used, it is thrown into the direction in which you aim with the analog stick on release. +KEY_GamepadUseAlt=Use / Throw (other hand) +KEY_GamepadUseAlt_Desc=Use the item in the other hand. If the item cannot be used, it is thrown into the direction in which you aim with the analog stick on release. + +KEY_Left=Left +KEY_Left_Desc=Run, swim, hangle to the left or let go from a right wall. While climbing on a left wall, you can collect an item that is stuck in it with this key. +KEY_Right=Right +KEY_Right_Desc=Run, swim, hangle to the right or let go from a left wall. While climbing on a right wall, you can collect an item that is stuck in it with this key. +KEY_Up=Up +KEY_Up_Desc=Climb or swim up. While hangling, you can collect an item that is stuck in the ceiling. +KEY_Down=Down +KEY_Down_Desc=Climb, swim down or drop down from the ceiling while hangling. While standing on the ground, you can collect an item that is lying about. + +KEY_AimAxis_Desc=Aim with the analog stick to throw or use some item into a direction. Can also be used instead of the direction pad for controlling the Clonk. + +KEY_Interact=Interact +KEY_Interact_Desc=Interact with vehicles, buildings and other things that stand next to the Clonk: enter and exit buildings, control and push vehicles into buildings, produce tools and weapons in workshops and much more. + +KEY_Hotkey_Desc=Hotkeys:|No + l/r mouse click - Take the respective item in the/the other hand|No + Shift - Drop the respective item|No + Interact - Interact with the respective thing|No + Ctrl - Select the respective clonk from the crew list + +KEY_Ungrab=Let go vehicle \ No newline at end of file diff --git a/planet/Tests.ocf/AI.ocs/Scenario.txt b/planet/Tests.ocf/AI.ocs/Scenario.txt new file mode 100644 index 000000000..9a0ef1b06 --- /dev/null +++ b/planet/Tests.ocf/AI.ocs/Scenario.txt @@ -0,0 +1,10 @@ +[Head] +Title=AIBattle +Version=5,3,2 +MaxPlayer=2 + +[Definitions] +Definition2=Experimental.ocd\EnemyAI.ocd + +[Landscape] +MapWidth=20 diff --git a/planet/Tests.ocf/AI.ocs/Script.c b/planet/Tests.ocf/AI.ocs/Script.c new file mode 100644 index 000000000..01bb035c2 --- /dev/null +++ b/planet/Tests.ocf/AI.ocs/Script.c @@ -0,0 +1,47 @@ +func Initialize() +{ + // Script player as opponent. + CreateScriptPlayer("S2", 0xffffc000, nil, CSPF_FixedAttributes); +} + +func InitializePlayer(int plr) +{ + if (GetPlayerType(plr) == C4PT_Script) return InitializeScriptPlayer(plr); + GetCrew(plr)->SetPosition(LandscapeWidth()-10, 190); + GetCrew(plr)->CreateContents(Bow); + GetCrew(plr)->CreateContents(Arrow); + GetCrew(plr)->CreateContents(Rock); + GetCrew(plr)->CreateContents(Rock); + GetCrew(plr)->CreateContents(Rock); + GetCrew(plr)->CreateContents(Rock); + GetCrew(plr)->CreateContents(Rock); + GetCrew(plr)->CreateContents(Rock); + return true; +} + +func InitializeScriptPlayer(int plr) +{ + // Remove old crew. + var index = 0; + while (GetCrew(plr, index)) + { + GetCrew(plr, index)->RemoveObject(); + index++; + } + // Create enemies + CreateEnemy(Clonk, 40,200, plr, [Rock, Rock, Sword, Shield], 40); + return; +} + +func CreateEnemy(id clonktype, int x,int y, int plr, array contents, int life) +{ + var enemy = CreateObject(clonktype, x, y, plr); + if (!enemy) return nil; + enemy->SetDir(DIR_Right); + enemy->MakeCrewMember(plr); + enemy->SetMaxEnergy(life); + if (contents) for (var c in contents) enemy->CreateContents(c); + S2AI->AddAI(enemy); + //CreateObject(EnergyBar)->SetTarget(enemy); + return enemy; +} diff --git a/planet/Tests.ocf/AirRace.ocs/DescDE.rtf b/planet/Tests.ocf/AirRace.ocs/DescDE.rtf deleted file mode 100644 index 583b9f574..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/DescUS.rtf b/planet/Tests.ocf/AirRace.ocs/DescUS.rtf deleted file mode 100644 index 064760c1b..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Boompack.skeleton b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Boompack.skeleton deleted file mode 100644 index 5af94ec94..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Boompack.skeleton and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/DefCore.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/DefCore.txt deleted file mode 100644 index 7f11dc1c7..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/DefCore.txt +++ /dev/null @@ -1,16 +0,0 @@ -[DefCore] -id=GuidedRocket -Version=5,2,0,1 -Category=C4D_Object -Width=8 -Height=14 -Offset=-4,-7 -Vertices=4 -VertexX=2,-2,-4,4 -VertexY=-4,-4,7,7 -VertexFriction=80,60,60 -Value=10 -Mass=8 -Components=Blackpowder=3;Wood=1;Metal=1; -Rotate=1 -ColorByOwner=1 diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Graphics.mesh b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Graphics.mesh deleted file mode 100644 index 1db1cd04f..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Graphics.mesh and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Script.c b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Script.c deleted file mode 100644 index e79eb2eb9..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/Script.c +++ /dev/null @@ -1,64 +0,0 @@ -/*-- - Guided Rocket - Author: Maikel - - Ammunition for the airplane ---*/ - -#include Rocket - -public func MaxStackCount() { return 2; } - -protected func FxIntFlightTimer(object target, effect, int time) -{ - if(fuel<=0) - DoFireworks(); - - var ignition = time % 9; - - // speed up rocket to certain speed. - var angle = GetR(); - var speed = Distance(0, 0, GetXDir(100), GetYDir(100)); - speed += Max(0, (Rocket_MaxSpeed * 10 - speed) / 12); - SetXDir(Sin(angle, speed), 100); - SetYDir(-Cos(angle, speed), 100); - - - // Check if there is a plane to explode at. - if (time > 10) - if (FindObject(Find_ID(Plane), Find_Exclude(shooter), Find_Exclude(this), Find_AtPoint())) - DoFireworks(); - - // Follow nearest other vehicle. - for (var to_follow in FindObjects(Find_ID(Plane), Find_Exclude(shooter), Find_Exclude(this), Find_Distance(300), Sort_Distance())) - { - // Vehicle must be in 60 degree front wedge. - var angle = Angle(GetX(), GetY(), to_follow->GetX(), to_follow->GetY()); - if (Inside(Abs(angle - GetR()), 3, 60)) - { - if (angle > GetR()) - SetR(GetR() + 4); - if (angle < GetR()) - SetR(GetR() - 4); - break; - } - } - - var sizemod = ignition*ignition/5; - - var x = -Sin(GetR(),16); - var y = Cos(GetR(),16); - - CreateParticle("ExploSmoke",x,y,RandomX(-1,1),RandomX(-1,2),RandomX(80,180),RGBa(130,130,130,75)); - CreateParticle("Thrust",x,y,GetXDir()/2,GetYDir()/2,RandomX(45,70)+sizemod,RGBa(255,200,200,160)); - - fuel--; -} - -func Definition(def) -{ - SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(30,0,0,1),Trans_Rotate(-30,1,0,0),Trans_Scale(1300)),def); -} -local Collectible = 1; -local Name = "$Name$"; -local Description = "$Description$"; diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/StringTblDE.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/StringTblDE.txt deleted file mode 100644 index 440067993..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Boompack -Description=Ziele und drücke [Benutzen], um die Rakete zu zünden und auf ihr in eine beliebige Richtung katapultiert zu werden. \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/StringTblUS.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/StringTblUS.txt deleted file mode 100644 index 9a9fe1b80..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Guided Rocket -Description=Can be hung under an airplane, especially suited for destroying moving targets. \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/boompack.png b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/boompack.png deleted file mode 100644 index b4da738b7..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/GuidedRocket.ocd/boompack.png and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Boompack.skeleton b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Boompack.skeleton deleted file mode 100644 index 5af94ec94..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Boompack.skeleton and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/DefCore.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/DefCore.txt deleted file mode 100644 index af6168155..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/DefCore.txt +++ /dev/null @@ -1,16 +0,0 @@ -[DefCore] -id=Rocket -Version=5,2,0,1 -Category=C4D_Object -Width=8 -Height=14 -Offset=-4,-7 -Vertices=4 -VertexX=2,-2,-4,4 -VertexY=-4,-4,7,7 -VertexFriction=80,60,60 -Value=10 -Mass=8 -Components=Blackpowder=3;Wood=1;Metal=1; -Rotate=1 -ColorByOwner=1 diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Graphics.mesh b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Graphics.mesh deleted file mode 100644 index 1db1cd04f..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Graphics.mesh and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Script.c b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Script.c deleted file mode 100644 index 654e4d2d6..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/Script.c +++ /dev/null @@ -1,107 +0,0 @@ -/*-- - Rocket - Author: Maikel - - Ammunition for the airplane ---*/ - -#include Library_Stackable - -static const Rocket_MaxSpeed = 150; - -local fuel; -local shooter; - -public func MaxStackCount() { return 3; } -public func IsPlaneWeapon() { return true; } -public func GetCoolDownTime() { return 20; } - -protected func Initialize() -{ - //flight length - fuel=100; -} - -public func SetShooter(object plane) -{ - shooter = plane; - return; -} - -public func Launch(object plane, int angle) -{ - var rocket = TakeObject(); - rocket->SetProperty("Collectible",0); - rocket->SetCategory(C4D_Vehicle); - rocket->SetShooter(plane); - - rocket->Exit(); - AddEffect("IntFlight", rocket, 150, 1, rocket); - - var level = 6; - var i=0, count = 3+level/8, r = Random(360); - while (count > 0 && ++i < count*6) - { - r += RandomX(40,80); - var smokex = +Sin(r,RandomX(level/4,level/2)); - var smokey = -Cos(r,RandomX(level/4,level/2)); - if(GBackSolid(smokex,smokey)) - continue; - CreateSmokeTrail(2*level,r,smokex,smokey,nil,true); - count--; - } - - rocket->SetR(plane->GetR()); - var speed = Distance(0, 0, plane->GetXDir(), plane->GetYDir()); - rocket->SetVelocity(angle, speed); -} - -protected func FxIntFlightTimer(object target, effect, int time) -{ - if(fuel<=0) - DoFireworks(); - - var ignition = time % 9; - - // speed up rocket to certain speed. - var angle = GetR(); - var speed = Distance(0, 0, GetXDir(100), GetYDir(100)); - speed += Max(0, (Rocket_MaxSpeed * 10 - speed) / 15); - SetXDir(Sin(angle, speed), 100); - SetYDir(-Cos(angle, speed), 100); - - // Check if there is a plane to explode at. - if (time > 10) - if (FindObject(Find_ID(Plane), Find_Exclude(shooter), Find_Exclude(this), Find_AtPoint())) - DoFireworks(); - - var sizemod = ignition*ignition/5; - - var x = -Sin(GetR(),16); - var y = Cos(GetR(),16); - - CreateParticle("ExploSmoke",x,y,RandomX(-1,1),RandomX(-1,2),RandomX(80,180),RGBa(130,130,130,75)); - CreateParticle("Thrust",x,y,GetXDir()/2,GetYDir()/2,RandomX(45,70)+sizemod,RGBa(255,200,200,160)); - - fuel--; -} - -protected func Hit() -{ - if(GetEffect("IntFlight",this)) DoFireworks(); - Sound("WoodHit"); -} - -func DoFireworks() -{ - RemoveEffect("IntFlight",this); - Fireworks(); - Explode(30); -} - -func Definition(def) { - SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(30,0,0,1),Trans_Rotate(-30,1,0,0),Trans_Scale(1300)),def); -} -local Collectible = 1; -local Name = "$Name$"; -local Description = "$Description$"; diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/StringTblDE.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/StringTblDE.txt deleted file mode 100644 index c4ae3ed18..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Rocket -Description=Ziele und drücke [Benutzen], um die Rakete zu zünden und auf ihr in eine beliebige Richtung katapultiert zu werden. \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/StringTblUS.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/StringTblUS.txt deleted file mode 100644 index bd6fbf4d2..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Rocket -Description=Can be hung under an airplane, especially suited for destroying static targets. \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/boompack.png b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/boompack.png deleted file mode 100644 index b4da738b7..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/Rocket.ocd/boompack.png and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/Graphics.png b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/Graphics.png deleted file mode 100644 index 2ccaf89ee..000000000 Binary files a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/Script.c b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/Script.c deleted file mode 100644 index 5134501da..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/Script.c +++ /dev/null @@ -1,108 +0,0 @@ -/*-- - Weapon Spawn - Author: Maikel - - Spawns weapons for the air plane, pick up on fly through. ---*/ - -/*-- Checkpoint size --*/ -local ws_size; - -public func SetSpawnSize(int size) -{ - ws_size = BoundBy(size, 10, 100); - return; -} - -public func GetSpawnSize() { return ws_size; } - -/*-- Initialize --*/ - -local spawn_weapon; - -protected func Initialize() -{ - ws_size = 20; - spawn_weapon = FindSpawnWeapon(); - UpdateGraphics(); - AddEffect("IntWeaponSpawn", this, 100, 1, this); - return; -} - -protected func FxIntWeaponSpawnTimer(object target, effect, int fxtime) -{ - // Check if there is a weapon. - if (!spawn_weapon && !GetEffect("IntSpawnWait", this)) - FindSpawnWeapon(); - // Check for planes. - if (!(fxtime % 5)) - CheckForPlanes(); - // Update graphics. - UpdateGraphics(fxtime); - return FX_OK; -} - -protected func CheckForPlanes() -{ - // Loop through all clonks inside the checkpoint. - var plane = FindObject(Find_ID(Plane), Find_Distance(ws_size), Sort_Distance()); - if (!plane) - return; - if (!spawn_weapon) - return; - - plane->CreateContents(spawn_weapon); - spawn_weapon = nil; - DoGraphics(); - AddEffect("IntSpawnWait", this, 100, 108, this); - return; -} - -protected func FxIntSpawnWaitStop() -{ - return 1; -} - -protected func FindSpawnWeapon() -{ - var index = 0, weapon_def, weapon_list = []; - while (weapon_def = GetDefinition(index)) - { - if (weapon_def->~IsPlaneWeapon()) - weapon_list[GetLength(weapon_list)] = weapon_def; - index++; - } - spawn_weapon = weapon_list[Random(GetLength(weapon_list))]; - DoGraphics(); - return; -} - -// Mode graphics. -protected func DoGraphics() -{ - // Clear all overlays first. - SetGraphics(0, 0, 1); - if (spawn_weapon) - { - SetGraphics("", spawn_weapon, 1, GFXOV_MODE_Base); - SetObjDrawTransform(50 * ws_size, 0, 0, 0, 50 * ws_size, 0, 1); - //SetClrModulation(RGBa(255, 255, 255, 160) , 1); - } - return; -} - -// Player graphics. -protected func UpdateGraphics(int time) -{ - // Create two sparks at opposite sides. - var angle = (time * 10) % 360; - var color = RGB(255, 255, 255); - CreateParticle("PSpark", Sin(angle, ws_size), -Cos(angle, ws_size), 0, 0, 32, color); - angle = (angle + 180) % 360; - var color = RGB(255, 255, 255); - CreateParticle("PSpark", Sin(angle, ws_size), -Cos(angle, ws_size), 0, 0, 32, color); - return; -} - -/*-- Proplist --*/ -local Name = "$Name$"; diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/StringTblDE.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/StringTblDE.txt deleted file mode 100644 index aad8d05e9..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Waffenspawn - diff --git a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/StringTblUS.txt b/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/StringTblUS.txt deleted file mode 100644 index 4fc125b10..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Extra.ocd/WeaponSpawn.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Weapon Spawn - diff --git a/planet/Tests.ocf/AirRace.ocs/Landscape.txt b/planet/Tests.ocf/AirRace.ocs/Landscape.txt deleted file mode 100644 index 94ed5112c..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Landscape.txt +++ /dev/null @@ -1,95 +0,0 @@ -/*-- AirRace --*/ - -// Rndchecker filler pattern for RandomMatFill. -overlay Mats -{ - algo = rndchecker; - a = 8; - zoomX = -50; zoomY = -50; - turbulence = 500; loosebounds = 1; -}; - -// Fills the specified region with some random materials. -overlay RandomMatFill -{ - overlay { mat = Earth; tex = earth; loosebounds = 1; }; - Mats { mat = Gold; tex = gold; a = 20; }; - Mats { mat = Ore; tex = ore; a = 20; }; - Mats { mat = Tunnel; tex = tunnel; a = 20; }; - Mats { mat = Rock; tex = rock; a = 20; }; - Mats { mat = Gold; tex = gold; a = 20; }; - Mats { mat = Ore; tex = ore; a = 20; }; - Mats { mat = Tunnel; tex = tunnel; a = 20; }; - Mats { mat = Rock; tex = rock; a = 20; }; - Mats { mat = Earth; tex = earth_dry; }; - Mats { mat = Earth; tex = earth_rough; }; -}; - - -// A challenging map to fly through with the airplane. -map AirRace -{ - // Random parkour, with sky islands, cliffs, caverns, etc. - // TODO: Remove if map is nice. - overlay - { - algo = rndchecker; - x = 0; y = 0; - wdt = 100; hgt = 100; - RandomMatFill{}; - zoomX = -50; zoomY = -50; - a = 6; - loosebounds = 1; - turbulence = 1000; - }; - - // Sky island on the left, to take off from. - overlay - { - x = 0; y = 50; - wdt = 12; hgt = 10; - }; - overlay - { - x = 0; y = 60; - wdt = 6; hgt = 4; - mat = BrickSoft; tex = brick1; - }; - overlay - { - algo = poly; - RandomMatFill{}; - loosebounds = 1; - turbulence = 25; - point { x = 0%; y = 62%; }; - point { x = 0%; y = 66%; }; - point { x = 2%; y = 67%; }; - point { x = 5%; y = 66%; }; - point { x = 6%; y = 62%; }; - }; - - // Sky island on the right, to take finish on. - overlay - { - x = 88; y = 50; - wdt = 13; hgt = 10; - }; - overlay - { - x = 94; y = 60; - wdt = 7; hgt = 4; - mat = BrickSoft; tex = brick1; - }; - overlay - { - algo = poly; - RandomMatFill{}; - loosebounds = 1; - turbulence = 25; - point { x = 94%; y = 62%; }; - point { x = 94%; y = 66%; }; - point { x = 96%; y = 67%; }; - point { x = 99%; y = 66%; }; - point { x = 100%; y = 62%; }; - }; -}; \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Scenario.txt b/planet/Tests.ocf/AirRace.ocs/Scenario.txt deleted file mode 100644 index 7896f137c..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Scenario.txt +++ /dev/null @@ -1,34 +0,0 @@ -[Head] -Icon=37 -Title=AirRace - -[Game] -Goals=Goal_Parkour - -[Player1] -Crew=Clonk=1 - -[Player2] -Crew=Clonk=1 - -[Player3] -Crew=Clonk=1 - -[Player4] -Crew=Clonk=1 - -[Landscape] -InEarth=Rock=1;Firestone=1;Loam=1 -InEarthLevel=40 -Sky=Clouds1 -TopOpen=1 -BottomOpen=1 -MapWidth=640 -MapHeight=160 -MapZoom=10 -SkyScrollMode=2 - -[Weather] -Climate=40 -YearSpeed=20,10 -Wind=0,100 \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Script.c b/planet/Tests.ocf/AirRace.ocs/Script.c deleted file mode 100644 index b0c018782..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Script.c +++ /dev/null @@ -1,177 +0,0 @@ -/*-- - AirRace - Author: Maikel - - Fly with an airplane round a parkour, the first one to reach the finish wins. - On the way some checkpoints must be passed, also weapons can be picked up. ---*/ - - -/*-- Scenario properties --*/ - -protected func Initialize() -{ - // Create the parkour. - CreateParkour(); - - // Create some weapon spawns. - CreateWeaponSpawns(); - - // Vegetation. - PlaceGrass(100); - - // Environment. - Cloud->Place(40); - - return; -} - -// Create parkour, start & finish on the brick islands, random separated checkpoints in-between. -private func CreateParkour() -{ - // Find parkour goal and create on if non-existent. - var goal = FindObject(Find_ID(Goal_Parkour)); - if (!goal) - goal = CreateObject(Goal_Parkour, 0, 0, NO_OWNER); - - var x, y; - // Create start checkpoint. - x = 50; y = LandscapeHeight() / 2; - while (!GBackSolid(x, y + 20) && y < LandscapeHeight()) - y += 20; - goal->SetStartpoint(x, y)->SetCPSize(40); - - // Create some checkpoints in between. - var mode = PARKOUR_CP_Check | PARKOUR_CP_Ordered | PARKOUR_CP_Respawn | PARKOUR_CP_Bonus; - for (var dx = 500; dx < LandscapeWidth() - 600; dx += RandomX(500, 600)) - { - var pos = FindCheckpointPosition(dx, 200, 250, LandscapeHeight() - 400, 40); - if (pos) - goal->AddCheckpoint(pos[0], pos[1], mode)->SetCPSize(40); - } - - // Create finish checkpoint. - x = LandscapeWidth() - 200; y = LandscapeHeight() / 2; - while (!GBackSolid(x, y + 20) && y < LandscapeHeight()) - y += 20; - goal->SetFinishpoint(x, y)->SetCPSize(40); - return; -} - -// Finds a position a plane - of size - can actually fly through, returns [x, y] as a position. -private func FindCheckpointPosition(int rx, int ry, int wdt, int hgt, int size) -{ - for (var i = 0; i < 500; i++) - { - var x = rx + Random(wdt); - var y = ry + Random(hgt); - // Not to close to other checkpoints. - if (FindObject(Find_Distance(800, x, y), Find_ID(ParkourCheckpoint))) - continue; - // Check circle of size, with 5x5 raster. - var found_pos = true; - for (var cx = -size; cx <= size; cx += 5) - for (var cy = -size; cy <= size; cy += 5) - if (Distance(0, 0, cx, cy) < size ** 2) - if (GBackSemiSolid(x + cx, y + cy)) - found_pos = false; - if (found_pos) - return [x, y]; - } - return nil; -} - -// Creates some weapon spawns, players have to fly through them to pick up the weapon. -private func CreateWeaponSpawns() -{ - for (var i = 0; i < 12; i++) - { - var pos = FindWeaponSpawnPosition(300, 200, LandscapeWidth() - 600, LandscapeHeight() - 400, 40); - if (pos) - CreateObject(WeaponSpawn, pos[0], pos[1], NO_OWNER)->SetSpawnSize(40); - } - return; -} - -// Finds a position a plane - of size - can actually fly through, returns [x, y] as a position. -private func FindWeaponSpawnPosition(int rx, int ry, int wdt, int hgt, int size) -{ - for (var i = 0; i < 500; i++) - { - var x = rx + Random(wdt); - var y = ry + Random(hgt); - // Not to close to other checkpoints. - if (FindObject(Find_Distance(700, x, y), Find_ID(WeaponSpawn))) - continue; - if (FindObject(Find_Distance(400, x, y), Find_ID(ParkourCheckpoint))) - continue; - // Check circle of size, with 5x5 raster. - var found_pos = true; - for (var cx = -size; cx <= size; cx += 5) - for (var cy = -size; cy <= size; cy += 5) - if (Distance(0, 0, cx, cy) < size ** 2) - if (GBackSemiSolid(x + cx, y + cy)) - found_pos = false; - if (found_pos) - return [x, y]; - } - return nil; -} - -/*-- Player respawn --*/ - -// Callback from parkour goal, on player respawn. -protected func OnPlayerRespawn(int plr, object cp) -{ - var clonk = GetCrew(plr); - var plane = CreateObject(Plane, cp->GetX(), cp->GetY(), plr); - clonk->Enter(plane); - //plane->CreateContents(Bullet); // there is no bullet def - var mode = cp->GetCPMode(); - if (mode & PARKOUR_CP_Start) - plane->SetR(90); - else if (mode & PARKOUR_CP_Respawn) - { - var angle = FindPlaneAngle(cp); - plane->StartInstantFlight(angle, 15); - } - return; -} - -private func FindPlaneAngle(object cp) -{ - // Start to the right. - var angle = 90, i = 0, dir = 1; - var x = cp->GetX(); - var y = cp->GetY(); - while (Abs(i) < 180) - { - if (PathFree(x, y, x + Sin(angle + i, 200), y + Cos(angle + i, 200))) - { - dir = 1; - break; - } - if (PathFree(x, y, x + Sin(angle - i, 200), y + Cos(angle - i, 200))) - { - dir = -1; - break; - } - i += 10; - } - return angle + dir * i; -} - -protected func GivePlrBonus(int plr, object cp) -{ - //var plane = GetCursor(plr)->Contained(); - //if (plane && plane->GetID() == Plane) - //plane->CreateContents(Bullet); // there is no bullet def - return; -} - -protected func InitializePlayer(int plr) -{ - // No fog ow war in this scenario. - SetFoW(false, plr); - return; -} diff --git a/planet/Tests.ocf/AirRace.ocs/System.ocg/Plane.c b/planet/Tests.ocf/AirRace.ocs/System.ocg/Plane.c deleted file mode 100644 index 25ec2cae5..000000000 --- a/planet/Tests.ocf/AirRace.ocs/System.ocg/Plane.c +++ /dev/null @@ -1,8 +0,0 @@ -// Plane does not eject contents. - -#appendto Plane - -private func PlaneDeath() -{ - Explode(50); -} diff --git a/planet/Tests.ocf/AirRace.ocs/System.ocg/Restart.c b/planet/Tests.ocf/AirRace.ocs/System.ocg/Restart.c deleted file mode 100644 index cf8f600b1..000000000 --- a/planet/Tests.ocf/AirRace.ocs/System.ocg/Restart.c +++ /dev/null @@ -1,21 +0,0 @@ -// Restart will remove plane and contents instead of clonk. - -#appendto Rule_Restart - -public func Activate(int plr) -{ - // Notify scenario. - if (GameCall("OnPlayerRestart", plr)) - return; - // Remove the player's clonk, including contents. - var clonk = GetCrew(plr); - if (clonk) - { - var plane = clonk->Contained(); - if (plane) - plane->RemoveObject(); - else - clonk->RemoveObject(); - } - return; -} \ No newline at end of file diff --git a/planet/Tests.ocf/AirRace.ocs/Title.txt b/planet/Tests.ocf/AirRace.ocs/Title.txt deleted file mode 100644 index 70baca344..000000000 --- a/planet/Tests.ocf/AirRace.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:AirRace -US:AirRace \ No newline at end of file diff --git a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.png b/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.png deleted file mode 100644 index 8377bca7d..000000000 Binary files a/planet/Tests.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Lorry.ocd/lorry.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/Graphics.png b/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/Graphics.png deleted file mode 100644 index 2eedb36aa..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/CableReel.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/DefCore.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/DefCore.txt deleted file mode 100644 index b06e783ff..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/DefCore.txt +++ /dev/null @@ -1,20 +0,0 @@ -[DefCore] -id=LiftTower -Version=5,2,0,1 -Category=C4D_Structure -Timer=5 -TimerCall=SpinWheel -Width=23 -Height=68 -Offset=-11,-10 -Vertices=4 -VertexX=-11,11,-11,11 -VertexY=-10,-10,58,58 -VertexFriction=50,50,100,100 -Value=200 -Mass=4500 -Components=Metal=2;Wood=4; -Exclusive=1 -BlastIncinerate=100 -Construction=1 -ContainBlast=1 \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Graphics.mesh b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Graphics.mesh deleted file mode 100644 index 7499e3406..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Graphics.mesh and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/Graphics.8.png b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/Graphics.8.png deleted file mode 100644 index be364ef23..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/Graphics.8.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png deleted file mode 100644 index c680cc38d..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/GraphicsInvis.8.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/Script.c b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/Script.c deleted file mode 100644 index 3fa1671a2..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/Script.c +++ /dev/null @@ -1,135 +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"))); - 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->AddMenuItem(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("MetalHit?"); -} - -func Construction(object constructor) -{ - tower = constructor; -} - -func SetRope(bool no_connect) -{ - rope = CreateObject(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; \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblDE.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblDE.txt deleted file mode 100644 index 1f09d0c03..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblDE.txt +++ /dev/null @@ -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. \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblUS.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblUS.txt deleted file mode 100644 index e2438fb9b..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Hook.ocd/StringTblUS.txt +++ /dev/null @@ -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. \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/LiftTower.skeleton b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/LiftTower.skeleton deleted file mode 100644 index 59a7a2f28..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/LiftTower.skeleton and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/Graphics.10.png b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/Graphics.10.png deleted file mode 100644 index e256b4310..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/Graphics.10.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png deleted file mode 100644 index 557b6a059..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsInvis.10.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png deleted file mode 100644 index c6e4a190c..000000000 Binary files a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/GraphicsShort.10.png and /dev/null differ diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/Script.c b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/Script.c deleted file mode 100644 index 599cfb193..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/Script.c +++ /dev/null @@ -1,259 +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 Weight = 1; - -// Call this to break the rope. -public func BreakRope(bool silent) -{ - if(length == -1) return; - length = -1; - var act1 = objects[0][0]; - var act2 = 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 = CreateObject(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) -{ - StartRopeConnect(obj1, obj2); - SetMaxLength(200); - SetFixed(true, false); - - SetAction("Hide"); - - AddEffect("IntHang", this, 1, 1, this); - return; -} - -public func Reconnect(object reconnect) -{ - objects[1][0] = reconnect; -} - -public func GetConnectStatus() { return !length_auto; } - -public func HookRemoved() -{ - BreakRope(); -} - -func FxIntHangTimer() { TimeStep(); } - -local last_point; - -func UpdateLines() -{ - var oldangle; - for(var i=1; i < ParticleCount; i++) - { - // Update the Position of the Segment - segments[i]->SetPosition(GetPartX(i), GetPartY(i)); - - // Calculate the angle to the previous segment - var angle = Angle(particles[i][0][0], particles[i][0][1], particles[i-1][0][0], particles[i-1][0][1]); - - // Draw the left line - var start = particles[i-1][0][:]; - var end = particles[i][0][:]; - - if(i == 1 && ParticleCount > 2) - { - angle = Angle(particles[2][0][0], particles[2][0][1], particles[0][0][0], particles[0][0][1]); - end = particles[0][0][:]; - end[0] += -Sin(angle, 45*Rope_Precision/10); - end[1] += +Cos(angle, 45*Rope_Precision/10); - segments[i]->SetGraphics("Invis"); - } - - if(i == 2) - { - angle = Angle(particles[2][0][0], particles[2][0][1], particles[0][0][0], particles[0][0][1]); - start = particles[0][0][:]; - start[0] += -Sin(angle, 45*Rope_Precision/10); - start[1] += +Cos(angle, 45*Rope_Precision/10); - 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/Rope_Precision/10; - - if(i == ParticleCount-1) - { - var old = particles[i-2][0][:]; - var old_diff = Vec_Sub(start,old); - var o_length = Vec_Length(old_diff)*1000/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)); - last_point = point; - } - - segments[i]->SetGraphics(nil); - SetLineTransform(segments[i], -diffangle, point[0]*10-GetPartX(i)*1000,point[1]*10-GetPartY(i)*1000, length ); - - // Remember the angle - oldangle = angle; - } -} - -func GetHookAngle() -{ - if(ParticleCount > 3) - return Angle(particles[-2][0][0], particles[-2][0][1], particles[-3][0][0], particles[-3][0][1])+180; -} - -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(!length) return; - - var redo = LengthAutoTryCount(); - while(length_auto && redo) - { - var speed = Vec_Length(Vec_Sub(particles[-1][0], particles[-1][1])); - if(length == GetMaxLength()) - { - if(ObjContact(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 = ParticleCount-1; - var obj = objects[i][0]; - - if(obj == nil || objects[i][1] == 0) continue; - - if(obj->Contained()) obj = obj->Contained(); - - if( (obj->GetAction() == "Walk" || obj->GetAction() == "Scale" || obj->GetAction() == "Hangle")) - obj->SetAction("Jump"); - if( obj->GetAction() == "Climb") - obj->SetAction("Jump"); - - var xdir = BoundBy(particles[j][0][0]-particles[j][1][0], -100, 100); - var ydir = particles[j][0][1]-particles[j][1][1]; - - if (!obj->GetContact(-1)) - ydir = BoundBy(ydir, -50, 50); - - 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, Rope_Precision); - obj->SetYDir( obj->GetYDir() + ydir, Rope_Precision); - //Log("%v, %v", xdir, ydir); - } -} - -// Altered to function in 'ConnectPull' mode -public func ConstraintObjects() -{ - if(length < GetMaxLength()) // in the rope library this is - { // if(length_auto && length < GetMaxLength()) - 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 = objects[0][0]; // First connected object - var obj2 = 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$"; \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblDE.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblDE.txt deleted file mode 100644 index 31839e7a9..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Seil \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblUS.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblUS.txt deleted file mode 100644 index f6c2f84f9..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Rope.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Rope \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Scene.material b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Scene.material deleted file mode 100644 index 5d15c8010..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Scene.material +++ /dev/null @@ -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 - } - } -} \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Script.c b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Script.c deleted file mode 100644 index 453c50214..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/Script.c +++ /dev/null @@ -1,163 +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), Anim_Const(1000)); - stopped = true; -} - -/* Rope */ - -func OnRopeBreak() -{ - if (!hook) - hook = CreateObject(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$" }; -} - -func Interact(object clonk) -{ - if (!hook) OnRopeBreak(); - - if (clonk->GetAction() == "Walk") - { - if (hook->Contained() == this) - if (clonk->Collect(hook)) - hook->SetRope(); - return true; - } - return false; -} - -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 SpinWheel() -{ - 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), Anim_Const(1000)); - else - anim_no = PlayAnimation("Turn", 10, Anim_Linear(GetAnimationPosition(anim_no), 0, GetAnimationLength("Turn"), 40, ANIM_Loop), Anim_Const(1000)); -} - -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 = 1; \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/StringTblDE.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/StringTblDE.txt deleted file mode 100644 index f88a7420f..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/StringTblDE.txt +++ /dev/null @@ -1,3 +0,0 @@ -Name=Hebeturm -Description=Um schwere Lasten zu heben. -TakeHook=Haken nehmen. \ No newline at end of file diff --git a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/StringTblUS.txt b/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/StringTblUS.txt deleted file mode 100644 index 270f078fe..000000000 --- a/planet/Tests.ocf/Experimental.ocd/LiftTower.ocd/StringTblUS.txt +++ /dev/null @@ -1,3 +0,0 @@ -Name=Lift Tower -Description=For pulling heavy loads. -TakeHook=Take the hook. \ No newline at end of file diff --git a/planet/Tests.ocf/GrappleBow.ocs/Map.bmp b/planet/Tests.ocf/GrappleBow.ocs/Map.bmp new file mode 100644 index 000000000..1802ceb00 Binary files /dev/null and b/planet/Tests.ocf/GrappleBow.ocs/Map.bmp differ diff --git a/planet/Tests.ocf/GrappleBow.ocs/Scenario.txt b/planet/Tests.ocf/GrappleBow.ocs/Scenario.txt new file mode 100644 index 000000000..02515c695 --- /dev/null +++ b/planet/Tests.ocf/GrappleBow.ocs/Scenario.txt @@ -0,0 +1,5 @@ +[Head] +Title=GrappleBow + +[Landscape] +TopOpen=0 diff --git a/planet/Tests.ocf/GrappleBow.ocs/Script.c b/planet/Tests.ocf/GrappleBow.ocs/Script.c new file mode 100644 index 000000000..07cf95655 --- /dev/null +++ b/planet/Tests.ocf/GrappleBow.ocs/Script.c @@ -0,0 +1,15 @@ +func InitializePlayer(int plr) +{ + Log("init plr"); + var clonk = GetCrew(plr); + if (clonk) + { + clonk->CreateContents(GrappleBow); + clonk->CreateContents(WindBag); + clonk->CreateContents(Shovel); + clonk->CreateContents(GrappleBow); + clonk->CreateContents(Dynamite); + clonk->CreateContents(Dynamite); + clonk->SetPosition(300,100); + } +} diff --git a/planet/Tests.ocf/GrappleRace.ocs/DescDE.rtf b/planet/Tests.ocf/GrappleRace.ocs/DescDE.rtf deleted file mode 100644 index fd8ca25c0..000000000 --- a/planet/Tests.ocf/GrappleRace.ocs/DescDE.rtf +++ /dev/null @@ -1,159 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;} -{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} -{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f79\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;}{\f80\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;} -{\f82\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f83\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;}{\f84\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);}{\f85\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);} -{\f86\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f87\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid12601583}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator MimmoO} -{\creatim\yr2010\mo11\dy7\hr16\min58}{\revtim\yr2010\mo11\dy7\hr16\min59}{\version2}{\edmins0}{\nofpages1}{\nofwords5}{\nofchars31}{\nofcharsws35}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale160\rsidroot12601583 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 -\af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\lang1043\langfe1031\langnp1043\insrsid12601583 -\hich\af0\dbch\af31505\loch\f0 GrappleRace}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\lang1043\langfe1031\langnp1043\insrsid12601583 -\par -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1043\langfe1031\langnp1043\insrsid12601583 \hich\af0\dbch\af31505\loch\f0 Grapple dic\hich\af0\dbch\af31505\loch\f0 h -\hich\af0\dbch\af31505\loch\f0 zum Ziel.}{\rtlch\fcs1 \af4\afs24 \ltrch\fcs0 \f4\fs24\lang1043\langfe1031\langnp1043\insrsid12601583 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f0000000000000000000000000019 -d4cd947ecb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/Tests.ocf/GrappleRace.ocs/DescUS.rtf b/planet/Tests.ocf/GrappleRace.ocs/DescUS.rtf deleted file mode 100644 index 9da7cc7ca..000000000 --- a/planet/Tests.ocf/GrappleRace.ocs/DescUS.rtf +++ /dev/null @@ -1,161 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1031\deflangfe1031\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;} -{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} -{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f79\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;}{\f80\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;} -{\f82\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f83\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;}{\f84\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);}{\f85\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);} -{\f86\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f87\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; -\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp -\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 \snext0 \sqformat \spriority0 Normal;} -{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid12004887}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator MimmoO} -{\creatim\yr2010\mo11\dy7\hr16\min59}{\revtim\yr2010\mo11\dy7\hr17}{\version2}{\edmins0}{\nofpages1}{\nofwords5}{\nofchars34}{\nofcharsws38}{\vern32859}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120 -\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale160\rsidroot12004887 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}} -{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9 -\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 -\af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1031\langfe1031\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1031\langfenp1031 {\rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\f0\fs20\lang1043\langfe1031\langnp1043\insrsid12004887 -\hich\af0\dbch\af31505\loch\f0 GrappleRace }{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\insrsid12004887\charrsid12004887 -\par }{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f0\fs20\lang1043\langfe1031\langnp1043\insrsid12004887 -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \f0\fs16\lang1043\langfe1031\langnp1043\insrsid12004887 \hich\af0\dbch\af31505\loch\f0 Grap\hich\af0\dbch\af31505\loch\f0 ple to the finish.}{ -\rtlch\fcs1 \af4\afs24 \ltrch\fcs0 \f4\fs24\lang1043\langfe1031\langnp1043\insrsid12004887 -\par -\par -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100e35a492797060000551b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594d6f1b4518be23f11f467b6f6327761a4775aad8b11b6852a2d82dea71bc3bde9d66766735334eea1b6a8f484888823850891b0704546a252e -e5d7048aa048fd0bbc33b3bbde89d72469235a417d48bcb3cfbcdf5f33be7aed5eccd0211192f2a4edd52fd73c44129f073409dbdead61ffd29a87a4c2498019 -4f48db9b12e95ddb78ffbdab785d45242608f627721db7bd48a9747d6949fab08ce5659e9204de8db988b18247112e05021f01dd982d2dd76aab4b31a6898712 -1c03d91d2ca894f8d21691344cbc8d9c7c8f018f4449bde03331d0c489bbc7808383ba86c8a9ec32810e316b7bc02ae04743724f798861a9e045dbab998fb7b4 -717509af679b985ab0b7b4af6f3ed9be6c4370b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83aa569632cd467faddec9699640f6 -eb3ced6ead596bb8f812fd9539995b9d4ea7d9ca64b1440dc87e6dcce1d76aab8dcd65076f4016df9cc3373a9bddeeaa8337208b5f9dc3f7afb4561b2ede8022 -46938339b47668bf9f512f2063ceb62be16b005fab65f0190aa2a1082fcd62cc13b530d8627c978b3e203492614513a4a62919631f22b98be391a05873c0eb04 -97ded8255fce2d696648fa82a6aaed7d9862c88a19bd97cf7e78f9ec093abefff4f8fecfc70f1e1cdfffc91272766de3242cef7af1dde77f3dfa04fdf9e4db17 -0fbfacc6cb32feb71f3ffdf5972faa81903f33719e7ff5f8f7a78f9f7ffdd91fdf3fac806f0a3c2ac387342612dd2447689fc7a098b18a2b391989f3ed184698 -96776c26a1c409d65c2ae8f754e4a06f4e31cbbce3c8d121ae056f0ba81f55c0eb93bb8ec083484c14ade07c238a1de02ee7acc345a5156e685e25330f274958 -cd5c4ccab87d8c0fab787771e2f8b73749a172e661e928de8d8823e61ec389c221498842fa1d3f20a442bb3b943a76dda5bee0928f15ba435107d34a930ce9c8 -89a6d9a66d1a835fa6553a83bf1ddbecde461dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583ef6015550939980abf8ceb49059e0e09 -e3a81710686d15527c2440df92d36f602859956edf65d3d8450a450faa68ee60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19 -fc809385eebe4d89e3eed3abc12d1a3a22cd0244bf99086d45a8d54e058e69f24fe59851a8c7d6fa17578ea1003effe651854fdfd642bc093da92a13b64f94df -45b89345b7cb4540dffe9abb8527c91e81309f6f3cef4aeebb92ebfde74beea27c3e6ba19dd55628bb7a6eb053b19991e3c523f298323650534676a499922534 -8aa00f8b7aa3392292e2cc9446f0352bec0e2e14d8ec4182ab8fa98a06114e61c2ae7b9a482833d2a144299770b433cb95b4351ea674650f864d7d64b0054162 -b5cb03bbbca297f3934141c6b49bd09c3f73462b9ac05999ad5cc98882daafc2acae853a33b7ba11cdd43a875ba13238715e35582cac09130882b905acbc0a87 -74cd1a4e26989140dbdd36dfdc2dc60b17e92219e180643ed27acffba86e9c94c78ab90c80d8a9f0913ee69d62b512b79626fb1adccee2a432bbc60276b9f75e -c74b7904cfbca413f7443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc3a116bec629785deaa10fb3106e877c256cd89f9acc26cb67de6ce58ab94950878b0a -6bf739859d3a900aa9b6b08c6c6898575908b04473b2f22f37c1ac17a5808df4579062650d82e18d490176745d4bc663e2abb2b34b2bda76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f4025dc4d988aa01fe0264d5bdbbc728b739674e5fb2b83b3eb98a511cecaad4ed13c932ddce4712183792a8907ba55ca6e94 -3bbf2a26e52f48957218ffcf54d1fd04ae0a5602ed011fee7205463a5fdb1e172ae25085d288fa7d019383a91d102d701b0baf21a8e046d9fc17e450ffb73967 -6998b486139fdaa7211214fa918a04217b50964cf49d42ac9ef52e4b9265844c4495c495a9157b440e091bea1ab8aa7bbb87220875534db232607027e3cf7dce -326814ea21a79c6f4e0d297aafcd817f7bf2b1c90c4ab975d80c34b9fd0b112bbaaadd6fb6e7bdb7ac887e311bb31a795600b3522b686569ff8a229cb3d5da8a -35a7f17233170ebc38af312c1603510a173e48ff81fe4785cf880963dd50877c1f6a2b829f1a3431081b88ea4b76f040ba40dac5110c4e76d1069326654d9b8d -4eda6a79b3bee049b7e07bc2d85ab2b3f8fb9cc62e8633979d938b1769ecccc28eadedda425383674fa6282c8df3938c718cf95dabfcc3131fdd05476fc105ff -84296982097e55121846cf81c903487ecbd16cddf81b0000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f -7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f -2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31 -98720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d98505 -28a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c02000013000000000000000000000000 -00000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000000000000000000000 -00002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000000000001402000074 -68656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100e35a492797060000551b0000160000000000000000 -0000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000 -0000000000000000009c0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000970a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000400b -37de947ecb01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/planet/Tests.ocf/GrappleRace.ocs/Landscape.txt b/planet/Tests.ocf/GrappleRace.ocs/Landscape.txt deleted file mode 100644 index a3646a885..000000000 --- a/planet/Tests.ocf/GrappleRace.ocs/Landscape.txt +++ /dev/null @@ -1,23 +0,0 @@ -map AirRace -{ - overlay{ mat=Rock; y=45; hgt=10; wdt=5; }; - overlay{ mat=Rock; hgt=3; }; - overlay{ mat=Earth; x=5; y=0; wdt=30; hgt=100; algo=lines; a=2; b=9; }; - overlay{ mat=Granite; x=37; y=0; wdt=30; hgt=100; algo=lines; a=2; b=9; }; - overlay{ mat=Gold; x=70; y=0; wdt=30; hgt=100; algo=lines; a=2; b=9; }; - overlay{ algo=poly; - point{ x=5%; y=40%; }; - point{ x=15%; y=40%; }; - point{ x=35%; y=70%; }; - point{ x=42%; y=80%; }; - point{ x=45%; y=65%; }; - point{ x=70%; y=50%; }; - point{ x=100%; y=00%; }; - point{ x=100%; y=150%; }; - point{ x=5%; y=150%; }; - }; - - overlay{ mat=Granite; y=85; hgt=3; wdt=5; x=34;}; - overlay{ mat=Gold; y=107; hgt=3; wdt=7; x=61; loosebounds=1; rotate=10;}; - -}; \ No newline at end of file diff --git a/planet/Tests.ocf/GrappleRace.ocs/Scenario.txt b/planet/Tests.ocf/GrappleRace.ocs/Scenario.txt deleted file mode 100644 index dd39bfb9e..000000000 --- a/planet/Tests.ocf/GrappleRace.ocs/Scenario.txt +++ /dev/null @@ -1,37 +0,0 @@ -[Head] -Icon=37 -Title=GrappleRace - -[Definitions] -Definition1=Objects.ocd - -[Game] -Goals=Goal_Parkour - -[Player1] -Crew=Clonk=1 - -[Player2] -Crew=Clonk=1 - -[Player3] -Crew=Clonk=1 - -[Player4] -Crew=Clonk=1 - -[Landscape] -InEarth=Rock=1;Firestone=1;Loam=1 -InEarthLevel=40 -Sky=Clouds1 -TopOpen=1 -BottomOpen=1 -MapWidth=640 -MapHeight=160 -MapZoom=10 -SkyScrollMode=2 - -[Weather] -Climate=40 -YearSpeed=20,10 -Wind=0,100 \ No newline at end of file diff --git a/planet/Tests.ocf/GrappleRace.ocs/Script.c b/planet/Tests.ocf/GrappleRace.ocs/Script.c deleted file mode 100644 index fb4fe89dc..000000000 --- a/planet/Tests.ocf/GrappleRace.ocs/Script.c +++ /dev/null @@ -1,86 +0,0 @@ -/*-- - GrappleRace - Author: Mimmo - - You got two grapplers. Get to the goal as fast as possible! ---*/ - - -/*-- Scenario properties --*/ - -protected func Initialize() -{ - // Create the parkour. - CreateParkour(); - - // Environment. - Cloud->Place(30); - - return; -} - -// Create parkour, start & finish on the brick islands, random separated checkpoints in-between. -private func CreateParkour() -{ - // Find parkour goal and create on if non-existent. - var goal = FindObject(Find_ID(Goal_Parkour)); - if (!goal) - goal = CreateObject(Goal_Parkour, 0, 0, NO_OWNER); - - var x, y; - // Create start checkpoint. - x = 50; y = LandscapeHeight() / 2 -120; - goal->SetStartpoint(x, y)->SetCPSize(40); - - var mode = PARKOUR_CP_Respawn | PARKOUR_CP_Ordered | PARKOUR_CP_Team; - goal->AddCheckpoint(2325, 1300, mode)->SetCPSize(30);; - goal->AddCheckpoint(4400, 930, mode)->SetCPSize(30);; - - // Create finish checkpoint. - x = LandscapeWidth() - 600; y = LandscapeHeight() -300; - goal->SetFinishpoint(x, y)->SetCPSize(60); - return; -} - -/*-- Player respawn --*/ - -// Callback from parkour goal, on player respawn. -protected func OnPlayerRespawn(int plr, object cp) -{ - var clonk = GetCrew(plr); - - clonk->SetPosition(cp->GetX(),cp->GetY()); - clonk->CreateContents(GrappleBow,2); - return; -} - -private func FindPlaneAngle(object cp) -{ - // Start to the right. - var angle = 90, i = 0, dir = 1; - var x = cp->GetX(); - var y = cp->GetY(); - while (Abs(i) < 180) - { - if (PathFree(x, y, x + Sin(angle + i, 200), y + Cos(angle + i, 200))) - { - dir = 1; - break; - } - if (PathFree(x, y, x + Sin(angle - i, 200), y + Cos(angle - i, 200))) - { - dir = -1; - break; - } - i += 10; - } - return angle + dir * i; -} - - -protected func InitializePlayer(int plr) -{ - // No fog ow war in this scenario. - SetFoW(false, plr); - return; -} diff --git a/planet/Tests.ocf/GrappleRace.ocs/Title.txt b/planet/Tests.ocf/GrappleRace.ocs/Title.txt deleted file mode 100644 index d355bc7be..000000000 --- a/planet/Tests.ocf/GrappleRace.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Grapple-Rennen -US:Grapple Race \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/DefCore.txt b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/DefCore.txt new file mode 100644 index 000000000..698893151 --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=DummyParent +Version=5,3,0,0 +Category=C4D_StaticBack +Width=8 +Height=8 +Offset=-4,-4 diff --git a/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/Graphics.png b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/Graphics.png new file mode 100644 index 000000000..b15f128ed Binary files /dev/null and b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/Graphics.png differ diff --git a/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/Script.c b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/Script.c new file mode 100644 index 000000000..1f43bcc86 --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/Script.c @@ -0,0 +1,13 @@ +local ActMap= +{ + Attach = + { + Prototype = Action, + Name="Attach", + Procedure=DFA_ATTACH, + NextAction="Be", + Length=1, + FacetBase=1, + AbortCall = "AttachTargetLost" + } +}; \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/StringTblDE.txt b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/StringTblDE.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/StringTblUS.txt b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/StringTblUS.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/Dummy.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/DefCore.txt b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/DefCore.txt new file mode 100644 index 000000000..becef86c3 --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=DummyChild +Version=5,3,0,0 +Category=C4D_StaticBack +Width=8 +Height=8 +Offset=-4,-4 diff --git a/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/Graphics.png b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/Graphics.png new file mode 100644 index 000000000..b15f128ed Binary files /dev/null and b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/Graphics.png differ diff --git a/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/Script.c b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/Script.c new file mode 100644 index 000000000..b05e1f9ee --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/Script.c @@ -0,0 +1,2 @@ + +#include DummyParent \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/StringTblDE.txt b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/StringTblDE.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/StringTblDE.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/StringTblUS.txt b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/StringTblUS.txt new file mode 100644 index 000000000..7c701c28c --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/DummyChild.ocd/StringTblUS.txt @@ -0,0 +1 @@ +Name=Dummy \ No newline at end of file diff --git a/planet/Tests.ocf/IncludeTest.ocs/Scenario.txt b/planet/Tests.ocf/IncludeTest.ocs/Scenario.txt new file mode 100644 index 000000000..0519ecba6 --- /dev/null +++ b/planet/Tests.ocf/IncludeTest.ocs/Scenario.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/planet/Tests.ocf/Lines.ocs/Title.txt b/planet/Tests.ocf/Lines.ocs/Title.txt deleted file mode 100644 index c7b42aa05..000000000 --- a/planet/Tests.ocf/Lines.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Test 1 -US:Test 1 \ No newline at end of file diff --git a/planet/Tests.ocf/LocalDefsOnly.ocs/Dummy.ocd/DefCore.txt b/planet/Tests.ocf/LocalDefsOnly.ocs/Dummy.ocd/DefCore.txt new file mode 100644 index 000000000..d9e829ad5 --- /dev/null +++ b/planet/Tests.ocf/LocalDefsOnly.ocs/Dummy.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=Clonk +Version=5,3,0,0 +Category=C4D_StaticBack +Width=8 +Height=8 +Offset=-4,-4 diff --git a/planet/Tests.ocf/LocalDefsOnly.ocs/Dummy.ocd/Graphics.png b/planet/Tests.ocf/LocalDefsOnly.ocs/Dummy.ocd/Graphics.png new file mode 100644 index 000000000..b15f128ed Binary files /dev/null and b/planet/Tests.ocf/LocalDefsOnly.ocs/Dummy.ocd/Graphics.png differ diff --git a/planet/Tests.ocf/LocalDefsOnly.ocs/Scenario.txt b/planet/Tests.ocf/LocalDefsOnly.ocs/Scenario.txt new file mode 100644 index 000000000..e2693e919 --- /dev/null +++ b/planet/Tests.ocf/LocalDefsOnly.ocs/Scenario.txt @@ -0,0 +1,2 @@ +[Definitions] +LocalOnly=1 diff --git a/planet/Tests.ocf/Materials.ocs/Map.bmp b/planet/Tests.ocf/Materials.ocs/Map.bmp deleted file mode 100644 index b2ac3f9a7..000000000 Binary files a/planet/Tests.ocf/Materials.ocs/Map.bmp and /dev/null differ diff --git a/planet/Tests.ocf/Materials.ocs/Material.ocg/BigRock.ocm b/planet/Tests.ocf/Materials.ocs/Material.ocg/BigRock.ocm deleted file mode 100644 index e81e4cf04..000000000 --- a/planet/Tests.ocf/Materials.ocs/Material.ocg/BigRock.ocm +++ /dev/null @@ -1,13 +0,0 @@ -[Material] -Name=BigRock -Shape=Flat -ShapeTexture=ShapeBigRock.txt -Density=50 -Friction=100 -BlastFree=1 -Blast2Object=Rock -Blast2ObjectRatio=75 -MaxAirSpeed=100 -MaxSlide=250 -Placement=50 -TextureOverlay=BigRock diff --git a/planet/Tests.ocf/Materials.ocs/Material.ocg/BigRock.png b/planet/Tests.ocf/Materials.ocs/Material.ocg/BigRock.png deleted file mode 100644 index 2516e951a..000000000 Binary files a/planet/Tests.ocf/Materials.ocs/Material.ocg/BigRock.png and /dev/null differ diff --git a/planet/Tests.ocf/Materials.ocs/Material.ocg/ShapeBigRock.png b/planet/Tests.ocf/Materials.ocs/Material.ocg/ShapeBigRock.png deleted file mode 100644 index 00174e636..000000000 Binary files a/planet/Tests.ocf/Materials.ocs/Material.ocg/ShapeBigRock.png and /dev/null differ diff --git a/planet/Tests.ocf/Materials.ocs/Material.ocg/ShapeBigRock.txt b/planet/Tests.ocf/Materials.ocs/Material.ocg/ShapeBigRock.txt deleted file mode 100644 index 1bf95f350..000000000 --- a/planet/Tests.ocf/Materials.ocs/Material.ocg/ShapeBigRock.txt +++ /dev/null @@ -1,4 +0,0 @@ -[Shape] -Width=512 -Height=512 -Shape=1,510,1,510,1,505,1,499,1,499,3,499,4,499,4,499,5,500,5,500,5,500,6,500,7,500,8,500,8,501,8,501,8,501,9,501,9,501,10,501,10,501,10,500,10,500,11,500,11,500,12,500,12,500,12,500,12,500,13,500,13,500,14,500,14,500,14,500,14,500,14,500,15,500,15,500,15,501,15,501,15,502,16,502,16,502,16,503,16,503,16,503,16,504,17,504,17,504,17,505,17,506,17,508,17,509,17,509,18,509,18,510,17,511,17,511,15,511,9,511,2,511,2,511,2,511;19,511,19,510,19,510,19,510,19,510,19,510,18,510,18,509,18,507,18,506,18,505,19,505,19,505,19,504,19,503,19,502,19,501,19,501,19,501,20,500,20,499,20,498,20,498,20,498,21,498,22,497,22,497,23,496,23,496,24,496,24,496,24,495,24,495,24,495,24,495,25,495,25,495,26,495,26,495,26,494,27,494,28,494,29,494,30,494,30,494,30,494,31,494,33,494,34,494,35,494,35,494,35,494,35,494,36,494,36,494,37,494,37,495,37,495,37,495,38,495,39,495,39,495,40,496,41,497,42,499,41,499,41,499,41,500,41,501,41,501,41,502,41,502,40,502,40,503,40,505,40,507,40,508,41,508,41,508,41,509,40,510,39,511,39,511,38,511,37,511,36,511,36,511,36,511,33,511,28,511,21,511,20,511,19,511;42,510,42,510,42,510,43,510,43,510,42,511,42,512,42,512,42,511;44,511,44,510,44,510,44,510,44,509,43,509,42,507,42,507,42,505,42,503,42,503,42,503,43,503,43,503,43,503,43,502,44,502,45,502,45,502,46,502,46,502,46,502,47,502,48,502,49,502,50,501,50,501,50,501,50,501,50,501,51,501,51,501,51,501,51,500,52,500,55,500,57,500,58,500,58,500,58,500,58,500,59,500,59,500,60,499,60,499,60,499,60,499,61,499,61,499,62,499,62,499,62,498,62,498,62,498,63,498,63,498,63,498,63,498,63,498,64,498,64,498,65,497,65,497,65,497,65,497,66,497,67,497,68,498,68,499,68,500,68,500,69,500,69,500,69,501,69,503,69,504,69,506,69,506,69,506,70,506,70,506,70,507,70,507,70,507,70,507,70,508,69,509,69,509,68,510,67,510,67,510,66,510,66,510,66,510,66,510,66,510,65,510,65,510,65,511,65,511,64,511,64,511,63,511,63,511,63,511,63,511,60,511,54,511,47,511,45,511,45,511;86,511,83,511,78,511,70,511,70,511,70,510,70,510,70,510,70,510,71,510,71,509,71,509,71,509,74,509,80,509,85,509,88,509,88,509,88,508,89,508,89,508,90,508,90,508,90,508,90,508,91,508,92,508,92,508,93,507,93,507,93,507,94,507,95,507,97,507,97,507,97,508,97,508,97,508,97,508,96,508,96,509,96,509,96,510,95,511,93,511,92,511,91,511,91,511,91,511,90,512,88,512,87,512,86,511,86,511;101,511,100,511,100,511,99,511,99,511,99,510,99,510,99,510,100,510,100,510,101,509,101,509,102,508,102,508,102,508,102,509,103,509,103,509,103,509,104,509,104,509,104,509,104,510,105,510,106,510,106,510,106,510,106,511,106,511,106,511,105,511,105,511,105,511,105,511,104,512,103,512,102,512,101,511,101,511;107,510,107,509,107,509,107,508,106,508,105,508,104,508,104,508,103,508,103,507,102,507,102,507,101,507,101,506,102,505,103,505,103,504,103,503,103,503,103,502,103,502,103,502,104,501,104,500,104,498,104,498,105,498,105,498,106,497,106,497,106,496,107,496,114,496,123,496,123,497,124,498,124,498,124,500,124,501,124,502,125,502,125,502,125,502,125,502,125,503,125,503,125,503,125,503,126,504,126,505,126,506,126,507,126,507,126,507,126,508,126,508,126,510,126,510,125,511,125,512,117,511,109,511,108,510;128,510,128,509,128,508,128,508,127,507,127,507,127,507,127,506,127,505,127,504,127,503,127,503,127,503,128,503,128,503,128,502,127,502,127,502,126,502,126,502,126,501,126,500,126,500,128,500,129,500,129,500,129,500,129,500,129,501,128,501,128,501,128,501,128,501,128,501,129,501,129,501,129,500,130,500,131,500,131,500,132,500,132,500,132,500,132,500,133,500,134,500,135,499,135,499,135,499,136,499,139,499,141,499,142,499,142,499,142,498,143,498,145,498,147,498,147,498,147,499,147,500,147,500,146,501,146,501,146,501,146,503,146,505,143,507,142,509,141,510,141,510,141,510,140,510,140,510,140,511,139,511,139,511,138,511,138,511,138,511,138,511,136,511,134,511,129,511,129,511,128,511;147,511,146,511,145,511,143,511,142,511,142,510,142,510,143,509,145,508,147,505,147,503,147,501,147,501,148,501,148,500,148,500,148,500,148,499,149,499,149,498,150,497,150,498,151,499,151,499,152,499,152,499,152,499,153,500,153,500,153,500,154,500,154,500,155,500,155,501,155,501,156,502,157,502,157,502,158,502,158,502,158,503,159,503,159,503,160,503,160,503,161,504,161,504,161,504,162,504,162,504,163,504,163,505,163,505,164,506,164,506,164,506,165,506,165,506,165,507,166,507,166,507,167,507,168,508,168,510,168,511,161,511,157,511,154,511,154,511,154,511,153,512,151,512,148,512,147,511,147,511;170,511,170,510,170,510,171,509,171,509,171,511,171,512,171,512,170,511;172,510,172,510,172,505,172,499,172,499,174,499,174,499,175,499,175,500,176,500,176,500,177,500,178,500,178,500,178,501,178,501,179,501,179,501,180,501,180,501,180,501,180,500,181,500,181,500,182,500,182,500,182,500,182,500,183,500,183,500,184,500,184,500,184,500,184,500,184,500,185,500,185,500,186,500,186,501,186,501,186,502,186,502,187,502,187,503,187,503,187,503,187,504,187,504,187,504,188,505,188,506,188,508,188,509,188,509,188,509,188,510,188,511,187,511,186,511,180,511,173,511,173,511,172,511;190,511,190,510,190,510,190,510,189,510,189,510,189,510,189,509,189,507,189,506,189,505,189,505,189,505,190,504,190,503,190,502,190,501,190,501,190,501,190,500,190,499,190,498,190,498,191,498,192,498,192,497,193,497,193,496,194,496,194,496,195,496,195,495,195,495,195,495,195,495,196,495,196,495,196,495,196,495,196,494,197,494,199,494,200,494,201,494,201,494,201,494,202,494,203,494,205,494,206,494,206,494,206,494,206,494,207,494,207,494,208,494,208,495,208,495,208,495,209,495,210,495,210,495,211,496,212,497,213,499,212,499,212,499,212,500,212,501,212,501,211,502,211,502,211,502,211,503,211,505,211,507,211,508,211,508,212,508,212,509,211,510,210,511,210,511,208,511,208,511,207,511,207,511,207,511,204,511,199,511,192,511,190,511,190,511;212,510,212,510,213,510,214,510,214,510,213,511,212,512,212,512,212,511;215,511,215,510,215,510,215,510,214,509,214,509,212,507,212,507,212,505,212,503,212,503,213,503,213,503,214,503,214,503,214,502,214,502,215,502,216,502,217,502,217,502,217,502,218,502,219,502,219,502,220,501,220,501,220,501,220,501,221,501,221,501,222,501,222,501,222,500,223,500,225,500,227,500,229,500,229,500,229,500,229,500,230,500,230,500,230,499,230,499,230,499,231,499,231,499,232,499,232,499,232,499,232,498,232,498,233,498,233,498,234,498,234,498,234,498,234,498,235,498,235,498,236,497,236,497,236,497,237,497,238,498,238,498,239,499,239,499,239,500,239,500,239,500,239,500,240,501,240,503,240,504,240,506,240,506,240,506,240,506,240,506,240,507,240,507,241,507,241,507,241,508,240,509,239,509,239,510,238,510,237,510,237,510,237,510,237,510,237,510,236,510,236,510,236,510,236,511,236,511,235,511,235,511,234,511,234,511,234,511,234,511,230,511,225,511,217,511,216,511,215,511;256,511,253,511,248,511,240,511,240,511,240,510,240,510,240,510,241,510,241,510,242,509,242,509,242,509,245,509,250,509,256,509,259,509,259,509,259,508,259,508,260,508,260,508,261,508,261,508,261,508,261,508,262,508,263,508,264,507,264,507,264,507,264,507,266,507,267,507,268,507,268,508,268,508,267,508,267,508,267,508,267,509,267,509,267,510,266,511,264,511,262,511,262,511,262,511,262,511,260,512,259,512,257,512,256,511,256,511;272,511,271,511,271,511,270,511,270,511,270,510,270,510,270,510,270,510,271,510,272,509,272,509,272,508,273,508,273,508,273,509,273,509,274,509,274,509,274,509,274,509,274,509,275,510,276,510,277,510,277,510,277,510,277,511,277,511,276,511,276,511,276,511,276,511,276,511,275,512,274,512,272,512,272,511,272,511;278,510,278,509,278,509,278,508,277,508,276,508,275,508,274,508,274,508,274,507,273,507,273,507,272,507,272,506,273,505,273,505,274,504,274,503,274,503,274,502,274,502,274,502,274,501,274,500,274,498,275,498,276,498,276,498,276,497,277,497,277,496,277,496,285,496,293,496,294,497,295,498,295,498,295,500,295,501,295,502,295,502,295,502,296,502,296,502,296,503,296,503,296,503,296,503,296,504,296,505,296,506,296,507,297,507,297,507,297,508,297,508,297,510,297,510,296,511,295,512,287,511,280,511,279,510;298,510,298,509,298,508,298,508,298,507,298,507,298,507,298,506,298,505,298,504,298,503,298,503,298,503,298,503,298,503,298,502,298,502,298,502,297,502,297,502,297,501,297,500,297,500,298,500,299,500,300,500,300,500,300,500,299,501,299,501,299,501,299,501,299,501,299,501,299,501,300,501,300,500,301,500,301,500,302,500,302,500,302,500,302,500,303,500,304,500,305,500,306,499,306,499,306,499,307,499,309,499,311,499,313,499,313,499,313,498,314,498,315,498,317,498,318,498,318,499,318,500,317,500,317,501,316,501,316,501,316,503,316,505,314,507,313,509,312,510,311,510,311,510,311,510,311,510,310,511,310,511,309,511,309,511,309,511,309,511,309,511,307,511,304,511,300,511,300,511,299,511;318,511,317,511,315,511,313,511,313,511,313,510,313,510,314,509,315,508,318,505,318,503,318,501,318,501,318,501,319,500,319,500,319,500,319,499,319,499,320,498,321,497,321,498,321,499,322,499,322,499,322,499,323,499,323,500,323,500,324,500,325,500,325,500,326,500,326,501,326,501,327,502,327,502,328,502,328,502,329,502,329,503,329,503,330,503,330,503,331,503,331,504,331,504,332,504,333,504,333,504,334,504,334,505,334,505,335,506,335,506,335,506,336,506,336,506,336,507,337,507,337,507,338,507,339,508,339,510,339,511,332,511,327,511,325,511,325,511,325,511,323,512,321,512,319,512,318,511,318,511;340,511,340,510,341,510,341,509,342,509,342,511,342,512,341,512,341,511;342,510,342,510,342,505,342,499,342,499,344,499,345,499,346,499,346,500,346,500,347,500,348,500,348,500,349,500,349,501,349,501,349,501,350,501,350,501,351,501,351,501,351,500,351,500,352,500,352,500,353,500,353,500,353,500,353,500,354,500,354,500,355,500,355,500,355,500,355,500,356,500,356,500,356,500,356,501,356,501,356,502,357,502,357,502,358,503,358,503,358,503,358,504,358,504,358,504,358,505,358,506,358,508,358,509,359,509,359,509,359,510,358,511,358,511,357,511,351,511,344,511,344,511,343,511;360,511,360,510,360,510,360,510,360,510,360,510,360,510,360,509,360,507,360,506,360,505,360,505,360,505,360,504,360,503,360,502,360,501,361,501,361,501,361,500,361,499,361,498,361,498,362,498,362,498,363,497,364,497,364,496,365,496,365,496,365,496,366,495,366,495,366,495,366,495,366,495,367,495,367,495,367,495,367,494,368,494,369,494,371,494,372,494,372,494,372,494,373,494,374,494,375,494,376,494,376,494,376,494,377,494,377,494,378,494,378,494,378,495,378,495,379,495,379,495,380,495,381,495,382,496,383,497,383,499,383,499,382,499,382,500,382,501,382,501,382,502,382,502,382,502,382,503,382,505,382,507,382,508,382,508,382,508,382,509,381,510,381,511,380,511,379,511,378,511,378,511,378,511,378,511,375,511,369,511,363,511,361,511,361,511;383,510,383,510,384,510,384,510,384,510,384,511,383,512,383,512,383,511;386,511,386,510,386,510,386,510,385,509,384,509,383,507,383,507,383,505,383,503,383,503,384,503,384,503,384,503,384,503,384,502,385,502,386,502,387,502,388,502,388,502,388,502,388,502,389,502,390,502,391,501,391,501,391,501,391,501,392,501,392,501,392,501,392,501,392,500,394,500,396,500,398,500,400,500,400,500,400,500,400,500,400,500,401,500,401,499,401,499,401,499,401,499,402,499,402,499,403,499,403,499,403,498,403,498,404,498,404,498,404,498,404,498,404,498,405,498,405,498,406,498,406,497,406,497,406,497,408,497,409,498,409,498,410,499,410,499,410,500,410,500,410,500,410,500,410,501,410,503,410,504,410,506,411,506,411,506,411,506,411,506,411,507,411,507,411,507,412,507,412,508,411,509,410,509,409,510,409,510,408,510,408,510,408,510,408,510,407,510,407,510,406,510,406,510,406,511,406,511,406,511,405,511,405,511,404,511,404,511,404,511,401,511,395,511,388,511,386,511,386,511;427,511,424,511,419,511,411,511,411,511,411,510,411,510,411,510,412,510,412,510,412,509,412,509,412,509,415,509,421,509,426,509,430,509,430,509,430,508,430,508,431,508,431,508,432,508,432,508,432,508,432,508,433,508,434,508,434,507,434,507,434,507,435,507,436,507,438,507,438,507,438,508,438,508,438,508,438,508,438,508,438,509,438,509,438,510,437,511,434,511,433,511,432,511,432,511,432,511,431,512,430,512,428,512,427,511,427,511;442,511,442,511,441,511,440,511,440,511,440,510,440,510,440,510,441,510,442,510,442,509,443,509,443,508,443,508,443,508,443,509,444,509,444,509,445,509,445,509,445,509,445,509,445,510,446,510,447,510,448,510,448,510,448,511,447,511,447,511,446,511,446,511,446,511,446,511,445,512,444,512,443,512,442,511,442,511;449,510,448,509,448,509,448,508,448,508,447,508,445,508,445,508,445,508,444,507,444,507,443,507,443,507,443,506,444,505,444,505,444,504,444,503,444,503,444,502,445,502,445,502,445,501,445,500,445,498,445,498,446,498,446,498,447,497,447,497,448,496,448,496,456,496,464,496,465,497,465,498,466,498,466,500,466,501,466,502,466,502,466,502,466,502,466,502,466,503,466,503,467,503,467,503,467,504,467,505,467,506,467,507,467,507,467,507,468,508,468,508,468,510,467,510,467,511,466,512,458,511,450,511,449,510;469,510,469,509,469,508,469,508,469,507,469,507,468,507,468,506,468,505,468,504,468,503,469,503,469,503,469,503,469,503,469,502,469,502,468,502,468,502,468,502,468,501,468,500,468,500,469,500,470,500,470,500,470,500,470,500,470,501,470,501,470,501,469,501,470,501,470,501,470,501,470,501,471,500,471,500,472,500,472,500,473,500,473,500,473,500,474,500,475,500,475,500,476,499,476,499,476,499,478,499,480,499,482,499,484,499,484,499,484,498,485,498,486,498,488,498,488,498,488,499,488,500,488,500,488,501,487,501,487,501,487,503,487,505,485,507,483,509,482,510,482,510,482,510,481,510,481,510,481,511,480,511,480,511,480,511,480,511,480,511,480,511,478,511,475,511,471,511,470,511,470,511;488,511,487,511,486,511,484,511,484,511,484,510,484,510,485,509,486,508,488,505,488,503,488,501,488,501,489,501,489,500,490,500,490,500,490,499,490,499,490,498,491,497,492,498,492,499,493,499,493,499,493,499,494,499,494,500,494,500,495,500,495,500,496,500,496,500,497,501,497,501,497,502,498,502,498,502,499,502,499,502,499,503,500,503,501,503,501,503,502,503,502,504,502,504,503,504,503,504,504,504,504,504,505,505,505,505,505,506,506,506,506,506,506,506,507,506,507,507,507,507,507,507,508,507,510,508,510,510,510,511,503,511,498,511,496,511,496,511,496,511,494,512,492,512,490,512,488,511,488,511;511,511,511,510,511,510,512,509,512,509,512,511,512,512,512,512,511,511;76,508,75,508,74,508,73,508,72,507,72,507,72,507,72,507,72,507,71,507,71,507,71,506,71,506,71,506,71,506,70,506,70,504,70,503,70,500,71,500,72,500,73,500,74,499,74,499,74,499,75,499,77,499,78,499,80,499,80,499,80,498,80,498,80,498,81,498,81,498,81,498,81,498,81,498,82,498,82,498,83,497,83,497,83,497,83,497,83,497,84,498,88,498,88,497,88,497,88,497,90,497,91,497,92,497,92,497,92,496,93,496,95,496,98,496,99,496,99,497,99,497,99,498,100,498,100,498,100,499,100,501,100,503,100,504,99,504,99,504,98,504,98,505,97,505,97,506,95,506,94,506,93,506,93,506,93,506,92,506,92,506,91,506,90,506,90,507,90,507,90,507,89,507,88,507,88,507,88,507,88,507,87,508,86,508,84,508,84,508,84,508,84,508,82,508,80,508,77,508,76,508,76,508;246,508,245,508,245,508,244,508,243,507,243,507,243,507,243,507,242,507,242,507,242,507,242,506,242,506,241,506,241,506,241,506,241,504,241,503,241,500,241,500,243,500,244,500,244,499,244,499,244,499,245,499,247,499,249,499,250,499,250,499,250,498,250,498,251,498,251,498,252,498,252,498,252,498,252,498,252,498,253,498,254,497,254,497,254,497,254,497,254,497,254,498,258,498,258,497,258,497,259,497,260,497,261,497,262,497,262,497,262,496,264,496,266,496,269,496,270,496,270,497,270,497,270,498,270,498,271,498,271,499,271,501,271,503,270,504,269,504,269,504,269,504,269,505,268,505,268,506,266,506,264,506,264,506,264,506,264,506,263,506,262,506,261,506,261,506,261,507,261,507,260,507,260,507,259,507,258,507,258,507,258,507,257,508,256,508,255,508,254,508,254,508,254,508,253,508,250,508,248,508,246,508,246,508;417,508,416,508,415,508,414,508,414,507,414,507,414,507,413,507,413,507,412,507,412,507,412,506,412,506,412,506,412,506,412,506,412,504,412,503,412,500,412,500,414,500,414,500,415,499,415,499,415,499,416,499,418,499,420,499,421,499,421,499,421,498,421,498,422,498,422,498,422,498,422,498,422,498,423,498,423,498,424,498,424,497,424,497,424,497,425,497,425,497,425,498,429,498,429,497,429,497,430,497,431,497,432,497,433,497,433,497,433,496,434,496,437,496,440,496,440,496,440,497,440,497,440,498,441,498,441,498,442,499,442,501,442,503,441,504,440,504,440,504,439,504,439,505,439,505,438,506,436,506,435,506,434,506,434,506,434,506,434,506,433,506,432,506,432,506,432,507,432,507,431,507,430,507,429,507,429,507,429,507,429,507,428,508,427,508,426,508,425,508,425,508,425,508,423,508,421,508,418,508,417,508,417,508;170,503,170,502,171,502,171,502,171,503,171,505,171,507,171,508,170,508,170,508,170,507,170,505;340,503,341,502,341,502,341,502,342,503,342,505,342,507,341,508,341,508,340,508,340,507,340,505;511,503,511,502,512,502,512,502,512,503,512,505,512,507,512,508,512,508,511,508,511,507,511,505;167,506,167,506,166,506,166,506,165,505,165,505,165,504,164,504,164,504,164,504,163,504,163,504,163,503,162,503,162,503,162,503,161,503,161,502,161,502,160,502,160,502,159,502,159,501,159,501,158,500,158,500,157,500,157,500,157,500,157,500,157,499,157,499,158,499,159,499,160,499,160,499,160,498,160,498,160,498,161,498,161,498,161,498,161,498,161,498,162,498,163,498,164,497,164,497,164,497,168,497,169,497,170,498,170,500,169,500,169,500,169,500,169,501,169,502,169,503,169,503,168,503,168,503,168,504,168,505,168,505,168,506,167,506,167,506,167,506;338,506,337,506,337,506,337,506,336,505,336,505,336,504,335,504,335,504,335,504,334,504,334,504,334,503,333,503,333,503,333,503,332,503,332,502,332,502,331,502,331,502,330,502,329,501,329,501,329,500,328,500,328,500,328,500,328,500,328,500,328,499,328,499,329,499,330,499,330,499,330,499,330,498,330,498,331,498,331,498,332,498,332,498,332,498,332,498,333,498,334,498,334,497,334,497,334,497,339,497,340,497,340,498,340,500,340,500,340,500,340,500,340,501,340,502,339,503,339,503,339,503,339,503,339,504,339,505,339,505,338,506,338,506,338,506,338,506;508,506,508,506,508,506,507,506,507,505,507,505,506,504,506,504,506,504,505,504,505,504,505,504,504,503,504,503,504,503,503,503,503,503,503,502,502,502,502,502,501,502,501,502,500,501,500,501,500,500,499,500,499,500,498,500,498,500,498,500,498,499,498,499,500,499,500,499,501,499,501,499,501,498,501,498,502,498,502,498,502,498,502,498,502,498,503,498,504,498,504,498,505,497,505,497,505,497,510,497,510,497,511,498,511,500,511,500,510,500,510,500,510,501,510,502,510,503,510,503,510,503,510,503,510,504,510,505,509,505,509,506,508,506,508,506,508,506;42,500,42,499,43,499,43,499,43,498,43,497,43,496,43,496,44,496,44,496,44,496,44,496,44,496,45,496,45,496,46,496,47,496,47,497,47,497,48,498,48,498,49,498,50,498,50,499,50,500,49,500,48,500,47,500,46,500,46,501,46,501,46,501,45,501,44,501,44,501,44,501,44,502,43,502,43,501;213,500,213,499,213,499,213,499,214,498,214,497,214,496,214,496,214,496,215,496,215,496,215,496,215,496,215,496,216,496,217,496,217,496,218,497,218,497,219,498,219,498,219,498,220,498,220,499,220,500,220,500,219,500,218,500,217,500,217,501,217,501,216,501,216,501,215,501,214,501,214,501,214,502,214,502,213,501;383,500,383,499,384,499,384,499,384,498,384,497,384,496,384,496,385,496,385,496,386,496,386,496,386,496,386,496,387,496,388,496,388,496,389,497,389,497,389,498,389,498,390,498,391,498,391,499,391,500,391,500,389,500,388,500,388,500,388,501,388,501,387,501,386,501,385,501,385,501,385,501,385,502,384,502,384,501;8,499,7,499,7,499,6,499,6,499,6,498,6,497,5,496,5,496,5,496,5,495,5,495,6,494,7,494,7,495,7,495,7,495,8,495,8,495,8,495,8,495,8,496,10,498,10,498,11,498,11,498,11,498,11,499,11,499,10,499,9,499,9,499,9,499,9,499,9,500,8,500,8,500,8,499,8,499;178,499,178,499,177,499,176,499,176,499,176,498,176,497,176,496,176,496,175,496,175,495,176,495,177,494,178,494,178,495,178,495,178,495,178,495,179,495,179,495,179,495,179,496,179,496,180,497,180,497,181,498,181,498,181,498,182,498,182,498,182,499,181,499,181,499,180,499,180,499,180,499,180,499,179,500,179,500,178,500,178,499,178,499;349,499,348,499,348,499,347,499,347,499,347,498,347,497,347,496,347,496,346,496,346,495,347,495,347,494,348,494,348,495,348,495,348,495,349,495,349,495,350,495,350,495,350,496,350,496,350,497,351,497,351,498,352,498,352,498,352,498,352,498,352,499,352,499,351,499,351,499,350,499,350,499,350,499,350,500,350,500,349,500,349,499,349,499;125,497,125,495,125,495,126,495,126,493,125,493,124,492,124,492,124,491,124,491,124,491,124,491,123,491,123,490,124,489,124,489,126,489,129,489,132,489,134,489,134,489,134,488,135,488,135,488,136,488,136,488,136,488,136,488,138,488,142,488,145,488,148,487,148,487,148,487,148,487,150,487,151,487,152,487,152,487,152,486,152,486,152,486,153,486,154,486,154,486,154,485,154,486,154,486,155,486,155,487,152,489,150,491,150,492,150,493,150,493,149,494,149,494,148,494,148,495,148,495,148,496,147,497,145,497,144,497,144,497,144,497,144,497,142,498,140,498,137,498,136,498,136,498,136,498,134,498,131,498,127,498,126,498,126,497;152,498,152,498,152,498,151,498,151,497,150,497,149,496,149,495,150,495,150,495,150,495,150,494,150,494,150,494,151,494,151,494,151,493,151,493,151,492,154,488,155,488,155,488,156,488,156,488,156,487,157,487,159,487,160,487,162,487,162,487,162,487,162,488,164,488,165,488,166,488,166,488,166,488,166,488,167,488,168,488,168,488,168,489,168,489,168,490,169,490,169,490,169,490,169,492,169,493,169,494,169,494,169,494,170,494,170,494,170,495,169,495,169,495,168,495,168,495,168,495,168,495,167,496,166,496,164,496,163,496,163,496,163,496,162,496,162,496,161,496,160,496,160,497,159,497,159,498,158,498,157,498,157,498,157,498,157,498,156,498,155,498,153,498,152,498,152,498;295,497,295,495,296,495,296,495,296,493,296,493,295,492,295,492,295,491,295,491,295,491,295,491,294,491,294,490,295,489,295,489,296,489,300,489,303,489,305,489,305,489,305,488,305,488,306,488,306,488,307,488,307,488,307,488,309,488,313,488,316,488,318,487,318,487,318,487,319,487,320,487,321,487,322,487,322,487,322,486,323,486,323,486,324,486,324,486,324,486,324,485,325,486,325,486,326,486,325,487,323,489,321,491,320,492,320,493,320,493,320,494,320,494,319,494,319,495,319,495,319,496,318,497,316,497,315,497,314,497,314,497,314,497,313,498,310,498,308,498,306,498,306,498,306,498,304,498,302,498,297,498,297,498,296,497;323,498,323,498,322,498,322,498,321,497,321,497,320,496,320,495,321,495,321,495,321,495,321,494,321,494,321,494,321,494,321,494,322,493,322,493,322,492,325,488,326,488,326,488,326,488,327,488,327,487,327,487,330,487,331,487,332,487,332,487,332,487,333,488,334,488,335,488,336,488,336,488,336,488,337,488,338,488,339,488,339,488,339,489,339,489,339,490,339,490,339,490,340,490,340,492,340,493,340,494,340,494,340,494,340,494,340,494,340,495,340,495,340,495,339,495,339,495,339,495,339,495,338,496,336,496,335,496,334,496,334,496,334,496,333,496,332,496,331,496,331,496,331,497,330,497,330,498,329,498,328,498,328,498,328,498,328,498,327,498,325,498,324,498,323,498,323,498;466,497,466,495,467,495,467,495,467,493,466,493,466,492,466,492,466,491,466,491,465,491,465,491,465,491,465,490,465,489,466,489,467,489,471,489,474,489,476,489,476,489,476,488,476,488,477,488,477,488,478,488,478,488,478,488,480,488,483,488,487,488,489,487,489,487,489,487,490,487,491,487,492,487,493,487,493,487,493,486,493,486,494,486,494,486,495,486,495,486,495,485,495,486,496,486,496,486,496,487,494,489,492,491,491,492,491,493,491,493,491,494,490,494,490,494,490,495,490,495,490,496,489,497,487,497,486,497,485,497,485,497,485,497,483,498,481,498,478,498,477,498,477,498,477,498,475,498,472,498,468,498,468,498,467,497;494,498,493,498,493,498,493,498,492,497,492,497,491,496,491,495,491,495,491,495,492,495,492,494,492,494,492,494,492,494,492,494,492,493,492,493,492,492,495,488,496,488,496,488,497,488,497,488,498,487,498,487,500,487,502,487,503,487,503,487,503,487,504,488,505,488,506,488,507,488,507,488,507,488,507,488,508,488,509,488,510,488,510,489,510,489,510,490,510,490,510,490,510,490,510,492,510,493,510,494,511,494,511,494,511,494,511,494,511,495,511,495,510,495,510,495,510,495,510,495,510,495,508,496,507,496,505,496,504,496,504,496,504,496,504,496,503,496,502,496,502,496,501,497,501,497,500,498,499,498,499,498,498,498,498,498,498,498,497,498,496,498,495,498,494,498,494,498;0,488,0,488,1,488,1,488,2,488,2,489,2,489,2,489,3,489,4,489,4,492,4,494,4,495,4,495,4,495,4,495,4,496,4,497,4,498,3,498,2,498,1,497,1,497,1,497,1,497,1,497,0,498,0,497,0,493;13,497,13,497,12,497,11,497,10,493,12,493,12,492,12,492,12,492,12,491,15,488,16,488,16,488,16,488,16,488,16,488,16,488,17,488,17,488,18,487,18,487,18,487,18,487,18,487,19,487,19,487,19,487,19,486,19,486,20,486,20,486,21,486,21,486,21,486,21,486,22,486,22,486,23,485,23,485,23,485,23,485,24,485,24,485,24,485,24,485,24,484,25,484,26,484,27,484,28,484,28,484,28,484,28,484,28,484,29,484,29,484,29,484,29,484,29,484,29,484,30,484,31,485,31,486,31,486,31,487,32,487,32,487,32,488,32,489,32,489,32,490,33,490,33,490,33,491,32,492,32,492,31,492,31,492,31,492,30,492,30,493,30,493,29,493,28,493,27,493,26,493,26,493,26,493,25,494,25,494,25,494,24,494,24,494,24,495,23,495,23,495,22,495,21,495,21,496,21,496,20,496,20,496,20,496,19,496,19,497,19,497,18,498,16,498,14,498,13,497,13,497;55,497,54,497,54,497,53,497,53,497,53,497,53,496,52,496,52,496,51,496,51,496,49,494,47,492,47,492,46,492,44,492,43,491,44,491,44,491,44,490,44,490,44,489,44,489,45,489,45,489,45,488,45,487,45,485,45,484,45,484,44,484,44,484,44,483,44,482,44,482,43,482,42,482,42,481,42,480,42,480,42,480,42,479,43,478,44,479,44,481,44,481,44,482,45,482,45,482,46,482,47,483,48,484,48,484,50,484,51,484,51,484,52,485,52,485,53,486,53,486,54,486,54,486,54,486,54,486,55,486,56,486,57,486,58,486,58,487,58,487,58,487,58,487,59,487,59,487,59,487,59,487,59,488,60,488,60,488,61,488,61,488,61,488,61,488,61,488,62,488,63,489,63,490,63,490,63,490,64,491,65,491,64,494,63,494,63,494,62,494,62,494,62,495,61,495,60,495,59,495,59,495,58,496,57,497,56,498,56,498,55,498,55,497,55,497;72,496,71,496,71,496,70,496,70,496,70,496,70,496,70,496,70,496,69,496,69,495,68,495,68,494,68,494,68,491,68,488,70,487,71,485,72,484,72,483,72,482,73,480,74,480,74,480,75,480,75,480,75,480,75,480,76,480,76,480,76,480,76,480,76,480,77,480,78,480,78,480,79,480,79,481,79,481,79,481,80,481,80,481,80,481,80,481,80,481,80,482,81,482,81,482,82,482,82,482,82,482,82,483,82,483,83,483,83,484,83,484,83,484,83,485,84,485,84,485,84,486,84,487,84,487,84,488,85,488,85,488,85,488,85,488,85,489,85,489,85,489,85,489,86,489,86,490,86,491,86,492,86,492,86,492,86,492,86,492,86,493,86,493,87,493,87,493,87,493,87,494,87,495,87,495,86,495,86,495,86,495,86,495,86,495,85,496,84,496,83,496,83,496,83,496,83,496,83,496,82,496,82,496,82,496,82,497,82,497,81,497,81,497,80,497,80,497,80,497,80,497,78,498,76,498,73,498,72,497,72,497;171,488,171,488,172,488,172,488,172,488,172,489,172,489,173,489,173,489,174,489,174,492,174,494,174,495,175,495,175,495,175,495,175,496,175,497,175,498,174,498,173,498,172,497,172,497,172,497,172,497,172,497,171,498,171,497,171,493;184,497,183,497,183,497,181,497,181,493,182,493,183,492,183,492,183,492,183,491,186,488,186,488,187,488,187,488,187,488,187,488,187,488,188,488,188,488,188,487,188,487,188,487,188,487,189,487,189,487,190,487,190,487,190,486,190,486,191,486,191,486,192,486,192,486,192,486,192,486,193,486,193,486,194,485,194,485,194,485,194,485,194,485,195,485,195,485,195,485,195,484,196,484,197,484,197,484,198,484,198,484,198,484,198,484,199,484,199,484,200,484,200,484,200,484,200,484,200,484,201,484,202,485,202,486,202,486,202,487,202,487,203,487,203,488,203,489,203,489,203,490,203,490,204,490,204,491,203,492,203,492,202,492,202,492,201,492,201,492,201,493,201,493,200,493,199,493,197,493,196,493,196,493,196,493,196,494,196,494,195,494,195,494,195,494,194,495,194,495,193,495,193,495,192,495,192,496,192,496,191,496,191,496,191,496,190,496,190,497,189,497,189,498,186,498,185,498,184,497,184,497;226,497,225,497,225,497,224,497,224,497,224,497,224,496,223,496,223,496,222,496,221,496,220,494,218,492,218,492,216,492,215,492,214,491,214,491,215,491,215,490,215,490,215,489,215,489,215,489,215,489,216,488,216,487,216,485,215,484,215,484,215,484,215,484,215,483,215,482,215,482,214,482,213,482,212,481,212,480,212,480,212,480,213,479,214,478,215,479,215,481,215,481,215,482,215,482,216,482,216,482,217,483,218,484,219,484,220,484,222,484,222,484,223,485,223,485,223,486,224,486,224,486,225,486,225,486,225,486,226,486,227,486,227,486,228,486,228,487,228,487,228,487,229,487,229,487,230,487,230,487,230,487,230,488,231,488,231,488,232,488,232,488,232,488,232,488,232,488,233,488,234,489,234,490,234,490,234,490,234,491,235,491,235,494,233,494,233,494,233,494,233,494,232,495,232,495,231,495,230,495,229,495,229,496,228,497,227,498,226,498,226,498,226,497,226,497;242,496,242,496,241,496,241,496,241,496,241,496,241,496,241,496,240,496,240,496,239,495,239,495,238,494,238,494,238,491,238,488,240,487,242,485,242,484,242,483,242,482,243,480,245,480,245,480,246,480,246,480,246,480,246,480,246,480,247,480,247,480,247,480,247,480,247,480,248,480,249,480,250,480,250,481,250,481,250,481,250,481,251,481,251,481,251,481,251,481,251,482,252,482,252,482,252,482,252,482,252,482,252,483,253,483,253,483,254,484,254,484,254,484,254,485,254,485,255,485,255,486,255,487,255,487,255,488,255,488,255,488,256,488,256,488,256,489,256,489,256,489,256,489,256,489,256,490,256,491,256,492,257,492,257,492,257,492,257,492,257,493,257,493,257,493,257,493,258,493,258,494,258,495,257,495,257,495,256,495,256,495,256,495,256,495,256,496,255,496,254,496,254,496,254,496,254,496,253,496,253,496,252,496,252,496,252,497,252,497,252,497,251,497,251,497,250,497,250,497,250,497,249,498,247,498,243,498,243,497,243,497;342,488,342,488,342,488,343,488,343,488,343,489,343,489,343,489,344,489,345,489,345,492,345,494,345,495,345,495,345,495,346,495,346,496,346,497,345,498,344,498,343,498,343,497,343,497,343,497,342,497,342,497,342,498,342,497,342,493;354,497,354,497,354,497,352,497,352,493,353,493,353,492,354,492,354,492,354,491,356,488,357,488,357,488,358,488,358,488,358,488,358,488,358,488,359,488,359,487,359,487,359,487,359,487,360,487,360,487,360,487,360,487,360,486,361,486,361,486,362,486,362,486,362,486,362,486,363,486,363,486,364,486,364,485,364,485,364,485,364,485,365,485,365,485,366,485,366,485,366,484,366,484,367,484,368,484,369,484,369,484,369,484,369,484,370,484,370,484,370,484,370,484,370,484,370,484,371,484,371,484,372,485,372,486,372,486,372,487,373,487,373,487,374,488,374,489,374,489,374,490,374,490,374,490,374,491,374,492,373,492,373,492,372,492,372,492,372,492,372,493,372,493,371,493,369,493,368,493,367,493,367,493,367,493,367,494,366,494,366,494,365,494,365,494,365,495,364,495,364,495,363,495,363,495,363,496,362,496,362,496,362,496,361,496,361,496,361,497,360,497,360,498,357,498,355,498,354,497,354,497;396,497,396,497,395,497,395,497,394,497,394,497,394,496,394,496,393,496,393,496,392,496,391,494,389,492,388,492,387,492,386,492,384,491,385,491,385,491,386,490,386,490,386,489,386,489,386,489,386,489,386,488,386,487,386,485,386,484,386,484,386,484,386,484,386,483,386,482,385,482,385,482,384,482,383,481,383,480,383,480,383,480,383,479,384,478,386,479,386,481,386,481,386,482,386,482,386,482,387,482,388,483,389,484,389,484,391,484,392,484,393,484,393,485,393,485,394,486,395,486,395,486,396,486,396,486,396,486,396,486,397,486,398,486,399,486,399,487,399,487,399,487,400,487,400,487,400,487,400,487,400,487,401,488,401,488,402,488,402,488,402,488,402,488,402,488,403,488,403,488,404,489,404,490,404,490,404,490,405,491,406,491,405,494,404,494,404,494,403,494,403,494,403,495,402,495,402,495,401,495,400,495,399,496,398,497,398,498,397,498,397,498,396,497,396,497;413,496,412,496,412,496,412,496,412,496,412,496,412,496,411,496,411,496,411,496,410,495,410,495,409,494,409,494,409,491,409,488,411,487,413,485,413,484,413,483,413,482,414,480,415,480,416,480,416,480,416,480,416,480,416,480,417,480,417,480,418,480,418,480,418,480,418,480,419,480,420,480,420,480,420,481,420,481,420,481,421,481,421,481,422,481,422,481,422,481,422,482,422,482,423,482,423,482,423,482,423,482,423,483,424,483,424,483,424,484,424,484,424,484,424,485,425,485,425,485,426,486,426,487,426,487,426,488,426,488,426,488,426,488,426,488,426,489,426,489,427,489,427,489,427,489,427,490,427,491,427,492,427,492,427,492,428,492,428,492,428,493,428,493,428,493,428,493,428,493,428,494,428,495,428,495,428,495,427,495,427,495,427,495,427,495,426,496,426,496,425,496,424,496,424,496,424,496,424,496,424,496,423,496,423,496,423,497,423,497,422,497,422,497,421,497,421,497,421,497,421,497,419,498,417,498,414,498,414,497,413,497;91,495,91,495,90,495,90,495,88,493,88,493,88,492,88,492,88,492,88,492,88,491,88,489,88,486,88,485,88,485,88,485,88,484,88,484,88,483,89,482,91,482,92,482,92,482,93,483,94,484,99,484,102,484,104,484,104,485,104,485,104,485,105,485,105,485,106,485,106,485,106,485,106,486,106,486,106,486,107,486,107,486,107,487,108,487,108,487,109,487,110,488,110,488,110,488,110,489,110,489,111,489,111,490,111,490,111,490,112,491,113,493,114,494,115,495,115,495,115,495,113,495,111,495,108,495,106,495,106,495,106,494,106,494,106,494,105,494,105,494,105,495,105,495,104,495,103,495,102,495,101,495,101,495,101,495,101,496,100,496,100,496,100,495,100,495,100,495,98,495,96,495,93,495,92,495,92,495,92,495,91,496,91,496,91,496,91,495,91,495;262,495,261,495,261,495,261,495,260,494,260,494,259,494,259,493,259,493,259,492,259,492,259,492,258,492,258,491,258,489,258,486,258,485,259,485,259,485,259,484,259,484,259,483,260,482,261,482,262,482,263,482,264,483,264,484,269,484,272,484,274,484,274,485,274,485,275,485,275,485,276,485,276,485,276,485,276,485,276,486,277,486,277,486,278,486,278,486,278,487,279,487,279,487,279,487,280,488,280,488,280,488,280,489,281,489,281,489,282,490,282,490,282,490,282,491,284,493,285,494,286,495,286,495,286,495,284,495,281,495,279,495,277,495,277,495,277,494,277,494,276,494,276,494,276,494,276,495,276,495,275,495,274,495,272,495,272,495,272,495,272,495,271,496,271,496,270,496,270,495,270,495,270,495,269,495,266,495,264,495,262,495,262,495,262,495,262,496,262,496,262,496,262,495,262,495;432,495,432,495,432,495,431,495,431,494,430,494,430,494,430,493,430,493,430,492,429,492,429,492,429,492,429,491,429,489,429,486,429,485,429,485,429,485,430,484,430,484,430,483,430,482,432,482,433,482,433,482,434,483,435,484,440,484,443,484,445,484,445,485,445,485,445,485,446,485,446,485,447,485,447,485,447,485,447,486,447,486,448,486,448,486,449,486,449,487,449,487,449,487,450,487,451,488,451,488,451,488,451,489,452,489,452,489,452,490,452,490,452,490,453,491,454,493,455,494,456,495,456,495,456,495,454,495,452,495,449,495,448,495,448,495,448,494,447,494,447,494,446,494,446,494,446,495,446,495,445,495,444,495,443,495,442,495,442,495,442,495,442,496,442,496,441,496,441,495,441,495,441,495,439,495,437,495,434,495,433,495,433,495,433,495,433,496,433,496,432,496,432,495,432,495;116,494,116,494,116,494,115,494,114,493,114,493,114,493,114,492,113,492,113,491,112,490,112,490,112,489,112,489,112,489,111,488,111,487,112,485,113,484,113,484,116,484,119,484,120,484,120,486,120,486,120,486,121,486,121,486,121,486,121,487,121,487,121,488,121,488,121,488,122,488,122,488,122,489,122,490,122,490,123,490,123,491,123,491,123,492,123,492,124,493,124,493,124,494,124,494,123,495,116,495,116,495;287,494,287,494,286,494,286,494,285,493,285,493,285,493,284,492,284,492,283,491,283,490,283,490,283,489,283,489,282,489,281,488,281,487,283,485,284,484,284,484,287,484,290,484,291,484,291,486,291,486,291,486,291,486,291,486,292,486,292,487,292,487,292,488,292,488,292,488,292,488,292,488,292,489,292,490,293,490,293,490,294,491,294,491,294,492,294,492,294,493,295,493,295,494,294,494,294,495,287,495,287,495;458,494,457,494,457,494,456,494,456,493,456,493,456,493,455,492,455,492,454,491,454,490,454,490,454,489,453,489,453,489,452,488,452,487,453,485,454,484,454,484,458,484,461,484,462,484,462,486,462,486,462,486,462,486,462,486,462,486,462,487,462,487,462,488,463,488,463,488,463,488,463,488,463,489,463,490,464,490,464,490,464,491,464,491,464,492,464,492,465,493,466,493,466,494,465,494,464,495,458,495,458,495;5,491,5,491,5,490,5,489,5,489,4,489,4,489,4,488,5,488,5,488,6,488,7,488,7,488,8,487,8,487,8,487,8,487,9,487,9,487,10,487,10,486,10,486,11,486,11,486,11,486,12,485,13,484,14,482,15,482,16,482,16,482,17,482,17,483,17,483,17,484,17,484,18,484,18,486,17,486,17,487,16,487,16,487,15,487,14,488,13,490,11,491,10,492,9,492,9,492,9,492,9,493,9,493,8,493,8,493,7,493,6,493,6,492;176,491,176,491,176,490,176,489,175,489,175,489,175,489,175,488,175,488,176,488,176,488,177,488,178,488,179,487,179,487,179,487,179,487,179,487,180,487,180,487,181,486,181,486,181,486,181,486,182,486,183,485,184,484,185,482,186,482,186,482,187,482,188,482,188,483,188,483,188,484,188,484,188,484,188,486,188,486,187,487,187,487,187,487,186,487,185,488,183,490,182,491,180,492,180,492,180,492,180,492,180,493,180,493,179,493,178,493,177,493,177,493,176,492;346,491,346,491,346,490,346,489,346,489,346,489,345,489,345,488,346,488,346,488,347,488,348,488,349,488,350,487,350,487,350,487,350,487,350,487,350,487,351,487,351,486,351,486,352,486,352,486,352,486,353,485,355,484,356,482,357,482,357,482,357,482,358,482,358,483,358,483,358,484,359,484,359,484,359,486,358,486,358,487,358,487,357,487,357,487,355,488,354,490,352,491,351,492,351,492,350,492,350,492,350,493,350,493,350,493,349,493,348,493,347,493,347,492;39,492,38,492,37,492,36,492,36,491,35,490,34,490,34,489,34,489,34,488,33,488,33,488,33,488,33,488,33,488,33,487,33,487,33,487,32,487,32,487,32,486,32,486,32,486,32,486,31,486,31,483,32,482,33,482,33,482,37,482,39,482,41,482,41,482,41,482,41,482,41,482,42,482,43,483,43,484,43,484,43,484,43,484,43,484,44,485,44,487,44,488,43,489,43,489,43,489,43,489,43,489,43,490,42,491,41,491,41,491,41,491,41,492,40,492,39,492,39,492;210,492,209,492,208,492,207,492,206,491,205,490,205,490,204,489,204,489,204,488,204,488,204,488,204,488,204,488,204,488,204,487,203,487,203,487,203,487,203,487,203,486,203,486,203,486,203,486,202,486,202,483,203,482,204,482,204,482,208,482,210,482,212,482,212,482,212,482,212,482,212,482,212,482,213,482,213,483,213,483,214,483,214,484,214,484,214,484,214,484,214,484,214,485,214,487,214,488,214,489,214,489,214,489,214,489,214,489,214,490,213,491,212,491,212,491,211,491,211,492,211,492,210,492,210,492;380,492,379,492,379,492,377,492,377,491,376,490,375,490,375,489,375,489,375,488,375,488,375,488,374,488,374,488,374,488,374,487,374,487,374,487,374,487,374,487,374,486,374,486,373,486,373,486,372,486,373,483,374,482,374,482,375,482,378,482,381,482,382,482,382,482,382,482,382,482,383,482,383,482,383,482,384,483,384,483,384,483,384,484,384,484,384,484,385,484,385,484,385,485,385,487,385,488,385,489,385,489,384,489,384,489,384,489,384,490,383,491,383,491,383,491,382,491,382,492,381,492,380,492,380,492;64,487,64,487,63,487,62,487,60,486,61,486,61,486,62,485,62,484,62,484,62,484,62,484,63,484,63,483,63,483,63,483,64,483,65,483,67,483,68,483,68,483,68,482,68,482,68,482,70,482,71,485,69,486,68,487,68,488,66,488,65,488,64,487,64,487;124,487,123,487,123,487,122,487,122,486,122,485,122,485,121,485,121,485,120,484,120,484,120,484,120,483,119,482,118,482,118,482,118,481,118,481,118,480,117,480,117,480,117,480,117,479,117,479,117,478,117,478,117,478,117,478,118,478,118,478,118,477,118,477,118,477,119,476,119,476,119,475,119,475,119,475,122,475,124,475,125,475,125,475,125,475,126,476,128,476,129,476,130,476,130,476,130,476,131,476,131,476,132,476,132,480,132,485,132,486,130,486,130,486,129,486,129,486,129,487,128,487,127,487,126,487,126,487,126,487,126,487,125,488,125,488,124,488,124,487,124,487;170,487,170,487,170,487,169,487,169,487,169,486,168,486,168,486,167,486,166,486,166,485,166,485,166,485,165,485,164,485,163,485,163,485,163,485,163,484,161,484,159,484,155,484,155,484,155,482,155,482,155,482,155,482,154,482,154,481,154,481,154,480,154,480,154,480,154,480,154,480,154,479,154,479,153,478,153,478,153,478,153,478,153,478,153,478,154,477,154,477,154,476,155,475,156,475,156,475,156,475,156,475,156,474,157,474,158,474,159,474,160,474,160,474,160,474,161,474,162,474,163,474,164,473,164,473,164,473,164,473,164,473,165,473,165,473,165,473,165,472,166,472,167,472,168,472,169,472,169,472,169,472,169,472,170,472,170,472,171,472,171,472,171,472,171,472,172,472,172,472,172,472,172,473,172,473,173,473,174,473,175,473,176,473,176,473,176,473,176,474,178,474,179,474,180,474,180,474,180,474,180,474,181,474,181,474,182,474,182,474,182,473,184,473,185,474,185,474,186,475,186,475,186,476,186,476,186,477,187,477,187,477,187,478,187,478,187,478,186,479,186,479,186,479,186,480,186,481,182,484,181,484,181,484,181,484,181,485,180,485,180,486,179,486,179,486,179,486,179,486,179,486,178,486,177,486,176,486,175,486,175,487,175,487,174,487,173,487,172,487,171,487,171,487,171,487,171,488,171,488,170,488,170,487,170,487;235,487,234,487,234,487,232,487,231,486,232,486,232,486,232,485,232,484,232,484,232,484,233,484,233,484,234,483,234,483,234,483,235,483,236,483,237,483,238,483,238,483,238,482,239,482,239,482,241,482,241,485,240,486,239,487,238,488,237,488,236,488,235,487,235,487;294,487,294,487,294,487,293,487,292,486,292,485,292,485,292,485,292,485,291,484,291,484,291,484,291,483,289,482,289,482,288,482,288,481,288,481,288,480,288,480,288,480,288,480,288,479,288,479,288,478,288,478,288,478,288,478,288,478,288,478,288,477,288,477,289,477,289,476,290,476,290,475,290,475,290,475,293,475,294,475,296,475,296,475,296,475,297,476,298,476,300,476,301,476,301,476,301,476,301,476,302,476,303,476,303,480,303,485,303,486,301,486,301,486,300,486,300,486,299,487,299,487,298,487,297,487,296,487,296,487,296,487,296,488,295,488,295,488,294,487,294,487;341,487,341,487,340,487,340,487,339,487,339,486,339,486,338,486,337,486,337,486,336,485,336,485,336,485,336,485,335,485,334,485,334,485,334,485,334,484,332,484,330,484,326,484,326,484,326,482,326,482,325,482,325,482,325,482,325,481,325,481,325,480,325,480,325,480,324,480,324,480,324,479,324,479,324,478,324,478,323,478,323,478,324,478,324,478,324,477,324,477,324,476,326,475,326,475,327,475,327,475,327,475,327,474,328,474,329,474,330,474,331,474,331,474,331,474,332,474,333,474,333,474,334,473,334,473,334,473,334,473,335,473,335,473,336,473,336,473,336,472,336,472,338,472,339,472,340,472,340,472,340,472,340,472,341,472,341,472,342,472,342,472,342,472,342,472,342,472,343,472,343,472,343,473,343,473,344,473,345,473,345,473,346,473,346,473,346,473,347,474,348,474,349,474,350,474,350,474,350,474,351,474,351,474,352,474,352,474,352,474,352,473,355,473,356,474,356,474,356,475,356,475,356,476,356,476,357,477,357,477,358,477,358,478,358,478,357,478,357,479,356,479,356,479,356,480,356,481,353,484,352,484,352,484,351,484,351,485,351,485,350,486,350,486,350,486,350,486,350,486,350,486,349,486,348,486,346,486,346,486,346,487,346,487,345,487,344,487,342,487,342,487,342,487,342,487,341,488,341,488,341,488,341,487,341,487;406,487,405,487,404,487,403,487,402,486,402,486,403,486,403,485,403,484,403,484,403,484,404,484,404,484,404,483,404,483,404,483,405,483,407,483,408,483,409,483,409,483,409,482,409,482,410,482,412,482,412,485,410,486,409,487,409,488,407,488,406,488,406,487,406,487;465,487,465,487,464,487,464,487,463,486,463,485,463,485,463,485,462,485,462,484,462,484,462,484,462,483,460,482,459,482,459,482,459,481,459,481,459,480,459,480,459,480,458,480,458,479,458,479,458,478,458,478,459,478,459,478,459,478,459,478,459,477,459,477,460,477,460,476,460,476,460,475,460,475,461,475,463,475,465,475,466,475,466,475,466,475,467,476,469,476,470,476,472,476,472,476,472,476,472,476,473,476,474,476,474,480,474,485,473,486,472,486,471,486,471,486,471,486,470,487,470,487,468,487,468,487,467,487,467,487,467,487,466,488,466,488,465,488,465,487,465,487;512,487,511,487,511,487,511,487,510,487,510,486,509,486,509,486,508,486,507,486,507,485,507,485,507,485,506,485,506,485,505,485,504,485,504,485,504,484,503,484,501,484,497,484,496,484,496,482,496,482,496,482,496,482,496,482,496,481,496,481,496,480,495,480,495,480,495,480,495,480,495,479,495,479,495,478,494,478,494,478,494,478,494,478,495,478,495,477,495,477,495,476,496,475,497,475,497,475,498,475,498,475,498,474,498,474,500,474,501,474,502,474,502,474,502,474,502,474,503,474,504,474,505,473,505,473,505,473,505,473,506,473,506,473,506,473,506,473,506,472,507,472,508,472,509,472,510,472,510,472,510,472,511,472,511,472,512,472,512,472,512,472,512,472,512,472,513,472,513,472,514,472,514,473,514,473,514,473,515,473,516,473,517,473,517,473,517,473,518,474,519,474,520,474,521,474,521,474,521,474,521,474,522,474,522,474,523,474,523,474,523,473,526,473,526,474,527,474,527,475,527,475,527,476,527,476,528,477,528,477,528,477,528,478,528,478,528,478,528,479,527,479,527,479,527,480,527,481,524,484,523,484,523,484,522,484,522,485,522,485,521,486,521,486,520,486,520,486,520,486,520,486,519,486,518,486,517,486,516,486,516,487,516,487,515,487,514,487,513,487,512,487,512,487,512,487,512,488,512,488,512,488,512,487,512,487;132,486,132,486,133,486,133,486,134,486,134,487,134,487,133,487,133,487,132,487,132,487,132,487;303,486,303,486,304,486,304,486,304,486,304,487,304,487,304,487,304,487,303,487,303,487,303,487;474,486,474,486,474,486,475,486,475,486,475,487,475,487,475,487,474,487,474,487,474,487,474,487;135,486,135,486,134,486,134,486,134,485,134,481,134,478,133,476,133,476,133,476,133,475,133,475,134,474,137,474,137,475,137,475,139,475,142,475,147,475,147,475,148,476,148,476,149,476,149,476,149,476,151,478,151,479,151,479,151,480,152,480,152,480,152,481,152,482,152,482,152,483,153,483,153,483,153,483,153,483,152,483,152,484,152,484,152,485,151,486,149,486,148,486,148,486,148,486,148,486,145,486,141,486,137,486,135,486,135,486;306,486,305,486,305,486,304,486,304,485,304,481,304,478,304,476,304,476,303,476,303,475,304,475,305,474,308,474,308,475,308,475,309,475,313,475,318,475,318,475,319,476,319,476,319,476,319,476,320,476,322,478,322,479,322,479,322,480,322,480,323,480,323,481,323,482,323,482,323,483,323,483,324,483,324,483,323,483,323,483,323,484,323,484,323,485,322,486,320,486,319,486,318,486,318,486,318,486,316,486,312,486,308,486,306,486,306,486;476,486,476,486,476,486,475,486,475,485,475,481,475,478,475,476,475,476,474,476,474,475,475,475,475,474,478,474,478,475,478,475,480,475,483,475,488,475,489,475,489,476,489,476,490,476,490,476,491,476,492,478,492,479,492,479,492,480,493,480,493,480,494,481,494,482,494,482,494,483,494,483,494,483,494,483,494,483,494,483,494,484,494,484,494,485,493,486,491,486,490,486,489,486,489,486,489,486,487,486,483,486,479,486,476,486,476,486;57,485,56,485,56,485,55,485,55,485,55,484,55,483,57,483,61,483,61,483,60,485,59,485,59,486,58,486,57,486,57,485,57,485;228,485,227,485,227,485,226,485,226,485,226,484,226,483,228,483,231,483,232,483,231,485,230,485,229,486,229,486,228,486,228,485,228,485;398,485,398,485,397,485,396,485,396,485,396,484,396,483,399,483,402,483,403,483,401,485,401,485,400,486,399,486,399,486,398,485,398,485;19,484,19,484,19,483,19,483,19,483,18,483,18,482,18,482,18,480,18,479,18,478,18,478,18,478,18,478,18,478,18,477,18,477,19,477,19,477,19,477,19,476,19,476,22,472,23,472,24,472,24,472,25,472,25,471,25,471,26,471,26,471,26,471,27,472,27,472,27,472,28,472,28,472,28,472,29,473,29,473,29,474,29,474,31,474,31,474,31,478,31,482,31,482,29,482,29,482,28,482,28,483,28,483,27,483,26,483,25,483,24,483,24,483,24,483,24,484,24,484,23,484,23,484,23,484,23,484,22,484,22,484,21,484,20,484,20,485,20,485,20,485,19,484;190,484,190,484,190,483,190,483,189,483,189,483,188,482,188,482,188,480,188,479,188,478,189,478,189,478,189,478,189,478,189,477,189,477,189,477,189,477,190,477,190,476,190,476,193,472,194,472,194,472,195,472,195,472,195,471,196,471,196,471,196,471,197,471,197,472,197,472,198,472,198,472,198,472,199,472,199,473,199,473,200,474,200,474,201,474,202,474,202,478,202,482,201,482,200,482,199,482,199,482,199,483,199,483,198,483,197,483,196,483,195,483,195,483,195,483,195,484,194,484,194,484,194,484,194,484,194,484,193,484,192,484,191,484,191,484,191,485,191,485,190,485,190,484;360,484,360,484,360,483,360,483,360,483,360,483,359,482,359,482,359,480,359,479,359,478,359,478,359,478,360,478,360,478,360,477,360,477,360,477,360,477,360,477,360,476,360,476,364,472,365,472,365,472,366,472,366,472,366,471,367,471,367,471,367,471,368,471,368,472,368,472,369,472,369,472,369,472,370,472,370,473,370,473,371,474,371,474,372,474,372,474,372,478,372,482,372,482,370,482,370,482,370,482,370,483,370,483,369,483,368,483,366,483,366,483,366,483,366,483,365,484,365,484,364,484,364,484,364,484,364,484,364,484,363,484,362,484,362,484,362,485,362,485,361,485,361,484;100,483,99,483,97,483,94,483,94,483,93,482,93,482,92,481,92,481,92,480,92,480,92,480,91,480,91,480,91,480,90,479,90,478,91,478,91,478,91,478,91,477,91,476,91,476,92,476,92,476,92,476,92,476,92,476,93,476,93,476,94,476,94,475,94,475,94,475,95,475,96,475,97,475,98,475,98,475,98,474,99,474,99,474,100,474,100,474,100,474,100,474,100,474,101,474,101,474,102,473,102,473,102,473,102,473,102,473,102,473,103,472,104,472,104,471,105,471,106,471,107,471,108,471,108,471,108,470,109,470,110,470,113,470,114,471,114,472,114,472,114,472,114,472,114,472,114,472,114,473,114,473,114,474,115,474,115,474,115,474,115,475,115,476,115,477,115,477,115,477,116,477,116,478,116,479,116,480,116,480,116,480,116,480,116,480,115,480,115,481,116,482,117,482,115,483,114,483,114,483,114,483,114,483,114,483,111,484,107,484,103,484,100,483,100,483;271,483,270,483,268,483,265,483,264,483,264,482,263,482,263,481,263,481,263,480,263,480,262,480,262,480,262,480,261,480,261,479,261,478,261,478,261,478,262,478,262,477,262,476,262,476,262,476,263,476,263,476,263,476,263,476,263,476,264,476,264,476,265,475,265,475,265,475,266,475,267,475,268,475,269,475,269,475,269,474,269,474,270,474,270,474,271,474,271,474,271,474,271,474,272,474,272,474,272,473,272,473,272,473,272,473,273,473,273,473,274,472,274,472,275,471,275,471,277,471,278,471,279,471,279,471,279,470,280,470,281,470,283,470,284,471,284,472,284,472,284,472,285,472,285,472,285,472,285,473,285,473,285,474,285,474,285,474,286,474,286,475,286,476,286,477,286,477,286,477,286,477,286,478,286,479,286,480,287,480,287,480,287,480,287,480,286,480,286,481,287,482,287,482,286,483,285,483,285,483,284,483,284,483,284,483,282,484,278,484,273,484,271,483,271,483;442,483,440,483,438,483,435,483,435,483,434,482,434,482,434,481,434,481,434,480,433,480,433,480,433,480,432,480,432,480,431,479,431,478,432,478,432,478,432,478,432,477,432,476,432,476,433,476,433,476,434,476,434,476,434,476,434,476,435,476,435,476,436,475,436,475,436,475,436,475,438,475,439,475,440,475,440,475,440,474,440,474,441,474,441,474,442,474,442,474,442,474,442,474,442,474,443,474,443,473,443,473,443,473,443,473,443,473,444,473,444,472,445,472,446,471,446,471,448,471,449,471,450,471,450,471,450,470,450,470,452,470,454,470,455,471,455,472,455,472,455,472,455,472,455,472,456,472,456,473,456,473,456,474,456,474,456,474,456,474,456,475,456,476,456,477,457,477,457,477,457,477,457,478,457,479,457,480,457,480,458,480,458,480,457,480,457,480,457,481,457,482,458,482,457,483,456,483,455,483,455,483,455,483,455,483,452,484,448,484,444,484,442,483,442,483;46,481,46,480,46,480,46,480,45,479,45,479,44,479,44,478,44,478,44,478,44,478,44,478,44,478,44,477,44,477,44,476,44,476,44,476,44,476,44,476,44,475,44,474,45,472,47,472,47,472,48,472,48,472,48,472,48,472,49,472,50,472,51,471,51,471,51,471,52,471,53,471,54,471,55,471,55,471,55,470,56,470,58,470,59,470,60,470,60,470,60,469,66,469,67,470,68,471,68,476,67,476,67,476,67,477,67,477,68,478,68,480,68,480,67,481,67,481,66,481,65,481,65,481,65,481,65,481,63,482,60,482,55,482,55,482,55,482,54,483,54,483,51,483,48,483,48,483,47,482;217,481,216,480,216,480,216,480,216,479,216,479,215,479,215,478,215,478,215,478,215,478,215,478,214,478,214,477,214,477,214,476,214,476,215,476,215,476,215,476,215,475,215,474,216,472,217,472,218,472,218,472,218,472,218,472,219,472,220,472,221,472,222,471,222,471,222,471,222,471,224,471,225,471,226,471,226,471,226,470,227,470,228,470,230,470,231,470,231,470,231,469,237,469,238,470,238,471,238,476,238,476,237,476,238,477,238,477,239,478,239,480,238,480,238,481,237,481,237,481,236,481,236,481,236,481,236,481,234,482,231,482,226,482,226,482,225,482,225,483,224,483,222,483,218,483,218,483,217,482;387,481,387,480,387,480,387,480,387,479,386,479,386,479,386,478,386,478,386,478,385,478,385,478,385,478,385,477,385,477,385,476,385,476,385,476,385,476,386,476,386,475,386,474,387,472,388,472,388,472,389,472,389,472,389,472,390,472,391,472,391,472,392,471,392,471,392,471,393,471,394,471,395,471,396,471,396,471,396,470,397,470,399,470,400,470,402,470,402,470,402,469,408,469,408,470,409,471,409,476,408,476,408,476,408,477,409,477,410,478,410,480,409,480,409,481,408,481,407,481,407,481,406,481,406,481,406,481,404,482,401,482,397,482,396,482,396,482,395,483,395,483,392,483,389,483,389,483,388,482;82,480,82,480,82,480,81,480,81,480,81,480,81,480,81,480,80,480,80,480,80,479,80,479,80,479,79,479,78,479,77,479,77,479,77,479,77,478,77,478,76,478,76,478,75,477,75,477,75,476,75,476,75,476,74,476,74,476,74,476,74,475,74,475,75,475,75,475,75,475,75,474,75,474,75,474,76,474,76,474,76,473,76,473,76,472,77,472,78,472,79,472,80,471,80,471,80,471,80,471,82,471,83,471,84,471,84,471,84,471,84,472,85,472,85,472,86,472,86,472,86,472,86,472,87,472,89,472,90,473,90,476,90,478,89,479,88,479,88,479,88,479,88,479,88,479,87,480,87,480,86,480,86,480,86,480,86,480,86,480,85,480,84,480,84,480,84,481,84,481,83,481,83,481,82,481,82,481,82,481;253,480,253,480,252,480,252,480,252,480,252,480,252,480,251,480,251,480,250,480,250,479,250,479,250,479,250,479,249,479,248,479,248,479,248,479,248,478,247,478,247,478,247,478,246,478,246,478,246,477,246,477,246,477,246,476,245,476,245,476,245,476,245,476,245,476,245,475,245,475,245,475,245,475,246,475,246,474,246,474,246,474,246,474,247,474,247,473,247,473,247,472,248,472,249,472,250,472,250,471,250,471,250,471,251,471,252,471,253,471,254,471,254,471,254,471,255,472,255,472,256,472,256,472,256,472,256,472,257,472,257,472,259,472,260,473,260,476,260,478,260,479,259,479,258,479,258,479,258,479,258,479,258,480,258,480,257,480,257,480,257,480,257,480,256,480,256,480,255,480,254,480,254,481,254,481,254,481,254,481,253,481,253,481,253,481;424,480,423,480,423,480,422,480,422,480,422,480,422,480,422,480,422,480,421,480,421,479,421,479,421,479,420,479,420,479,419,479,418,479,418,479,418,478,418,478,418,478,417,478,417,478,417,478,416,477,416,477,416,477,416,476,416,476,416,476,416,476,416,476,416,476,416,475,416,475,416,475,416,475,416,475,416,474,416,474,416,474,417,474,417,474,418,473,418,473,418,472,418,472,420,472,420,472,421,471,421,471,421,471,422,471,423,471,424,471,425,471,425,471,425,471,425,472,426,472,426,472,427,472,427,472,427,472,427,472,428,472,430,472,431,473,431,476,431,478,430,479,429,479,429,479,429,479,429,479,429,479,429,480,428,480,428,480,428,480,428,480,428,480,427,480,426,480,425,480,425,480,425,481,425,481,425,481,424,481,424,481,424,481,424,481;34,480,34,480,34,480,33,480,32,479,32,477,32,474,33,474,34,474,35,474,36,473,36,473,36,473,42,473,42,473,43,474,43,476,43,476,42,476,42,477,42,478,42,479,42,479,41,479,41,479,40,479,40,480,39,480,39,480,37,480,35,480,34,480,34,480;205,480,205,480,204,480,203,480,203,479,203,477,203,474,203,474,205,474,206,474,206,473,206,473,206,473,212,473,213,473,214,474,214,476,213,476,213,476,213,477,213,478,213,479,213,479,212,479,211,479,211,479,211,480,210,480,210,480,207,480,206,480,205,480,205,480;376,480,375,480,375,480,374,480,374,479,374,477,374,474,374,474,376,474,376,474,377,473,377,473,377,473,383,473,384,473,384,474,384,476,384,476,384,476,384,477,384,478,384,479,383,479,383,479,382,479,381,479,381,480,381,480,380,480,378,480,377,480,376,480,376,480;150,475,149,475,149,475,148,475,148,475,148,474,148,474,148,474,149,474,149,474,150,474,150,474,150,474,150,474,151,474,152,474,153,474,153,475,153,475,153,475,153,476,152,477,151,477,150,476;320,475,320,475,319,475,319,475,319,475,319,474,319,474,319,474,320,474,320,474,320,474,320,474,320,474,321,474,322,474,323,474,323,474,324,475,324,475,324,475,323,476,322,477,322,477,321,476;491,475,490,475,490,475,490,475,490,475,490,474,490,474,490,474,490,474,491,474,491,474,491,474,491,474,492,474,492,474,493,474,494,474,494,475,495,475,495,475,494,476,493,477,493,477,492,476;68,471,68,471,69,471,69,471,70,471,70,471,70,471,71,472,72,472,74,472,74,473,74,473,74,474,74,474,73,474,73,474,73,474,72,475,72,475,72,475,71,475,71,475,71,476,70,476,70,476,69,476,68,476,68,474;239,471,239,471,240,471,240,471,240,471,240,471,240,471,241,472,243,472,245,472,245,473,245,473,245,474,244,474,244,474,243,474,243,474,243,475,242,475,242,475,242,475,241,475,241,476,241,476,240,476,240,476,239,476,239,474;410,471,410,471,410,471,411,471,411,471,411,471,411,471,412,472,413,472,416,472,416,473,416,473,415,474,415,474,415,474,414,474,414,474,414,475,413,475,413,475,413,475,412,475,412,476,412,476,411,476,410,476,410,476,410,474;16,474,17,473,18,473,19,473,19,473,19,474,19,475,19,475,18,475,18,475,18,475,18,475,18,475,17,476,17,476,16,476,16,475,16,475;187,474,187,474,187,473,188,473,188,473,189,473,189,473,190,473,190,474,190,475,189,475,189,475,188,475,188,475,188,475,188,475,188,476,188,476,187,476,187,475,187,475;358,474,358,474,358,473,358,473,359,473,359,473,360,473,360,473,360,474,360,475,360,475,360,475,359,475,359,475,359,475,359,475,359,476,358,476,358,476,358,475,358,475;90,474,90,474,90,474,91,474,91,473,91,473,91,471,91,471,96,471,100,471,100,471,100,471,100,472,99,473,98,473,98,473,98,473,98,473,98,473,97,474,96,474,95,474,94,474,94,474,94,474,94,474,93,474,93,474,92,474,92,475,92,475,91,475,91,474;261,474,261,474,261,474,261,474,262,473,262,473,262,471,262,471,267,471,270,471,271,471,271,471,271,472,270,473,269,473,269,473,268,473,268,473,268,473,267,474,267,474,266,474,265,474,265,474,265,474,264,474,264,474,263,474,263,474,263,475,263,475,262,475,261,474;431,474,431,474,432,474,432,474,432,473,432,473,432,471,433,471,437,471,441,471,442,471,442,471,442,472,441,473,440,473,439,473,439,473,439,473,439,473,438,474,437,474,436,474,436,474,436,474,436,474,435,474,435,474,434,474,434,474,434,475,434,475,432,475,432,474;116,473,116,472,116,472,116,472,115,472,115,472,115,472,115,470,116,470,116,470,116,469,116,469,116,468,116,468,117,468,117,468,118,468,118,468,118,467,118,467,118,468,119,468,119,469,119,470,119,472,119,472,118,473,117,474,117,474,116,473;130,472,130,472,127,472,125,472,124,472,123,471,122,470,122,470,122,468,122,468,122,467,122,467,122,467,122,467,122,466,122,466,121,465,121,465,120,465,120,464,120,462,120,459,121,458,122,458,122,458,122,458,122,458,122,458,124,458,126,458,129,458,129,458,130,458,130,459,131,459,132,459,132,459,133,459,133,459,133,459,133,460,134,460,134,460,135,460,135,460,135,460,136,460,137,460,137,460,138,460,138,461,138,461,139,461,139,461,140,461,140,461,140,461,140,461,141,462,142,462,143,462,144,462,144,463,144,464,144,464,145,464,145,464,145,465,145,466,145,467,145,468,145,468,144,468,144,468,144,469,144,469,144,470,144,470,143,470,143,470,143,470,143,470,142,470,142,470,141,470,140,470,140,471,139,471,139,472,137,472,136,472,136,472,136,472,136,472,135,472,134,472,133,472,133,472,133,473,133,473,133,474,132,474,131,474,131,473,131,473;141,472,141,472,141,472,142,472,142,472,143,472,143,471,144,471,145,472,145,472,145,473,145,473,145,473,144,474,143,474,141,474,141,473,141,473;155,473,154,473,152,473,151,473,150,473,150,473,150,472,149,472,148,472,147,472,147,472,147,472,147,471,147,471,146,471,145,470,145,469,147,467,148,466,148,466,149,466,150,466,151,466,151,467,151,467,151,467,152,467,153,467,154,467,154,467,154,467,154,468,154,468,155,468,155,468,155,468,155,468,155,468,156,468,156,468,157,468,157,469,157,469,159,469,161,469,164,469,166,469,166,469,166,469,166,470,168,470,169,470,170,470,170,470,170,471,169,471,167,471,166,471,165,471,165,471,165,471,165,472,164,472,164,472,164,472,164,472,164,472,163,472,162,472,161,472,160,472,160,473,160,473,159,473,158,473,157,473,156,473,156,473,156,473,156,474,156,474,155,474,155,473,155,473;286,473,286,472,286,472,286,472,286,472,286,472,285,472,285,470,286,470,287,470,287,469,287,469,287,468,287,468,287,468,288,468,288,468,288,468,288,467,289,467,289,468,289,468,290,469,290,470,290,472,289,472,289,473,288,474,287,474,287,473;301,472,300,472,298,472,295,472,295,472,294,471,293,470,293,470,293,468,293,468,293,467,293,467,292,467,292,467,292,466,292,466,292,465,292,465,291,465,291,464,291,462,291,459,291,458,292,458,293,458,293,458,293,458,293,458,294,458,296,458,300,458,300,458,301,458,301,459,301,459,302,459,303,459,304,459,304,459,304,459,304,460,305,460,305,460,306,460,306,460,306,460,306,460,307,460,308,460,309,460,309,461,309,461,309,461,310,461,310,461,311,461,311,461,311,461,312,462,312,462,314,462,315,462,315,463,315,464,315,464,315,464,315,464,316,465,316,466,316,467,315,468,315,468,315,468,315,468,315,469,315,469,315,470,314,470,314,470,314,470,314,470,314,470,313,470,312,470,311,470,311,470,311,471,310,471,310,472,308,472,307,472,306,472,306,472,306,472,306,472,305,472,304,472,304,472,304,473,304,473,303,474,303,474,302,474,301,473,301,473;312,472,312,472,312,472,312,472,313,472,313,472,314,471,314,471,315,472,316,472,316,473,316,473,315,473,315,474,313,474,312,474,312,473,312,473;326,473,324,473,323,473,321,473,320,473,320,473,320,472,320,472,319,472,318,472,318,472,318,472,318,471,317,471,317,471,316,470,316,469,317,467,318,466,319,466,320,466,321,466,322,466,322,467,322,467,322,467,323,467,324,467,324,467,324,467,324,467,324,468,325,468,325,468,326,468,326,468,326,468,326,468,327,468,327,468,328,468,328,469,328,469,329,469,332,469,335,469,336,469,336,469,336,469,337,470,338,470,340,470,340,470,340,470,340,471,340,471,338,471,337,471,336,471,336,471,336,471,335,472,335,472,334,472,334,472,334,472,334,472,333,472,333,472,332,472,331,472,331,473,331,473,330,473,329,473,328,473,327,473,327,473,327,473,327,474,326,474,326,474,326,473,326,473;457,473,457,472,457,472,457,472,457,472,457,472,456,472,456,470,457,470,457,470,458,469,458,469,458,468,458,468,458,468,458,468,459,468,459,468,459,467,459,467,460,468,460,468,460,469,460,470,460,472,460,472,459,473,458,474,458,474,457,473;471,472,471,472,469,472,466,472,466,472,465,471,464,470,464,470,464,468,464,468,463,467,463,467,463,467,463,467,463,466,463,466,463,465,462,465,462,465,462,464,462,462,462,459,462,458,463,458,463,458,464,458,464,458,464,458,465,458,467,458,470,458,471,458,471,458,472,459,472,459,473,459,474,459,474,459,474,459,474,459,475,460,475,460,476,460,476,460,476,460,476,460,477,460,478,460,479,460,480,460,480,461,480,461,480,461,481,461,481,461,482,461,482,461,482,461,482,462,483,462,485,462,486,462,486,463,486,464,486,464,486,464,486,464,486,465,486,466,486,467,486,468,486,468,486,468,486,468,486,469,486,469,485,470,485,470,484,470,484,470,484,470,484,470,484,470,483,470,482,470,482,470,481,471,481,471,480,472,479,472,478,472,477,472,477,472,477,472,476,472,476,472,474,472,474,472,474,473,474,473,474,474,473,474,473,474,472,473,472,473;482,472,482,472,483,472,483,472,484,472,484,472,484,471,485,471,486,472,487,472,487,473,486,473,486,473,485,474,484,474,482,474,482,473,482,473;496,473,495,473,494,473,492,473,491,473,491,473,491,472,490,472,490,472,488,472,488,472,488,472,488,471,488,471,488,471,487,470,487,469,488,467,489,466,489,466,491,466,491,466,492,466,492,467,492,467,493,467,494,467,494,467,495,467,495,467,495,467,495,468,496,468,496,468,496,468,496,468,496,468,497,468,497,468,498,468,498,468,498,469,498,469,500,469,503,469,505,469,507,469,507,469,507,469,508,470,509,470,511,470,511,470,511,470,511,471,511,471,509,471,507,471,506,471,506,471,506,471,506,472,506,472,505,472,505,472,505,472,505,472,504,472,503,472,502,472,502,472,502,473,502,473,501,473,500,473,498,473,498,473,498,473,498,473,497,474,497,474,496,474,496,473,496,473;9,472,8,472,7,472,6,472,5,472,5,472,5,472,4,472,4,472,2,472,1,470,2,469,3,469,3,468,3,468,3,468,3,467,4,467,4,467,4,466,4,466,4,466,4,465,5,465,5,465,6,464,6,464,6,464,8,462,8,462,9,462,9,461,9,461,9,461,9,461,10,461,10,461,10,461,10,461,10,460,11,460,11,460,13,460,14,460,14,459,14,458,14,458,15,458,15,458,16,458,16,458,16,459,17,459,17,459,17,459,18,459,18,460,18,460,19,460,20,460,21,460,22,460,22,461,22,461,22,461,23,461,23,461,24,461,24,462,25,462,25,463,25,466,25,468,25,469,25,469,24,469,24,469,24,470,24,470,24,470,24,470,23,470,23,470,23,471,23,471,22,471,22,471,21,471,21,471,21,471,21,471,20,472,19,472,18,472,17,472,17,472,17,472,16,472,14,472,13,472,12,472,12,473,12,473,11,473,10,473,9,473,9,473,9,473;180,472,179,472,178,472,176,472,176,472,176,472,176,472,175,472,174,472,172,472,172,470,173,469,173,469,174,468,174,468,174,468,174,467,174,467,175,467,175,466,175,466,175,466,175,465,176,465,176,465,176,464,176,464,176,464,178,462,179,462,179,462,180,461,180,461,180,461,180,461,180,461,181,461,181,461,181,461,181,460,181,460,182,460,183,460,184,460,184,459,184,458,185,458,186,458,186,458,186,458,187,458,187,459,187,459,188,459,188,459,188,459,189,460,189,460,189,460,191,460,192,460,193,460,193,461,193,461,193,461,193,461,194,461,194,461,195,462,195,462,196,463,196,466,196,468,195,469,195,469,195,469,195,469,195,470,195,470,195,470,194,470,194,470,194,470,194,471,194,471,193,471,193,471,192,471,192,471,192,471,192,471,191,472,190,472,188,472,188,472,188,472,188,472,186,472,185,472,183,472,182,472,182,473,182,473,182,473,181,473,180,473,180,473,180,473;350,472,349,472,348,472,347,472,346,472,346,472,346,472,346,472,345,472,343,472,342,470,344,469,344,469,344,468,344,468,344,468,344,467,345,467,345,467,346,466,346,466,346,466,346,465,346,465,347,465,347,464,347,464,347,464,349,462,350,462,350,462,350,461,350,461,350,461,350,461,351,461,351,461,352,461,352,461,352,460,352,460,353,460,354,460,355,460,355,459,355,458,356,458,356,458,356,458,357,458,357,458,357,459,358,459,358,459,358,459,359,459,359,460,360,460,360,460,362,460,363,460,364,460,364,461,364,461,364,461,364,461,364,461,365,461,365,462,366,462,366,463,366,466,366,468,366,469,366,469,366,469,366,469,366,470,366,470,365,470,365,470,364,470,364,470,364,471,364,471,364,471,363,471,363,471,362,471,362,471,362,471,361,472,360,472,359,472,358,472,358,472,358,472,357,472,356,472,354,472,353,472,353,473,353,473,352,473,352,473,351,473,350,473,350,473;30,472,30,472,29,472,29,472,28,471,28,471,28,471,28,471,28,471,27,471,27,471,27,470,27,470,27,470,27,470,26,470,26,469,26,468,26,467,26,466,27,466,27,466,27,465,27,465,27,463,28,462,29,462,30,462,30,461,31,461,31,460,31,460,33,460,35,460,36,460,36,460,36,460,36,460,36,460,37,460,37,459,37,459,37,459,38,459,41,459,45,459,45,460,45,460,45,461,46,462,47,462,47,463,47,463,47,464,47,465,48,466,49,467,50,467,50,468,50,468,50,468,50,468,50,468,50,469,50,469,50,470,50,470,49,470,48,470,47,470,47,471,47,471,46,471,46,471,45,471,45,471,45,471,45,471,43,472,40,472,37,472,35,472,35,472,35,472,34,472,33,472,31,472,30,472,30,472;201,472,200,472,200,472,199,472,199,471,199,471,199,471,199,471,198,471,198,471,198,471,198,470,198,470,197,470,197,470,197,470,197,469,197,468,197,467,197,466,197,466,197,466,198,465,198,465,198,463,199,462,200,462,200,462,201,461,201,461,202,460,202,460,204,460,205,460,206,460,206,460,206,460,206,460,207,460,207,460,208,459,208,459,208,459,209,459,212,459,216,459,216,460,216,460,216,461,217,462,217,462,218,463,218,463,218,464,218,465,219,466,220,467,220,467,220,468,220,468,220,468,221,468,221,468,221,469,221,469,221,470,221,470,219,470,218,470,218,470,218,471,218,471,217,471,217,471,216,471,216,471,216,471,216,471,214,472,211,472,207,472,206,472,206,472,206,472,205,472,203,472,202,472,201,472,201,472;372,472,371,472,371,472,370,472,370,471,370,471,370,471,369,471,369,471,368,471,368,471,368,470,368,470,368,470,368,470,368,470,368,469,368,468,368,467,368,466,368,466,368,466,368,465,368,465,368,463,369,462,371,462,371,462,372,461,372,461,372,460,373,460,375,460,376,460,377,460,377,460,377,460,377,460,378,460,378,460,378,459,378,459,378,459,380,459,382,459,386,459,386,460,386,460,387,461,387,462,388,462,388,463,388,463,388,464,388,465,390,466,390,467,391,467,391,468,391,468,391,468,391,468,391,468,392,469,392,469,392,470,391,470,390,470,389,470,388,470,388,471,388,471,388,471,387,471,387,471,386,471,386,471,386,471,384,472,381,472,378,472,376,472,376,472,376,472,375,472,374,472,373,472,372,472,372,472;68,468,67,468,66,468,65,467,65,467,64,467,64,466,65,466,65,466,66,465,66,465,66,465,66,464,66,464,67,464,67,463,67,463,67,462,67,462,67,462,68,462,68,462,69,461,70,460,70,460,71,460,72,460,72,460,72,460,72,460,73,460,73,460,74,460,74,459,74,459,74,459,77,459,78,459,78,460,78,460,78,460,78,460,78,461,78,462,78,462,77,463,77,463,77,463,77,464,77,465,77,467,77,468,77,468,78,468,78,469,77,470,77,470,76,470,72,470,68,470,68,469;84,470,83,470,82,470,80,470,79,469,79,468,79,467,79,467,79,467,78,467,78,466,78,465,78,464,78,463,79,463,79,463,79,462,79,461,79,459,79,459,80,459,80,459,81,459,81,459,81,459,82,460,84,460,86,460,87,460,87,460,87,460,89,460,93,460,100,460,100,460,101,461,101,462,102,462,102,466,102,469,101,469,101,470,101,470,100,470,100,470,100,469,92,469,92,470,92,470,91,470,88,470,85,470,84,470,84,470;103,469,103,460,103,460,103,460,104,459,104,458,104,457,104,456,104,455,105,455,107,455,107,455,107,455,107,456,108,456,108,456,108,456,108,456,108,456,109,456,110,456,111,456,112,456,112,457,112,457,113,457,114,457,117,457,118,457,118,458,118,458,118,459,118,459,119,460,119,460,119,462,119,465,119,465,118,466,118,466,117,467,116,467,116,467,115,467,115,468,114,469,114,469,111,469,109,469,108,469,108,469,108,469,107,470,106,470,105,470,104,470,104,470,104,470,104,470,103,470;239,468,237,468,236,468,236,467,235,467,235,467,235,466,235,466,236,466,236,465,236,465,236,465,236,464,237,464,237,464,238,463,238,463,238,462,238,462,238,462,238,462,239,462,240,461,240,460,241,460,242,460,242,460,243,460,243,460,243,460,243,460,244,460,244,460,245,459,245,459,245,459,248,459,248,459,249,460,249,460,249,460,248,460,248,461,248,462,248,462,248,463,248,463,248,463,248,464,248,465,248,467,248,468,248,468,248,468,248,469,248,470,247,470,246,470,243,470,239,470,239,469;254,470,253,470,252,470,250,470,250,469,250,468,250,467,249,467,249,467,249,467,249,466,249,465,249,464,249,463,249,463,249,463,250,462,250,461,250,459,250,459,251,459,251,459,252,459,252,459,252,459,253,460,255,460,256,460,258,460,258,460,258,460,260,460,264,460,270,460,271,460,271,461,272,462,272,462,272,466,272,469,272,469,272,470,271,470,271,470,271,470,271,469,263,469,263,470,263,470,261,470,259,470,256,470,254,470,254,470;273,469,273,460,274,460,274,460,274,459,274,458,274,457,274,456,275,455,275,455,278,455,278,455,278,455,278,456,278,456,279,456,279,456,279,456,279,456,280,456,281,456,282,456,283,456,283,457,283,457,284,457,285,457,287,457,288,457,288,458,288,458,288,459,289,459,289,460,290,460,290,462,290,465,289,465,289,466,288,466,288,467,287,467,287,467,286,467,286,468,285,469,284,469,282,469,280,469,279,469,279,469,279,469,278,470,277,470,276,470,275,470,275,470,275,470,274,470,274,470;410,468,408,468,407,468,406,467,406,467,405,467,405,466,406,466,407,466,407,465,407,465,407,465,407,464,408,464,408,464,408,463,408,463,408,462,408,462,409,462,409,462,410,462,410,461,411,460,411,460,412,460,413,460,414,460,414,460,414,460,414,460,415,460,415,460,416,459,416,459,416,459,418,459,419,459,420,460,420,460,419,460,419,460,419,461,419,462,419,462,419,463,419,463,418,463,418,464,418,465,418,467,418,468,419,468,419,468,419,469,418,470,418,470,417,470,414,470,410,470,410,469;425,470,424,470,423,470,421,470,420,469,420,468,420,467,420,467,420,467,420,467,420,466,420,465,420,464,420,463,420,463,420,463,420,462,420,461,420,459,420,459,421,459,422,459,422,459,422,459,422,459,423,460,425,460,427,460,428,460,428,460,428,460,431,460,435,460,441,460,441,460,442,461,443,462,443,462,443,466,443,469,443,469,442,470,442,470,442,470,442,470,441,469,434,469,434,470,434,470,432,470,429,470,427,470,425,470,425,470;444,469,444,460,445,460,445,460,445,459,445,458,445,457,445,456,445,455,446,455,448,455,448,455,448,455,448,456,449,456,449,456,450,456,450,456,450,456,450,456,452,456,453,456,454,456,454,457,454,457,454,457,456,457,458,457,459,457,459,458,459,458,459,459,460,459,460,460,460,460,460,462,460,465,460,465,459,466,459,466,458,467,458,467,457,467,457,467,456,468,455,469,455,469,452,469,451,469,450,469,450,469,450,469,449,470,448,470,446,470,446,470,446,470,446,470,445,470,445,470;52,469,52,468,52,468,52,468,52,468,52,468,52,468,52,467,52,466,52,465,52,464,53,464,53,464,54,464,54,464,54,463,55,463,55,463,55,463,56,463,56,462,56,462,57,462,57,462,57,462,58,461,58,461,58,461,58,461,59,461,59,461,60,461,60,461,60,461,60,462,61,462,62,462,63,461,63,461,63,461,65,461,65,462,66,463,65,463,65,464,64,465,64,465,64,465,64,466,64,466,64,466,64,466,64,466,64,467,63,468,62,468,61,468,61,468,61,469,61,469,60,469,58,469,57,469,56,469,56,469,56,470,53,470,53,469;223,469,223,468,223,468,223,468,223,468,223,468,222,468,222,467,222,466,222,465,223,464,224,464,224,464,224,464,225,464,225,463,225,463,226,463,226,463,226,463,227,462,227,462,227,462,228,462,228,462,228,461,228,461,228,461,229,461,229,461,230,461,230,461,230,461,230,461,231,462,232,462,233,462,234,461,234,461,234,461,235,461,236,462,237,463,236,463,235,464,235,465,235,465,235,465,235,466,235,466,234,466,234,466,234,466,234,467,234,467,234,468,233,468,233,468,232,468,232,468,232,468,232,469,232,469,230,469,229,469,227,469,226,469,226,469,226,470,224,470,223,469;394,469,394,468,394,468,394,468,393,468,393,468,393,468,393,467,393,466,393,465,393,464,394,464,394,464,395,464,395,464,395,463,396,463,396,463,396,463,397,463,397,462,397,462,398,462,398,462,399,462,399,461,399,461,399,461,399,461,400,461,400,461,401,461,401,461,401,461,402,462,403,462,403,462,404,461,404,461,404,461,406,461,407,462,408,463,407,463,406,464,406,465,406,465,406,465,405,466,405,466,405,466,405,466,405,466,405,467,405,467,404,468,404,468,403,468,403,468,403,468,402,468,402,469,402,469,401,469,400,469,398,469,397,469,397,469,397,470,394,470,394,469;162,468,161,468,160,468,158,468,158,467,158,467,158,467,157,467,156,467,155,467,155,467,155,467,155,466,155,466,154,466,154,466,154,466,154,466,154,466,153,466,153,466,152,466,152,465,152,465,152,465,150,465,149,465,146,465,146,463,146,462,145,461,144,461,144,461,144,461,144,460,144,459,144,459,144,459,145,459,145,459,145,459,145,458,146,458,147,458,149,458,150,458,150,458,150,458,151,458,153,458,154,458,156,457,156,457,156,457,156,457,157,457,158,458,158,458,157,458,157,458,157,459,157,459,157,460,157,460,159,460,160,460,161,460,161,461,161,461,162,462,163,462,163,462,164,462,164,462,164,462,164,462,165,462,166,462,166,462,166,463,166,463,167,463,167,463,169,463,170,463,170,464,170,465,170,465,170,465,171,465,171,465,171,467,171,468,166,468,163,468,162,468,162,468;332,468,331,468,330,468,329,468,328,467,328,467,328,467,328,467,327,467,326,467,326,467,326,467,326,466,325,466,325,466,324,466,324,466,324,466,324,466,324,466,323,466,323,466,322,465,322,465,322,465,321,465,319,465,316,465,316,463,316,462,316,461,315,461,314,461,314,461,314,460,314,459,314,459,315,459,315,459,316,459,316,459,316,458,317,458,318,458,319,458,320,458,320,458,320,458,321,458,323,458,325,458,326,457,326,457,326,457,327,457,328,457,328,458,328,458,328,458,328,458,328,459,328,459,328,460,328,460,329,460,331,460,331,460,332,461,332,461,333,462,333,462,334,462,334,462,334,462,334,462,335,462,336,462,336,462,337,462,337,463,337,463,337,463,338,463,339,463,340,463,340,464,340,465,340,465,341,465,341,465,342,465,342,467,342,468,337,468,334,468,332,468,332,468;503,468,502,468,501,468,500,468,499,467,499,467,499,467,498,467,498,467,497,467,496,467,496,467,496,466,496,466,496,466,495,466,495,466,495,466,495,466,494,466,494,466,493,466,493,465,493,465,493,465,492,465,490,465,487,465,487,463,487,462,486,461,485,461,485,461,485,461,485,460,485,459,485,459,486,459,486,459,486,459,486,459,486,458,487,458,489,458,490,458,491,458,491,458,491,458,492,458,494,458,496,458,497,457,497,457,497,457,498,457,498,457,499,458,499,458,499,458,498,458,498,459,498,459,498,460,498,460,500,460,502,460,502,460,503,461,503,461,503,462,504,462,504,462,505,462,505,462,505,462,505,462,506,462,507,462,508,462,508,463,508,463,508,463,509,463,510,463,511,463,511,464,511,465,511,465,512,465,512,465,512,465,512,467,512,468,508,468,505,468,503,468,503,468;48,462,48,462,47,462,47,462,47,461,47,461,47,461,47,460,46,460,46,460,46,460,47,459,47,459,48,459,51,459,53,459,54,459,54,459,54,459,54,460,55,460,55,460,56,460,56,461,56,461,55,462,55,462,54,462,54,462,54,462,54,462,54,462,54,462,53,462,53,462,53,463,53,463,52,463,51,463,49,463,49,463,49,462;219,462,218,462,218,462,218,462,218,461,218,461,218,461,217,460,217,460,217,460,217,460,217,459,218,459,218,459,221,459,223,459,225,459,225,459,225,459,225,460,226,460,226,460,226,460,226,461,226,461,226,462,226,462,225,462,225,462,225,462,225,462,225,462,224,462,224,462,224,462,224,463,224,463,223,463,222,463,220,463,220,463,219,462;390,462,389,462,389,462,388,462,388,461,388,461,388,461,388,460,388,460,387,460,387,460,388,459,388,459,389,459,392,459,394,459,396,459,396,459,396,459,396,460,396,460,397,460,397,460,397,461,397,461,397,462,396,462,396,462,396,462,396,462,396,462,395,462,395,462,394,462,394,462,394,463,394,463,393,463,392,463,391,463,390,463,390,462;170,460,169,460,167,460,166,460,165,460,165,460,165,460,164,460,163,460,161,460,160,459,160,459,160,459,160,459,160,459,159,459,159,459,159,456,159,455,159,454,159,454,159,454,160,453,160,453,160,452,160,452,160,452,160,452,160,452,160,451,160,451,160,450,161,450,161,450,162,449,162,449,162,448,162,447,162,447,163,447,163,446,163,446,163,446,163,446,165,446,167,446,168,446,168,446,168,446,168,446,169,446,169,446,170,446,170,447,170,447,170,447,170,447,171,447,171,447,171,448,171,448,171,448,172,448,172,448,173,448,173,449,173,449,174,450,174,450,175,450,175,450,175,450,175,450,175,450,176,450,176,450,176,450,176,451,176,451,177,451,177,451,179,451,180,452,180,453,180,453,180,454,181,454,181,454,182,455,182,455,182,455,182,456,182,456,183,456,183,457,183,458,183,459,183,459,182,459,181,459,181,459,181,459,181,459,180,460,180,460,179,460,179,460,179,460,179,460,177,460,175,460,172,460,171,460,171,461,171,461,171,461,170,461,170,461,170,461,170,461;340,460,339,460,338,460,337,460,336,460,336,460,336,460,335,460,333,460,332,460,331,459,331,459,331,459,331,459,330,459,330,459,330,459,330,456,330,455,330,454,330,454,330,454,330,453,330,453,330,452,330,452,331,452,331,452,331,452,331,451,331,451,331,450,332,450,332,450,332,449,332,449,332,448,332,447,333,447,333,447,334,446,334,446,334,446,334,446,336,446,337,446,338,446,338,446,338,446,339,446,339,446,340,446,340,446,340,447,340,447,340,447,341,447,341,447,342,447,342,448,342,448,342,448,342,448,343,448,344,448,344,449,344,449,345,450,345,450,345,450,346,450,346,450,346,450,346,450,346,450,347,450,347,450,347,451,347,451,347,451,348,451,349,451,351,452,351,453,351,453,351,454,352,454,352,454,352,455,352,455,352,455,352,456,353,456,353,456,354,457,354,458,354,459,353,459,353,459,352,459,352,459,352,459,352,459,351,460,351,460,350,460,350,460,350,460,350,460,348,460,346,460,343,460,342,460,342,461,342,461,341,461,341,461,340,461,340,461,340,461;511,460,510,460,509,460,507,460,506,460,506,460,506,460,505,460,504,460,503,460,502,459,502,459,502,459,501,459,501,459,500,459,500,459,500,456,500,455,500,454,501,454,501,454,501,453,501,453,501,452,501,452,501,452,501,452,502,452,502,451,502,451,502,450,502,450,503,450,503,449,503,449,503,448,503,447,504,447,504,447,504,446,504,446,504,446,504,446,507,446,508,446,509,446,509,446,509,446,509,446,510,446,510,446,511,446,511,447,511,447,511,447,512,447,512,447,512,447,512,448,512,448,512,448,513,448,514,448,514,448,515,449,515,449,515,450,516,450,516,450,516,450,516,450,516,450,516,450,517,450,517,450,518,450,518,451,518,451,518,451,519,451,520,451,522,452,522,453,522,453,522,454,522,454,523,454,523,455,523,455,523,455,523,456,524,456,524,456,524,457,524,458,524,459,524,459,523,459,523,459,522,459,522,459,522,459,522,460,521,460,521,460,520,460,520,460,520,460,519,460,516,460,514,460,512,460,512,461,512,461,512,461,512,461,511,461,511,461,511,461;60,458,60,457,60,457,60,457,60,456,60,456,60,455,59,455,59,455,59,455,59,454,59,453,59,452,59,452,59,452,58,452,58,451,58,450,58,449,61,449,62,449,64,449,64,449,64,448,64,448,64,448,64,448,65,448,65,448,65,447,66,447,66,447,67,447,67,447,67,447,67,446,67,446,68,446,68,446,69,445,72,443,76,439,76,439,77,439,79,439,79,442,79,444,79,446,79,446,79,446,80,448,80,451,80,456,78,456,76,456,76,456,75,457,75,457,74,458,74,458,74,458,74,458,74,458,74,458,73,458,73,458,72,458,72,458,72,459,72,459,71,459,71,459,70,459,69,459,69,460,69,460,68,460,66,460,64,460,63,460,63,460,63,459,62,459,62,460,62,460,62,460,61,460,60,460,60,460,60,459;231,458,231,457,231,457,230,457,230,456,230,456,230,455,230,455,230,455,230,455,230,454,230,453,230,452,229,452,229,452,229,452,229,451,229,450,229,449,232,449,233,449,234,449,234,449,234,448,234,448,235,448,235,448,236,448,236,448,236,447,237,447,237,447,237,447,238,447,238,447,238,446,238,446,238,446,239,446,240,445,243,443,246,439,247,439,248,439,250,439,250,442,250,444,250,446,250,446,250,446,250,448,250,451,250,456,248,456,247,456,246,456,246,457,246,457,245,458,245,458,244,458,244,458,244,458,244,458,244,458,243,458,243,458,242,458,242,459,242,459,242,459,241,459,241,459,240,459,240,460,239,460,239,460,236,460,234,460,233,460,233,460,233,459,233,459,233,460,233,460,232,460,232,460,231,460,231,460,231,459;402,458,401,457,401,457,401,457,401,456,401,456,401,455,401,455,401,455,400,455,400,454,400,453,400,452,400,452,400,452,400,452,400,451,400,450,400,449,402,449,404,449,405,449,405,449,405,448,405,448,405,448,406,448,406,448,407,448,407,447,407,447,408,447,408,447,408,447,408,447,408,446,409,446,409,446,410,446,411,445,414,443,417,439,417,439,419,439,420,439,420,442,420,444,420,446,421,446,421,446,421,448,421,451,421,456,419,456,417,456,417,456,417,457,416,457,416,458,415,458,415,458,415,458,415,458,415,458,414,458,414,458,413,458,413,458,413,459,413,459,412,459,412,459,411,459,411,459,411,460,410,460,410,460,407,460,405,460,404,460,404,460,404,459,404,459,404,460,404,460,403,460,402,460,402,460,402,460,402,459;22,459,21,459,20,459,19,459,19,459,19,459,19,458,19,458,18,458,18,458,18,458,18,458,18,458,17,458,17,458,16,458,16,457,16,457,16,456,16,455,17,455,17,455,18,454,18,454,18,453,18,453,18,453,18,453,18,453,18,452,18,452,18,452,19,452,19,452,19,451,19,451,19,450,19,450,19,450,20,450,20,449,21,449,21,448,21,448,22,448,22,448,22,448,23,448,23,447,23,447,24,447,24,447,24,447,25,446,25,446,25,446,26,446,26,446,27,445,27,445,27,445,27,445,28,445,28,445,28,445,28,444,28,443,29,443,30,443,31,443,32,443,32,443,32,442,32,442,33,442,34,442,34,442,34,443,34,443,34,443,35,443,35,443,37,444,37,445,37,445,37,446,37,446,37,446,38,446,38,446,38,446,38,447,38,447,39,448,39,448,39,449,39,450,39,450,39,450,38,450,38,450,38,451,38,451,38,452,38,452,38,452,38,452,38,453,38,454,37,454,37,454,37,454,37,455,37,456,37,457,37,457,36,458,35,459,35,459,33,459,31,459,30,459,30,459,30,459,29,460,26,460,23,460,22,459,22,459;192,459,192,459,191,459,190,459,190,459,190,459,190,458,189,458,189,458,188,458,188,458,188,458,188,458,188,458,188,458,187,458,187,457,187,457,187,456,187,455,188,455,188,455,188,454,188,454,188,453,188,453,189,453,189,453,189,453,189,452,189,452,189,452,189,452,189,452,190,451,190,451,190,450,190,450,190,450,190,450,191,449,191,449,191,448,192,448,192,448,192,448,193,448,193,448,193,447,194,447,194,447,194,447,195,447,195,446,195,446,196,446,197,446,197,446,198,445,198,445,198,445,198,445,198,445,199,445,199,445,199,444,199,443,200,443,201,443,202,443,202,443,202,443,202,442,203,442,204,442,204,442,205,442,205,443,205,443,205,443,205,443,206,443,206,443,207,444,207,444,208,445,208,445,208,445,208,446,208,446,208,446,208,446,208,446,208,446,208,447,209,447,209,448,210,448,210,449,210,450,209,450,209,450,209,450,209,450,209,451,209,451,209,452,209,452,208,452,208,452,208,453,208,454,208,454,208,454,208,454,208,455,208,456,208,457,207,457,207,458,206,459,206,459,203,459,202,459,201,459,201,459,201,459,199,460,197,460,194,460,192,459,192,459;363,459,362,459,362,459,361,459,360,459,360,459,360,458,360,458,360,458,359,458,359,458,359,458,359,458,359,458,358,458,358,458,358,457,358,457,358,456,358,455,358,455,359,455,359,454,359,454,359,453,359,453,359,453,359,453,360,453,360,452,360,452,360,452,360,452,360,452,360,451,360,451,360,450,360,450,361,450,361,450,362,449,362,449,362,448,363,448,363,448,363,448,364,448,364,448,364,447,365,447,365,447,365,447,366,447,366,446,366,446,367,446,367,446,368,446,368,445,368,445,368,445,368,445,369,445,369,445,370,445,370,444,370,443,370,443,372,443,372,443,373,443,373,443,373,442,373,442,374,442,375,442,376,442,376,443,376,443,376,443,376,443,376,443,377,443,377,444,378,444,378,445,378,445,378,445,378,446,379,446,379,446,379,446,379,446,379,446,379,447,380,447,380,448,380,448,380,449,380,450,380,450,380,450,380,450,380,450,380,451,380,451,379,452,379,452,379,452,379,452,379,453,379,454,379,454,379,454,378,454,378,455,378,456,378,457,378,457,377,458,377,459,376,459,374,459,373,459,372,459,372,459,372,459,370,460,367,460,365,460,363,459,363,459;56,458,55,458,54,458,53,458,52,458,52,458,52,458,50,458,48,458,45,458,45,457,45,457,44,456,44,456,43,456,42,456,42,456,42,456,42,456,41,456,41,456,40,456,40,455,39,455,39,454,39,452,39,452,39,452,40,452,40,451,40,451,40,450,40,450,40,450,40,450,40,450,40,449,40,449,41,449,41,449,41,448,40,448,39,447,39,446,39,446,39,446,39,445,38,445,38,445,38,444,38,444,38,443,40,443,42,443,43,443,43,442,43,442,44,442,45,442,45,442,46,441,46,441,46,441,47,441,48,441,49,441,50,441,50,441,50,441,50,442,51,442,51,442,52,442,53,443,55,445,55,445,55,447,55,448,55,448,56,449,56,449,56,449,56,450,56,450,56,451,57,451,57,451,57,451,57,452,57,452,57,452,57,452,57,452,58,453,58,454,58,454,58,455,58,455,58,455,58,455,58,456,58,456,58,457,59,457,59,457,59,458,58,458,58,459,56,459,56,459;227,458,226,458,225,458,223,458,222,458,222,458,222,458,221,458,219,458,216,458,216,457,215,457,215,456,214,456,213,456,213,456,212,456,212,456,212,456,212,456,211,456,211,456,210,455,210,455,209,454,209,452,210,452,210,452,210,452,210,451,210,451,210,450,211,450,211,450,211,450,211,450,211,449,211,449,211,449,212,449,211,448,211,448,210,447,210,446,210,446,210,446,209,445,209,445,208,445,208,444,208,444,208,443,211,443,213,443,213,443,214,442,214,442,215,442,215,442,216,442,216,441,216,441,216,441,217,441,219,441,220,441,221,441,221,441,221,441,221,442,221,442,222,442,223,442,224,443,225,445,226,445,226,447,226,448,226,448,226,449,227,449,227,449,227,450,227,450,227,451,227,451,227,451,228,451,228,452,228,452,228,452,228,452,228,452,228,453,228,454,228,454,228,455,229,455,229,455,229,455,229,456,229,456,229,457,229,457,230,457,230,458,229,458,228,459,227,459,227,459;398,458,397,458,395,458,394,458,393,458,393,458,393,458,392,458,390,458,387,458,386,457,386,457,385,456,385,456,384,456,383,456,383,456,383,456,383,456,382,456,382,456,382,456,381,455,381,455,380,454,380,452,381,452,381,452,381,452,381,451,381,451,381,450,381,450,381,450,382,450,382,450,382,449,382,449,382,449,382,449,382,448,381,448,381,447,380,446,380,446,380,446,380,445,380,445,379,445,379,444,379,444,379,443,381,443,384,443,384,443,385,442,385,442,385,442,386,442,386,442,387,441,387,441,387,441,388,441,389,441,391,441,392,441,392,441,392,441,392,442,392,442,392,442,393,442,394,443,396,445,396,445,396,447,396,448,396,448,397,449,397,449,398,449,398,450,398,450,398,451,398,451,398,451,398,451,398,452,398,452,398,452,399,452,399,452,399,453,399,454,399,454,399,455,399,455,399,455,400,455,400,456,400,456,400,457,400,457,400,457,400,458,400,458,399,459,398,459,398,459;82,455,82,455,82,451,82,448,82,448,83,447,83,447,84,446,84,446,85,446,85,446,85,446,85,446,87,446,91,446,95,446,97,446,97,446,97,446,97,446,98,446,98,446,99,446,99,447,99,447,100,447,101,447,102,447,103,447,103,447,104,448,104,448,103,448,103,448,103,449,103,450,103,451,103,452,103,452,102,452,102,452,102,454,102,455,102,456,102,456,101,457,100,457,92,457,84,457,83,456;253,455,253,455,253,451,253,448,253,448,254,447,254,447,255,446,255,446,255,446,256,446,256,446,256,446,258,446,262,446,265,446,268,446,268,446,268,446,268,446,269,446,269,446,270,446,270,447,270,447,270,447,271,447,273,447,273,447,274,447,274,448,274,448,274,448,274,448,274,449,274,450,274,451,273,452,273,452,273,452,273,452,273,454,273,455,273,456,272,456,272,457,270,457,263,457,254,457,254,456;424,455,424,455,424,451,424,448,424,448,424,447,425,447,425,446,426,446,426,446,426,446,426,446,426,446,428,446,432,446,436,446,438,446,438,446,438,446,439,446,439,446,440,446,440,446,440,447,440,447,441,447,442,447,443,447,444,447,444,447,445,448,445,448,445,448,444,448,444,449,444,450,444,451,444,452,444,452,444,452,444,452,444,454,444,455,443,456,443,456,443,457,441,457,434,457,425,457,424,456;12,454,12,454,13,453,14,452,15,453,15,455,15,456,14,457,13,455;121,456,119,456,116,456,113,456,112,455,112,455,112,455,111,455,110,455,109,455,109,455,109,454,108,454,108,454,107,454,107,454,106,453,105,452,104,451,104,451,104,449,104,448,104,448,105,448,105,448,105,446,105,444,105,441,105,441,106,440,106,440,107,440,109,440,111,440,112,440,112,440,112,440,113,440,114,440,115,440,116,440,116,441,116,441,116,441,116,441,117,441,117,441,117,441,117,441,117,442,118,442,118,442,119,442,119,442,119,442,119,442,120,442,120,442,121,442,121,443,121,443,122,443,123,443,123,443,124,443,124,443,124,443,125,444,125,444,126,444,126,444,126,444,126,444,127,444,127,444,128,444,128,444,129,445,129,445,129,446,130,446,130,446,130,446,130,447,130,447,130,448,131,448,131,448,131,449,131,452,131,456,126,456,123,456,121,456,121,456;143,456,142,456,140,456,138,456,136,455,136,455,136,455,135,455,134,455,132,455,132,451,132,449,132,448,132,448,132,448,132,447,132,447,132,446,132,446,132,446,133,446,133,446,133,446,133,446,133,446,134,446,134,446,135,445,136,445,136,444,137,444,137,444,137,444,138,444,139,445,139,446,140,446,140,446,141,446,141,446,141,447,141,447,141,447,142,447,143,447,144,447,144,447,144,447,144,448,145,448,145,448,146,448,146,448,146,448,147,448,148,448,149,448,150,448,150,448,150,448,151,448,153,448,154,448,156,447,156,447,156,447,157,447,158,447,160,447,160,447,160,448,160,448,160,449,160,449,159,449,159,450,159,451,159,451,159,452,159,452,158,452,158,452,158,453,158,453,158,454,158,454,158,454,158,454,158,454,158,455,157,455,157,455,156,455,156,455,156,455,156,455,156,456,155,456,155,456,154,456,154,456,154,456,152,456,149,456,145,456,143,456,143,456;183,454,183,454,183,453,184,452,186,453,186,455,186,456,185,457,184,455;292,456,290,456,287,456,284,456,282,455,282,455,282,455,282,455,281,455,280,455,280,455,279,454,279,454,278,454,278,454,277,454,277,453,276,452,275,451,275,451,275,449,275,448,275,448,275,448,275,448,276,446,276,444,276,441,276,441,276,440,277,440,277,440,280,440,282,440,283,440,283,440,283,440,284,440,285,440,285,440,286,440,286,441,286,441,286,441,287,441,287,441,288,441,288,441,288,441,288,442,289,442,289,442,290,442,290,442,290,442,290,442,291,442,291,442,292,442,292,443,292,443,292,443,293,443,294,443,295,443,295,443,295,443,295,444,296,444,296,444,297,444,297,444,297,444,297,444,298,444,298,444,299,444,299,445,299,445,300,446,300,446,301,446,301,446,301,447,301,447,301,448,301,448,301,448,302,449,302,452,302,456,297,456,293,456,292,456,292,456;314,456,312,456,310,456,308,456,307,455,307,455,307,455,306,455,305,455,303,455,303,451,303,449,303,448,303,448,302,448,302,447,302,447,302,446,302,446,303,446,303,446,304,446,304,446,304,446,304,446,304,446,305,446,306,445,306,445,307,444,307,444,307,444,308,444,308,444,309,445,310,446,311,446,311,446,311,446,312,446,312,447,312,447,312,447,313,447,314,447,314,447,314,447,314,447,315,448,315,448,316,448,316,448,316,448,316,448,317,448,319,448,320,448,321,448,321,448,321,448,322,448,324,448,325,448,326,447,326,447,326,447,327,447,329,447,331,447,331,447,331,448,331,448,331,449,330,449,330,449,330,450,330,451,330,451,329,452,329,452,329,452,329,452,329,453,329,453,329,454,329,454,328,454,328,454,328,454,328,455,328,455,328,455,327,455,327,455,327,455,327,455,326,456,326,456,325,456,325,456,325,456,325,456,323,456,319,456,316,456,314,456,314,456;353,454,353,454,354,453,355,452,356,453,356,455,356,456,355,457,354,455;462,456,460,456,458,456,455,456,453,455,453,455,453,455,452,455,452,455,451,455,450,455,450,454,450,454,449,454,449,454,448,454,447,453,447,452,446,451,446,451,446,449,446,448,446,448,446,448,446,448,446,446,446,444,446,441,446,441,447,440,448,440,448,440,451,440,452,440,454,440,454,440,454,440,454,440,455,440,456,440,457,440,457,441,457,441,457,441,458,441,458,441,458,441,458,441,458,441,459,442,459,442,460,442,460,442,460,442,460,442,461,442,461,442,462,442,462,442,462,443,462,443,463,443,464,443,465,443,466,443,466,443,466,443,466,444,467,444,467,444,468,444,468,444,468,444,468,444,468,444,469,444,470,444,470,445,470,445,471,446,471,446,471,446,472,446,472,447,472,447,472,448,472,448,472,448,472,449,472,452,472,456,467,456,464,456,462,456,462,456;484,456,483,456,481,456,479,456,478,455,478,455,478,455,477,455,476,455,474,455,474,451,474,449,473,448,473,448,473,448,473,447,473,447,473,446,473,446,474,446,474,446,474,446,474,446,474,446,475,446,475,446,476,446,476,445,477,445,477,444,478,444,478,444,478,444,479,444,480,445,481,446,481,446,482,446,482,446,482,446,482,447,482,447,483,447,484,447,484,447,485,447,485,447,485,447,485,448,486,448,486,448,487,448,487,448,487,448,488,448,489,448,491,448,492,448,492,448,492,448,493,448,494,448,496,448,497,447,497,447,497,447,498,447,499,447,501,447,502,447,502,448,502,448,501,449,501,449,500,449,500,450,500,451,500,451,500,452,500,452,500,452,500,452,500,453,500,453,499,454,499,454,499,454,499,454,499,454,499,455,499,455,498,455,498,455,498,455,498,455,498,455,497,456,497,456,496,456,496,456,496,456,496,456,493,456,490,456,486,456,484,456,484,456;11,451,11,451,10,451,10,451,8,449,8,449,8,449,8,448,8,448,7,448,7,447,7,446,7,446,7,446,8,446,8,446,8,445,8,445,8,445,9,445,11,445,12,445,13,445,13,445,13,444,14,444,15,444,17,444,17,446,17,446,17,447,17,447,16,447,16,447,16,447,16,448,13,451,13,451,12,451,12,451,12,451,12,451,12,452,12,452,11,452,11,451,11,451;182,451,181,451,181,451,180,451,179,449,179,449,179,449,179,448,178,448,178,448,178,447,178,446,178,446,178,446,178,446,179,446,179,445,179,445,179,445,180,445,181,445,183,445,184,445,184,445,184,444,184,444,186,444,188,444,188,446,188,446,187,447,187,447,187,447,187,447,187,447,187,448,186,449,185,449,185,450,184,451,183,451,183,451,183,451,183,451,183,451,183,452,182,452,182,452,182,451,182,451;352,451,352,451,352,451,351,451,350,449,350,449,350,449,349,448,349,448,348,448,348,447,348,446,348,446,348,446,349,446,349,446,350,445,350,445,350,445,351,445,352,445,353,445,354,445,354,445,354,444,355,444,356,444,358,444,358,446,358,446,358,447,358,447,358,447,358,447,358,447,358,448,357,449,356,449,355,450,354,451,354,451,354,451,354,451,354,451,354,451,353,452,353,452,352,452,352,451,352,451;16,449,16,449,17,449,17,448,18,448,18,448,18,447,18,447,18,447,19,446,19,446,19,445,19,445,19,444,19,444,19,444,20,444,20,445,20,445,20,445,21,445,21,445,22,445,22,445,23,446,23,446,22,446,22,447,22,447,21,447,21,447,21,447,21,448,20,448,20,448,20,448,19,448,19,448,19,449,18,449,16,450,16,449;187,449,187,449,188,449,188,448,188,448,188,448,188,447,188,447,189,447,189,446,190,446,190,445,190,445,190,444,190,444,190,444,190,444,190,445,190,445,191,445,191,445,192,445,193,445,193,445,193,446,193,446,193,446,193,447,192,447,192,447,192,447,191,447,191,448,191,448,190,448,190,448,190,448,189,448,189,449,189,449,187,450,187,449;358,449,358,449,358,449,359,448,359,448,359,448,359,447,359,447,360,447,360,446,360,446,360,445,360,445,360,444,361,444,361,444,361,444,361,445,361,445,361,445,362,445,363,445,363,445,364,445,364,446,364,446,364,446,363,447,363,447,363,447,363,447,362,447,362,448,362,448,361,448,361,448,361,448,360,448,360,449,359,449,358,450,358,449;5,448,4,448,4,448,3,448,2,447,2,446,2,446,2,446,2,446,3,446,3,446,3,446,3,446,3,446,4,446,4,446,4,446,4,447,4,447,4,447,5,447,5,447,6,447,6,448,6,448,5,449,5,449,5,449,5,449,5,449;176,448,175,448,175,448,174,448,172,447,172,446,172,446,172,446,173,446,173,446,174,446,174,446,174,446,174,446,174,446,175,446,175,446,175,447,175,447,175,447,176,447,176,447,176,447,176,448,176,448,176,449,176,449,176,449,176,449,176,449;346,448,346,448,345,448,344,448,343,447,343,446,343,446,343,446,344,446,344,446,344,446,344,446,344,446,344,446,345,446,345,446,346,446,346,447,346,447,346,447,346,447,347,447,347,447,347,448,347,448,347,449,347,449,346,449,346,449,346,449;146,446,145,446,145,446,144,446,144,446,144,446,144,446,143,446,142,446,141,446,141,445,141,445,140,444,140,444,139,444,139,444,139,444,139,443,139,443,139,442,138,442,138,442,138,441,138,440,138,440,137,439,137,439,137,439,137,439,137,439,137,439,138,438,138,437,138,436,138,436,138,435,139,435,139,434,139,434,139,434,139,434,139,434,140,434,140,433,141,433,141,432,141,432,142,432,142,432,142,432,142,432,142,432,142,432,143,432,143,432,144,430,146,429,147,428,148,427,148,427,149,427,149,427,149,427,149,426,149,426,150,426,151,426,152,427,154,429,155,430,156,431,156,432,156,432,156,432,157,433,157,433,158,433,158,434,158,434,158,434,158,434,158,434,158,434,158,435,158,435,158,436,159,436,159,436,159,436,159,436,159,436,159,437,160,437,160,437,160,438,160,438,160,439,160,439,161,439,161,439,161,439,161,440,161,440,161,440,161,440,161,440,162,441,162,441,162,442,162,442,162,443,163,443,163,444,162,445,161,445,161,446,159,446,158,446,157,446,157,446,157,446,156,446,154,446,152,446,151,446,151,447,151,447,150,447,148,447,147,447,146,447,146,447;316,446,316,446,315,446,315,446,314,446,314,446,314,446,314,446,313,446,312,446,312,445,311,445,311,444,310,444,310,444,310,444,310,444,310,443,310,443,309,442,309,442,308,442,308,441,308,440,308,440,308,439,308,439,307,439,307,439,308,439,308,439,308,438,308,437,308,436,308,436,309,435,309,435,310,434,310,434,310,434,310,434,310,434,310,434,311,433,311,433,311,432,312,432,312,432,313,432,313,432,313,432,313,432,313,432,313,432,314,432,315,430,316,429,317,428,319,427,319,427,319,427,320,427,320,427,320,426,320,426,321,426,322,426,322,427,324,429,326,430,327,431,327,432,327,432,327,432,328,433,328,433,328,433,328,434,328,434,328,434,329,434,329,434,329,434,329,435,329,435,329,436,329,436,329,436,330,436,330,436,330,436,330,437,330,437,331,437,331,438,331,438,331,439,331,439,331,439,331,439,332,439,332,440,332,440,332,440,332,440,332,440,332,441,332,441,332,442,332,442,333,443,334,443,334,444,333,445,332,445,332,446,330,446,328,446,328,446,328,446,328,446,326,446,325,446,323,446,322,446,322,447,322,447,320,447,319,447,317,447,316,447,316,447;487,446,486,446,486,446,485,446,485,446,485,446,485,446,484,446,484,446,483,446,482,445,482,445,482,444,481,444,481,444,480,444,480,444,480,443,480,443,480,442,480,442,479,442,479,441,479,440,479,440,479,439,478,439,478,439,478,439,478,439,479,439,479,438,479,437,479,436,479,436,480,435,480,435,480,434,480,434,480,434,480,434,481,434,481,434,482,433,482,433,482,432,483,432,483,432,483,432,484,432,484,432,484,432,484,432,484,432,484,432,486,430,487,429,488,428,489,427,490,427,490,427,490,427,490,427,490,426,491,426,491,426,492,426,493,427,495,429,496,430,498,431,498,432,498,432,498,432,498,433,499,433,499,433,499,434,499,434,499,434,499,434,499,434,500,434,500,435,500,435,500,436,500,436,500,436,500,436,500,436,500,436,500,437,501,437,501,437,502,438,502,438,502,439,502,439,502,439,502,439,502,439,502,440,502,440,502,440,503,440,503,440,503,441,503,441,503,442,503,442,504,443,504,443,504,444,503,445,503,445,502,446,500,446,499,446,498,446,498,446,498,446,497,446,495,446,493,446,492,446,492,447,492,447,491,447,490,447,488,447,487,447,487,447;58,444,58,444,57,444,56,444,55,443,55,442,55,442,55,442,55,442,54,442,54,441,54,441,54,440,54,440,56,440,57,440,58,440,58,440,58,440,58,440,59,440,60,440,60,440,60,440,60,440,61,440,63,440,64,440,65,440,65,441,65,441,66,441,67,441,68,441,69,441,69,441,69,441,69,442,70,442,71,442,71,442,71,442,71,443,69,444,69,444,68,444,68,444,68,445,68,445,68,445,68,445,67,445,67,445,67,445,67,445,65,446,63,446,59,446,59,445,59,445;82,445,82,444,82,442,82,440,82,440,83,439,84,438,84,438,86,438,87,438,88,437,88,437,88,437,88,437,89,437,91,437,91,437,92,438,92,438,93,438,95,438,96,438,98,438,98,439,98,439,98,439,99,439,101,439,101,439,102,440,103,441,104,441,104,443,104,443,103,444,103,444,103,444,103,444,103,445,103,445,103,446,101,446,100,446,100,445,100,445,100,445,99,445,98,445,97,445,97,445,97,445,97,444,95,444,92,444,88,444,86,444,86,445,86,445,85,445,85,445,84,445,83,445,83,445,83,446,82,446,82,445;128,443,128,443,127,443,127,443,126,443,126,443,126,442,126,442,125,442,125,442,124,442,124,442,124,442,123,442,123,442,121,442,121,441,121,441,121,440,121,440,121,440,121,440,122,439,122,438,122,437,122,437,122,437,122,437,122,437,122,436,122,436,122,436,123,436,123,436,123,435,123,435,123,433,124,433,125,433,126,433,126,433,126,433,126,432,127,432,128,432,129,432,130,432,130,432,130,432,130,432,131,432,132,432,132,432,132,432,132,432,132,432,133,432,133,432,134,432,134,433,134,433,134,433,135,433,135,433,136,433,136,433,136,433,136,434,136,434,137,434,137,434,137,435,137,435,137,436,137,436,136,436,136,437,136,438,136,439,136,440,136,440,136,440,136,441,136,442,136,442,135,443,135,443,135,443,135,443,135,444,135,444,135,444,134,444,133,444,133,444,133,445,133,445,133,445,132,445,132,445,132,445,132,445,132,446,130,445,129,444;229,444,228,444,228,444,227,444,226,443,226,442,226,442,225,442,225,442,225,442,225,441,225,441,225,440,225,440,227,440,227,440,228,440,228,440,228,440,229,440,230,440,230,440,231,440,231,440,231,440,232,440,233,440,235,440,236,440,236,441,236,441,236,441,238,441,239,441,240,441,240,441,240,441,240,442,241,442,242,442,242,442,241,443,240,444,240,444,239,444,239,444,239,444,239,445,239,445,239,445,238,445,238,445,238,445,238,445,238,445,236,446,234,446,230,446,230,445,229,445;252,445,252,444,252,442,252,440,252,440,253,439,254,438,255,438,256,438,257,438,258,437,258,437,258,437,259,437,260,437,262,437,262,437,263,438,263,438,263,438,266,438,267,438,268,438,268,439,268,439,269,439,270,439,272,439,272,439,273,440,274,441,274,441,274,443,274,443,274,444,274,444,274,444,274,444,274,445,274,445,273,446,272,446,271,446,270,445,270,445,270,445,270,445,269,445,268,445,268,445,268,445,268,444,266,444,262,444,259,444,257,444,257,445,257,445,256,445,255,445,254,445,254,445,254,445,254,446,253,446,253,445;299,443,298,443,298,443,297,443,297,443,297,443,297,442,296,442,296,442,295,442,295,442,295,442,295,442,294,442,293,442,292,442,292,441,292,441,292,440,292,440,292,440,292,440,292,439,292,438,292,437,292,437,293,437,293,437,293,437,293,436,293,436,293,436,293,436,293,436,294,435,294,435,294,433,294,433,296,433,296,433,297,433,297,433,297,432,298,432,299,432,299,432,300,432,300,432,300,432,301,432,302,432,302,432,303,432,303,432,303,432,303,432,304,432,304,432,304,432,304,433,304,433,305,433,305,433,306,433,306,433,306,433,306,433,306,434,307,434,307,434,308,434,308,435,308,435,307,436,307,436,307,436,307,437,307,438,307,439,307,440,307,440,306,440,306,441,306,442,306,442,306,443,306,443,306,443,306,443,306,444,306,444,305,444,305,444,304,444,304,444,304,445,304,445,303,445,303,445,302,445,302,445,302,445,302,446,301,445,300,444;400,444,399,444,399,444,398,444,396,443,396,442,396,442,396,442,396,442,396,442,396,441,396,441,396,440,396,440,397,440,398,440,399,440,399,440,399,440,399,440,400,440,401,440,402,440,402,440,402,440,403,440,404,440,405,440,406,440,406,441,406,441,407,441,408,441,409,441,410,441,410,441,410,441,411,442,411,442,412,442,412,442,411,443,411,444,410,444,410,444,410,444,410,444,410,445,410,445,409,445,409,445,408,445,408,445,408,445,408,445,407,446,404,446,401,446,400,445,400,445;423,445,423,444,423,442,423,440,423,440,424,439,425,438,425,438,427,438,428,438,429,437,429,437,429,437,430,437,431,437,432,437,433,437,433,438,434,438,434,438,436,438,438,438,439,438,439,439,439,439,440,439,441,439,442,439,443,439,444,440,445,441,445,441,445,443,445,443,445,444,445,444,444,444,444,444,444,445,444,445,444,446,443,446,442,446,441,445,441,445,441,445,440,445,440,445,439,445,438,445,438,445,438,444,436,444,433,444,430,444,428,444,428,445,428,445,427,445,426,445,425,445,424,445,424,445,424,446,424,446,423,445;470,443,469,443,468,443,468,443,468,443,468,443,468,442,467,442,467,442,466,442,466,442,466,442,466,442,465,442,464,442,462,442,462,441,462,441,462,440,462,440,463,440,463,440,463,439,463,438,463,437,463,437,463,437,463,437,464,437,464,436,464,436,464,436,464,436,464,436,464,435,464,435,464,433,465,433,466,433,467,433,468,433,468,433,468,432,468,432,469,432,470,432,471,432,471,432,471,432,471,432,472,432,473,432,474,432,474,432,474,432,474,432,474,432,475,432,475,432,475,433,475,433,475,433,476,433,476,433,477,433,477,433,477,433,477,434,478,434,478,434,478,434,478,435,478,435,478,436,478,436,478,436,478,437,478,438,478,439,477,440,477,440,477,440,477,441,477,442,477,442,477,443,477,443,476,443,476,443,476,444,476,444,476,444,475,444,475,444,474,444,474,445,474,445,474,445,474,445,473,445,473,445,473,445,473,446,472,445,471,444;173,444,172,444,171,444,170,444,169,444,169,444,169,444,168,444,167,444,165,444,165,443,164,442,163,442,163,441,163,440,163,440,163,439,162,439,162,439,162,438,162,438,162,438,161,437,161,437,160,437,160,436,160,434,160,432,161,432,162,432,163,432,163,433,164,433,164,434,166,434,167,434,168,434,168,434,168,434,169,434,170,434,170,434,171,434,171,435,171,435,172,435,172,435,174,435,175,435,175,437,175,437,175,438,175,438,175,438,176,438,176,438,176,439,176,439,176,439,176,439,176,439,176,440,176,441,176,442,177,442,177,442,177,442,177,442,177,443,177,443,177,443,177,443,178,443,178,444,178,444,177,444,177,444,176,444,176,444,176,445,176,445,175,445,175,445,174,445,173,445,173,445;344,444,343,444,342,444,340,444,340,444,340,444,340,444,339,444,338,444,336,444,336,443,335,442,334,442,334,441,334,440,334,440,333,439,333,439,332,439,332,438,332,438,332,438,332,437,332,437,331,437,331,436,331,434,331,432,332,432,333,432,333,432,334,433,334,433,335,434,337,434,338,434,339,434,339,434,339,434,339,434,340,434,341,434,342,434,342,435,342,435,342,435,343,435,345,435,346,435,346,437,346,437,346,438,346,438,346,438,346,438,346,438,346,439,346,439,347,439,347,439,347,439,347,440,347,441,347,442,347,442,347,442,348,442,348,442,348,443,348,443,348,443,348,443,348,443,348,444,348,444,348,444,348,444,347,444,347,444,347,445,347,445,346,445,345,445,344,445,344,445,344,445;514,444,513,444,512,444,511,444,510,444,510,444,510,444,509,444,508,444,507,444,506,443,505,442,505,442,504,441,504,440,504,440,504,439,504,439,503,439,503,438,503,438,503,438,503,437,502,437,502,437,502,436,502,434,502,432,503,432,504,432,504,432,505,433,505,433,505,434,507,434,509,434,510,434,510,434,510,434,510,434,511,434,512,434,512,434,512,435,512,435,513,435,514,435,515,435,516,435,516,437,516,437,516,438,517,438,517,438,517,438,517,438,517,439,517,439,517,439,517,439,518,439,518,440,518,441,518,442,518,442,518,442,518,442,518,442,518,443,518,443,519,443,519,443,519,443,519,444,519,444,519,444,518,444,518,444,518,444,518,445,518,445,517,445,516,445,515,445,514,445,514,445;7,441,7,441,7,440,7,439,7,439,7,439,6,439,6,439,6,438,6,438,6,438,6,438,6,438,6,437,6,435,6,434,5,433,5,433,5,433,5,432,5,432,5,431,5,431,5,431,5,431,6,431,6,430,6,430,6,430,6,430,7,430,8,430,8,431,8,432,9,432,10,432,11,432,12,432,12,433,12,433,12,433,13,433,13,433,14,433,14,433,14,433,15,434,17,434,18,434,20,434,20,434,20,434,20,434,21,434,22,434,23,434,23,435,23,435,24,435,26,435,28,435,28,437,28,439,28,440,28,440,28,440,28,440,28,441,28,441,27,442,27,442,27,442,27,442,27,442,27,443,26,444,22,444,20,444,18,443,18,443,18,443,17,443,16,443,15,443,14,443,14,443,14,443,13,443,12,443,9,443,9,443,8,442;178,441,178,441,178,440,178,439,177,439,177,439,177,439,177,439,177,438,177,438,177,438,177,438,176,438,176,437,176,435,176,434,176,433,176,433,176,433,176,432,176,432,176,431,176,431,176,431,176,431,176,431,176,430,176,430,176,430,177,430,178,430,179,430,179,431,179,432,180,432,181,432,182,432,182,432,182,433,182,433,183,433,183,433,184,433,184,433,184,433,184,433,185,434,187,434,189,434,190,434,190,434,190,434,191,434,192,434,193,434,194,434,194,435,194,435,195,435,196,435,199,435,199,437,199,439,199,440,199,440,198,440,198,440,198,441,198,441,198,442,198,442,198,442,198,442,198,442,198,443,197,444,193,444,190,444,189,443,189,443,189,443,188,443,187,443,186,443,185,443,185,443,185,443,184,443,182,443,180,443,180,443,179,442;348,441,348,441,348,440,348,439,348,439,348,439,348,439,348,439,348,438,348,438,347,438,347,438,347,438,347,437,347,435,347,434,347,433,347,433,346,433,346,432,346,432,346,431,346,431,347,431,347,431,347,431,347,430,347,430,347,430,348,430,349,430,350,430,350,431,350,432,350,432,352,432,352,432,353,432,353,433,353,433,353,433,354,433,354,433,355,433,355,433,355,433,356,434,358,434,360,434,361,434,361,434,361,434,362,434,363,434,363,434,364,434,364,435,364,435,365,435,367,435,370,435,370,437,370,439,369,440,369,440,369,440,369,440,369,441,369,441,369,442,369,442,368,442,368,442,368,442,368,443,367,444,363,444,361,444,360,443,360,443,360,443,359,443,358,443,356,443,356,443,356,443,356,443,354,443,353,443,350,443,350,443,349,442;32,440,32,440,32,440,31,440,31,440,31,439,31,438,31,438,31,438,30,438,30,435,31,434,31,434,32,434,32,434,32,434,33,433,33,433,33,433,34,433,35,433,35,433,36,433,36,433,36,432,38,432,42,432,45,432,48,432,48,432,48,432,49,432,52,432,54,432,56,431,56,431,56,431,57,431,58,431,58,432,58,433,58,435,58,438,57,438,57,438,56,438,56,438,56,438,55,438,53,438,51,438,50,438,50,439,50,439,48,439,47,439,45,439,44,439,44,439,44,439,43,440,42,440,41,440,40,440,40,440,40,440,38,440,37,440,35,440,34,440,34,441,34,441,34,441,33,441,33,441,32,441,32,441;203,440,203,440,202,440,202,440,202,440,202,439,202,438,201,438,201,438,201,438,201,435,201,434,202,434,202,434,203,434,203,434,204,433,204,433,204,433,204,433,205,433,206,433,207,433,207,433,207,432,209,432,213,432,216,432,218,432,218,432,218,432,220,432,222,432,225,432,226,431,226,431,226,431,228,431,228,431,229,432,229,433,229,435,229,438,228,438,227,438,227,438,227,438,227,438,226,438,224,438,222,438,220,438,220,439,220,439,219,439,218,439,216,439,215,439,215,439,215,439,214,440,213,440,211,440,210,440,210,440,210,440,209,440,208,440,206,440,205,440,205,441,205,441,204,441,204,441,203,441,203,441,203,441;374,440,373,440,373,440,372,440,372,440,372,439,372,438,372,438,372,438,371,438,371,435,372,434,372,434,373,434,373,434,374,434,374,433,374,433,374,433,375,433,376,433,377,433,378,433,378,433,378,432,380,432,383,432,387,432,389,432,389,432,389,432,390,432,393,432,395,432,397,431,397,431,397,431,398,431,399,431,399,432,400,433,400,435,400,438,399,438,398,438,398,438,398,438,398,438,396,438,394,438,392,438,391,438,391,439,391,439,390,439,388,439,387,439,386,439,386,439,386,439,385,440,383,440,382,440,381,440,381,440,381,440,380,440,378,440,377,440,376,440,376,441,376,441,375,441,375,441,374,441,374,441,374,441;118,439,118,439,117,439,117,439,116,439,116,439,116,438,116,438,115,438,115,438,114,438,114,438,114,438,113,438,112,438,110,438,109,437,109,437,109,437,107,437,103,437,100,437,98,437,98,437,98,437,97,438,97,438,96,438,96,437,96,437,96,437,95,437,95,437,94,437,94,437,94,436,94,435,94,435,96,435,96,435,97,435,97,435,97,434,97,434,98,434,98,434,98,434,98,434,98,434,99,434,100,434,100,434,101,433,101,433,101,433,101,433,102,433,102,433,102,433,102,433,102,432,103,432,104,432,104,432,105,432,105,432,105,432,105,432,106,432,106,432,106,431,106,431,106,431,107,431,108,431,108,431,109,431,109,431,109,430,109,430,110,430,110,430,110,430,110,430,110,430,111,430,112,430,113,430,114,429,114,429,114,429,114,429,114,429,115,429,115,429,115,429,115,429,115,430,116,430,116,430,117,430,117,430,117,431,118,431,118,431,119,431,122,433,122,434,122,434,121,435,121,435,121,435,121,435,121,436,121,436,121,436,121,436,120,436,120,437,120,438,120,439,120,439,120,439,119,439,119,439,119,439,119,439,119,440,119,440,118,440,118,439,118,439;289,439,288,439,288,439,287,439,287,439,287,439,287,438,286,438,286,438,285,438,285,438,285,438,285,438,284,438,282,438,281,438,280,437,280,437,280,437,277,437,274,437,270,437,268,437,268,437,268,437,268,438,267,438,267,438,266,437,266,437,266,437,266,437,266,437,265,437,265,437,265,436,265,435,265,435,266,435,267,435,268,435,268,435,268,434,268,434,268,434,269,434,269,434,269,434,269,434,269,434,270,434,271,434,272,433,272,433,272,433,272,433,272,433,273,433,273,433,273,433,273,432,273,432,274,432,275,432,276,432,276,432,276,432,276,432,276,432,277,432,277,431,277,431,277,431,277,431,278,431,279,431,280,431,280,431,280,430,280,430,280,430,281,430,281,430,281,430,281,430,282,430,283,430,283,430,284,429,284,429,284,429,284,429,285,429,285,429,286,429,286,429,286,429,286,430,286,430,287,430,288,430,288,430,288,431,289,431,289,431,290,431,292,433,292,434,292,434,292,435,292,435,292,435,292,435,292,436,292,436,291,436,291,436,291,436,291,437,291,438,291,439,291,439,290,439,290,439,290,439,290,439,290,439,289,440,289,440,289,440,289,439,289,439;460,439,459,439,459,439,458,439,458,439,458,439,458,438,457,438,457,438,456,438,456,438,456,438,456,438,454,438,453,438,451,438,450,437,450,437,450,437,448,437,445,437,441,437,439,437,439,437,439,437,438,438,438,438,437,438,437,437,437,437,437,437,437,437,436,437,436,437,436,437,436,436,436,435,436,435,437,435,438,435,438,435,438,435,438,434,438,434,439,434,439,434,440,434,440,434,440,434,440,434,441,434,442,434,442,433,442,433,442,433,442,433,443,433,443,433,444,433,444,433,444,432,444,432,445,432,446,432,446,432,446,432,446,432,446,432,447,432,447,432,448,431,448,431,448,431,448,431,449,431,450,431,450,431,450,431,450,430,450,430,451,430,451,430,452,430,452,430,452,430,452,430,453,430,454,430,455,429,455,429,455,429,455,429,456,429,456,429,456,429,456,429,456,429,457,430,457,430,458,430,458,430,459,430,459,431,459,431,460,431,461,431,463,433,463,434,463,434,463,435,463,435,462,435,462,435,462,436,462,436,462,436,462,436,462,436,462,437,462,438,462,439,461,439,461,439,460,439,460,439,460,439,460,439,460,440,460,440,460,440,460,439,460,439;73,437,72,437,70,437,68,437,66,437,66,437,66,436,65,436,64,436,61,436,60,435,60,433,60,431,61,431,64,431,66,431,68,431,68,431,68,430,69,430,70,430,72,430,73,430,73,431,73,431,73,431,74,431,76,431,76,431,76,434,76,436,76,437,76,437,75,438,73,438,73,437;244,437,242,437,240,437,238,437,237,437,237,437,237,436,236,436,235,436,232,436,231,435,231,433,231,431,231,431,235,431,237,431,238,431,238,431,238,430,239,430,241,430,242,430,244,430,244,431,244,431,244,431,245,431,246,431,247,431,247,434,247,436,247,437,246,437,246,438,244,438,244,437;414,437,413,437,411,437,409,437,408,437,408,437,408,436,407,436,405,436,403,436,402,435,402,433,402,431,402,431,406,431,408,431,409,431,409,431,409,430,410,430,412,430,413,430,414,430,414,431,414,431,415,431,415,431,417,431,418,431,418,434,418,436,417,437,417,437,416,438,414,438,414,437;77,434,78,431,80,431,80,431,81,431,81,431,81,430,81,430,82,430,82,430,83,430,83,430,83,430,84,430,85,430,85,430,86,429,86,429,86,429,86,429,87,429,87,429,88,429,88,429,88,429,88,430,88,430,89,430,90,430,90,430,91,431,91,431,91,433,91,435,91,436,84,435,80,435,78,435,78,435;247,434,249,431,251,431,251,431,252,431,252,431,252,430,252,430,253,430,253,430,254,430,254,430,254,430,254,430,255,430,256,430,257,429,257,429,257,429,257,429,258,429,258,429,258,429,258,429,258,429,259,430,259,430,259,430,260,430,261,430,261,431,262,431,262,433,262,435,261,436,255,435,250,435,249,435,249,435;418,434,419,431,421,431,422,431,422,431,422,431,422,430,423,430,423,430,424,430,424,430,424,430,424,430,425,430,426,430,427,430,428,429,428,429,428,429,428,429,428,429,429,429,429,429,429,429,429,429,429,430,430,430,430,430,431,430,431,430,432,431,432,431,432,433,432,435,432,436,425,435,421,435,420,435,419,435;92,432,92,432,93,432,93,432,94,432,94,432,94,432,94,432,95,432,95,432,96,432,96,433,96,433,95,434,95,434,94,434,94,434,94,434,94,434,94,434,93,434,92,434,92,434,92,433;263,432,263,432,264,432,264,432,264,432,264,432,264,432,265,432,265,432,266,432,266,432,266,433,266,433,266,434,266,434,265,434,265,434,265,434,265,434,264,434,264,434,263,434,263,434,263,433;434,432,434,432,434,432,435,432,435,432,435,432,435,432,435,432,436,432,437,432,437,432,437,433,437,433,437,434,436,434,436,434,436,434,436,434,436,434,435,434,435,434,434,434,434,434,434,433;1,432,1,431,1,431,2,430,2,430,3,431,3,431,4,432,4,433,4,433,3,433,3,433,2,433,1,433,1,433;171,432,171,431,172,431,172,430,173,430,173,431,174,431,174,432,174,433,174,433,174,433,173,433,173,433,172,433,172,433;342,432,342,431,343,431,343,430,343,430,344,431,344,431,345,432,345,433,345,433,345,433,344,433,343,433,343,433,343,433;168,432,167,432,166,432,165,432,164,432,164,432,164,432,164,432,164,432,163,432,163,431,163,431,163,431,162,431,162,431,160,431,160,429,160,427,160,427,161,426,162,426,162,426,165,426,167,426,169,425,169,425,169,425,170,425,171,425,171,425,172,425,172,425,172,425,173,426,175,426,177,426,178,426,178,427,178,428,178,428,178,428,177,428,177,428,177,429,177,429,176,429,174,429,171,429,171,431,171,433,170,433,169,433,168,433,168,433;339,432,338,432,337,432,336,432,335,432,335,432,335,432,335,432,334,432,334,432,334,431,334,431,334,431,333,431,332,431,331,431,331,429,331,427,331,427,332,426,332,426,333,426,336,426,338,426,340,425,340,425,340,425,340,425,341,425,342,425,343,425,343,425,343,425,344,426,345,426,348,426,349,426,349,427,349,428,349,428,348,428,348,428,348,428,348,429,348,429,346,429,345,429,342,429,342,431,342,433,340,433,339,433,339,433,339,433;510,432,509,432,508,432,506,432,506,432,506,432,506,432,505,432,505,432,504,432,504,431,504,431,504,431,504,431,503,431,502,431,502,429,502,427,502,427,502,426,503,426,503,426,507,426,509,426,510,425,510,425,510,425,511,425,512,425,513,425,514,425,514,425,514,425,515,426,516,426,519,426,520,426,520,427,520,428,519,428,519,428,518,428,518,428,518,429,518,429,517,429,515,429,512,429,512,431,512,433,511,433,510,433,510,433,510,433;14,432,13,432,13,432,12,432,12,431,12,431,12,431,12,431,11,431,10,431,10,429,10,427,10,426,13,426,13,426,14,425,14,425,14,425,17,425,23,425,28,425,31,425,31,425,31,424,32,424,34,424,36,424,37,424,37,425,37,425,37,425,37,425,38,425,38,425,38,425,39,426,39,426,37,428,36,429,35,430,35,430,35,431,35,431,34,431,34,431,34,431,34,431,34,431,31,432,27,432,22,432,20,432,20,432,20,432,18,432,17,432,15,432,14,432,14,432;98,432,98,431,98,431,99,431,99,430,99,430,99,429,100,429,101,429,102,429,102,429,102,429,102,429,103,430,103,430,104,430,104,430,104,430,104,431,104,431,103,431,102,431,102,431,101,432,101,432,100,432,99,432,98,432,98,432,98,432;136,432,136,432,135,432,135,432,134,431,134,431,134,431,134,431,134,431,132,431,132,428,133,426,133,426,134,426,135,426,135,426,136,425,136,425,136,425,137,425,139,425,140,425,142,425,142,425,142,424,142,424,142,424,143,424,143,424,143,425,143,425,143,425,144,425,144,425,145,425,145,425,145,425,145,426,146,426,147,426,147,426,147,426,147,427,144,430,143,430,143,430,143,430,143,430,143,430,143,430,142,430,142,430,142,430,142,431,142,431,140,431,140,430,140,430,140,430,140,430,140,431,139,431,139,431,138,431,138,431,138,431,138,431,138,432,138,432,137,432,137,432,137,432,137,432,137,432,137,432,136,432,136,432,136,432;184,432,184,432,184,432,183,432,183,431,183,431,183,431,182,431,182,431,180,431,180,429,180,427,181,426,183,426,184,426,185,425,185,425,185,425,188,425,193,425,199,425,202,425,202,425,202,424,203,424,205,424,206,424,208,424,208,425,208,425,208,425,208,425,208,425,209,425,209,425,209,426,209,426,208,428,206,429,206,430,206,430,206,431,205,431,205,431,204,431,204,431,204,431,204,431,202,432,197,432,193,432,190,432,190,432,190,432,189,432,187,432,185,432,184,432,184,432;268,432,268,431,269,431,269,431,270,430,270,430,270,429,270,429,272,429,272,429,273,429,273,429,273,429,273,430,274,430,275,430,275,430,275,430,275,431,275,431,274,431,273,431,272,431,272,432,271,432,271,432,270,432,269,432,268,432,268,432;307,432,306,432,306,432,305,432,305,431,305,431,305,431,305,431,304,431,303,431,302,428,304,426,304,426,305,426,305,426,306,426,306,425,306,425,306,425,307,425,309,425,311,425,312,425,312,425,312,424,312,424,313,424,313,424,314,424,314,425,314,425,314,425,315,425,315,425,316,425,316,425,316,425,316,426,317,426,318,426,318,426,316,428,315,429,314,430,314,430,314,430,314,430,314,430,314,430,313,430,313,430,312,430,312,430,312,431,312,431,311,431,311,430,311,430,310,430,310,430,310,431,310,431,309,431,309,431,309,431,309,431,309,431,309,432,308,432,308,432,308,432,308,432,308,432,307,432,307,432,307,432,307,432,307,432;355,432,355,432,354,432,354,432,354,431,354,431,354,431,353,431,352,431,351,431,351,429,351,427,352,426,354,426,355,426,356,425,356,425,356,425,359,425,364,425,369,425,372,425,372,425,372,424,373,424,375,424,377,424,378,424,378,425,378,425,378,425,379,425,379,425,379,425,380,425,380,426,380,426,378,428,377,429,376,430,376,430,376,431,376,431,376,431,375,431,375,431,375,431,375,431,372,432,368,432,363,432,361,432,361,432,361,432,360,432,358,432,356,432,355,432,355,432;439,432,439,431,440,431,440,431,440,430,440,430,440,429,441,429,442,429,443,429,444,429,444,429,444,429,444,430,445,430,445,430,446,430,446,430,446,431,445,431,444,431,443,431,443,431,443,432,442,432,442,432,440,432,440,432,439,432,439,432;478,432,477,432,477,432,476,432,476,431,476,431,476,431,475,431,475,431,473,431,473,428,474,426,475,426,476,426,476,426,476,426,477,425,477,425,477,425,478,425,480,425,482,425,483,425,483,425,483,424,483,424,484,424,484,424,484,424,484,425,484,425,485,425,485,425,486,425,486,425,486,425,486,425,487,426,487,426,489,426,488,426,487,428,486,429,485,430,485,430,484,430,484,430,484,430,484,430,484,430,484,430,483,430,483,430,483,431,483,431,482,431,481,430,481,430,481,430,481,430,481,431,480,431,480,431,480,431,480,431,480,431,480,431,479,432,479,432,478,432,478,432,478,432,478,432,478,432,478,432,478,432,478,432,478,432;94,430,93,430,92,430,92,430,91,429,91,429,91,428,90,428,90,428,89,428,89,428,89,428,88,427,88,427,87,427,87,427,87,427,87,426,87,426,86,425,86,425,85,424,84,423,84,423,84,422,83,422,83,422,82,422,82,421,82,420,82,420,81,420,81,420,81,420,81,419,81,419,81,418,81,418,83,418,83,418,84,418,84,419,84,419,85,419,86,419,86,419,87,419,87,419,87,419,87,420,88,420,88,420,88,420,88,420,88,420,91,420,97,420,105,420,105,420,106,421,106,421,107,422,108,422,108,422,109,422,109,422,109,423,110,423,111,423,111,423,112,423,112,424,112,425,111,425,110,425,109,425,108,425,108,425,108,424,107,424,105,424,101,424,100,425,99,426,99,427,99,427,99,427,99,428,98,428,98,428,98,429,98,429,98,430,97,430,97,430,97,430,97,430,97,431,97,432,95,432,94,431;264,430,264,430,263,430,263,430,262,429,262,429,262,428,261,428,261,428,260,428,259,428,259,428,259,427,258,427,258,427,258,427,258,427,258,426,258,426,257,425,256,425,255,424,255,423,255,423,255,422,254,422,254,422,253,422,252,421,252,420,252,420,252,420,252,420,252,420,252,419,252,419,252,418,252,418,253,418,254,418,255,418,255,419,255,419,255,419,256,419,257,419,258,419,258,419,258,419,258,420,258,420,259,420,259,420,259,420,259,420,262,420,267,420,276,420,276,420,277,421,277,421,277,422,278,422,279,422,280,422,280,422,280,423,281,423,281,423,282,423,282,423,282,424,282,425,282,425,281,425,280,425,279,425,279,425,279,424,277,424,275,424,272,424,271,425,270,426,270,427,270,427,270,427,269,428,269,428,268,428,268,429,268,429,268,430,268,430,268,430,268,430,268,430,268,431,268,432,266,432,265,431;435,430,434,430,434,430,433,430,433,429,433,429,432,428,432,428,431,428,431,428,430,428,430,428,430,427,429,427,429,427,428,427,428,427,428,426,428,426,428,425,427,425,426,424,426,423,426,423,426,422,425,422,424,422,424,422,423,421,423,420,423,420,423,420,423,420,422,420,422,419,422,419,422,418,422,418,424,418,425,418,426,418,426,419,426,419,426,419,427,419,428,419,428,419,428,419,428,419,428,420,429,420,429,420,430,420,430,420,430,420,433,420,438,420,446,420,447,420,447,421,447,421,448,422,449,422,450,422,450,422,451,422,451,423,451,423,452,423,453,423,453,423,453,424,453,425,453,425,451,425,450,425,450,425,450,425,450,424,448,424,446,424,442,424,441,425,441,426,440,427,440,427,440,427,440,428,440,428,439,428,439,429,439,429,439,430,439,430,439,430,438,430,438,430,438,431,438,432,437,432,436,431;53,430,51,430,49,430,47,430,46,430,46,430,46,430,44,430,42,430,39,430,38,429,38,429,38,429,38,428,38,428,39,427,39,427,41,427,42,427,42,427,43,426,43,426,43,426,45,426,45,426,46,425,46,425,46,425,48,425,50,425,52,425,53,425,53,425,53,425,53,426,54,426,55,426,56,426,56,426,56,426,56,426,56,426,57,426,57,426,57,427,57,427,57,427,58,427,58,427,58,427,58,428,58,428,58,428,58,428,57,428,57,428,57,429,56,429,56,430,56,430,55,430,55,430,55,430,54,431,53,431,53,431;224,430,222,430,220,430,218,430,216,430,216,430,216,430,215,430,213,430,210,430,209,429,209,429,208,429,208,428,209,428,210,427,210,427,211,427,212,427,213,427,213,426,214,426,214,426,215,426,216,426,217,425,217,425,217,425,218,425,220,425,222,425,224,425,224,425,224,425,224,426,225,426,226,426,226,426,226,426,226,426,226,426,227,426,227,426,228,426,228,427,228,427,228,427,228,427,229,427,229,427,229,428,229,428,229,428,228,428,228,428,227,428,227,429,227,429,226,430,226,430,226,430,225,430,225,430,225,431,224,431,224,431;394,430,393,430,391,430,388,430,387,430,387,430,387,430,385,430,383,430,381,430,380,429,379,429,379,429,379,428,380,428,380,427,381,427,382,427,383,427,383,427,384,426,384,426,385,426,386,426,387,426,388,425,388,425,388,425,389,425,391,425,393,425,394,425,394,425,394,425,395,426,396,426,396,426,397,426,397,426,397,426,397,426,398,426,398,426,398,426,398,427,398,427,398,427,399,427,399,427,400,427,400,428,400,428,399,428,399,428,399,428,398,428,398,429,398,429,397,430,397,430,397,430,396,430,396,430,395,431,394,431,394,431;60,428,60,425,61,425,61,424,63,424,69,424,77,424,78,424,78,425,78,425,78,426,78,426,79,426,79,427,79,428,79,429,74,429,71,429,69,429,69,429,69,430,61,430,61,429;231,428,231,425,231,425,232,424,233,424,240,424,248,424,248,424,248,425,248,425,248,426,249,426,249,426,250,427,250,428,250,429,245,429,241,429,240,429,240,429,240,430,232,430,231,429;401,428,401,425,402,425,402,424,404,424,411,424,418,424,419,424,419,425,419,425,419,426,420,426,420,426,420,427,420,428,420,429,415,429,412,429,410,429,410,429,410,430,402,430,402,429;81,428,80,427,80,427,80,427,80,426,80,426,79,425,79,425,79,424,79,423,79,422,78,422,78,422,77,422,77,421,76,421,76,420,76,418,76,417,76,416,77,416,78,416,79,418,79,419,79,420,80,422,81,422,81,422,82,422,83,424,85,426,86,426,86,427,86,428,85,428,84,428,83,428,83,428,83,429,83,429,82,429,81,428;106,428,105,428,104,428,103,428,102,428,102,428,102,428,102,428,102,428,101,428,101,427,101,427,100,427,100,426,101,426,101,426,102,426,106,426,110,426,111,426,111,426,112,427,112,427,112,428,111,428,111,428,109,428,108,428,108,428,108,429,108,429,107,429,107,429,106,429,106,429,106,429;251,428,251,427,251,427,251,427,251,426,250,426,250,425,250,425,250,424,250,423,249,422,249,422,249,422,248,422,248,421,247,421,247,420,247,418,247,417,247,416,247,416,248,416,250,418,250,419,250,420,251,422,251,422,252,422,253,422,254,424,256,426,256,426,256,427,256,428,256,428,255,428,254,428,254,428,254,429,254,429,252,429,252,428;277,428,276,428,275,428,274,428,273,428,273,428,273,428,273,428,272,428,272,428,272,427,271,427,271,427,271,426,271,426,272,426,273,426,276,426,281,426,281,426,282,426,283,427,283,427,282,428,282,428,281,428,280,428,279,428,278,428,278,429,278,429,278,429,278,429,277,429,277,429,277,429;422,428,422,427,422,427,422,427,421,426,421,426,420,425,420,425,420,424,420,423,420,422,420,422,419,422,419,422,418,421,418,421,418,420,418,418,418,417,418,416,418,416,419,416,420,418,420,419,420,420,421,422,422,422,422,422,423,422,425,424,427,426,427,426,427,427,427,428,427,428,426,428,425,428,424,428,424,429,424,429,423,429,422,428;448,428,447,428,446,428,444,428,444,428,444,428,444,428,443,428,443,428,443,428,442,427,442,427,442,427,442,426,442,426,442,426,443,426,447,426,452,426,452,426,453,426,453,427,453,427,453,428,453,428,452,428,451,428,450,428,449,428,449,429,449,429,449,429,448,429,448,429,448,429,448,429;114,426,114,426,114,426,114,426,114,426,114,427,114,427,114,427,114,427,114,427,114,427,114,427;284,426,284,426,285,426,285,426,285,426,285,427,285,427,285,427,285,427,284,427,284,427,284,427;455,426,455,426,455,426,455,426,456,426,456,427,456,427,455,427,455,427,455,427,455,427,455,427;151,425,150,425,150,425,149,425,149,425,149,425,149,424,148,424,147,424,146,424,145,424,145,424,145,424,143,424,141,424,138,424,136,423,136,423,136,423,136,423,136,423,135,423,135,423,135,422,134,422,134,420,135,420,135,420,135,419,135,419,135,418,135,418,135,418,135,418,136,417,136,416,136,415,135,414,135,414,135,414,135,413,135,411,135,407,135,407,136,407,136,407,136,407,136,407,136,406,136,406,137,406,137,406,138,406,138,406,138,406,138,406,139,406,140,406,140,405,140,405,140,405,142,405,144,405,146,405,147,405,147,405,147,405,148,406,149,406,150,406,151,406,151,406,151,406,151,406,152,406,152,406,152,406,152,407,152,407,152,407,153,407,153,407,154,407,154,408,154,408,155,408,155,408,155,408,156,409,156,409,157,410,157,410,157,413,157,415,157,416,157,416,158,416,158,417,157,417,157,417,157,418,157,420,157,423,157,423,156,424,156,424,155,425,155,425,154,425,154,425,154,425,154,425,153,426,153,426,152,426,151,425,151,425;322,425,321,425,321,425,320,425,320,425,320,425,320,424,319,424,318,424,316,424,316,424,316,424,316,424,314,424,311,424,309,424,307,423,307,423,307,423,307,423,306,423,306,423,306,423,305,422,305,422,305,420,305,420,305,420,306,419,306,419,306,418,306,418,306,418,306,418,306,417,306,416,306,415,306,414,306,414,306,414,306,413,306,411,306,407,306,407,306,407,307,407,307,407,307,407,307,406,307,406,308,406,308,406,308,406,308,406,308,406,309,406,310,406,310,406,311,405,311,405,311,405,312,405,314,405,316,405,318,405,318,405,318,405,318,406,320,406,321,406,322,406,322,406,322,406,322,406,322,406,323,406,323,406,323,407,323,407,323,407,323,407,324,407,324,407,325,408,325,408,325,408,325,408,326,408,326,409,327,409,327,410,328,410,328,413,328,415,328,416,328,416,328,416,328,417,328,417,328,417,328,418,328,420,328,423,327,423,327,424,326,424,326,425,325,425,325,425,325,425,325,425,325,425,324,426,323,426,322,426,322,425,322,425;492,425,492,425,491,425,491,425,490,425,490,425,490,424,489,424,488,424,487,424,486,424,486,424,486,424,485,424,482,424,479,424,478,423,478,423,478,423,477,423,477,423,477,423,476,423,476,422,475,422,475,420,476,420,476,420,476,419,476,419,476,418,476,418,477,418,477,418,477,417,477,416,477,415,477,414,477,414,476,414,476,413,476,411,476,407,476,407,477,407,477,407,478,407,478,407,478,406,478,406,478,406,479,406,479,406,479,406,479,406,479,406,480,406,481,406,482,405,482,405,482,405,483,405,485,405,487,405,488,405,488,405,488,405,489,406,490,406,491,406,492,406,492,406,492,406,492,406,493,406,493,406,494,406,494,407,494,407,494,407,494,407,494,407,495,407,495,408,495,408,496,408,496,408,496,408,497,409,497,409,498,410,498,410,498,413,498,415,498,416,499,416,499,416,499,417,499,417,498,417,498,418,498,420,498,423,498,423,497,424,497,424,496,425,496,425,496,425,496,425,496,425,496,425,495,426,494,426,493,426,492,425,492,425;40,423,39,423,39,423,38,423,37,423,37,422,37,422,36,422,36,422,35,422,35,421,35,421,35,420,35,420,35,420,34,420,34,419,34,418,34,416,34,415,34,415,34,415,34,415,34,414,34,414,34,414,34,414,34,414,34,413,34,413,34,412,34,412,35,412,35,412,35,412,35,412,35,410,36,410,40,410,43,410,44,410,44,411,44,411,44,411,45,411,45,411,47,412,47,413,47,413,47,414,48,414,48,414,48,415,48,415,48,415,48,416,49,416,49,416,49,416,49,417,49,417,49,418,49,418,48,418,48,418,48,418,48,419,48,420,48,420,47,420,47,420,48,420,48,420,48,420,48,421,48,421,48,422,49,422,50,422,50,423,49,423,49,423,48,424,48,424,47,424,47,424,47,424,47,424,46,424,44,424,41,424,40,424,40,424;174,424,172,424,170,424,168,424,166,423,166,423,166,423,165,423,163,423,160,423,159,423,159,422,158,422,158,417,159,417,159,417,159,416,159,416,159,415,159,415,160,415,160,414,160,414,160,414,160,413,160,413,161,413,161,412,162,412,162,411,162,411,162,411,162,411,163,411,163,411,163,411,163,411,163,412,164,412,164,412,164,412,164,412,164,412,164,412,165,412,165,412,166,412,166,413,166,413,166,413,167,413,168,413,169,413,169,413,169,412,169,412,170,412,170,412,170,412,170,411,169,411,168,411,168,411,168,411,167,412,167,412,166,412,166,411,166,411,166,411,165,411,165,411,164,411,164,411,164,410,164,410,164,409,165,409,165,409,166,408,166,408,166,408,166,407,167,407,168,407,168,406,169,406,169,405,170,405,170,405,171,405,171,404,171,402,171,399,173,399,174,399,175,399,176,399,176,400,176,402,176,402,176,402,176,403,176,405,176,407,176,408,176,408,176,408,176,410,176,412,176,415,176,416,177,416,177,416,177,417,177,418,177,418,177,419,177,419,176,419,176,420,176,421,176,421,176,422,177,422,177,422,177,423,176,424,176,424,174,424,174,424;210,423,210,423,209,423,209,423,208,423,208,422,208,422,207,422,206,422,206,422,206,421,206,421,206,420,205,420,205,420,205,420,205,419,205,418,205,416,205,415,205,415,204,415,204,415,204,414,204,414,204,414,205,414,205,414,205,413,205,413,205,412,205,412,205,412,205,412,206,412,206,412,206,410,206,410,211,410,213,410,215,410,215,411,215,411,215,411,215,411,216,411,218,412,218,413,218,413,218,414,218,414,219,414,219,415,219,415,219,415,219,416,219,416,219,416,220,416,220,417,220,417,219,418,219,418,219,418,219,418,219,418,219,419,219,420,218,420,218,420,218,420,218,420,219,420,219,420,219,421,219,421,219,422,220,422,220,422,220,423,220,423,219,423,219,424,218,424,218,424,218,424,218,424,218,424,216,424,214,424,211,424,211,424,211,424;344,424,343,424,341,424,338,424,337,423,337,423,337,423,335,423,333,423,331,423,330,423,329,422,329,422,329,417,329,417,329,417,330,416,330,416,330,415,330,415,330,415,331,414,331,414,331,414,331,413,331,413,332,413,332,412,332,412,332,411,332,411,332,411,333,411,333,411,334,411,334,411,334,411,334,412,334,412,335,412,335,412,335,412,335,412,335,412,336,412,336,412,336,412,336,413,336,413,337,413,338,413,339,413,340,413,340,413,340,412,340,412,340,412,341,412,341,412,340,411,340,411,338,411,338,411,338,411,338,412,337,412,337,412,336,411,336,411,336,411,336,411,336,411,335,411,335,411,335,410,335,410,335,409,336,409,336,409,336,408,336,408,336,408,337,407,338,407,338,407,339,406,340,406,340,405,341,405,341,405,341,405,342,404,342,402,342,399,344,399,345,399,346,399,346,399,347,400,347,402,347,402,346,402,346,403,346,405,346,407,346,408,347,408,347,408,347,410,347,412,347,415,347,416,347,416,347,416,348,417,348,418,348,418,347,419,347,419,347,419,347,420,347,421,347,421,347,422,347,422,348,422,348,423,347,424,346,424,344,424,344,424;381,423,380,423,380,423,379,423,379,423,379,422,378,422,378,422,377,422,376,422,376,421,376,421,376,420,376,420,376,420,376,420,376,419,376,418,376,416,375,415,375,415,375,415,375,415,375,414,375,414,375,414,375,414,375,414,376,413,376,413,376,412,376,412,376,412,376,412,376,412,376,412,376,410,377,410,381,410,384,410,386,410,386,411,386,411,386,411,386,411,387,411,388,412,388,413,388,413,388,414,389,414,389,414,390,415,390,415,390,415,390,416,390,416,390,416,390,416,390,417,390,417,390,418,390,418,390,418,390,418,390,418,390,419,389,420,389,420,389,420,389,420,389,420,389,420,390,420,390,421,390,421,390,422,390,422,391,422,391,423,390,423,390,423,389,424,389,424,389,424,388,424,388,424,388,424,387,424,385,424,382,424,382,424,381,424;515,424,513,424,511,424,509,424,508,423,508,423,508,423,506,423,504,423,501,423,500,423,500,422,499,422,499,417,500,417,500,417,500,416,500,416,500,415,500,415,501,415,501,414,502,414,502,414,502,413,502,413,502,413,503,412,503,412,503,411,503,411,503,411,504,411,504,411,504,411,504,411,504,411,504,412,505,412,505,412,506,412,506,412,506,412,506,412,506,412,507,412,507,412,507,413,507,413,508,413,509,413,509,413,510,413,510,413,510,412,510,412,511,412,512,412,512,412,511,411,510,411,509,411,509,411,509,411,508,412,508,412,507,412,507,411,507,411,507,411,507,411,506,411,506,411,506,411,506,410,506,410,506,409,506,409,507,409,507,408,507,408,507,408,508,407,509,407,509,407,510,406,510,406,511,405,511,405,512,405,512,405,512,404,512,402,512,399,514,399,516,399,517,399,517,399,518,400,518,402,517,402,517,402,517,403,517,405,517,407,517,408,517,408,517,408,518,410,518,412,518,415,518,416,518,416,518,416,518,417,518,418,518,418,518,419,518,419,518,419,518,420,518,421,518,421,518,422,518,422,518,422,518,423,518,424,517,424,515,424,515,424;50,422,50,421,50,420,50,420,49,419,49,419,49,419,49,419,49,419,49,419,50,418,50,416,50,415,50,414,50,414,50,414,50,414,50,414,50,413,50,413,51,413,51,413,51,412,51,412,51,411,51,411,51,411,51,411,52,410,52,410,52,409,52,408,52,408,52,408,52,408,52,408,52,407,52,407,55,407,56,407,58,407,58,407,58,407,60,408,64,408,67,408,70,408,70,408,70,408,70,408,70,408,71,408,72,409,72,410,72,410,72,410,73,411,73,411,74,411,74,412,74,412,74,412,74,413,75,413,75,413,75,417,75,420,75,421,76,421,76,421,76,422,76,422,76,423,75,423,64,423,51,423,50,422;114,422,114,422,113,422,113,422,112,422,112,422,112,422,112,422,111,422,111,422,110,421,110,421,110,421,110,421,110,421,109,421,109,421,109,421,109,420,108,420,108,420,107,420,107,420,107,420,107,419,107,419,107,419,106,419,106,418,106,418,106,417,106,417,107,417,107,417,107,416,107,415,107,414,107,414,107,414,107,414,108,413,108,412,108,411,108,411,108,411,108,411,108,411,108,410,108,409,109,409,111,409,111,409,112,409,112,409,112,409,113,410,113,410,114,410,115,410,115,410,116,411,116,411,117,411,118,411,118,411,118,411,118,411,119,412,119,412,120,412,120,412,120,412,120,412,121,412,122,412,122,412,123,412,123,412,123,412,124,412,125,412,126,412,127,412,127,412,127,412,128,412,129,412,130,412,131,412,131,413,131,413,131,413,132,413,133,413,134,414,134,414,134,415,134,415,134,415,134,415,134,415,134,416,134,416,134,417,134,417,134,417,134,417,134,418,134,419,133,419,133,420,132,420,132,421,132,421,132,421,132,422,132,422,131,422,131,422,131,422,131,422,129,422,126,422,123,422,121,422,121,423,121,423,120,423,118,423,116,423,114,423,114,423;221,422,220,421,220,420,220,420,220,419,220,419,219,419,219,419,220,419,220,419,220,418,220,416,220,415,220,414,221,414,221,414,221,414,221,414,221,413,221,413,221,413,221,413,222,412,222,412,222,411,222,411,222,411,222,411,222,410,222,410,222,409,222,408,223,408,223,408,223,408,223,408,223,407,223,407,226,407,227,407,228,407,228,407,228,407,230,408,234,408,238,408,240,408,240,408,240,408,241,408,241,408,242,408,243,409,243,410,243,410,243,410,244,411,244,411,244,411,244,412,244,412,244,412,245,413,245,413,246,413,246,417,246,420,246,421,246,421,247,421,247,422,247,422,247,423,246,423,234,423,222,423,221,422;285,422,284,422,284,422,283,422,283,422,283,422,283,422,282,422,282,422,281,422,281,421,281,421,281,421,281,421,280,421,280,421,280,421,280,421,280,420,279,420,279,420,278,420,278,420,278,420,278,419,277,419,277,419,277,419,277,418,277,418,277,417,277,417,277,417,277,417,278,416,278,415,278,414,278,414,278,414,278,414,278,413,278,412,278,411,278,411,279,411,279,411,279,411,279,410,279,409,280,409,281,409,282,409,283,409,283,409,283,409,283,410,284,410,285,410,285,410,286,410,286,411,287,411,288,411,288,411,289,411,289,411,289,411,289,412,290,412,290,412,291,412,291,412,291,412,291,412,292,412,293,412,294,412,294,412,294,412,294,412,296,412,297,412,298,412,298,412,298,412,298,412,300,412,301,412,302,412,302,413,302,413,302,413,302,413,303,413,304,414,304,414,304,415,304,415,305,415,305,415,305,415,305,416,305,416,305,417,305,417,304,417,304,417,304,418,304,419,304,419,304,420,303,420,303,421,303,421,303,421,303,422,302,422,302,422,302,422,302,422,302,422,300,422,297,422,293,422,292,422,292,423,292,423,290,423,288,423,286,423,285,423,285,423;391,422,391,421,391,420,391,420,391,419,390,419,390,419,390,419,390,419,391,419,391,418,391,416,391,415,391,414,391,414,391,414,392,414,392,414,392,413,392,413,392,413,392,413,392,412,392,412,392,411,392,411,393,411,393,411,393,410,393,410,393,409,393,408,393,408,393,408,394,408,394,408,394,407,394,407,396,407,398,407,399,407,399,407,399,407,401,408,405,408,409,408,411,408,411,408,411,408,411,408,412,408,413,408,414,409,414,410,414,410,414,410,414,411,415,411,415,411,415,412,415,412,415,412,416,413,416,413,416,413,416,417,416,420,416,421,417,421,417,421,418,422,418,422,418,423,417,423,405,423,392,423,392,422;456,422,455,422,455,422,454,422,454,422,454,422,454,422,453,422,453,422,452,422,452,421,452,421,452,421,451,421,451,421,450,421,450,421,450,421,450,420,450,420,449,420,448,420,448,420,448,420,448,419,448,419,448,419,448,419,448,418,448,418,448,417,448,417,448,417,448,417,448,416,448,415,448,414,448,414,449,414,449,414,449,413,449,412,449,411,449,411,449,411,449,411,450,411,450,410,450,409,450,409,452,409,453,409,454,409,454,409,454,409,454,410,455,410,456,410,456,410,457,410,457,411,457,411,458,411,459,411,460,411,460,411,460,411,460,412,461,412,461,412,462,412,462,412,462,412,462,412,463,412,464,412,464,412,464,412,464,412,465,412,466,412,467,412,468,412,468,412,468,412,469,412,470,412,471,412,472,412,472,413,472,413,473,413,473,413,474,413,475,414,475,414,475,415,475,415,475,415,475,415,476,415,476,416,476,416,475,417,475,417,475,417,475,417,475,418,475,419,475,419,474,420,474,420,474,421,474,421,474,421,473,422,473,422,472,422,472,422,472,422,472,422,470,422,467,422,464,422,462,422,462,423,462,423,461,423,459,423,457,423,456,423,456,423;10,422,10,422,10,422,9,422,8,421,8,420,8,419,8,419,9,419,9,419,10,419,10,418,10,418,11,418,11,418,11,418,12,417,12,417,12,416,13,416,13,416,13,416,14,416,14,416,14,415,15,415,15,415,15,415,16,415,16,414,16,414,17,414,17,414,17,414,18,413,18,413,18,412,19,412,19,412,19,412,20,412,20,412,20,411,21,411,21,411,21,411,22,411,22,410,22,410,23,410,23,410,24,410,24,409,25,409,25,408,25,408,25,408,26,408,27,409,27,410,27,410,27,410,27,410,27,410,28,410,28,411,28,411,28,412,28,412,28,412,28,412,28,412,28,413,28,414,29,414,29,414,30,415,30,415,30,416,30,416,30,416,30,416,30,416,30,417,30,417,30,418,31,418,31,418,31,418,31,418,31,419,31,420,32,420,32,420,32,421,32,422,31,422,29,422,21,422,14,422,10,422,10,422;181,422,181,422,180,422,180,422,179,421,179,420,179,419,179,419,179,419,180,419,180,419,181,418,181,418,181,418,182,418,182,418,182,417,183,417,183,416,183,416,184,416,184,416,184,416,185,416,185,415,185,415,186,415,186,415,186,415,187,414,187,414,187,414,188,414,188,414,188,413,189,413,189,412,189,412,190,412,190,412,190,412,191,412,191,411,191,411,192,411,192,411,192,411,193,410,193,410,193,410,194,410,194,410,195,409,195,409,195,408,196,408,196,408,197,408,198,409,198,410,198,410,198,410,198,410,198,410,198,410,198,411,198,411,198,412,199,412,199,412,199,412,199,412,199,413,199,414,200,414,200,414,200,415,200,415,200,416,200,416,201,416,201,416,201,416,201,417,201,417,201,418,201,418,201,418,202,418,202,418,202,419,202,420,202,420,203,420,203,421,202,422,202,422,200,422,191,422,185,422,181,422,181,422;352,422,351,422,351,422,350,422,350,421,350,420,350,419,350,419,350,419,350,419,351,419,351,418,351,418,352,418,352,418,352,418,353,417,353,417,353,416,354,416,354,416,354,416,355,416,355,416,355,415,356,415,356,415,356,415,357,415,357,414,357,414,358,414,358,414,358,414,359,413,359,413,359,412,360,412,360,412,360,412,361,412,361,412,361,411,362,411,362,411,362,411,363,411,363,410,363,410,364,410,365,410,365,410,366,409,366,409,366,408,367,408,367,408,367,408,368,409,368,410,368,410,368,410,369,410,369,410,369,410,369,411,369,411,369,412,369,412,369,412,370,412,370,412,370,413,370,414,370,414,371,414,371,415,371,415,371,416,371,416,371,416,371,416,372,416,372,417,372,417,372,418,372,418,372,418,372,418,372,418,372,419,372,420,373,420,374,420,374,421,373,422,373,422,371,422,362,422,355,422,352,422,352,422;90,418,90,418,91,418,92,418,93,417,93,417,93,417,94,417,95,417,96,417,97,417,97,417,97,416,98,416,100,416,102,416,103,416,103,416,103,415,103,416,104,416,105,417,105,418,104,418,104,419,102,419,97,419,90,419,90,419,90,418;260,418,260,418,262,418,263,418,264,417,264,417,264,417,264,417,266,417,267,417,268,417,268,417,268,416,269,416,270,416,273,416,273,416,274,416,274,415,274,416,275,416,276,417,276,418,275,418,275,419,273,419,267,419,260,419,260,419,260,418;431,418,431,418,433,418,433,418,434,417,434,417,434,417,435,417,436,417,437,417,438,417,438,417,438,416,439,416,441,416,443,416,444,416,444,416,444,415,445,416,445,416,446,417,446,418,446,418,445,419,444,419,438,419,431,419,431,419,431,418;7,409,7,409,9,409,10,409,10,409,10,409,10,408,12,408,14,408,17,408,17,408,18,409,18,409,19,410,19,410,19,410,20,410,20,410,20,411,19,411,19,411,19,411,18,411,18,412,18,412,17,412,17,412,17,412,16,412,16,413,16,413,15,414,15,414,15,414,14,414,14,414,14,415,13,415,13,415,13,415,12,415,12,416,12,416,11,416,11,416,11,416,10,416,10,417,9,417,9,418,8,418,7,418,7,414;178,409,178,409,180,409,180,409,181,409,181,409,181,408,182,408,184,408,188,408,188,408,189,409,189,409,189,410,190,410,190,410,190,410,190,410,190,411,190,411,190,411,189,411,189,411,189,412,188,412,188,412,188,412,187,412,187,412,187,413,186,413,186,414,186,414,185,414,185,414,185,414,184,415,184,415,184,415,183,415,183,415,183,416,182,416,182,416,182,416,181,416,181,416,181,417,180,417,180,418,179,418,178,418,178,414;348,409,348,409,350,409,351,409,352,409,352,409,352,408,353,408,355,408,358,408,359,408,359,409,359,409,360,410,360,410,361,410,361,410,361,410,361,411,361,411,360,411,360,411,359,411,359,412,359,412,358,412,358,412,358,412,357,412,357,413,357,413,356,414,356,414,356,414,355,414,355,414,355,415,354,415,354,415,354,415,353,415,353,416,353,416,352,416,352,416,352,416,351,416,351,417,351,417,350,418,349,418,348,418,348,414;30,413,30,412,30,412,30,411,29,411,29,411,29,411,29,411,29,410,29,410,29,410,30,410,30,410,31,410,31,410,31,410,31,410,32,410,33,410,34,411,34,411,34,412,31,414,31,414,31,414,31,414,30,413;201,413,200,412,200,412,200,411,200,411,200,411,200,411,200,411,200,410,200,410,200,410,201,410,201,410,202,410,202,410,202,410,202,410,202,410,203,410,204,411,204,411,204,412,202,414,202,414,202,414,201,414,201,413;371,413,371,412,371,412,371,411,371,411,371,411,370,411,370,411,370,410,370,410,370,410,371,410,372,410,372,410,372,410,372,410,373,410,373,410,374,410,375,411,375,411,375,412,373,414,372,414,372,414,372,414,372,413;131,411,130,411,130,411,128,411,128,411,128,410,128,409,130,407,132,407,133,407,134,408,134,409,134,410,133,411,133,411,132,412,131,412,131,411;302,411,301,411,300,411,299,411,299,411,299,410,299,409,301,407,302,407,304,407,304,408,304,409,304,410,304,411,304,411,303,412,302,412,302,411;472,411,472,411,471,411,470,411,470,411,470,410,470,409,472,407,473,407,474,407,475,408,475,409,475,410,475,411,474,411,474,412,472,412,472,411;160,410,159,410,159,410,159,410,158,409,158,409,158,408,157,408,157,408,157,408,156,408,156,407,155,407,154,406,154,406,154,406,154,406,154,406,154,406,153,406,153,406,152,406,152,405,152,405,152,405,152,405,151,405,151,405,150,405,150,405,150,404,150,404,150,404,149,404,147,402,147,401,147,401,147,401,147,401,147,401,148,401,148,400,148,400,148,400,148,400,148,400,148,399,148,399,148,398,148,398,149,398,149,398,150,397,150,397,150,396,151,396,152,396,154,396,154,396,155,397,155,397,155,398,156,398,157,398,158,398,158,398,158,399,159,399,159,399,159,399,160,399,161,400,161,401,162,402,162,402,162,402,163,402,163,402,164,403,164,403,164,406,164,409,164,410,162,410,162,410,162,410,162,410,162,410,161,410,161,410,160,410,160,410,160,410;330,410,330,410,330,410,329,410,329,409,329,409,328,408,328,408,328,408,327,408,327,408,326,407,326,407,325,406,325,406,324,406,324,406,324,406,324,406,324,406,324,406,323,406,323,405,323,405,323,405,322,405,322,405,321,405,321,405,321,405,321,404,321,404,320,404,320,404,319,404,319,403,318,402,317,401,318,401,318,401,318,401,318,400,318,400,318,400,319,400,319,400,319,399,319,399,319,398,319,398,319,398,320,398,320,397,321,397,321,396,321,396,323,396,324,396,325,396,325,397,325,397,326,398,327,398,328,398,328,398,329,398,329,399,329,399,329,399,330,399,330,399,331,400,332,401,333,402,333,402,333,402,334,402,334,402,335,403,335,403,335,406,335,409,334,410,333,410,333,410,332,410,332,410,332,410,332,410,331,410,331,410,330,410,330,410;501,410,501,410,500,410,500,410,499,409,499,409,499,408,498,408,498,408,498,408,497,408,497,407,496,407,496,406,495,406,495,406,495,406,495,406,495,406,495,406,494,406,494,406,494,405,494,405,494,405,493,405,493,405,492,405,492,405,492,405,492,404,491,404,491,404,491,404,490,404,489,403,488,402,488,401,489,401,489,401,489,401,489,400,489,400,489,400,489,400,489,400,490,399,490,399,490,398,490,398,490,398,490,398,491,397,491,397,492,396,492,396,494,396,495,396,495,396,496,397,496,397,497,398,498,398,498,398,499,398,499,398,499,399,500,399,500,399,500,399,501,399,502,400,503,401,503,402,503,402,504,402,504,402,505,402,505,403,506,403,506,406,506,409,505,410,504,410,503,410,503,410,503,410,503,410,502,410,502,410,501,410,501,410,501,410;46,409,43,409,38,409,33,409,30,409,30,409,30,408,29,408,29,408,27,408,27,405,27,402,27,401,27,401,27,401,28,401,28,400,28,400,29,398,30,398,30,398,31,398,31,399,31,399,31,399,32,399,33,399,34,399,34,399,34,400,34,400,34,399,34,399,35,399,36,399,38,399,38,399,39,398,39,398,39,398,40,398,40,398,41,397,41,397,42,396,44,396,44,397,44,397,45,398,46,398,46,398,46,398,46,399,46,399,47,399,48,399,49,399,50,399,50,399,50,400,50,400,50,400,50,400,50,401,50,401,50,401,50,402,50,402,50,404,50,404,50,405,51,405,51,405,51,406,51,406,51,406,51,406,52,406,52,407,51,407,51,407,51,407,51,407,51,408,50,408,50,409,49,409,49,410,47,410,46,410,46,409,46,409;99,409,98,409,98,409,97,409,96,409,96,409,96,408,95,408,95,408,94,408,93,408,93,408,93,408,93,408,92,408,92,408,92,407,92,407,92,407,91,407,91,407,90,407,90,407,90,406,90,406,89,406,89,406,89,406,89,405,89,405,89,404,89,404,89,404,89,404,90,404,90,403,90,402,90,402,90,401,91,401,91,400,91,400,91,400,91,399,92,399,92,399,92,398,92,398,92,398,92,397,93,397,93,397,94,396,94,396,94,396,94,395,94,395,95,395,95,394,95,394,95,394,98,391,98,391,99,391,99,391,99,391,99,390,100,390,101,391,101,392,102,392,102,392,103,392,104,394,104,395,104,395,104,396,105,396,105,396,106,397,106,397,106,398,106,398,106,399,107,399,107,399,107,400,107,400,107,400,108,401,108,401,108,401,108,403,108,405,108,406,108,406,107,406,107,406,107,406,106,407,106,407,105,407,104,407,103,407,103,408,103,408,102,408,102,408,102,408,101,408,101,409,101,410,99,410,99,409;216,409,213,409,209,409,204,409,201,409,201,409,201,408,200,408,199,408,198,408,198,405,198,402,198,401,198,401,198,401,198,401,198,400,198,400,200,398,201,398,201,398,202,398,202,399,202,399,202,399,203,399,204,399,204,399,204,399,204,400,205,400,205,399,205,399,206,399,207,399,208,399,209,399,209,398,209,398,210,398,211,398,211,398,212,397,212,397,212,396,215,396,215,397,215,397,215,397,215,398,216,398,216,398,216,398,217,398,217,398,217,399,217,399,218,399,219,399,220,399,220,399,220,399,220,400,220,400,221,400,221,400,221,401,221,401,220,401,220,402,220,402,220,404,220,404,221,405,221,405,222,405,222,406,222,406,222,406,222,406,222,406,222,407,222,407,222,407,222,407,222,407,222,408,221,408,221,409,220,409,220,410,218,410,217,410,216,409,216,409;270,409,269,409,268,409,267,409,267,409,267,409,267,408,266,408,265,408,264,408,264,408,264,408,264,408,263,408,263,408,262,408,262,407,262,407,262,407,262,407,261,407,260,407,260,407,260,406,260,406,260,406,260,406,260,406,260,405,260,405,260,404,260,404,260,404,260,404,260,404,260,403,260,402,260,402,261,401,261,401,262,400,262,400,262,400,262,399,262,399,263,399,263,398,263,398,263,398,263,397,264,397,264,397,264,396,264,396,264,396,264,395,265,395,265,395,266,394,266,394,266,394,268,391,269,391,269,391,270,391,270,391,270,390,271,390,272,391,272,392,273,392,273,392,273,392,275,394,275,395,275,395,275,396,276,396,276,396,276,397,276,397,276,398,276,398,277,399,277,399,278,399,278,400,278,400,278,400,278,401,279,401,279,401,279,403,279,405,279,406,278,406,278,406,277,406,277,406,277,407,276,407,276,407,275,407,274,407,274,408,274,408,273,408,273,408,273,408,272,408,272,409,271,410,270,410,270,409;387,409,384,409,379,409,374,409,372,409,372,409,372,408,371,408,370,408,368,408,368,405,368,402,368,401,369,401,369,401,369,401,369,400,369,400,370,398,371,398,372,398,372,398,372,399,372,399,373,399,373,399,374,399,375,399,375,399,375,400,375,400,375,399,375,399,376,399,377,399,379,399,379,399,380,398,380,398,381,398,381,398,382,398,382,397,383,397,383,396,386,396,386,397,386,397,386,397,386,398,386,398,387,398,387,398,387,398,388,398,388,399,388,399,388,399,389,399,391,399,391,399,391,399,391,400,391,400,391,400,392,400,392,401,391,401,391,401,391,402,391,402,391,404,391,404,392,405,392,405,392,405,392,406,392,406,392,406,393,406,393,406,393,407,393,407,392,407,392,407,392,407,392,408,392,408,391,409,391,409,390,410,389,410,388,410,387,409,387,409;440,409,440,409,439,409,438,409,438,409,438,409,438,408,437,408,436,408,435,408,434,408,434,408,434,408,434,408,434,408,433,408,433,407,433,407,433,407,432,407,432,407,431,407,431,407,431,406,431,406,431,406,431,406,430,406,430,405,430,405,430,404,430,404,431,404,431,404,431,404,431,403,431,402,431,402,432,401,432,401,432,400,432,400,432,400,432,399,433,399,433,399,434,398,434,398,434,398,434,397,434,397,435,397,435,396,435,396,435,396,435,395,436,395,436,395,436,394,436,394,436,394,439,391,440,391,440,391,440,391,440,391,440,390,441,390,442,391,443,392,443,392,443,392,444,392,446,394,446,395,446,395,446,396,446,396,447,396,447,397,447,397,447,398,447,398,448,399,448,399,448,399,448,400,448,400,448,400,449,401,449,401,450,401,450,403,450,405,449,406,449,406,449,406,448,406,448,406,448,407,447,407,446,407,445,407,445,407,445,408,444,408,444,408,444,408,443,408,443,408,443,409,442,410,440,410,440,409;18,407,18,406,18,402,18,398,19,398,21,398,21,398,22,398,22,399,23,399,23,400,23,400,23,400,24,401,24,401,24,401,24,402,24,402,24,403,25,403,25,403,25,403,25,404,25,404,25,404,25,404,24,404,24,404,24,405,24,405,24,406,25,406,25,406,25,406,25,406,25,407,25,407,25,407,24,407,24,407,24,408,24,408,24,408,22,408,19,408,19,408,18,407;188,407,188,406,188,402,188,398,190,398,192,398,192,398,193,398,193,399,194,399,194,400,194,400,194,400,194,401,195,401,195,401,195,402,195,402,195,403,195,403,195,403,196,403,196,404,196,404,195,404,195,404,195,404,195,404,195,405,195,405,195,406,195,406,195,406,196,406,196,406,196,407,195,407,195,407,195,407,195,407,195,408,195,408,195,408,192,408,190,408,190,408,189,407;359,407,359,406,359,402,359,398,361,398,362,398,363,398,363,398,364,399,364,399,364,400,364,400,364,400,365,401,365,401,366,401,366,402,366,402,366,403,366,403,366,403,366,403,366,404,366,404,366,404,366,404,366,404,366,404,366,405,366,405,366,406,366,406,366,406,366,406,366,406,366,407,366,407,366,407,366,407,366,407,366,408,366,408,365,408,363,408,361,408,360,408,360,407;6,406,6,405,6,404,6,403,6,402,7,402,7,402,7,402,7,401,7,400,7,400,9,400,9,400,10,400,10,400,10,400,10,400,11,400,11,400,12,399,12,399,12,399,13,399,14,399,16,399,16,402,16,407,16,407,13,407,12,407,12,407,12,407,12,407,11,407,10,407,8,407,8,407,7,407;117,407,117,407,116,407,116,407,115,407,115,406,115,406,114,406,114,406,114,406,113,405,113,405,111,403,113,400,115,400,116,400,116,400,116,400,116,400,116,400,117,400,117,400,118,399,118,399,118,399,118,399,118,399,118,399,119,399,119,398,119,398,120,398,120,398,121,398,121,397,121,397,121,397,121,397,122,397,122,397,122,397,122,397,122,396,123,396,124,396,125,396,126,396,126,396,126,395,126,395,126,396,126,396,127,396,127,396,129,396,131,398,131,400,131,400,131,401,131,401,132,401,132,402,131,403,130,403,130,404,129,404,129,404,129,404,129,404,129,404,129,404,128,404,128,404,127,405,127,406,126,406,125,407,125,407,124,407,124,407,124,407,124,407,123,408,121,408,118,408,117,407,117,407;177,406,177,405,177,404,177,403,177,402,177,402,177,402,178,402,178,401,178,400,178,400,179,400,180,400,181,400,181,400,181,400,181,400,182,400,182,400,182,399,182,399,182,399,183,399,185,399,187,399,187,402,187,407,187,407,184,407,183,407,182,407,182,407,182,407,181,407,180,407,179,407,178,407,178,407;288,407,287,407,287,407,287,407,286,407,286,406,286,406,285,406,285,406,285,406,284,405,284,405,282,403,283,400,286,400,286,400,287,400,287,400,287,400,287,400,288,400,288,400,288,399,288,399,288,399,288,399,289,399,289,399,290,399,290,398,290,398,291,398,291,398,291,398,292,397,292,397,292,397,292,397,292,397,293,397,293,397,293,397,293,396,294,396,294,396,295,396,296,396,296,396,296,395,297,395,297,396,297,396,297,396,298,396,300,396,302,398,302,400,302,400,302,401,302,401,302,401,302,402,301,403,301,403,300,404,300,404,300,404,300,404,300,404,300,404,299,404,299,404,299,404,298,405,297,406,296,406,296,407,295,407,295,407,295,407,295,407,295,407,293,408,291,408,289,408,288,407,288,407;348,406,348,405,348,404,348,403,348,402,348,402,348,402,348,402,348,401,348,400,348,400,350,400,351,400,352,400,352,400,352,400,352,400,352,400,353,400,353,399,353,399,353,399,354,399,355,399,358,399,358,402,358,407,357,407,355,407,354,407,353,407,353,407,353,407,352,407,351,407,349,407,349,407,348,407;458,407,458,407,458,407,457,407,457,407,457,406,456,406,456,406,456,406,455,406,455,405,454,405,453,403,454,400,456,400,457,400,458,400,458,400,458,400,458,400,458,400,459,400,459,399,459,399,459,399,459,399,459,399,460,399,460,399,461,398,461,398,461,398,462,398,462,398,462,397,462,397,462,397,462,397,463,397,463,397,464,397,464,397,464,396,464,396,465,396,466,396,467,396,467,396,467,395,467,395,467,396,467,396,468,396,469,396,470,396,472,398,472,400,472,400,472,401,473,401,473,401,473,402,472,403,472,403,471,404,471,404,470,404,470,404,470,404,470,404,470,404,470,404,469,404,469,405,468,406,467,406,466,407,466,407,466,407,466,407,466,407,466,407,464,408,462,408,460,408,458,407,458,407;74,406,72,406,68,406,64,406,62,405,62,405,61,404,61,404,62,404,62,404,62,403,62,403,62,402,65,400,66,400,66,400,66,399,66,399,66,399,67,399,67,399,68,399,68,399,69,398,69,398,69,398,70,398,70,398,71,397,71,397,72,396,72,396,74,396,75,396,76,396,76,396,76,396,77,396,78,396,79,396,80,395,80,395,80,395,81,395,82,395,82,395,83,395,83,395,83,394,83,394,84,394,84,394,84,394,84,394,84,393,87,393,88,394,88,394,88,395,88,395,88,396,88,396,89,396,89,396,89,397,89,398,89,398,89,399,89,399,90,399,90,401,89,401,88,401,88,402,88,403,88,403,88,404,88,404,88,404,88,404,88,404,88,404,87,405,87,405,86,406,86,406,80,406,76,406,74,406,74,406;245,406,243,406,239,406,234,406,233,405,233,405,232,404,232,404,233,404,233,404,233,403,233,403,233,403,234,402,234,401,235,400,236,400,236,400,237,400,237,399,237,399,237,399,237,399,238,399,238,399,239,399,239,398,239,398,240,398,241,398,241,398,242,397,242,397,242,396,243,396,244,396,245,396,246,396,246,396,246,396,247,396,249,396,250,396,251,395,251,395,251,395,251,395,252,395,253,395,254,395,254,395,254,394,254,394,254,394,255,394,255,394,255,394,255,393,258,393,258,394,259,394,259,395,259,395,259,396,259,396,259,396,259,396,260,397,260,398,260,398,260,399,260,399,260,399,260,401,260,401,259,401,259,402,259,403,259,403,259,404,259,404,258,404,258,404,258,404,258,404,258,405,257,405,257,406,256,406,251,406,247,406,245,406,245,406;416,406,413,406,410,406,405,406,404,405,403,405,403,404,403,404,403,404,403,404,404,403,404,403,404,403,404,402,405,401,406,400,407,400,407,400,407,400,408,399,408,399,408,399,408,399,408,399,409,399,410,399,410,398,410,398,411,398,411,398,412,398,412,397,413,397,413,396,413,396,415,396,416,396,417,396,417,396,417,396,418,396,419,396,421,396,422,395,422,395,422,395,422,395,423,395,424,395,424,395,424,395,424,394,424,394,425,394,425,394,426,394,426,394,426,393,428,393,429,394,429,394,430,395,430,395,430,396,430,396,430,396,430,396,430,397,430,398,430,398,430,399,431,399,431,399,431,401,430,401,430,401,430,402,430,403,430,403,429,404,429,404,429,404,429,404,429,404,429,404,428,405,428,405,427,406,427,406,421,406,418,406,416,406,416,406;51,403,51,401,52,400,52,399,53,399,53,399,53,399,54,398,55,397,57,395,59,395,61,395,62,395,62,395,62,395,62,396,62,396,63,396,63,396,63,396,63,396,64,396,65,396,67,396,68,396,68,397,68,397,67,398,67,398,67,398,65,399,64,400,62,402,61,403,61,403,61,403,60,403,60,404,60,404,59,404,59,404,58,404,58,404,58,405,58,405,57,405,55,405,53,405,52,405,52,404;221,403,221,401,222,400,223,399,223,399,224,399,224,399,225,398,226,397,228,395,230,395,231,395,232,395,232,395,232,395,232,396,233,396,233,396,234,396,234,396,234,396,235,396,236,396,238,396,238,396,238,397,238,397,238,398,238,398,237,398,236,399,235,400,233,402,232,403,231,403,231,403,231,403,231,404,230,404,230,404,229,404,229,404,229,404,229,405,229,405,228,405,226,405,223,405,223,405,222,404;392,403,392,401,393,400,393,399,394,399,394,399,394,399,395,398,397,397,398,395,401,395,402,395,403,395,403,395,403,395,403,396,404,396,404,396,404,396,404,396,404,396,405,396,407,396,409,396,409,396,409,397,409,397,409,398,408,398,408,398,407,399,405,400,404,402,402,403,402,403,402,403,401,403,401,404,401,404,400,404,400,404,400,404,400,404,400,405,400,405,398,405,397,405,394,405,394,405,393,404;146,404,146,404,145,404,144,404,144,403,143,403,143,403,143,402,143,402,144,401,146,401,146,402,146,402,146,403,146,403,147,404,147,404,147,404,146,404,146,404,146,404;167,403,166,403,166,403,166,403,165,402,165,402,164,401,163,400,163,400,163,400,162,400,161,399,160,398,160,398,159,398,159,398,159,397,159,396,159,394,159,393,160,393,161,393,163,395,163,396,163,396,163,396,163,396,163,396,164,396,164,397,164,397,164,398,166,398,167,398,168,398,168,398,168,398,168,398,168,398,169,398,170,400,170,401,170,402,170,402,170,402,170,402,170,403,170,403,170,404,169,404,169,404,168,404,167,404,167,404;317,404,316,404,316,404,315,404,314,403,314,403,314,403,314,402,314,402,315,401,316,401,316,402,316,402,316,403,317,403,318,404,318,404,317,404,317,404,317,404,317,404;338,403,337,403,337,403,337,403,336,402,335,402,334,401,334,400,334,400,333,400,333,400,332,399,331,398,330,398,330,398,330,398,330,397,330,396,330,394,330,393,331,393,331,393,334,395,334,396,334,396,334,396,334,396,334,396,334,396,334,397,334,397,334,398,336,398,337,398,338,398,338,398,338,398,338,398,339,398,340,398,341,400,341,401,341,402,341,402,341,402,340,402,340,403,340,403,340,404,340,404,339,404,339,404,338,404,338,404;488,404,487,404,486,404,486,404,485,403,485,403,484,403,484,402,485,402,485,401,487,401,487,402,487,402,487,403,488,403,488,404,488,404,488,404,488,404,488,404,488,404;508,403,508,403,508,403,507,403,507,402,506,402,505,401,504,400,504,400,504,400,503,400,503,399,502,398,501,398,501,398,500,398,500,397,500,396,500,394,501,393,501,393,502,393,504,395,504,396,504,396,504,396,505,396,505,396,505,396,505,397,505,397,505,398,507,398,508,398,509,398,509,398,509,398,509,398,509,398,510,398,512,400,512,401,512,402,511,402,511,402,511,402,511,403,511,403,511,404,511,404,510,404,509,404,509,404,509,404;136,403,135,403,135,403,134,403,133,402,133,401,133,401,133,400,133,400,132,400,132,400,132,399,132,399,132,398,132,398,131,398,131,398,132,398,132,398,132,397,132,397,132,396,135,394,136,394,136,394,137,393,137,393,137,393,137,393,138,393,139,393,140,393,140,393,140,392,140,392,141,392,143,392,143,392,143,393,143,393,143,394,143,394,143,394,144,395,144,397,144,399,143,400,143,400,143,400,143,400,143,401,143,401,141,403,140,403,140,403,140,403,140,403,140,403,139,404,138,404,136,404,136,403,136,403;306,403,306,403,305,403,305,403,304,403,304,402,304,402,304,401,304,401,304,401,303,400,303,400,303,400,303,400,303,399,303,399,303,398,302,398,302,398,302,398,302,398,303,398,303,397,303,397,303,396,306,394,307,394,307,394,308,393,308,393,308,393,308,393,309,393,310,393,310,393,310,393,310,392,311,392,312,392,313,392,314,392,314,393,314,393,314,394,314,394,314,394,314,395,314,397,314,399,314,400,314,400,314,400,314,400,314,401,314,401,312,403,311,403,311,403,310,403,310,403,310,403,309,404,308,404,307,404,306,403,306,403;477,403,476,403,476,403,476,403,475,403,475,402,474,402,474,401,474,401,474,401,474,400,474,400,474,400,474,400,474,399,474,399,473,398,473,398,473,398,473,398,473,398,473,398,474,397,474,397,474,396,476,394,477,394,478,394,478,393,478,393,478,393,479,393,480,393,480,393,481,393,481,393,481,392,482,392,483,392,484,392,484,392,484,393,484,393,484,394,485,394,485,394,485,395,485,397,485,399,485,400,485,400,484,400,484,400,484,401,484,401,483,403,482,403,481,403,481,403,481,403,481,403,480,404,479,404,478,404,477,403,477,403;51,398,51,398,50,398,50,398,50,398,50,398,50,398,49,398,48,398,47,398,47,397,47,397,46,396,46,396,46,396,45,396,44,395,44,395,44,394,44,394,44,394,44,394,44,393,44,392,44,391,44,390,44,390,44,390,44,389,44,389,44,389,45,388,45,388,46,387,46,387,50,387,53,387,54,387,54,387,54,387,54,388,55,388,55,388,56,388,56,388,56,388,56,388,57,388,57,388,58,388,58,389,58,389,58,390,58,390,59,390,59,391,59,391,59,391,58,392,58,392,57,392,55,394,55,395,55,396,55,396,54,396,54,396,53,397,53,398,51,399,51,399,51,399;107,398,107,397,107,397,107,396,107,396,106,395,105,395,105,394,106,394,107,393,110,393,110,394,110,394,110,394,112,394,113,394,114,394,114,395,114,395,114,395,114,395,115,395,115,395,115,396,115,397,114,398,113,398,113,398,112,398,112,398,112,398,112,398,112,398,111,398,111,398,111,399,111,399,108,399,107,398;116,398,116,398,116,398,116,398,116,398,116,399,116,399,116,399,116,399,116,399,116,399,116,399;145,398,145,396,145,395,146,395,146,395,147,395,149,395,149,395,148,397,147,397,147,398,147,398,147,399,146,399,145,398;222,398,221,398,221,398,220,398,220,398,220,398,220,398,220,398,219,398,218,398,218,397,217,397,217,396,216,396,216,396,216,396,215,395,215,395,215,394,215,394,215,394,214,394,214,393,214,392,214,391,214,390,215,390,215,390,215,389,215,389,215,389,215,388,216,388,216,387,217,387,221,387,223,387,225,387,225,387,225,387,225,388,226,388,226,388,226,388,226,388,226,388,227,388,227,388,228,388,228,388,228,389,228,389,228,390,229,390,229,390,230,391,230,391,230,391,229,392,228,392,227,392,226,394,226,395,226,396,225,396,225,396,225,396,224,397,223,398,222,399,222,399,222,399;278,398,278,397,278,397,278,396,277,396,277,395,276,395,276,394,277,394,277,393,280,393,280,394,280,394,281,394,282,394,283,394,284,394,284,395,284,395,284,395,285,395,286,395,286,396,285,397,285,397,284,398,284,398,283,398,283,398,283,398,283,398,283,398,282,398,282,398,282,398,282,399,282,399,278,399,278,398;286,398,286,398,287,398,287,398,287,398,287,399,287,399,287,399,287,399,286,399,286,399,286,399;315,398,315,396,316,395,316,395,317,395,318,395,320,395,320,395,319,397,318,397,318,398,318,398,318,399,316,399,316,398;392,398,392,398,392,398,391,398,391,398,391,398,391,398,390,398,390,398,389,398,388,397,388,397,388,396,387,396,387,396,386,396,386,395,386,395,386,394,385,394,385,394,385,394,385,393,385,392,385,391,385,390,385,390,385,390,386,389,386,389,386,389,386,388,386,388,387,387,387,387,391,387,394,387,396,387,396,387,396,387,396,388,396,388,397,388,397,388,397,388,397,388,397,388,398,388,399,388,399,388,399,389,399,389,399,390,400,390,400,390,400,391,400,391,400,391,399,392,399,392,398,392,396,394,396,395,396,396,396,396,396,396,395,396,395,397,394,398,393,399,392,399,392,399;448,398,448,397,448,397,448,396,448,396,447,395,447,395,447,394,447,394,448,393,451,393,451,394,451,394,452,394,453,394,454,394,455,394,455,395,455,395,455,395,456,395,456,395,456,396,456,397,455,397,455,398,454,398,454,398,454,398,454,398,454,398,453,398,453,398,452,398,452,398,452,399,452,399,449,399,449,398;457,398,457,398,457,398,457,398,458,398,458,399,458,399,457,399,457,399,457,399,457,399,457,399;486,398,486,396,487,395,487,395,488,395,489,395,490,395,491,395,489,397,489,397,488,398,488,398,488,399,487,399,487,398;-1,397,-1,397,-2,397,-3,397,-3,397,-3,397,-3,396,-4,396,-5,396,-6,396,-7,396,-7,396,-7,395,-7,395,-7,395,-8,394,-8,394,-8,394,-8,393,-9,392,-10,392,-11,390,-11,390,-11,388,-11,388,-11,387,-11,387,-11,387,-11,387,-11,386,-11,386,-10,386,-10,386,-9,386,-9,385,-9,385,-9,385,-7,385,-4,385,0,385,2,385,2,385,2,384,2,384,2,384,3,384,4,384,4,384,4,383,5,383,6,383,7,383,8,383,8,383,8,383,8,384,9,384,10,384,10,384,10,384,10,384,11,384,12,384,13,384,13,384,14,385,14,385,15,386,16,386,16,386,17,386,17,386,17,386,17,386,18,386,18,386,18,386,18,387,18,387,19,387,19,387,19,387,20,387,21,388,21,388,22,389,22,391,22,393,21,394,20,394,19,394,19,394,19,395,19,395,18,395,16,395,13,395,12,395,12,396,11,396,11,396,10,396,9,396,8,396,8,397,8,397,8,397,8,397,7,397,7,397,7,397,7,397,5,398,3,398,1,398,-1,397,-1,397;31,397,30,397,29,397,28,397,27,397,27,397,27,396,26,396,26,396,24,396,24,396,24,394,24,393,23,393,23,393,23,393,23,392,23,392,23,391,23,390,24,389,25,389,25,388,26,388,26,388,27,388,27,388,28,387,28,387,30,387,32,387,33,387,33,387,33,386,34,386,35,386,35,386,36,386,36,386,36,386,37,386,38,386,38,386,39,386,39,386,39,386,40,386,40,386,43,386,43,387,43,390,43,391,43,392,43,392,42,392,42,393,42,393,42,394,40,396,39,396,39,396,39,396,39,397,38,397,38,398,34,398,32,398,31,397,31,397;116,396,116,395,117,395,117,394,120,394,120,395,121,395,121,395,120,396,118,398,117,398,117,397;170,397,170,397,169,397,168,397,168,397,168,397,168,396,167,396,166,396,164,396,164,396,164,396,164,395,164,395,164,395,163,394,163,394,163,394,163,393,162,392,161,392,160,390,160,390,160,388,160,388,160,387,160,387,160,387,160,387,160,386,160,386,160,386,161,386,162,386,162,385,162,385,162,385,164,385,167,385,170,385,172,385,172,385,172,384,173,384,173,384,174,384,174,384,175,384,175,383,175,383,177,383,177,383,178,383,178,383,178,383,179,384,180,384,180,384,181,384,181,384,181,384,182,384,182,384,184,384,184,384,185,385,185,385,185,386,186,386,187,386,188,386,188,386,188,386,188,386,188,386,189,386,189,386,189,387,189,387,189,387,190,387,190,387,191,387,191,388,192,388,192,389,192,391,192,393,192,394,190,394,190,394,190,394,190,395,190,395,188,395,186,395,183,395,183,395,183,396,182,396,182,396,180,396,180,396,179,396,179,397,179,397,179,397,178,397,178,397,178,397,178,397,178,397,176,398,174,398,172,398,170,397,170,397;202,397,201,397,200,397,198,397,198,397,198,397,198,396,197,396,196,396,196,396,195,396,195,396,194,395,194,395,194,394,194,393,194,393,194,393,194,393,194,392,194,392,194,391,194,390,195,389,195,389,196,388,197,388,197,388,198,388,198,388,198,387,199,387,201,387,202,387,204,387,204,387,204,386,204,386,205,386,206,386,207,386,207,386,207,386,207,386,208,386,209,386,210,386,210,386,210,386,210,386,211,386,213,386,214,387,214,390,214,391,213,392,213,392,213,392,213,393,213,393,213,394,211,396,210,396,210,396,209,396,209,397,209,397,208,398,205,398,203,398,202,397,202,397;287,396,287,395,287,395,288,394,290,394,291,395,291,395,291,395,290,396,289,398,288,398,287,397;341,397,340,397,340,397,339,397,338,397,338,397,338,396,337,396,337,396,335,396,335,396,335,396,335,395,335,395,334,395,334,394,334,394,334,394,334,393,333,392,332,392,330,390,330,390,330,388,330,388,330,387,331,387,331,387,331,387,331,386,331,386,331,386,332,386,332,386,333,385,333,385,333,385,335,385,338,385,341,385,343,385,343,385,343,384,343,384,344,384,344,384,345,384,345,384,346,383,346,383,347,383,348,383,349,383,349,383,349,383,349,384,350,384,351,384,352,384,352,384,352,384,352,384,353,384,354,384,355,384,355,385,356,385,356,386,357,386,358,386,358,386,358,386,358,386,358,386,359,386,359,386,360,386,360,387,360,387,360,387,360,387,361,387,362,387,362,388,363,388,363,389,363,391,363,393,362,394,361,394,361,394,360,394,360,395,360,395,359,395,357,395,354,395,354,395,353,396,353,396,352,396,351,396,350,396,350,396,350,397,350,397,349,397,349,397,348,397,348,397,348,397,348,397,347,398,345,398,342,398,341,397,341,397;372,397,371,397,370,397,369,397,368,397,368,397,368,396,368,396,367,396,366,396,366,396,365,396,365,395,365,395,365,394,365,393,365,393,365,393,364,393,364,392,364,392,364,391,364,390,365,389,366,389,367,388,367,388,368,388,368,388,369,388,369,387,369,387,372,387,373,387,374,387,374,387,374,386,375,386,376,386,377,386,378,386,378,386,378,386,378,386,379,386,380,386,380,386,380,386,380,386,381,386,382,386,384,386,384,387,384,390,384,391,384,392,384,392,384,392,384,393,384,393,384,394,382,396,381,396,381,396,380,396,380,397,379,397,379,398,376,398,374,398,372,397,372,397;457,396,457,395,458,395,459,394,461,394,462,395,462,395,462,395,461,396,460,398,459,398,458,397;129,395,129,395,129,395,129,395,130,395,130,394,130,394,130,393,131,393,132,392,132,391,132,390,132,389,133,389,134,390,135,392,135,392,133,394,131,396,130,397,129,396;154,395,154,395,153,395,152,395,152,395,152,395,152,394,151,394,151,394,150,394,150,394,150,394,150,394,149,394,148,394,147,394,146,393,146,393,146,393,146,393,145,393,144,393,144,391,144,389,144,388,145,388,145,388,146,387,146,387,146,387,146,386,146,386,147,386,147,385,147,385,147,383,148,383,150,383,152,383,153,383,153,384,153,384,154,384,154,384,154,384,155,384,155,385,155,385,156,386,156,386,157,386,157,386,157,386,157,387,157,387,157,387,157,387,158,387,158,388,158,388,158,388,158,388,158,388,158,389,158,391,158,392,158,394,158,394,158,394,158,394,158,395,158,396,157,396,156,396,155,396,155,396,155,396;299,395,299,395,300,395,300,395,300,395,300,394,300,394,301,393,302,393,302,392,303,391,303,390,303,389,304,389,305,390,306,392,306,392,304,394,302,396,301,397,300,396;325,395,324,395,323,395,323,395,322,395,322,395,322,394,322,394,321,394,321,394,320,394,320,394,320,394,319,394,319,394,318,394,317,393,317,393,317,393,316,393,316,393,315,393,315,391,315,389,315,388,316,388,316,388,316,387,316,387,316,387,316,386,317,386,317,386,318,385,318,385,318,383,318,383,321,383,323,383,323,383,324,384,324,384,325,384,325,384,325,384,326,384,326,385,326,385,327,386,327,386,327,386,328,386,328,386,328,387,328,387,328,387,328,387,328,387,328,388,328,388,328,388,329,388,329,388,329,389,329,391,329,392,329,394,329,394,328,394,328,394,328,395,328,396,328,396,327,396,326,396,326,396,325,396;470,395,470,395,470,395,471,395,471,395,471,394,471,394,471,393,472,393,473,392,474,391,474,390,474,389,474,389,475,390,477,392,476,392,474,394,472,396,471,397,471,396;495,395,495,395,494,395,493,395,493,395,493,395,493,394,492,394,492,394,491,394,491,394,491,394,491,394,490,394,489,394,488,394,488,393,488,393,488,393,487,393,487,393,486,393,486,391,486,389,486,388,486,388,487,388,487,387,487,387,487,387,487,386,488,386,488,386,488,385,488,385,488,383,489,383,492,383,494,383,494,383,495,384,495,384,495,384,496,384,496,384,496,384,497,385,497,385,497,386,498,386,498,386,498,386,498,386,498,387,498,387,499,387,499,387,499,387,499,388,499,388,499,388,499,388,499,388,500,389,500,391,500,392,499,394,499,394,499,394,499,394,499,395,499,396,499,396,498,396,497,396,496,396,496,396;63,394,63,394,62,394,62,394,62,394,62,394,62,394,61,394,60,394,59,394,59,393,59,393,59,393,59,392,60,392,60,392,60,391,60,391,60,390,60,390,61,390,61,390,61,390,61,390,61,389,61,389,61,389,61,389,62,388,62,387,62,385,62,385,62,385,63,384,63,384,63,384,63,383,64,382,64,382,64,383,65,383,66,383,67,383,68,383,68,383,68,383,69,384,69,384,70,384,70,384,70,384,70,384,71,384,71,384,72,384,73,384,73,385,73,385,74,386,75,386,75,386,76,386,76,386,76,386,76,386,77,386,78,386,79,386,79,387,79,387,80,387,82,387,86,387,86,389,86,390,85,391,84,392,84,392,83,393,83,393,82,393,82,393,82,393,82,393,80,394,77,394,74,394,72,394,72,394,72,394,72,394,72,394,71,394,71,394,71,395,71,395,69,395,67,395,64,395,63,395,63,395;124,394,124,394,124,394,123,394,123,394,123,394,123,394,122,394,122,394,121,394,121,393,121,393,121,393,120,393,119,393,117,393,116,393,116,393,116,393,115,394,115,394,114,394,113,393,113,393,113,393,112,393,111,393,110,393,110,393,110,393,110,392,109,392,108,392,107,392,107,392,107,392,107,391,107,391,106,391,106,391,106,390,106,390,107,390,107,390,107,390,107,389,107,389,108,389,108,388,108,388,108,387,108,387,108,387,109,387,109,387,109,386,109,384,109,382,109,381,109,381,110,380,111,380,111,381,112,381,112,382,113,382,114,382,115,382,115,382,115,382,116,382,117,382,119,382,120,382,120,383,120,383,120,383,122,383,123,383,124,383,124,383,124,383,124,384,125,384,125,384,126,384,126,384,126,384,127,384,128,384,131,384,131,385,131,386,131,386,131,386,131,386,132,387,132,388,132,388,131,389,131,389,131,389,131,389,131,390,131,390,131,391,131,391,130,391,130,391,130,391,130,392,129,393,129,393,127,395,127,395,126,395,125,395,124,395,124,395;234,394,233,394,233,394,232,394,232,394,232,394,232,394,232,394,231,394,230,394,230,393,230,393,230,393,230,392,230,392,231,392,231,391,231,391,231,390,231,390,231,390,231,390,232,390,232,390,232,389,232,389,232,389,232,389,232,388,232,387,232,385,232,385,233,385,233,384,234,384,234,384,234,383,235,382,235,382,235,383,236,383,237,383,238,383,239,383,239,383,239,383,239,384,240,384,240,384,241,384,241,384,241,384,241,384,242,384,243,384,243,384,244,385,244,385,245,386,245,386,246,386,246,386,246,386,246,386,247,386,248,386,249,386,250,386,250,387,250,387,251,387,253,387,256,387,256,389,256,390,256,391,255,392,254,392,254,393,253,393,253,393,253,393,253,393,253,393,251,394,248,394,245,394,243,394,243,394,243,394,243,394,242,394,242,394,242,394,242,395,242,395,240,395,238,395,235,395,234,395,234,395;295,394,295,394,294,394,294,394,294,394,294,394,294,394,293,394,293,394,292,394,292,393,292,393,292,393,291,393,289,393,288,393,287,393,287,393,287,393,286,394,285,394,284,394,284,393,284,393,284,393,283,393,282,393,281,393,280,393,280,393,280,392,280,392,279,392,278,392,278,392,278,392,278,391,277,391,277,391,277,391,277,390,277,390,277,390,278,390,278,390,278,389,278,389,278,389,279,388,279,388,279,387,279,387,279,387,279,387,279,387,280,386,280,384,280,382,280,381,280,381,281,380,281,380,282,381,282,381,283,382,284,382,285,382,286,382,286,382,286,382,287,382,288,382,289,382,290,382,290,383,290,383,291,383,292,383,293,383,294,383,294,383,294,383,295,384,295,384,296,384,296,384,296,384,296,384,297,384,299,384,302,384,302,385,302,386,302,386,302,386,302,386,302,387,302,388,302,388,302,389,302,389,302,389,302,389,302,390,302,390,301,391,301,391,301,391,301,391,301,391,301,392,300,393,299,393,298,395,298,395,296,395,296,395,295,395,295,395;404,394,404,394,404,394,403,394,403,394,403,394,403,394,402,394,402,394,400,394,400,393,400,393,400,393,400,392,401,392,401,392,402,391,402,391,402,390,402,390,402,390,402,390,402,390,402,390,402,389,402,389,403,389,403,389,403,388,403,387,403,385,403,385,404,385,404,384,404,384,404,384,404,383,405,382,405,382,406,383,406,383,408,383,409,383,410,383,410,383,410,383,410,384,411,384,411,384,412,384,412,384,412,384,412,384,413,384,414,384,414,384,415,385,415,385,415,386,416,386,416,386,417,386,417,386,417,386,418,386,419,386,419,386,420,386,420,387,420,387,422,387,424,387,427,387,427,389,427,390,427,391,426,392,425,392,424,393,424,393,424,393,424,393,424,393,424,393,422,394,419,394,415,394,414,394,414,394,414,394,413,394,413,394,412,394,412,394,412,395,412,395,411,395,408,395,406,395,404,395,404,395;466,394,465,394,465,394,464,394,464,394,464,394,464,394,464,394,463,394,463,394,462,393,462,393,462,393,461,393,460,393,459,393,458,393,458,393,458,393,457,394,456,394,455,394,454,393,454,393,454,393,453,393,453,393,452,393,451,393,451,393,451,392,450,392,450,392,448,392,448,392,448,392,448,391,448,391,448,391,447,391,447,390,448,390,448,390,448,390,448,390,448,389,448,389,449,389,449,388,450,388,450,387,450,387,450,387,450,387,450,387,450,386,450,384,450,382,450,381,451,381,451,380,452,380,453,381,453,381,453,382,455,382,455,382,456,382,456,382,456,382,457,382,459,382,460,382,461,382,461,383,461,383,462,383,463,383,464,383,465,383,465,383,465,383,465,384,466,384,466,384,467,384,467,384,467,384,468,384,470,384,472,384,472,385,472,386,472,386,473,386,473,386,473,387,473,388,473,388,473,389,473,389,472,389,472,389,472,390,472,390,472,391,472,391,472,391,472,391,472,391,472,392,471,393,470,393,469,395,468,395,467,395,466,395,466,395,466,395;94,392,93,392,92,392,90,392,90,391,90,391,90,391,89,391,89,391,87,391,87,390,87,389,87,388,87,388,87,388,86,388,86,387,86,387,86,386,86,386,87,386,87,386,87,386,87,385,87,384,87,384,88,384,88,384,88,384,88,384,88,384,90,384,93,384,96,384,98,384,98,384,98,384,99,384,99,384,100,384,102,385,102,386,102,387,99,390,98,390,98,390,97,390,97,390,97,391,96,391,96,391,96,391,95,391,95,392,95,392,94,392,94,392;264,392,263,392,262,392,261,392,260,391,260,391,260,391,260,391,259,391,258,391,258,390,258,389,258,388,257,388,257,388,257,388,257,387,257,387,257,386,257,386,257,386,257,386,258,386,258,385,258,384,258,384,258,384,259,384,259,384,259,384,259,384,261,384,264,384,267,384,269,384,269,384,269,384,269,384,270,384,271,384,272,385,272,386,272,387,269,390,269,390,269,390,268,390,268,390,268,391,267,391,267,391,267,391,266,391,266,392,265,392,264,392,264,392;435,392,434,392,433,392,432,392,431,391,431,391,431,391,430,391,430,391,429,391,428,390,428,389,428,388,428,388,428,388,428,388,428,387,428,387,428,386,428,386,428,386,428,386,428,386,428,385,428,384,428,384,429,384,429,384,430,384,430,384,430,384,431,384,435,384,438,384,440,384,440,384,440,384,440,384,440,384,441,384,443,385,443,386,443,387,440,390,439,390,439,390,439,390,439,390,438,391,438,391,438,391,437,391,437,391,437,392,436,392,435,392,435,392;134,388,133,387,133,387,133,386,133,386,133,386,132,386,132,385,132,385,132,383,132,383,133,383,133,382,134,382,134,382,134,381,134,380,136,380,136,380,137,380,138,382,139,383,139,383,140,383,141,383,142,383,142,384,142,384,142,385,142,385,142,385,142,385,142,386,142,386,142,387,143,387,143,387,143,389,142,390,142,390,142,390,141,390,141,390,141,390,141,391,141,391,140,391,139,391,136,391,135,389;304,388,304,387,304,387,304,386,303,386,303,386,303,386,303,385,303,385,303,383,303,383,304,383,304,382,304,382,304,382,304,381,305,380,306,380,307,380,308,380,309,382,310,383,310,383,311,383,312,383,312,383,312,384,312,384,312,385,313,385,313,385,313,385,313,386,313,386,313,387,313,387,314,387,314,389,313,390,313,390,312,390,312,390,312,390,312,390,312,391,312,391,311,391,309,391,307,391,305,389;475,388,474,387,474,387,474,386,474,386,474,386,474,386,474,385,474,385,474,383,474,383,474,383,475,382,475,382,475,382,475,381,476,380,477,380,478,380,478,380,479,382,480,383,481,383,482,383,483,383,483,383,483,384,483,384,483,385,483,385,483,385,484,385,484,386,484,386,484,387,484,387,484,387,484,389,484,390,483,390,483,390,483,390,482,390,482,390,482,391,482,391,481,391,480,391,478,391,476,389;105,386,104,386,104,385,104,384,105,383,105,384,105,384,106,384,106,384,106,384,107,384,107,385,108,385,108,386,107,386,107,386,107,386,107,387,107,388,106,388,105,387;275,386,275,386,275,385,275,384,276,383,276,384,276,384,276,384,277,384,277,384,277,384,278,385,278,385,278,386,278,386,278,386,278,386,278,387,278,388,277,388,276,387;446,386,446,386,446,385,446,384,447,383,447,384,447,384,447,384,447,384,448,384,448,384,448,385,449,385,449,386,449,386,448,386,448,386,448,387,448,388,447,388,446,387;156,385,156,384,157,384,157,384,158,384,158,384,159,384,160,384,160,385,160,385,159,386,159,386,158,386,158,386,158,386,158,386,158,386,157,385;327,385,327,384,327,384,328,384,328,384,329,384,330,384,330,384,330,385,330,385,330,386,330,386,329,386,329,386,329,386,329,386,328,386,328,385;498,385,498,384,498,384,498,384,499,384,500,384,501,384,501,384,501,385,501,385,501,386,500,386,500,386,500,386,500,386,500,386,499,386,498,385;17,384,17,384,16,384,15,384,15,384,15,384,15,384,15,384,14,384,14,384,14,383,14,383,14,383,13,383,12,383,11,383,10,383,10,383,10,382,10,382,10,382,9,382,7,380,8,380,8,380,8,380,8,379,8,378,9,378,10,378,10,378,11,377,11,377,11,376,12,376,13,376,13,376,14,376,14,376,14,375,15,375,16,375,17,375,18,375,18,375,18,374,20,374,24,374,28,374,30,374,30,375,30,375,32,375,34,375,36,375,37,375,37,375,37,375,37,376,37,376,38,376,39,376,39,378,39,379,39,380,39,380,40,380,40,380,39,380,39,380,39,380,39,381,39,381,39,382,38,382,38,382,38,383,38,383,38,383,37,384,36,384,36,384,36,384,36,385,36,385,35,385,34,385,33,385,32,385,32,385,32,385,31,386,29,386,27,386,26,385,26,385,26,385,25,385,25,385,24,385,24,385,24,385,24,385,23,386,21,386,19,386,18,385,18,385;44,385,43,385,43,385,42,385,41,385,41,384,40,384,40,381,41,381,41,381,41,380,41,380,40,380,40,379,40,378,40,375,41,374,42,374,42,374,43,374,43,374,43,374,44,374,45,374,46,374,47,373,47,373,47,373,47,373,48,373,48,373,49,373,49,373,49,372,50,372,51,372,53,372,54,372,54,372,54,372,55,372,57,372,58,372,60,372,60,372,60,372,60,372,60,372,60,372,61,372,61,373,61,373,62,374,62,374,63,374,63,374,63,375,63,375,63,376,63,376,63,376,64,376,64,377,64,378,63,378,63,378,63,378,63,379,63,379,63,380,62,382,61,382,61,382,60,382,60,382,59,383,59,383,58,383,57,383,57,383,57,383,57,383,57,384,56,384,56,384,56,384,56,384,56,384,55,384,54,384,53,384,53,384,53,385,53,385,52,385,51,385,49,385,48,385,48,385,48,385,47,386,46,386,45,386,44,385,44,385;79,385,78,385,78,385,77,385,76,385,76,385,76,384,76,384,76,384,75,384,75,384,75,384,75,383,75,383,77,383,77,383,78,383,78,383,78,382,79,382,80,382,81,382,82,382,82,382,82,382,83,382,83,382,84,382,84,382,84,382,84,382,84,383,85,383,85,383,86,384,86,385,86,386,82,386,80,386,79,385,79,385;188,384,188,384,187,384,186,384,186,384,186,384,186,384,185,384,185,384,184,384,184,383,184,383,184,383,183,383,183,383,182,383,181,383,181,383,181,382,181,382,180,382,180,382,178,380,178,380,179,380,179,380,179,379,179,378,180,378,181,378,181,378,182,377,182,377,182,376,183,376,183,376,184,376,184,376,185,376,185,375,185,375,187,375,188,375,189,375,189,375,189,374,191,374,195,374,199,374,201,374,201,375,201,375,202,375,204,375,206,375,208,375,208,375,208,375,208,376,208,376,209,376,210,376,210,378,210,379,210,380,210,380,210,380,210,380,210,380,210,380,210,380,210,381,210,381,209,382,209,382,208,382,208,383,208,383,208,383,207,384,207,384,206,384,206,384,206,385,206,385,205,385,205,385,204,385,203,385,203,385,203,385,202,386,200,386,198,386,196,385,196,385,196,385,196,385,196,385,195,385,195,385,195,385,195,385,194,386,192,386,189,386,189,385,189,385;215,385,214,385,213,385,212,385,212,385,211,384,211,384,211,381,211,381,212,381,212,380,211,380,211,380,211,379,211,378,211,375,211,374,213,374,213,374,214,374,214,374,214,374,214,374,216,374,217,374,218,373,218,373,218,373,218,373,219,373,219,373,220,373,220,373,220,372,221,372,222,372,223,372,224,372,224,372,224,372,225,372,227,372,229,372,230,372,230,372,230,372,230,372,231,372,231,372,232,372,232,373,232,373,233,374,233,374,233,374,234,374,234,375,234,375,234,376,234,376,234,376,234,376,234,377,234,378,234,378,234,378,234,378,234,379,234,379,234,380,232,382,231,382,231,382,231,382,231,382,230,383,230,383,229,383,228,383,228,383,228,383,228,383,227,384,227,384,226,384,226,384,226,384,226,384,226,384,225,384,224,384,224,384,224,385,224,385,223,385,221,385,220,385,219,385,219,385,219,385,218,386,217,386,216,386,215,385,215,385;250,385,249,385,248,385,247,385,247,385,247,385,247,384,247,384,246,384,246,384,246,384,246,384,246,383,246,383,247,383,248,383,249,383,249,383,249,382,250,382,251,382,252,382,253,382,253,382,253,382,253,382,254,382,255,382,255,382,255,382,255,382,255,383,256,383,256,383,256,384,256,385,256,386,253,386,251,386,250,385,250,385;359,384,358,384,357,384,357,384,356,384,356,384,356,384,356,384,356,384,355,384,355,383,355,383,355,383,354,383,353,383,352,383,352,383,352,383,352,382,351,382,351,382,350,382,349,380,349,380,349,380,350,380,350,379,350,378,350,378,351,378,352,378,352,377,353,377,353,376,353,376,354,376,354,376,355,376,355,376,356,375,356,375,358,375,359,375,360,375,360,375,360,374,362,374,366,374,369,374,372,374,372,375,372,375,373,375,375,375,377,375,378,375,378,375,378,375,378,376,379,376,380,376,380,376,380,378,380,379,380,380,381,380,381,380,381,380,381,380,380,380,380,380,380,381,380,381,380,382,380,382,379,382,379,383,379,383,379,383,378,384,377,384,377,384,377,384,377,385,377,385,376,385,375,385,374,385,374,385,374,385,374,385,372,386,370,386,368,386,367,385,367,385,367,385,367,385,366,385,366,385,366,385,366,385,366,385,364,386,363,386,360,386,360,385,359,385;386,385,385,385,384,385,383,385,382,385,382,384,381,384,381,381,382,381,382,381,382,380,382,380,382,380,382,379,382,378,382,375,382,374,383,374,384,374,384,374,384,374,384,374,385,374,386,374,387,374,388,373,388,373,388,373,389,373,389,373,390,373,390,373,390,373,390,372,391,372,393,372,394,372,395,372,395,372,395,372,396,372,398,372,400,372,401,372,401,372,401,372,401,372,401,372,402,372,402,372,403,373,403,373,403,374,404,374,404,374,404,374,404,375,404,375,404,376,405,376,405,376,405,376,405,377,405,378,405,378,405,378,404,378,404,379,404,379,404,380,403,382,402,382,402,382,401,382,401,382,401,383,400,383,399,383,399,383,398,383,398,383,398,383,398,384,398,384,397,384,397,384,397,384,397,384,396,384,396,384,395,384,394,384,394,385,394,385,393,385,392,385,391,385,390,385,390,385,390,385,389,386,388,386,386,386,386,385,386,385;420,385,420,385,419,385,418,385,418,385,418,385,418,384,417,384,417,384,416,384,416,384,416,384,416,383,416,383,418,383,419,383,420,383,420,383,420,382,420,382,422,382,423,382,424,382,424,382,424,382,424,382,425,382,425,382,426,382,426,382,426,382,426,383,426,383,427,383,427,384,427,385,427,386,424,386,422,386,420,385,420,385;0,383,0,383,0,383,-1,383,-1,382,-2,382,-3,381,-3,380,-3,379,-3,378,-3,377,-3,377,-3,377,-3,376,-3,375,-3,374,-1,374,0,374,0,369,0,365,0,365,1,365,1,365,2,365,2,365,2,364,2,364,2,364,3,364,3,364,3,364,3,364,4,364,5,364,7,364,8,363,8,363,8,363,9,363,13,363,18,363,19,364,20,365,21,367,20,368,19,368,19,369,19,369,19,369,19,370,19,370,18,370,18,370,18,370,18,370,18,371,17,372,17,372,16,373,16,373,16,373,16,374,15,374,15,374,14,374,14,374,14,374,14,374,14,374,13,374,13,374,13,375,13,375,12,375,12,375,11,375,11,375,11,376,10,376,10,376,7,376,5,376,4,376,4,376,4,376,4,376,4,376,3,376,3,375,3,375,3,375,2,375,2,375,0,375,0,375,0,376,0,376,0,376,1,376,2,376,3,377,3,378,3,378,3,378,3,378,3,378,4,378,4,379,4,379,3,380,3,380,3,380,3,380,3,381,3,382,2,383,1,383,1,383,1,383,1,383,1,383,1,384,1,384,0,384,0,383,0,383;171,383,171,383,170,383,170,383,169,382,169,382,168,381,168,380,168,379,168,378,168,377,168,377,168,377,168,376,168,375,168,374,170,374,171,374,171,369,171,365,171,365,172,365,172,365,172,365,172,365,172,364,172,364,173,364,173,364,174,364,174,364,174,364,175,364,176,364,177,364,178,363,178,363,178,363,180,363,183,363,189,363,190,364,191,365,191,367,190,368,190,368,190,369,190,369,190,369,189,370,189,370,189,370,189,370,189,370,189,370,188,371,188,372,187,372,187,373,187,373,187,373,187,374,186,374,185,374,185,374,185,374,185,374,185,374,184,374,184,374,184,374,184,375,184,375,183,375,183,375,182,375,181,375,181,376,181,376,180,376,178,376,176,376,175,376,175,376,175,376,175,376,174,376,174,376,174,375,174,375,174,375,173,375,172,375,171,375,171,375,171,376,171,376,171,376,172,376,173,376,174,377,174,378,174,378,174,378,174,378,174,378,174,378,174,379,174,379,174,380,174,380,174,380,174,380,174,381,174,382,173,383,172,383,172,383,172,383,172,383,172,383,171,384,171,384,171,384,171,383,171,383;342,383,341,383,341,383,341,383,340,382,339,382,338,381,338,380,338,379,338,378,338,377,339,377,339,377,339,376,339,375,339,374,340,374,342,374,342,369,342,365,342,365,342,365,343,365,343,365,343,365,343,364,343,364,344,364,344,364,344,364,344,364,344,364,345,364,347,364,348,364,349,363,349,363,349,363,351,363,354,363,359,363,360,364,362,365,362,367,361,368,360,368,360,369,360,369,360,369,360,370,360,370,360,370,360,370,360,370,360,370,359,371,359,372,358,372,358,373,358,373,358,373,357,374,357,374,356,374,356,374,356,374,356,374,355,374,355,374,354,374,354,374,354,375,354,375,354,375,353,375,353,375,352,375,352,376,351,376,351,376,348,376,347,376,346,376,346,376,346,376,345,376,345,376,344,376,344,375,344,375,344,375,344,375,343,375,342,375,342,375,342,376,342,376,342,376,342,376,343,376,344,377,344,378,344,378,344,378,345,378,345,378,345,378,345,379,345,379,345,380,345,380,344,380,344,380,344,381,344,382,344,383,343,383,342,383,342,383,342,383,342,383,342,384,342,384,342,384,342,383,342,383;126,382,125,382,125,382,124,382,124,382,124,382,124,382,123,382,122,382,120,382,120,381,120,381,120,381,119,381,117,381,116,381,115,381,115,381,115,380,114,380,114,380,112,380,112,380,112,380,112,379,112,379,113,379,113,379,113,378,113,378,112,378,112,378,112,377,112,377,112,376,112,376,111,376,111,375,111,374,111,373,111,373,110,373,109,372,109,371,110,371,111,370,112,370,112,371,112,371,113,371,114,371,116,371,116,371,117,372,117,372,117,372,120,372,121,372,122,372,122,373,122,373,123,373,124,373,125,373,126,373,126,373,126,373,127,374,129,374,131,374,132,374,132,374,132,374,133,374,134,374,135,374,135,374,136,375,136,375,137,376,137,376,137,377,135,378,135,378,134,378,134,379,134,380,134,380,133,380,133,381,132,381,132,381,132,381,132,382,131,383,128,383,127,383,126,383,126,383;296,382,296,382,295,382,295,382,294,382,294,382,294,382,293,382,292,382,291,382,290,381,290,381,290,381,289,381,288,381,287,381,286,381,286,381,286,380,285,380,284,380,283,380,283,380,283,380,283,379,283,379,283,379,284,379,284,378,283,378,283,378,283,378,283,377,283,377,283,376,282,376,282,376,282,375,282,374,282,373,281,373,281,373,280,372,280,371,281,371,281,370,283,370,283,371,283,371,284,371,285,371,286,371,287,371,287,372,288,372,288,372,290,372,292,372,293,372,293,373,293,373,294,373,295,373,296,373,297,373,297,373,297,373,298,374,300,374,302,374,303,374,303,374,303,374,304,374,304,374,306,374,306,374,307,375,307,375,308,376,308,376,308,377,306,378,305,378,305,378,304,379,304,380,304,380,304,380,304,381,303,381,303,381,303,381,303,382,302,383,299,383,297,383,296,383,296,383;467,382,466,382,466,382,465,382,465,382,465,382,465,382,464,382,463,382,462,382,461,381,461,381,461,381,460,381,459,381,457,381,456,381,456,381,456,380,456,380,455,380,454,380,454,380,454,380,454,379,454,379,454,379,454,379,454,378,454,378,454,378,454,378,454,377,454,377,453,376,453,376,452,376,452,375,452,374,452,373,452,373,452,373,451,372,451,371,451,371,452,370,454,370,454,371,454,371,454,371,455,371,457,371,457,371,458,372,458,372,459,372,461,372,462,372,464,372,464,373,464,373,464,373,466,373,467,373,468,373,468,373,468,373,469,374,471,374,472,374,474,374,474,374,474,374,474,374,475,374,476,374,477,374,477,375,478,375,478,376,478,376,478,377,477,378,476,378,476,378,475,379,475,380,475,380,475,380,474,381,474,381,474,381,474,381,474,382,473,383,470,383,468,383,467,383,467,383;72,382,71,382,70,382,69,382,68,381,68,380,68,379,68,379,68,379,67,378,67,378,67,376,67,375,67,375,68,375,68,375,68,375,68,375,68,374,69,374,71,374,72,374,73,374,73,374,73,374,73,374,74,374,74,374,75,373,75,373,75,373,75,373,76,373,76,373,76,373,76,373,76,372,77,372,77,372,78,372,78,372,78,372,78,372,79,372,79,372,80,372,80,371,80,371,80,371,81,371,82,371,83,371,84,371,84,371,84,370,84,370,85,370,86,370,87,370,87,370,87,370,87,370,88,370,88,370,88,370,88,370,88,370,89,370,90,370,92,370,93,370,93,371,94,371,94,372,94,373,94,373,94,374,95,374,95,374,95,375,95,376,95,379,95,379,94,379,94,379,94,379,94,379,94,379,92,380,91,380,89,380,88,380,88,380,88,380,87,380,85,380,83,380,82,380,82,381,82,381,81,381,80,381,79,381,78,381,78,381,78,381,77,382,76,382,75,382,74,382,74,382,74,382,74,382,73,382,72,382,72,382,72,382;142,382,141,382,141,382,139,382,139,381,139,381,139,380,139,380,139,380,138,380,138,379,138,378,138,376,138,375,139,375,139,375,139,375,139,374,139,374,139,374,140,374,140,374,140,373,140,373,140,373,141,373,143,373,144,373,146,373,146,373,146,372,148,372,153,372,158,372,160,372,160,373,160,373,161,373,162,373,163,373,164,373,164,373,164,373,164,374,165,374,166,374,166,374,166,376,166,377,165,378,165,378,165,378,165,378,165,379,165,379,165,380,165,380,164,380,164,380,164,380,164,381,163,382,162,382,161,382,161,382,161,382,161,382,159,382,157,382,154,382,153,382,153,382,153,382,152,382,150,382,148,382,147,382,147,382,147,382,146,382,145,382,143,382,142,382,142,382;242,382,242,382,241,382,240,382,239,381,239,380,239,379,239,379,238,379,238,378,238,378,238,376,238,375,238,375,238,375,239,375,239,375,239,375,239,374,240,374,241,374,243,374,244,374,244,374,244,374,244,374,245,374,245,374,246,373,246,373,246,373,246,373,246,373,247,373,247,373,247,373,247,372,247,372,248,372,248,372,249,372,249,372,249,372,249,372,250,372,250,372,251,371,251,371,251,371,252,371,253,371,253,371,254,371,254,371,254,370,255,370,256,370,257,370,258,370,258,370,258,370,258,370,258,370,259,370,259,370,259,370,259,370,260,370,261,370,263,370,263,370,264,371,264,371,265,372,265,373,265,373,265,374,265,374,265,374,266,375,266,376,266,379,265,379,265,379,264,379,264,379,264,379,264,379,263,380,262,380,260,380,259,380,259,380,259,380,258,380,256,380,254,380,253,380,253,381,253,381,252,381,251,381,250,381,249,381,249,381,249,381,248,382,247,382,246,382,245,382,245,382,245,382,244,382,244,382,243,382,242,382,242,382;313,382,312,382,311,382,310,382,310,381,310,381,310,380,309,380,309,380,309,380,309,379,309,378,309,376,309,375,309,375,309,375,310,375,310,374,310,374,310,374,310,374,311,374,311,373,311,373,311,373,312,373,314,373,315,373,316,373,316,373,316,372,319,372,324,372,328,372,331,372,331,373,331,373,332,373,333,373,333,373,334,373,334,373,334,373,335,374,335,374,336,374,336,374,336,376,336,377,336,378,336,378,336,378,336,378,336,379,336,379,335,380,335,380,335,380,335,380,335,380,335,381,334,382,333,382,332,382,332,382,332,382,332,382,330,382,328,382,325,382,324,382,324,382,324,382,322,382,321,382,319,382,318,382,318,382,318,382,317,382,315,382,314,382,313,382,313,382;413,382,412,382,412,382,410,382,410,381,410,380,410,379,409,379,409,379,408,378,408,378,408,376,408,375,408,375,409,375,409,375,410,375,410,375,410,374,411,374,412,374,413,374,414,374,414,374,414,374,415,374,415,374,416,374,416,373,416,373,416,373,416,373,417,373,417,373,418,373,418,373,418,372,418,372,419,372,419,372,420,372,420,372,420,372,420,372,421,372,421,372,422,371,422,371,422,371,422,371,423,371,424,371,425,371,425,371,425,370,426,370,427,370,427,370,428,370,428,370,428,370,428,370,429,370,429,370,430,370,430,370,430,370,430,370,432,370,434,370,434,370,435,371,435,371,436,372,436,373,436,373,436,374,436,374,436,374,436,375,436,376,436,379,436,379,436,379,435,379,435,379,435,379,435,379,434,380,432,380,431,380,430,380,430,380,430,380,428,380,427,380,425,380,424,380,424,381,424,381,423,381,422,381,420,381,420,381,420,381,420,381,419,382,418,382,416,382,416,382,416,382,416,382,415,382,414,382,413,382,413,382,413,382;484,382,483,382,482,382,480,382,480,381,480,381,480,380,480,380,480,380,480,380,480,379,480,378,480,376,480,375,480,375,480,375,480,375,480,374,480,374,480,374,481,374,481,374,482,373,482,373,482,373,483,373,484,373,486,373,487,373,487,373,487,372,490,372,494,372,499,372,502,372,502,373,502,373,502,373,503,373,504,373,505,373,505,373,505,373,505,374,506,374,507,374,507,374,507,376,507,377,507,378,507,378,506,378,506,378,506,379,506,379,506,380,506,380,506,380,506,380,506,380,506,381,505,382,503,382,503,382,502,382,502,382,502,382,501,382,498,382,496,382,494,382,494,382,494,382,493,382,491,382,489,382,488,382,488,382,488,382,487,382,486,382,485,382,484,382,484,382;98,379,98,378,98,378,98,377,97,377,97,377,96,376,96,376,96,375,96,374,96,374,96,374,95,374,95,371,96,370,97,369,103,369,103,370,103,370,104,370,105,370,107,370,108,371,108,372,108,372,108,372,109,372,109,372,109,372,109,373,109,373,109,374,109,374,109,374,110,374,110,375,110,375,110,376,110,376,110,376,110,376,110,376,110,377,110,377,111,377,111,377,111,378,110,378,110,379,110,379,109,379,109,379,109,379,109,379,109,379,107,379,104,379,99,379,98,379,98,379;268,379,268,378,268,378,268,377,268,377,268,377,267,376,267,376,267,375,267,374,267,374,267,374,266,374,266,371,267,370,267,369,274,369,274,370,274,370,274,370,276,370,278,370,279,371,279,372,279,372,279,372,279,372,279,372,280,372,280,373,280,373,280,374,280,374,280,374,280,374,280,375,280,375,280,376,281,376,281,376,281,376,281,376,281,377,281,377,281,377,282,377,282,378,281,378,281,379,280,379,280,379,280,379,280,379,280,379,280,379,278,379,274,379,270,379,269,379,269,379;439,379,439,378,439,378,439,377,439,377,438,377,438,376,438,376,438,375,438,374,437,374,437,374,437,374,437,371,437,370,438,369,444,369,444,370,444,370,445,370,446,370,449,370,450,371,450,372,450,372,450,372,450,372,450,372,450,372,450,373,450,373,450,374,451,374,451,374,451,374,451,375,451,375,451,376,451,376,451,376,452,376,452,376,452,377,452,377,452,377,452,377,452,378,452,378,451,379,451,379,451,379,450,379,450,379,450,379,450,379,448,379,445,379,441,379,440,379,439,379;36,374,35,374,33,374,30,374,29,373,29,373,29,373,27,373,24,373,19,373,19,372,19,371,19,370,20,370,20,370,20,369,20,369,20,369,20,368,21,368,21,368,22,367,22,367,22,367,22,366,22,366,23,366,23,365,23,365,23,365,23,364,24,364,24,364,24,363,24,363,24,363,24,362,25,362,25,362,26,361,26,361,26,360,26,360,26,360,26,360,26,360,26,360,26,359,27,359,27,358,28,358,28,357,28,357,28,357,29,356,29,356,30,355,32,354,33,356,33,356,34,356,35,356,35,356,36,356,36,357,36,357,37,359,37,359,38,359,44,364,44,365,44,365,44,366,45,367,46,368,47,369,47,369,47,369,47,370,47,370,48,370,48,370,47,370,47,370,47,370,47,371,47,372,46,372,44,372,44,372,43,372,43,373,43,373,42,373,42,373,41,373,40,373,40,373,40,373,40,374,40,374,39,374,39,374,39,374,39,374,38,374,38,374,37,374,36,374,36,374;207,374,205,374,203,374,201,374,200,373,200,373,200,373,198,373,195,373,190,373,190,372,190,371,190,370,190,370,191,370,191,369,191,369,191,369,191,368,192,368,192,368,192,367,192,367,192,367,192,366,193,366,193,366,194,365,194,365,194,365,194,364,194,364,195,364,195,363,195,363,195,363,195,362,196,362,196,362,196,361,196,361,196,360,196,360,197,360,197,360,197,360,197,360,197,359,197,359,198,358,198,358,199,357,199,357,199,357,199,356,200,356,201,355,203,354,204,356,204,356,205,356,205,356,206,356,206,356,206,357,206,357,208,359,208,359,209,359,214,364,214,365,214,365,215,366,216,367,217,368,218,369,218,369,218,369,218,370,218,370,218,370,218,370,218,370,218,370,218,370,218,371,218,372,217,372,215,372,214,372,214,372,214,373,214,373,213,373,212,373,211,373,211,373,211,373,211,373,211,374,210,374,210,374,210,374,210,374,210,374,209,374,208,374,207,374,207,374,207,374;378,374,376,374,374,374,372,374,370,373,370,373,370,373,368,373,365,373,360,373,360,372,360,371,360,370,361,370,361,370,362,369,362,369,362,369,362,368,362,368,363,368,363,367,363,367,363,367,363,366,364,366,364,366,364,365,364,365,364,365,364,364,365,364,365,364,366,363,366,363,366,363,366,362,366,362,367,362,367,361,367,361,367,360,367,360,367,360,367,360,368,360,368,360,368,359,368,359,369,358,369,358,370,357,370,357,370,357,370,356,370,356,371,355,374,354,375,356,375,356,375,356,376,356,377,356,377,356,377,357,377,357,378,359,379,359,379,359,385,364,385,365,385,365,386,366,387,367,387,368,388,369,388,369,388,369,388,370,389,370,389,370,389,370,389,370,388,370,388,370,388,371,388,372,387,372,386,372,385,372,384,372,384,373,384,373,384,373,383,373,382,373,382,373,382,373,382,373,381,374,381,374,380,374,380,374,380,374,380,374,380,374,379,374,378,374,378,374,378,374;69,372,69,371,69,371,69,371,70,370,70,370,70,369,70,369,70,369,70,369,70,369,70,368,70,368,70,368,71,368,71,368,71,367,71,366,71,365,71,364,72,364,73,364,73,364,73,364,73,363,73,363,73,363,73,363,74,362,74,362,74,361,74,361,74,361,75,360,75,360,75,360,75,359,75,359,76,359,76,358,76,358,76,357,76,356,78,355,78,355,78,355,79,354,80,354,81,352,81,352,83,352,84,352,84,352,85,353,85,353,85,354,86,354,86,354,87,354,87,354,87,355,88,355,89,355,89,355,90,355,90,356,90,356,91,356,91,356,92,356,92,356,92,357,92,357,93,357,94,357,95,357,96,357,96,359,96,359,96,360,97,360,97,360,97,360,97,360,97,361,97,361,97,361,96,361,96,362,96,362,96,364,96,364,95,365,95,365,94,366,94,366,94,366,93,366,93,366,93,367,92,367,92,367,91,367,90,367,90,368,89,368,89,368,88,368,87,368,87,368,87,369,87,369,86,369,85,369,84,369,84,369,84,369,84,369,83,370,82,370,80,370,80,370,80,370,80,370,79,370,79,370,78,370,78,370,78,371,78,371,78,371,77,371,76,371,76,371,75,372,75,372,74,372,73,372,73,372,72,372,72,373,72,373,70,373,69,372;239,372,239,371,240,371,240,371,240,370,240,370,240,369,240,369,241,369,241,369,241,369,241,368,241,368,241,368,241,368,241,368,242,367,242,366,242,365,242,364,243,364,243,364,244,364,244,364,244,363,244,363,244,363,244,363,244,362,244,362,244,361,244,361,245,361,245,360,246,360,246,360,246,359,246,359,246,359,247,358,247,358,247,357,247,356,248,355,249,355,249,355,250,354,251,354,252,352,252,352,253,352,254,352,255,352,255,353,255,353,256,354,257,354,257,354,258,354,258,354,258,355,259,355,259,355,260,355,260,355,261,356,261,356,261,356,262,356,262,356,263,356,263,357,263,357,264,357,264,357,266,357,267,357,267,359,267,359,267,360,267,360,267,360,268,360,268,360,268,361,267,361,267,361,267,361,267,362,267,362,267,364,267,364,266,365,266,365,265,366,265,366,265,366,264,366,264,366,264,367,263,367,262,367,261,367,261,367,261,368,260,368,260,368,259,368,258,368,258,368,258,369,258,369,257,369,256,369,255,369,254,369,254,369,254,369,253,370,252,370,251,370,250,370,250,370,250,370,250,370,250,370,249,370,249,370,249,371,249,371,248,371,248,371,247,371,246,371,246,372,245,372,245,372,244,372,243,372,243,372,243,373,243,373,240,373,240,372;410,372,410,371,411,371,411,371,411,370,411,370,411,369,411,369,411,369,411,369,412,369,412,368,412,368,412,368,412,368,412,368,412,367,412,366,412,365,413,364,414,364,414,364,414,364,414,364,414,363,414,363,415,363,415,363,415,362,415,362,415,361,415,361,416,361,416,360,416,360,416,360,416,359,416,359,417,359,417,358,418,358,418,357,418,356,419,355,420,355,420,355,420,354,421,354,422,352,423,352,424,352,425,352,425,352,426,353,426,353,427,354,427,354,428,354,428,354,429,354,429,355,429,355,430,355,430,355,431,355,431,356,431,356,432,356,433,356,433,356,434,356,434,357,434,357,434,357,435,357,437,357,438,357,438,359,438,359,438,360,438,360,438,360,438,360,438,360,438,361,438,361,438,361,438,361,438,362,438,362,438,364,437,364,437,365,436,365,436,366,435,366,435,366,435,366,435,366,434,367,434,367,433,367,432,367,431,367,431,368,431,368,430,368,429,368,429,368,428,368,428,369,428,369,427,369,427,369,426,369,425,369,425,369,425,369,424,370,423,370,422,370,421,370,421,370,421,370,421,370,420,370,420,370,420,370,420,371,420,371,419,371,418,371,417,371,417,371,417,372,416,372,416,372,415,372,414,372,414,372,414,373,414,373,411,373,411,372;164,372,163,372,162,372,160,372,160,371,160,371,160,371,158,371,155,371,151,371,151,371,151,370,150,370,150,370,149,370,147,370,147,369,146,368,145,368,145,367,145,367,145,367,146,366,146,366,146,365,146,364,146,364,146,364,146,364,145,363,145,362,144,362,144,361,144,361,144,361,144,361,143,360,143,360,143,359,143,359,143,359,142,359,142,359,142,358,142,358,143,358,143,358,143,357,143,357,143,356,143,356,143,356,144,355,144,354,144,353,143,352,143,352,143,352,143,352,143,352,143,351,143,351,144,351,144,351,145,351,145,351,145,352,145,352,145,351,146,351,147,351,151,351,154,351,156,351,156,351,156,350,157,350,160,350,163,350,165,350,165,351,165,351,165,351,165,351,166,351,166,351,166,351,167,352,167,352,166,353,166,353,165,354,165,354,165,354,164,354,164,354,163,355,163,357,164,358,164,358,164,359,164,359,164,360,164,360,165,360,165,360,165,360,165,361,165,361,165,362,165,362,165,362,166,362,166,363,166,363,166,364,166,364,166,364,166,364,166,364,166,365,166,365,167,365,167,365,167,366,167,367,167,368,167,369,166,369,166,369,166,370,166,370,166,371,165,371,165,372,164,372,164,372,164,372;167,370,168,369,169,369,169,369,170,369,170,370,170,371,169,372,168,372,167,372,167,372,167,371;334,372,333,372,332,372,331,372,330,371,330,371,330,371,329,371,326,371,322,371,322,371,321,370,321,370,320,370,319,370,318,370,318,369,317,368,316,368,316,367,316,367,316,367,316,366,316,366,316,365,316,364,317,364,317,364,317,364,316,363,315,362,315,362,315,361,315,361,315,361,314,361,314,360,314,360,314,359,314,359,313,359,313,359,313,359,313,358,313,358,313,358,314,358,314,357,314,357,314,356,314,356,314,356,314,355,314,354,314,353,314,352,314,352,314,352,314,352,314,352,314,351,314,351,314,351,315,351,316,351,316,351,316,352,316,352,316,351,316,351,318,351,321,351,324,351,326,351,326,351,326,350,328,350,331,350,334,350,336,350,336,351,336,351,336,351,336,351,336,351,337,351,337,351,337,352,337,352,337,353,336,353,336,354,336,354,335,354,335,354,334,354,333,355,333,357,334,358,335,358,335,359,335,359,335,360,335,360,335,360,335,360,336,360,336,361,336,361,336,362,336,362,336,362,336,362,336,363,336,363,336,364,337,364,337,364,337,364,337,364,337,365,337,365,337,365,337,365,338,366,338,367,338,368,337,369,337,369,336,369,336,370,336,370,336,371,336,371,336,372,335,372,334,372,334,372;338,370,339,369,340,369,340,369,340,369,340,370,340,371,340,372,338,372,338,372,338,372,338,371;505,372,504,372,503,372,502,372,501,371,501,371,501,371,499,371,497,371,493,371,492,371,492,370,491,370,491,370,490,370,489,370,488,369,487,368,487,368,486,367,486,367,487,367,487,366,487,366,487,365,487,364,487,364,488,364,487,364,487,363,486,362,486,362,486,361,486,361,485,361,485,361,484,360,484,360,484,359,484,359,484,359,484,359,483,359,483,358,484,358,484,358,484,358,484,357,484,357,484,356,485,356,485,356,485,355,485,354,485,353,485,352,485,352,484,352,484,352,484,352,484,351,484,351,485,351,486,351,486,351,486,351,486,352,487,352,487,351,487,351,488,351,492,351,495,351,497,351,497,351,497,350,499,350,502,350,504,350,506,350,506,351,506,351,506,351,507,351,507,351,507,351,508,351,508,352,508,352,507,353,507,353,506,354,506,354,506,354,505,354,505,354,504,355,504,357,505,358,505,358,506,359,506,359,506,360,506,360,506,360,506,360,506,360,506,361,506,361,506,362,507,362,507,362,507,362,507,363,507,363,507,364,507,364,507,364,508,364,508,364,508,365,508,365,508,365,508,365,508,366,508,367,508,368,508,369,508,369,507,369,507,370,507,370,507,371,507,371,506,372,506,372,505,372,505,372;508,370,510,369,510,369,511,369,511,369,511,370,511,371,510,372,509,372,508,372,508,372,508,371;63,371,62,371,61,371,60,371,60,371,60,371,60,370,58,370,57,370,55,370,54,370,54,371,54,371,50,371,49,370,49,370,49,369,49,363,49,359,49,356,49,356,49,356,50,356,50,355,50,354,50,354,52,354,54,354,54,354,55,354,55,355,55,355,55,355,56,355,56,355,57,356,58,357,59,358,59,358,59,358,60,358,61,359,61,360,62,360,63,360,63,360,64,360,64,361,64,361,65,362,65,362,65,362,66,362,66,362,66,363,67,363,67,363,67,363,68,364,68,364,68,365,68,365,69,365,69,365,69,365,69,366,69,366,69,366,69,366,68,366,68,367,68,367,68,368,68,368,68,369,67,369,67,369,67,369,67,370,65,372,64,372,63,372,63,371,63,371;127,371,126,371,124,371,122,371,122,371,122,370,122,370,121,370,121,370,121,370,121,368,121,366,121,363,121,362,122,362,122,361,123,361,128,361,134,361,135,362,136,363,136,363,136,364,136,364,136,364,137,365,137,365,138,365,138,366,138,366,138,367,138,367,139,367,139,368,139,368,139,368,139,369,140,369,140,369,140,370,140,371,140,372,134,372,129,372,127,371,127,371;234,371,233,371,232,371,231,371,230,371,230,371,230,370,229,370,228,370,226,370,225,370,225,371,225,371,221,371,220,370,220,370,220,369,220,363,220,359,220,356,220,356,220,356,220,356,220,355,220,354,221,354,223,354,224,354,225,354,225,354,225,355,226,355,226,355,226,355,227,355,228,356,229,357,229,358,230,358,230,358,230,358,231,359,232,360,233,360,233,360,234,360,234,360,235,361,235,361,235,362,236,362,236,362,236,362,237,362,237,363,237,363,237,363,238,363,239,364,239,364,239,365,239,365,239,365,239,365,240,365,240,366,240,366,239,366,239,366,239,366,239,367,239,367,239,368,239,368,238,369,238,369,238,369,238,369,238,370,236,372,235,372,234,372,234,371,234,371;298,371,296,371,295,371,292,371,292,371,292,370,292,370,292,370,292,370,292,370,292,368,292,366,292,363,292,362,292,362,293,361,293,361,299,361,305,361,306,362,306,363,307,363,307,364,307,364,307,364,308,365,308,365,308,365,308,366,308,366,308,367,309,367,309,367,310,368,310,368,310,368,310,369,310,369,311,369,311,370,311,371,311,372,304,372,300,372,298,371,298,371;404,371,403,371,403,371,402,371,401,371,401,371,401,370,400,370,398,370,397,370,396,370,396,371,396,371,391,371,391,370,390,370,390,369,390,363,390,359,390,356,391,356,391,356,391,356,391,355,391,354,392,354,394,354,395,354,395,354,396,354,396,355,397,355,397,355,397,355,398,355,399,356,399,357,400,358,400,358,400,358,401,358,402,359,403,360,403,360,404,360,404,360,405,360,405,361,405,361,406,362,406,362,406,362,407,362,407,362,407,363,408,363,408,363,409,363,410,364,410,364,410,365,410,365,410,365,410,365,410,365,410,366,410,366,410,366,410,366,410,366,410,367,410,367,410,368,409,368,409,369,408,369,408,369,408,369,408,370,407,372,405,372,405,372,404,371,404,371;468,371,467,371,466,371,463,371,463,371,463,370,463,370,463,370,463,370,462,370,462,368,462,366,462,363,462,362,463,362,464,361,464,361,469,361,475,361,476,362,477,363,478,363,478,364,478,364,478,364,478,365,479,365,479,365,479,366,479,366,479,367,480,367,480,367,480,368,480,368,480,368,480,369,481,369,481,369,482,370,482,371,482,372,475,372,471,372,468,371,468,371;112,369,111,369,110,369,108,369,107,369,107,369,107,368,106,368,105,368,103,368,102,368,102,368,102,368,101,368,100,368,99,368,98,367,98,367,97,366,97,365,97,365,97,365,98,364,98,363,98,362,98,361,98,361,98,361,98,361,98,360,98,360,98,360,98,360,97,360,97,358,98,358,99,357,100,357,100,357,100,357,101,357,101,357,101,356,102,356,104,356,106,356,107,356,107,356,107,356,107,356,108,356,108,356,109,355,109,355,109,355,116,362,116,362,116,362,117,363,118,364,119,365,119,365,119,366,119,367,119,368,119,368,120,368,120,368,119,369,118,370,112,370,112,369;283,369,282,369,280,369,279,369,278,369,278,369,278,368,277,368,275,368,274,368,273,368,273,368,273,368,272,368,271,368,269,368,269,367,268,367,267,366,267,365,268,365,268,365,268,364,268,363,268,362,268,361,269,361,269,361,269,361,269,360,269,360,269,360,269,360,268,360,268,358,269,358,269,357,270,357,271,357,271,357,272,357,272,357,272,356,273,356,275,356,276,356,278,356,278,356,278,356,278,356,278,356,279,356,280,355,280,355,280,355,287,362,287,362,287,362,287,363,288,364,289,365,290,365,290,366,290,367,290,368,290,368,290,368,290,368,290,369,289,370,283,370,283,369;454,369,452,369,451,369,449,369,448,369,448,369,448,368,447,368,446,368,445,368,444,368,444,368,444,368,443,368,442,368,440,368,440,367,439,367,438,366,438,365,439,365,439,365,439,364,439,363,439,362,439,361,439,361,439,361,440,361,440,360,440,360,439,360,439,360,439,360,439,358,440,358,440,357,441,357,441,357,442,357,442,357,442,357,442,356,443,356,445,356,447,356,448,356,448,356,448,356,449,356,449,356,450,356,450,355,450,355,450,355,458,362,458,362,458,362,458,363,459,364,460,365,460,365,460,366,460,367,460,368,461,368,461,368,461,368,460,369,460,370,454,370,454,369;46,366,46,366,46,365,46,365,45,365,45,365,44,365,41,361,41,361,41,361,42,360,42,360,42,360,42,359,42,358,43,358,43,358,45,358,47,358,48,358,48,362,48,365,47,366,47,366,46,367,46,367,46,366;216,366,216,366,216,365,216,365,216,365,216,365,215,365,211,361,212,361,212,361,212,360,212,360,212,360,213,359,213,358,214,358,214,358,216,358,218,358,218,358,218,362,218,365,218,366,218,366,217,367,217,367,217,366;387,366,387,366,387,365,387,365,387,365,386,365,386,365,382,361,382,361,383,361,383,360,383,360,383,360,383,359,384,358,384,358,385,358,386,358,389,358,389,358,389,362,389,365,389,366,388,366,388,367,388,367,387,366;168,364,168,364,168,364,167,364,167,363,167,362,167,361,167,361,166,361,166,360,166,360,166,359,166,358,165,357,165,357,164,357,164,355,165,355,165,355,166,354,167,353,169,351,170,351,170,354,170,356,170,357,170,357,170,357,170,363,170,364,169,364,168,364,168,364;339,364,339,364,338,364,338,364,338,363,338,362,338,361,337,361,337,361,336,360,336,360,336,359,336,358,336,357,336,357,335,357,335,355,335,355,336,355,337,354,338,353,340,351,340,351,340,354,340,356,340,357,341,357,341,357,341,363,340,364,340,364,339,364,339,364;510,364,509,364,509,364,508,364,508,363,508,362,508,361,508,361,508,361,507,360,507,360,507,359,507,358,507,357,506,357,505,357,505,355,506,355,506,355,507,354,508,353,511,351,511,351,511,354,511,356,511,357,511,357,512,357,512,363,511,364,510,364,510,364,510,364;119,363,119,363,118,363,118,363,118,363,118,362,118,362,117,362,117,362,117,362,117,361,117,361,117,360,117,360,119,360,120,360,120,362,120,363,120,364,120,364,119,364,119,363,119,363;290,363,289,363,289,363,288,363,288,363,288,362,288,362,288,362,288,362,288,362,288,361,288,361,288,360,288,360,289,360,291,360,291,362,291,363,291,364,290,364,290,364,290,363,290,363;460,363,460,363,460,363,459,363,459,363,459,362,459,362,459,362,459,362,458,362,458,361,458,361,458,360,458,360,460,360,462,360,462,362,462,363,461,364,461,364,460,364,460,363,460,363;138,362,138,362,138,361,138,361,138,360,139,360,139,360,139,360,140,361,140,361,140,361,140,362,140,362,139,363,139,363,139,363,138,363,138,362;308,362,308,362,308,361,308,361,309,360,310,360,310,360,310,360,310,361,311,361,311,361,311,362,311,362,310,363,309,363,309,363,309,363,309,362;479,362,479,362,479,361,479,361,480,360,480,360,480,360,481,360,481,361,481,361,482,361,482,362,482,362,481,363,480,363,480,363,479,363,479,362;2,357,2,357,2,357,3,356,3,356,3,355,3,354,3,354,4,354,4,354,4,353,4,353,4,353,4,353,5,353,5,353,6,353,6,353,6,352,6,352,7,352,8,352,8,352,8,352,8,352,9,352,9,352,10,352,10,351,10,351,10,351,11,351,12,351,12,351,13,351,13,351,13,350,14,350,16,350,18,350,19,350,19,351,19,351,19,351,20,351,21,351,22,351,22,351,22,351,22,352,22,352,23,352,24,352,24,352,25,353,25,353,25,355,25,356,25,357,25,357,24,357,24,358,24,358,24,360,24,361,22,361,21,361,21,361,21,361,21,361,19,362,16,362,12,362,10,362,10,362,10,362,9,362,6,362,2,362,2,360;172,357,172,357,173,357,173,356,174,356,174,355,174,354,174,354,174,354,175,354,175,353,175,353,175,353,175,353,176,353,176,353,176,353,176,353,176,352,177,352,178,352,178,352,179,352,179,352,179,352,179,352,180,352,180,352,181,351,181,351,181,351,181,351,182,351,183,351,184,351,184,351,184,350,185,350,187,350,188,350,190,350,190,351,190,351,190,351,191,351,192,351,192,351,192,351,192,351,193,352,193,352,193,352,194,352,195,352,195,353,196,353,196,355,196,356,195,357,195,357,195,357,195,358,195,358,195,360,194,361,193,361,192,361,192,361,192,361,192,361,190,362,186,362,183,362,181,362,181,362,181,362,179,362,177,362,172,362,172,360;343,357,343,357,344,357,344,356,344,356,344,355,344,354,344,354,345,354,345,354,346,353,346,353,346,353,346,353,346,353,347,353,347,353,347,353,347,352,347,352,348,352,349,352,350,352,350,352,350,352,350,352,351,352,351,352,352,351,352,351,352,351,352,351,353,351,354,351,354,351,354,351,354,350,355,350,357,350,359,350,360,350,360,351,360,351,361,351,362,351,362,351,363,351,363,351,363,351,363,352,364,352,364,352,365,352,365,352,366,353,366,353,366,355,366,356,366,357,366,357,366,357,366,358,366,358,366,360,365,361,363,361,363,361,362,361,362,361,362,361,360,362,357,362,354,362,352,362,352,362,352,362,350,362,347,362,343,362,343,360;120,359,119,359,117,359,114,359,114,359,114,358,114,358,114,358,115,358,115,358,115,357,115,357,115,356,115,356,115,356,116,356,117,355,118,354,119,353,120,352,120,352,120,352,121,352,122,351,123,350,126,350,128,350,129,350,129,350,129,350,130,350,132,350,134,350,135,350,135,351,135,351,136,351,138,351,141,351,142,351,142,352,142,352,142,352,142,352,142,352,142,353,142,354,142,355,142,356,142,356,142,356,142,356,142,357,142,357,141,358,141,358,141,358,140,358,140,358,139,359,139,359,137,359,136,359,136,359,136,359,136,359,133,360,128,360,123,360,120,359,120,359;291,359,290,359,288,359,285,359,285,359,285,358,285,358,285,358,285,358,285,358,286,357,286,357,286,356,286,356,286,356,286,356,287,355,289,354,290,353,291,352,291,352,291,352,292,352,293,351,294,350,297,350,298,350,300,350,300,350,300,350,301,350,303,350,304,350,306,350,306,351,306,351,307,351,309,351,312,351,312,351,312,352,312,352,312,352,313,352,313,352,313,353,313,354,313,355,313,356,313,356,312,356,312,356,312,357,312,357,312,358,312,358,311,358,311,358,311,358,310,359,310,359,308,359,307,359,306,359,306,359,306,359,303,360,299,360,294,360,291,359,291,359;462,359,460,359,459,359,456,359,456,359,456,358,456,358,456,358,456,358,456,358,456,357,456,357,456,356,456,356,457,356,457,356,458,355,459,354,460,353,461,352,462,352,462,352,462,352,463,351,464,350,467,350,469,350,470,350,470,350,470,350,471,350,473,350,475,350,476,350,476,351,476,351,478,351,480,351,483,351,483,351,483,352,483,352,483,352,483,352,483,352,484,353,484,354,484,355,483,356,483,356,483,356,483,356,483,357,483,357,483,358,482,358,482,358,481,358,481,358,481,359,480,359,479,359,478,359,477,359,477,359,477,359,474,360,469,360,464,360,462,359,462,359;26,357,26,356,26,356,27,355,27,355,27,355,26,355,26,353,27,352,28,352,28,351,28,352,28,352,29,352,29,352,30,352,30,353,28,355,27,355,27,356,27,357,27,357,27,358,26,358,26,358,26,357,26,357;196,357,197,356,197,356,197,355,198,355,197,355,197,355,197,353,198,352,198,352,199,351,199,352,199,352,199,352,200,352,201,352,200,353,199,355,198,355,198,356,198,357,198,357,197,358,197,358,196,358,196,357,196,357;367,357,367,356,368,356,368,355,368,355,368,355,367,355,367,353,368,352,369,352,369,351,369,352,369,352,370,352,370,352,371,352,371,353,370,355,369,355,368,356,368,357,368,357,368,358,368,358,367,358,367,357,367,357;0,354,0,354,1,354,1,354,2,354,2,355,2,356,1,357,0,357,0,357,0,356,0,355;61,356,61,356,60,356,60,356,59,356,59,356,59,355,58,355,58,355,58,355,58,355,58,354,58,354,57,353,57,353,57,353,57,353,57,353,57,353,58,352,58,352,58,351,58,351,58,351,59,350,59,350,59,349,59,349,59,348,59,348,60,347,63,347,63,348,63,348,64,348,65,348,66,348,67,348,67,349,67,349,67,349,68,349,68,349,69,349,69,349,69,349,70,350,72,350,73,350,74,350,74,350,74,350,75,350,75,350,76,350,76,350,76,351,76,351,77,351,77,351,77,351,78,351,78,351,79,352,79,354,78,354,78,354,77,354,77,355,75,356,75,356,74,356,73,356,73,356,73,357,73,357,71,357,67,357,63,357,61,357,61,357;171,354,171,354,172,354,172,354,172,354,172,355,172,356,172,357,171,357,171,357,171,356,171,355;232,356,231,356,231,356,231,356,230,356,230,356,230,355,229,355,229,355,228,355,228,355,228,354,228,354,228,353,228,353,227,353,227,353,228,353,228,353,228,352,228,352,228,351,228,351,229,351,229,350,230,350,230,349,230,349,230,348,230,348,231,347,234,347,234,348,234,348,234,348,236,348,237,348,238,348,238,349,238,349,238,349,239,349,239,349,240,349,240,349,240,349,241,350,242,350,244,350,245,350,245,350,245,350,245,350,246,350,246,350,247,350,247,351,247,351,247,351,248,351,248,351,249,351,249,351,250,352,250,354,249,354,249,354,248,354,247,355,246,356,246,356,245,356,244,356,244,356,244,357,244,357,241,357,238,357,234,357,232,357,232,357;342,354,342,354,342,354,343,354,343,354,343,355,343,356,342,357,342,357,342,357,342,356,342,355;402,356,402,356,402,356,401,356,401,356,401,356,400,355,400,355,399,355,399,355,399,355,399,354,399,354,399,353,398,353,398,353,398,353,398,353,399,353,399,352,399,352,399,351,399,351,400,351,400,350,400,350,400,349,400,349,400,348,401,348,401,347,404,347,404,348,404,348,405,348,406,348,407,348,408,348,408,349,408,349,409,349,409,349,410,349,410,349,410,349,410,349,411,350,413,350,414,350,416,350,416,350,416,350,416,350,417,350,417,350,418,350,418,351,418,351,418,351,418,351,419,351,419,351,420,351,420,352,420,354,420,354,419,354,419,354,418,355,417,356,416,356,415,356,415,356,414,356,414,357,414,357,412,357,408,357,404,357,402,357,402,357;38,356,37,356,37,356,36,356,36,355,36,355,36,355,35,355,35,355,35,355,34,355,34,354,34,354,33,354,33,354,32,354,32,353,32,352,32,351,33,350,34,350,35,350,36,350,36,351,36,351,36,351,37,351,38,351,38,351,38,351,38,352,39,352,39,351,39,351,39,351,40,351,41,351,41,351,43,349,45,347,46,347,46,348,46,349,46,349,47,349,47,349,47,349,47,350,47,350,47,351,47,351,47,351,48,351,48,352,48,352,48,352,48,352,49,352,48,354,47,355,46,356,42,356,39,356,38,356,38,356;111,355,110,354,110,354,110,354,110,354,110,354,110,354,109,354,109,354,108,354,108,354,108,354,108,354,108,354,108,354,107,354,107,354,107,355,107,355,106,355,105,355,104,355,104,355,104,355,104,356,102,356,102,355,101,354,101,354,101,353,101,353,101,353,101,353,100,353,100,352,100,352,100,351,102,350,103,350,103,350,104,349,104,349,104,349,105,349,109,349,114,349,114,349,115,350,115,350,116,351,116,352,116,353,115,354,115,354,115,354,115,354,115,355,115,356,113,357,112,355;208,356,208,356,207,356,207,356,206,355,206,355,206,355,206,355,206,355,205,355,205,355,205,354,204,354,204,354,204,354,203,354,202,353,202,352,202,351,204,350,205,350,206,350,206,350,206,351,206,351,207,351,207,351,208,351,209,351,209,351,209,352,209,352,209,351,209,351,210,351,211,351,212,351,212,351,214,349,215,347,217,347,217,348,217,349,217,349,217,349,217,349,218,349,218,350,218,350,218,351,218,351,218,351,218,351,218,352,218,352,218,352,219,352,219,352,219,354,218,355,217,356,212,356,210,356,208,356,208,356;282,355,281,354,281,354,280,354,280,354,280,354,280,354,280,354,280,354,279,354,279,354,279,354,279,354,279,354,278,354,278,354,278,354,278,355,278,355,277,355,276,355,275,355,274,355,274,355,274,356,273,356,272,355,272,354,272,354,272,353,272,353,271,353,271,353,271,353,271,351,272,350,272,350,273,350,273,350,274,350,274,349,274,349,274,349,276,349,279,349,284,349,285,349,285,350,286,350,286,351,286,352,286,353,286,354,286,354,286,354,286,354,286,355,286,356,283,357,282,355;379,356,378,356,378,356,377,356,377,355,377,355,377,355,377,355,376,355,376,355,375,355,375,354,375,354,374,354,374,354,374,354,373,353,373,352,373,351,374,350,376,350,376,350,377,350,377,351,377,351,377,351,378,351,379,351,380,351,380,351,380,352,380,352,380,351,380,351,381,351,381,351,382,351,383,351,384,349,386,347,388,347,388,348,388,349,388,349,388,349,388,349,388,349,388,350,388,350,388,351,389,351,389,351,389,351,389,352,389,352,389,352,389,352,390,352,389,354,388,355,387,356,383,356,380,356,379,356,379,356;452,355,452,354,451,354,451,354,451,354,451,354,451,354,451,354,450,354,450,354,450,354,450,354,450,354,449,354,449,354,448,354,448,354,448,355,448,355,447,355,447,355,446,355,445,355,445,355,445,356,444,356,443,355,443,354,442,354,442,353,442,353,442,353,442,353,441,353,442,351,442,350,443,350,444,350,444,350,444,350,445,349,445,349,445,349,447,349,450,349,455,349,455,349,456,350,457,350,457,351,457,352,457,353,457,354,457,354,456,354,456,354,456,355,456,356,454,357,453,355;98,354,96,354,94,354,92,354,90,354,90,354,90,354,90,354,89,354,89,354,88,353,88,353,88,352,87,352,86,352,86,352,86,352,86,352,86,351,85,351,85,351,85,351,85,350,85,350,85,350,86,350,86,350,86,349,86,348,88,348,89,348,90,348,90,348,90,348,90,348,91,348,92,348,92,348,92,348,92,348,93,348,94,348,96,348,97,348,98,349,99,350,99,351,99,352,99,353,99,354,99,354,99,354,100,354,100,354,100,355,99,355,99,355,98,355,98,355,98,355;268,354,267,354,265,354,262,354,261,354,261,354,261,354,260,354,260,354,259,354,259,353,259,353,258,352,258,352,257,352,256,352,256,352,256,352,256,351,256,351,256,351,255,351,255,350,256,350,256,350,256,350,256,350,256,349,257,348,259,348,259,348,260,348,260,348,260,348,261,348,262,348,262,348,263,348,263,348,263,348,264,348,265,348,267,348,267,348,268,349,269,350,270,351,270,352,270,353,270,354,270,354,270,354,270,354,270,354,270,355,270,355,269,355,269,355,268,355,268,355;439,354,437,354,435,354,433,354,432,354,432,354,432,354,431,354,431,354,430,354,429,353,429,353,429,352,428,352,428,352,427,352,427,352,427,352,427,351,427,351,426,351,426,351,426,350,426,350,427,350,427,350,427,350,427,349,428,348,429,348,430,348,431,348,431,348,431,348,431,348,432,348,433,348,434,348,434,348,434,348,434,348,436,348,438,348,438,348,439,349,440,350,440,351,440,352,440,353,440,354,441,354,441,354,441,354,441,354,441,355,441,355,440,355,439,355,439,355,439,355;2,348,3,348,4,348,4,348,4,349,4,350,4,350,5,350,5,350,5,351,5,351,4,351,4,351,4,352,4,352,4,352,3,352,2,352,2,350;48,351,48,350,48,349,48,349,48,348,48,348,47,348,47,347,47,347,47,347,47,346,46,346,46,346,46,345,46,345,46,343,46,343,52,343,57,343,58,343,58,343,59,344,59,344,59,344,58,344,58,345,58,346,58,347,58,348,58,348,58,348,58,348,58,349,58,350,57,350,57,351,56,351,56,351,56,352,56,352,56,352,55,352,55,352,54,352,54,352,54,351,54,351,54,352,54,352,53,352,52,352,50,352,50,352,49,351;117,350,119,348,119,349,119,349,119,350,120,350,121,350,121,350,121,350,121,351,121,351,120,351,120,351,119,351,119,352,119,352,118,352,118,352,117,352,117,352,117,351;172,348,174,348,175,348,175,348,175,349,175,350,175,350,175,350,176,350,176,351,175,351,175,351,175,351,175,352,175,352,175,352,174,352,172,352,172,350;219,351,219,350,219,349,219,349,219,348,218,348,218,348,218,347,218,347,218,347,217,346,217,346,216,346,216,345,216,345,216,343,217,343,223,343,228,343,229,343,229,343,230,344,230,344,229,344,229,344,229,345,229,346,229,347,229,348,229,348,228,348,228,348,228,349,228,350,228,350,228,351,227,351,227,351,227,352,227,352,227,352,226,352,225,352,225,352,225,352,225,351,224,351,224,352,224,352,223,352,222,352,221,352,220,352,220,351;288,350,289,348,289,349,289,349,290,350,291,350,291,350,292,350,292,350,292,351,291,351,291,351,291,351,290,351,290,352,290,352,289,352,288,352,288,352,288,352,288,351;343,348,344,348,345,348,346,348,346,349,346,350,346,350,346,350,346,350,346,351,346,351,346,351,346,351,346,352,346,352,345,352,344,352,343,352,343,350;390,351,390,350,390,349,390,349,389,348,389,348,388,348,388,347,388,347,388,347,388,346,388,346,387,346,387,345,387,345,387,343,387,343,394,343,398,343,399,343,400,343,400,344,400,344,400,344,400,344,400,345,400,346,400,347,399,348,399,348,399,348,399,348,399,349,399,350,399,350,398,351,398,351,398,351,398,352,398,352,397,352,397,352,396,352,395,352,395,352,395,351,395,351,395,352,395,352,394,352,393,352,391,352,391,352,390,351;458,350,460,348,460,349,460,349,461,350,461,350,462,350,462,350,462,350,462,351,462,351,462,351,461,351,461,351,461,352,460,352,460,352,459,352,458,352,458,352,458,351;6,350,6,349,6,349,6,348,4,347,3,347,2,347,2,347,2,347,2,346,1,346,1,346,0,346,0,346,0,345,0,344,0,344,1,344,1,344,2,343,2,343,2,343,4,343,7,343,13,343,14,343,14,344,14,345,14,345,15,345,15,345,15,345,15,345,15,346,15,346,16,347,16,347,16,347,16,348,16,348,16,348,15,348,14,348,14,348,13,349,13,349,12,350,11,350,10,350,10,350,10,350,10,350,9,350,9,350,8,350,8,350,8,351,8,351,7,351,6,350;29,350,29,350,28,350,28,350,27,349,27,348,27,348,27,348,28,348,28,348,28,348,28,348,28,348,29,348,29,348,30,348,31,349,31,350,31,351,31,351,30,351,29,351,29,351,29,351;169,350,168,350,168,350,168,350,168,349,168,349,168,348,168,348,168,348,169,348,169,348,169,348,169,348,169,348,170,348,171,348,171,348,171,349,171,351,171,351,170,351,170,351,169,351,169,350;177,350,176,349,176,349,176,348,175,347,173,347,173,347,172,347,172,347,172,346,172,346,172,346,171,346,171,346,171,345,171,344,171,344,172,344,172,344,172,343,172,343,172,343,174,343,178,343,184,343,185,343,185,344,185,345,185,345,185,345,185,345,186,345,186,345,186,346,186,346,186,347,187,347,187,347,187,348,187,348,187,348,186,348,185,348,184,348,184,349,183,349,183,350,182,350,181,350,180,350,180,350,180,350,180,350,180,350,179,350,179,350,179,351,179,351,178,351,177,350;200,350,199,350,199,350,198,350,198,349,198,348,198,348,198,348,198,348,199,348,199,348,199,348,199,348,199,348,200,348,200,348,201,348,201,349,201,349,202,350,202,350,202,351,201,351,201,351,200,351,200,351,200,351;340,350,339,350,339,350,338,350,338,349,338,349,338,348,338,348,339,348,339,348,340,348,340,348,340,348,340,348,341,348,341,348,342,348,342,349,342,351,341,351,341,351,341,351,340,351,340,350;347,350,347,349,347,349,347,348,345,347,344,347,343,347,343,347,343,347,343,346,343,346,342,346,342,346,342,346,342,345,342,344,342,344,342,344,343,344,343,343,343,343,343,343,345,343,349,343,355,343,356,343,356,344,356,345,356,345,356,345,356,345,356,345,356,345,356,346,356,346,357,347,357,347,358,347,358,348,358,348,357,348,356,348,355,348,355,348,355,349,354,349,354,350,352,350,352,350,351,350,351,350,351,350,351,350,350,350,350,350,350,350,350,351,350,351,348,351,348,350;370,350,370,350,370,350,369,350,368,349,368,348,368,348,368,348,369,348,369,348,370,348,370,348,370,348,370,348,370,348,371,348,371,348,372,349,372,349,372,350,372,350,372,351,372,351,371,351,371,351,370,351,370,351;510,350,510,350,509,350,509,350,509,349,509,349,509,348,509,348,510,348,510,348,510,348,510,348,510,348,511,348,511,348,512,348,512,348,512,349,512,351,512,351,512,351,511,351,511,351,511,350;22,350,21,350,20,350,19,350,19,350,19,348,19,347,19,347,19,347,20,347,20,347,21,346,21,346,21,346,23,346,25,346,26,346,26,348,26,349,25,349,25,350,24,350,22,350,22,350;39,350,38,350,37,350,36,350,36,349,36,349,36,349,35,349,34,349,33,349,33,349,33,349,33,348,33,348,32,348,32,348,31,348,31,348,31,347,30,347,30,347,28,347,27,346,27,345,27,344,27,344,28,344,30,344,30,344,31,344,31,343,31,343,33,343,33,343,34,343,34,343,34,342,36,342,38,342,40,342,42,342,42,343,42,343,42,343,42,343,43,343,43,343,43,343,43,344,43,344,44,345,45,345,44,346,43,348,42,349,41,350,41,350,40,350,40,350,40,350,40,350,40,350,40,350,39,350,39,350,39,350;145,350,144,350,143,350,140,350,140,349,140,348,140,347,141,347,141,347,138,344,137,344,137,344,137,344,137,344,137,343,137,343,151,343,165,343,166,344,167,345,167,347,166,348,166,348,166,349,166,349,166,349,165,350,156,350,150,350,146,350,146,350,146,350,146,350,146,350,145,350,145,350,145,350;192,350,192,350,191,350,190,350,190,350,190,348,190,347,190,347,190,347,190,347,191,347,191,346,192,346,192,346,193,346,196,346,196,346,196,348,196,349,196,349,196,350,195,350,192,350,192,350;210,350,209,350,208,350,207,350,206,349,206,349,206,349,206,349,205,349,204,349,204,349,204,349,204,348,203,348,203,348,203,348,202,348,202,348,202,347,201,347,200,347,199,347,198,346,198,345,198,344,198,344,199,344,200,344,201,344,201,344,202,343,202,343,203,343,204,343,205,343,205,343,205,342,206,342,209,342,211,342,212,342,212,343,212,343,212,343,213,343,213,343,214,343,214,343,214,344,214,344,214,345,215,345,215,346,213,348,213,349,212,350,211,350,211,350,211,350,211,350,211,350,211,350,210,350,210,350,210,350,210,350;316,350,315,350,313,350,311,350,311,349,311,348,311,347,311,347,312,347,309,344,308,344,308,344,308,344,308,344,308,343,308,343,322,343,336,343,337,344,338,345,338,347,337,348,336,348,336,349,336,349,336,349,336,350,327,350,320,350,317,350,317,350,317,350,317,350,316,350,316,350,316,350,316,350;363,350,362,350,362,350,360,350,360,350,360,348,360,347,360,347,361,347,361,347,362,347,362,346,362,346,363,346,364,346,366,346,367,346,367,348,367,349,367,349,366,350,366,350,363,350,363,350;380,350,379,350,379,350,378,350,377,349,377,349,377,349,376,349,376,349,375,349,374,349,374,349,374,348,374,348,374,348,373,348,373,348,373,348,372,347,372,347,371,347,370,347,368,346,368,345,368,344,369,344,370,344,371,344,371,344,372,344,372,343,373,343,374,343,375,343,376,343,376,343,376,342,377,342,379,342,381,342,383,342,383,343,383,343,383,343,384,343,384,343,384,343,384,343,384,344,384,344,385,345,386,345,386,346,384,348,383,349,382,350,382,350,382,350,382,350,382,350,382,350,381,350,381,350,380,350,380,350,380,350;486,350,485,350,484,350,482,350,482,349,482,348,482,347,482,347,482,347,479,344,479,344,478,344,478,344,478,344,478,343,478,343,492,343,507,343,507,344,508,345,509,347,508,348,507,348,507,349,507,349,507,349,506,350,497,350,491,350,488,350,488,350,488,350,487,350,487,350,486,350,486,350,486,350;78,348,78,347,78,347,78,346,77,346,77,346,77,346,77,345,77,344,77,343,77,343,78,343,78,343,79,343,79,343,79,342,81,342,84,342,90,342,90,343,90,344,88,346,87,346,87,346,87,346,87,346,86,347,86,347,85,347,85,347,85,347,85,347,85,347,85,348,84,348,84,348,84,348,84,348,84,348,83,348,83,348,82,348,81,348,81,349,81,350,79,350,78,349;248,348,248,347,248,347,248,346,248,346,248,346,248,346,248,345,248,344,248,343,248,343,249,343,249,343,250,343,250,343,250,342,252,342,255,342,260,342,260,343,260,344,259,346,258,346,258,346,257,346,257,346,257,347,256,347,256,347,256,347,256,347,256,347,256,347,255,348,255,348,254,348,254,348,254,348,254,348,254,348,253,348,253,348,252,348,252,349,251,350,250,350,249,349;419,348,419,347,419,347,419,346,419,346,419,346,418,346,418,345,418,344,418,343,418,343,419,343,420,343,420,343,420,343,420,342,422,342,426,342,431,342,431,343,431,344,430,346,429,346,429,346,428,346,428,346,428,347,427,347,427,347,426,347,426,347,426,347,426,347,426,348,426,348,425,348,425,348,425,348,425,348,424,348,424,348,423,348,423,348,423,349,422,350,421,350,420,349;122,348,122,348,121,348,120,348,120,348,119,348,119,347,118,347,118,347,118,347,118,347,118,346,118,346,117,346,117,346,117,346,117,345,117,345,117,344,117,344,118,344,118,344,119,344,119,344,120,343,120,343,125,343,128,343,130,343,130,343,130,343,130,344,132,344,133,344,134,344,134,344,134,344,134,344,134,344,135,344,136,344,136,345,136,345,137,346,137,346,138,346,139,346,139,347,139,348,138,348,136,348,135,348,134,348,134,348,134,348,133,348,132,348,131,348,130,348,130,348,130,348,129,348,127,348,125,348,124,348,124,349,124,349,124,349,123,349,123,349,122,349,122,349;293,348,292,348,292,348,291,348,290,348,290,348,290,347,289,347,289,347,288,347,288,347,288,346,288,346,288,346,288,346,288,346,288,345,288,345,288,344,288,344,288,344,289,344,290,344,290,344,290,343,291,343,295,343,298,343,300,343,300,343,300,343,301,344,302,344,303,344,304,344,304,344,304,344,305,344,305,344,306,344,306,344,307,345,307,345,307,346,308,346,309,346,310,346,310,347,310,348,309,348,307,348,306,348,305,348,305,348,305,348,304,348,303,348,302,348,301,348,301,348,301,348,300,348,298,348,296,348,295,348,295,349,295,349,294,349,294,349,293,349,293,349,293,349;464,348,463,348,462,348,461,348,461,348,461,348,460,347,460,347,459,347,459,347,459,347,459,346,459,346,459,346,459,346,458,346,458,345,458,345,458,344,458,344,459,344,460,344,460,344,461,344,461,343,461,343,466,343,469,343,471,343,471,343,471,343,472,344,473,344,474,344,475,344,475,344,475,344,475,344,476,344,476,344,477,344,477,345,477,345,478,346,478,346,479,346,480,346,480,347,480,348,479,348,477,348,476,348,476,348,476,348,476,348,475,348,474,348,472,348,472,348,472,348,472,348,470,348,469,348,467,348,466,348,466,349,466,349,465,349,465,349,464,349,464,349,464,349;16,346,16,345,16,345,16,344,16,344,17,344,17,344,18,344,18,345,19,345,19,346,18,346,18,346,18,346,18,347,18,347,17,347,17,346;67,346,66,346,65,346,64,346,64,346,64,346,64,346,63,346,63,346,63,346,62,345,62,345,61,344,62,344,64,344,65,344,66,343,66,343,67,343,67,342,67,342,66,342,66,342,66,342,66,342,68,342,71,342,75,342,75,343,75,345,74,346,73,346,72,346,72,346,72,346,72,346,71,346,71,346,70,346,70,346,70,347,70,347,69,347,69,347,68,347,67,347,67,347;88,346,88,346,89,346,89,346,90,345,91,344,91,343,92,343,92,343,93,343,93,343,93,342,93,342,93,342,93,342,93,343,94,343,94,343,95,343,96,344,96,345,96,345,95,346,95,346,94,347,92,347,91,346,91,346,91,346,91,346,91,347,90,347,89,347,88,347,88,347,88,346;97,346,97,344,98,343,98,342,106,342,114,342,115,343,116,344,116,345,115,345,115,345,115,345,115,345,115,347,114,347,106,347,99,347,98,347,97,346;187,346,187,345,187,345,187,344,187,344,188,344,188,344,189,344,189,345,190,345,190,346,189,346,188,346,188,346,188,347,188,347,188,347,187,346;238,346,237,346,236,346,235,346,234,346,234,346,234,346,234,346,234,346,233,346,233,345,233,345,232,344,233,344,235,344,236,344,237,343,237,343,238,343,238,342,237,342,237,342,237,342,237,342,237,342,239,342,241,342,246,342,246,343,246,345,245,346,243,346,243,346,242,346,242,346,242,346,242,346,242,346,241,346,241,346,241,347,241,347,240,347,239,347,238,347,238,347,238,347;259,346,259,346,259,346,260,346,260,345,261,344,262,343,263,343,263,343,263,343,264,343,264,342,264,342,264,342,264,342,264,343,264,343,265,343,266,343,266,344,266,345,266,345,266,346,266,346,265,347,262,347,262,346,262,346,262,346,262,346,262,347,261,347,260,347,259,347,259,347,259,346;267,346,267,344,268,343,269,342,277,342,285,342,285,343,286,344,286,345,286,345,286,345,286,345,286,345,286,347,285,347,276,347,270,347,268,347,268,346;358,346,358,345,358,345,358,344,358,344,358,344,359,344,359,344,360,345,360,345,360,346,360,346,359,346,359,346,359,347,359,347,358,347,358,346;408,346,407,346,407,346,406,346,405,346,405,346,405,346,405,346,404,346,404,346,404,345,403,345,402,344,403,344,406,344,407,344,407,343,408,343,408,343,408,342,408,342,408,342,408,342,408,342,408,342,409,342,412,342,416,342,416,343,416,345,416,346,414,346,413,346,413,346,413,346,413,346,413,346,412,346,412,346,412,346,412,347,412,347,411,347,410,347,409,347,408,347,408,347;430,346,430,346,430,346,430,346,431,345,432,344,433,343,433,343,434,343,434,343,434,343,434,342,434,342,435,342,435,342,435,343,435,343,435,343,436,343,437,344,437,345,437,345,437,346,436,346,436,347,433,347,433,346,433,346,432,346,432,346,432,347,432,347,431,347,430,347,430,347,430,346;438,346,438,344,439,343,440,342,448,342,455,342,456,343,457,344,457,345,457,345,456,345,456,345,456,345,456,347,456,347,447,347,441,347,439,347,439,346;169,345,169,345,169,345,169,345,170,345,170,345,170,345,169,346,169,346,169,346,169,345,169,345;340,345,340,345,340,345,340,345,340,345,340,345,340,345,340,346,340,346,340,346,340,345,340,345;510,345,510,345,511,345,511,345,511,345,511,345,511,345,511,346,511,346,510,346,510,345,510,345;21,344,20,344,18,344,15,344,15,343,15,342,23,342,27,342,30,342,30,342,30,342,29,343,28,343,27,343,26,343,26,344,25,344,25,344,23,344,22,344,21,344,21,344;192,344,190,344,189,344,186,344,186,343,186,342,193,342,197,342,201,342,201,342,201,342,200,343,198,343,197,343,197,343,197,344,196,344,196,344,194,344,192,344,192,344,192,344;362,344,361,344,359,344,356,344,356,343,356,342,364,342,368,342,372,342,372,342,372,342,370,343,369,343,368,343,368,343,367,344,367,344,366,344,364,344,363,344,362,344,362,344;44,342,44,342,45,342,45,342,46,342,46,342,46,342,45,342,45,342,44,342,44,342,44,342;215,342,215,342,216,342,216,342,216,342,216,342,216,342,216,342,216,342,215,342,215,342,215,342;386,342,386,342,386,342,387,342,387,342,387,342,387,342,387,342,386,342,386,342,386,342,386,342;1,339,1,339,1,334,1,329,1,328,3,328,4,328,4,328,5,329,5,329,5,330,6,330,7,330,8,330,8,330,8,330,8,330,9,330,9,330,10,330,10,330,10,330,10,330,11,330,11,330,12,329,12,329,12,329,12,329,13,329,13,329,14,329,14,329,14,329,14,330,14,330,15,330,15,330,15,330,15,330,15,331,16,331,16,331,16,332,16,332,16,333,16,333,17,333,17,333,17,334,17,336,17,337,17,338,17,338,18,338,18,340,17,340,17,341,15,341,9,341,2,341,2,341,2,340;19,340,19,340,19,339,19,339,19,339,19,339,18,339,18,338,18,337,18,335,18,334,19,334,19,334,19,333,19,332,19,331,19,330,19,330,19,330,20,329,20,329,20,327,20,327,20,327,21,327,22,326,22,326,23,325,23,325,24,325,24,325,24,325,24,325,24,324,24,324,25,324,25,324,26,324,26,324,26,324,27,324,28,324,29,324,30,323,30,323,30,323,31,323,33,323,34,323,35,323,35,323,35,323,35,324,36,324,36,324,37,324,37,324,37,324,37,324,38,324,39,324,39,324,40,325,41,326,42,328,41,328,41,328,41,329,41,330,41,331,41,332,41,332,40,332,40,333,40,335,40,336,40,338,41,338,41,338,41,339,40,339,39,340,39,340,38,340,37,340,36,340,36,341,36,341,33,341,28,341,21,341,20,341,19,340;42,339,42,339,42,339,43,339,43,340,42,340,42,341,42,341,42,340;44,340,44,340,44,339,44,339,44,339,43,338,42,337,42,336,42,334,42,332,42,332,42,332,43,332,43,332,43,332,43,332,44,332,45,332,45,332,46,331,46,331,46,331,47,331,48,331,49,331,50,331,50,331,50,330,50,330,50,330,51,330,51,330,51,330,51,330,52,330,55,330,57,330,58,329,58,329,58,329,58,329,59,329,59,329,60,329,60,329,60,328,60,328,61,328,61,328,62,328,62,328,62,328,62,328,62,328,63,328,63,327,63,327,63,327,63,327,64,327,64,327,65,327,65,327,65,326,65,326,66,326,67,326,68,328,68,329,68,329,68,330,69,330,69,330,69,331,69,332,69,334,69,335,69,335,69,335,70,335,70,336,70,336,70,336,70,336,70,336,70,337,69,338,69,339,68,339,67,339,67,339,66,339,66,339,66,339,66,340,66,340,65,340,65,340,65,340,65,340,64,340,64,340,63,340,63,340,63,341,63,341,60,341,54,341,47,341,45,341,45,340;86,340,83,340,78,340,70,340,70,340,70,340,70,339,70,339,70,339,71,339,71,339,71,339,71,338,74,338,80,338,85,338,88,338,88,338,88,338,89,338,89,338,90,338,90,337,90,337,90,337,91,337,92,337,92,337,93,337,93,337,93,336,94,336,95,336,97,336,97,336,97,337,97,337,97,338,97,338,96,338,96,338,96,338,96,340,95,340,93,340,92,340,91,340,91,341,91,341,90,341,88,341,87,341,86,341,86,341;101,340,100,340,100,340,99,340,99,340,99,340,99,339,99,339,100,339,100,339,101,339,101,338,102,338,102,337,102,338,102,338,103,338,103,338,103,338,104,338,104,339,104,339,104,339,105,339,106,339,106,339,106,340,106,340,106,340,106,340,105,340,105,340,105,341,105,341,104,341,103,341,102,341,101,341,101,341;107,339,107,338,107,338,107,338,106,338,105,338,104,338,104,337,103,337,103,336,102,336,102,336,101,336,101,335,102,335,103,334,103,334,103,333,103,332,103,332,103,332,103,332,104,331,104,330,104,328,104,327,105,327,105,327,106,327,106,326,106,326,107,326,114,326,123,326,123,326,124,327,124,327,124,329,124,330,124,331,125,331,125,331,125,331,125,332,125,332,125,332,125,332,125,332,126,333,126,334,126,335,126,336,126,336,126,336,126,337,126,338,126,339,126,339,125,340,125,341,117,341,109,341,108,340;128,339,128,339,128,338,128,337,127,336,127,336,127,336,127,335,127,334,127,333,127,332,127,332,127,332,128,332,128,332,128,332,127,332,127,332,126,332,126,331,126,330,126,329,126,329,128,329,129,329,129,329,129,329,129,330,129,330,128,330,128,330,128,331,128,331,128,331,129,331,129,330,129,330,130,330,131,330,131,330,132,329,132,329,132,329,132,329,133,329,134,329,135,329,135,329,135,328,136,328,139,328,141,328,142,328,142,328,142,328,143,328,145,328,147,328,147,328,147,328,147,329,147,330,146,330,146,330,146,331,146,332,146,335,143,337,142,338,141,339,141,339,141,339,140,339,140,340,140,340,139,340,139,340,138,340,138,340,138,341,138,341,136,341,134,341,129,341,129,341,128,340;147,340,146,340,145,340,143,340,142,340,142,340,142,339,143,338,145,337,147,335,147,332,147,331,147,330,148,330,148,330,148,329,148,329,148,329,149,328,149,328,150,327,150,327,151,328,151,328,152,328,152,328,152,328,153,329,153,329,153,330,154,330,154,330,155,330,155,330,155,331,156,331,157,331,157,331,158,331,158,332,158,332,159,332,159,332,160,332,160,332,161,333,161,333,161,334,162,334,162,334,163,334,163,334,163,335,164,335,164,335,164,335,165,335,165,336,165,336,166,336,166,336,167,336,168,338,168,339,168,340,161,340,157,340,154,340,154,341,154,341,153,341,151,341,148,341,147,341,147,341;170,340,170,340,170,339,171,339,171,339,171,340,171,341,171,341,170,340;172,339,172,339,172,334,172,329,172,328,174,328,174,328,175,328,175,329,176,329,176,330,177,330,178,330,178,330,178,330,178,330,179,330,179,330,180,330,180,330,180,330,180,330,181,330,181,330,182,330,182,329,182,329,182,329,183,329,183,329,184,329,184,329,184,329,184,329,184,330,185,330,185,330,186,330,186,330,186,330,186,331,186,331,187,331,187,332,187,332,187,333,187,333,187,333,187,333,188,334,188,336,188,337,188,338,188,338,188,338,188,340,188,340,187,341,186,341,180,341,173,341,173,341,172,340;190,340,190,340,190,339,190,339,189,339,189,339,189,339,189,338,189,337,189,335,189,334,189,334,189,334,190,333,190,332,190,331,190,330,190,330,190,330,190,329,190,329,190,327,190,327,191,327,192,327,192,326,193,326,193,325,194,325,194,325,195,325,195,325,195,325,195,324,195,324,196,324,196,324,196,324,196,324,196,324,197,324,199,324,200,324,201,323,201,323,201,323,202,323,203,323,205,323,206,323,206,323,206,323,206,324,207,324,207,324,208,324,208,324,208,324,208,324,209,324,210,324,210,324,211,325,212,326,213,328,212,328,212,328,212,329,212,330,212,331,211,332,211,332,211,332,211,333,211,335,211,336,211,338,211,338,212,338,212,339,211,339,210,340,210,340,208,340,208,340,207,340,207,341,207,341,204,341,199,341,192,341,190,341,190,340;212,339,212,339,213,339,214,339,214,340,213,340,212,341,212,341,212,340;215,340,215,340,215,339,215,339,214,339,214,338,212,337,212,336,212,334,212,332,212,332,213,332,213,332,214,332,214,332,214,332,214,332,215,332,216,332,217,331,217,331,217,331,218,331,219,331,219,331,220,331,220,331,220,330,220,330,221,330,221,330,222,330,222,330,222,330,223,330,225,330,227,330,229,329,229,329,229,329,229,329,230,329,230,329,230,329,230,329,230,328,231,328,231,328,232,328,232,328,232,328,232,328,232,328,233,328,233,328,234,327,234,327,234,327,234,327,235,327,235,327,236,327,236,327,236,326,237,326,238,327,238,327,239,328,239,329,239,329,239,330,239,330,239,330,240,331,240,332,240,334,240,335,240,335,240,335,240,335,240,336,240,336,240,336,241,336,241,336,241,337,240,338,239,339,239,339,238,339,237,339,237,339,237,339,237,339,237,340,236,340,236,340,236,340,236,340,236,340,235,340,235,340,234,340,234,340,234,341,234,341,230,341,225,341,217,341,216,341,215,340;256,340,253,340,248,340,240,340,240,340,240,340,240,339,240,339,241,339,241,339,242,339,242,339,242,338,245,338,250,338,256,338,259,338,259,338,259,338,259,338,260,338,260,338,261,337,261,337,261,337,261,337,262,337,263,337,264,337,264,337,264,336,264,336,266,336,267,336,268,336,268,337,268,337,267,338,267,338,267,338,267,338,267,338,267,340,266,340,264,340,262,340,262,340,262,341,262,341,260,341,259,341,257,341,256,341,256,341;272,340,271,340,271,340,270,340,270,340,270,340,270,339,270,339,270,339,271,339,272,339,272,338,272,338,273,337,273,338,273,338,273,338,274,338,274,338,274,338,274,339,274,339,275,339,276,339,277,339,277,339,277,340,277,340,277,340,276,340,276,340,276,340,276,341,276,341,275,341,274,341,272,341,272,341,272,341;278,339,278,338,278,338,278,338,277,338,276,338,275,338,274,337,274,337,274,336,273,336,273,336,272,336,272,335,273,335,273,334,274,334,274,333,274,332,274,332,274,332,274,332,274,331,274,330,274,328,275,327,276,327,276,327,276,327,277,326,277,326,277,326,285,326,293,326,294,326,295,327,295,327,295,329,295,330,295,331,295,331,295,331,296,331,296,332,296,332,296,332,296,332,296,332,296,333,296,334,296,335,296,336,297,336,297,336,297,337,297,338,297,339,297,339,296,340,295,341,287,341,280,341,279,340;298,339,298,339,298,338,298,337,298,336,298,336,298,336,298,335,298,334,298,333,298,332,298,332,298,332,298,332,298,332,298,332,298,332,298,332,297,332,297,331,297,330,297,329,297,329,298,329,299,329,300,329,300,329,300,330,299,330,299,330,299,330,299,331,299,331,299,331,299,331,300,330,300,330,301,330,301,330,302,330,302,329,302,329,302,329,303,329,304,329,305,329,306,329,306,329,306,328,307,328,309,328,311,328,313,328,313,328,313,328,314,328,315,328,317,328,318,328,318,328,318,329,317,330,317,330,316,330,316,331,316,332,316,335,314,337,313,338,312,339,311,339,311,339,311,339,311,340,310,340,310,340,309,340,309,340,309,340,309,341,309,341,307,341,304,341,300,341,300,341,299,340;318,340,317,340,315,340,313,340,313,340,313,340,313,339,314,338,315,337,318,335,318,332,318,331,318,330,318,330,319,330,319,329,319,329,319,329,319,328,320,328,321,327,321,327,321,328,322,328,322,328,322,328,323,328,323,329,323,329,324,330,325,330,325,330,326,330,326,330,326,331,327,331,327,331,328,331,328,331,329,332,329,332,329,332,330,332,330,332,331,332,331,333,331,333,332,334,333,334,333,334,334,334,334,334,334,335,335,335,335,335,335,335,336,335,336,336,336,336,337,336,337,336,338,336,339,338,339,339,339,340,332,340,327,340,325,340,325,341,325,341,323,341,321,341,319,341,318,341,318,341;340,340,340,340,341,339,341,339,342,339,342,340,342,341,341,341,341,340;342,339,342,339,342,334,342,329,342,328,344,328,345,328,346,328,346,329,346,329,347,330,348,330,348,330,349,330,349,330,349,330,349,330,350,330,350,330,351,330,351,330,351,330,351,330,352,330,352,330,353,329,353,329,353,329,353,329,354,329,354,329,355,329,355,329,355,329,355,330,356,330,356,330,356,330,356,330,356,330,356,331,357,331,357,331,358,332,358,332,358,333,358,333,358,333,358,333,358,334,358,336,358,337,358,338,359,338,359,338,359,340,358,340,358,341,357,341,351,341,344,341,344,341,343,340;360,340,360,340,360,339,360,339,360,339,360,339,360,339,360,338,360,337,360,335,360,334,360,334,360,334,360,333,360,332,360,331,360,330,361,330,361,330,361,329,361,329,361,327,361,327,362,327,362,327,363,326,364,326,364,325,365,325,365,325,365,325,366,325,366,325,366,324,366,324,366,324,367,324,367,324,367,324,367,324,368,324,369,324,371,324,372,323,372,323,372,323,373,323,374,323,375,323,376,323,376,323,376,323,377,324,377,324,378,324,378,324,378,324,378,324,379,324,379,324,380,324,381,324,382,325,383,326,383,328,383,328,382,328,382,329,382,330,382,331,382,332,382,332,382,332,382,333,382,335,382,336,382,338,382,338,382,338,382,339,381,339,381,340,380,340,379,340,378,340,378,340,378,341,378,341,375,341,369,341,363,341,361,341,361,340;383,339,383,339,384,339,384,339,384,340,384,340,383,341,383,341,383,340;386,340,386,340,386,339,386,339,385,339,384,338,383,337,383,336,383,334,383,332,383,332,384,332,384,332,384,332,384,332,384,332,385,332,386,332,387,332,388,331,388,331,388,331,388,331,389,331,390,331,391,331,391,331,391,330,391,330,392,330,392,330,392,330,392,330,392,330,394,330,396,330,398,330,400,329,400,329,400,329,400,329,400,329,401,329,401,329,401,329,401,328,401,328,402,328,402,328,403,328,403,328,403,328,403,328,404,328,404,328,404,327,404,327,404,327,405,327,405,327,406,327,406,327,406,327,406,326,408,326,409,327,409,327,410,328,410,329,410,329,410,330,410,330,410,330,410,331,410,332,410,334,410,335,411,335,411,335,411,335,411,336,411,336,411,336,411,336,412,336,412,337,411,338,410,339,409,339,409,339,408,339,408,339,408,339,408,339,407,340,407,340,406,340,406,340,406,340,406,340,406,340,405,340,405,340,404,340,404,341,404,341,401,341,395,341,388,341,386,341,386,340;427,340,424,340,419,340,411,340,411,340,411,340,411,339,411,339,412,339,412,339,412,339,412,339,412,338,415,338,421,338,426,338,430,338,430,338,430,338,430,338,431,338,431,338,432,337,432,337,432,337,432,337,433,337,434,337,434,337,434,337,434,336,435,336,436,336,438,336,438,336,438,337,438,337,438,338,438,338,438,338,438,338,438,338,438,340,437,340,434,340,433,340,432,340,432,341,432,341,431,341,430,341,428,341,427,341,427,341;442,340,442,340,441,340,440,340,440,340,440,340,440,339,440,339,441,339,442,339,442,339,443,338,443,338,443,337,443,338,443,338,444,338,444,338,445,338,445,338,445,339,445,339,445,339,446,339,447,339,448,339,448,340,448,340,447,340,447,340,446,340,446,340,446,341,446,341,445,341,444,341,443,341,442,341,442,341;449,339,448,338,448,338,448,338,448,338,447,338,445,338,445,337,445,337,444,336,444,336,443,336,443,336,443,335,444,335,444,334,444,334,444,333,444,332,444,332,445,332,445,332,445,331,445,330,445,328,445,327,446,327,446,327,447,327,447,326,448,326,448,326,456,326,464,326,465,326,465,327,466,327,466,329,466,330,466,331,466,331,466,331,466,331,466,332,466,332,466,332,467,332,467,332,467,333,467,334,467,335,467,336,467,336,467,336,468,337,468,338,468,339,467,339,467,340,466,341,458,341,450,341,449,340;469,339,469,339,469,338,469,337,469,336,469,336,468,336,468,335,468,334,468,333,468,332,469,332,469,332,469,332,469,332,469,332,469,332,468,332,468,332,468,331,468,330,468,329,468,329,469,329,470,329,470,329,470,329,470,330,470,330,470,330,470,330,469,331,470,331,470,331,470,331,470,330,471,330,471,330,472,330,472,330,473,329,473,329,473,329,474,329,475,329,475,329,476,329,476,329,476,328,478,328,480,328,482,328,484,328,484,328,484,328,485,328,486,328,488,328,488,328,488,328,488,329,488,330,488,330,487,330,487,331,487,332,487,335,485,337,483,338,482,339,482,339,482,339,481,339,481,340,481,340,480,340,480,340,480,340,480,340,480,341,480,341,478,341,475,341,471,341,470,341,470,340;488,340,487,340,486,340,484,340,484,340,484,340,484,339,485,338,486,337,488,335,488,332,488,331,488,330,489,330,489,330,490,329,490,329,490,329,490,328,490,328,491,327,492,327,492,328,493,328,493,328,493,328,494,328,494,329,494,329,495,330,495,330,496,330,496,330,497,330,497,331,497,331,498,331,498,331,499,331,499,332,499,332,500,332,501,332,501,332,502,332,502,333,502,333,503,334,503,334,504,334,504,334,505,334,505,335,505,335,506,335,506,335,506,335,507,336,507,336,507,336,507,336,508,336,510,338,510,339,510,340,503,340,498,340,496,340,496,341,496,341,494,341,492,341,490,341,488,341,488,341;511,340,511,340,511,339,512,339,512,339,512,340,512,341,512,341,511,340;76,337,75,337,74,337,73,337,72,337,72,337,72,336,72,336,72,336,71,336,71,336,71,336,71,335,71,335,71,335,70,335,70,334,70,332,70,329,71,329,72,329,73,329,74,329,74,329,74,328,75,328,77,328,78,328,80,328,80,328,80,328,80,328,80,328,81,328,81,327,81,327,81,327,81,327,82,327,82,327,83,327,83,326,83,326,83,326,83,326,84,327,88,327,88,327,88,326,88,326,90,326,91,326,92,326,92,326,92,326,93,326,95,326,98,326,99,326,99,326,99,326,99,327,100,327,100,328,100,328,100,330,100,333,100,334,99,334,99,334,98,334,98,334,97,335,97,335,95,335,94,335,93,335,93,335,93,335,92,336,92,336,91,336,90,336,90,336,90,336,90,336,89,336,88,336,88,336,88,337,88,337,87,337,86,337,84,337,84,337,84,337,84,337,82,338,80,338,77,338,76,337,76,337;246,337,245,337,245,337,244,337,243,337,243,337,243,336,243,336,242,336,242,336,242,336,242,336,242,335,241,335,241,335,241,335,241,334,241,332,241,329,241,329,243,329,244,329,244,329,244,329,244,328,245,328,247,328,249,328,250,328,250,328,250,328,250,328,251,328,251,328,252,327,252,327,252,327,252,327,252,327,253,327,254,327,254,326,254,326,254,326,254,326,254,327,258,327,258,327,258,326,259,326,260,326,261,326,262,326,262,326,262,326,264,326,266,326,269,326,270,326,270,326,270,326,270,327,270,327,271,328,271,328,271,330,271,333,270,334,269,334,269,334,269,334,269,334,268,335,268,335,266,335,264,335,264,335,264,335,264,335,263,336,262,336,261,336,261,336,261,336,261,336,260,336,260,336,259,336,258,336,258,337,258,337,257,337,256,337,255,337,254,337,254,337,254,337,253,338,250,338,248,338,246,337,246,337;417,337,416,337,415,337,414,337,414,337,414,337,414,336,413,336,413,336,412,336,412,336,412,336,412,335,412,335,412,335,412,335,412,334,412,332,412,329,412,329,414,329,414,329,415,329,415,329,415,328,416,328,418,328,420,328,421,328,421,328,421,328,421,328,422,328,422,328,422,327,422,327,422,327,423,327,423,327,424,327,424,327,424,326,424,326,425,326,425,326,425,327,429,327,429,327,429,326,430,326,431,326,432,326,433,326,433,326,433,326,434,326,437,326,440,326,440,326,440,326,440,326,440,327,441,327,441,328,442,328,442,330,442,333,441,334,440,334,440,334,439,334,439,334,439,335,438,335,436,335,435,335,434,335,434,335,434,335,434,336,433,336,432,336,432,336,432,336,432,336,431,336,430,336,429,336,429,336,429,337,429,337,428,337,427,337,426,337,425,337,425,337,425,337,423,338,421,338,418,338,417,337,417,337;170,332,170,331,171,331,171,331,171,332,171,334,171,337,171,337,170,337,170,337,170,337,170,334;340,332,341,331,341,331,341,331,342,332,342,334,342,337,341,337,341,337,340,337,340,337,340,334;511,332,511,331,512,331,512,331,512,332,512,334,512,337,512,337,512,337,511,337,511,337,511,334;167,335,167,335,166,335,166,335,165,335,165,334,165,334,164,334,164,334,164,334,163,333,163,333,163,332,162,332,162,332,162,332,161,332,161,332,161,331,160,331,160,331,159,331,159,331,159,330,158,330,158,330,157,330,157,330,157,329,157,329,157,328,157,328,158,328,159,328,160,328,160,328,160,328,160,328,160,328,161,328,161,327,161,327,161,327,161,327,162,327,163,327,164,327,164,327,164,326,168,326,169,327,170,327,170,329,169,329,169,329,169,330,169,331,169,331,169,332,169,332,168,332,168,333,168,333,168,334,168,335,168,335,167,336,167,336,167,335;338,335,337,335,337,335,337,335,336,335,336,334,336,334,335,334,335,334,335,334,334,333,334,333,334,332,333,332,333,332,333,332,332,332,332,332,332,331,331,331,331,331,330,331,329,331,329,330,329,330,328,330,328,330,328,330,328,329,328,329,328,328,328,328,329,328,330,328,330,328,330,328,330,328,330,328,331,328,331,328,332,327,332,327,332,327,332,327,333,327,334,327,334,327,334,327,334,326,339,326,340,327,340,327,340,329,340,329,340,329,340,330,340,331,340,331,339,332,339,332,339,332,339,333,339,333,339,334,339,335,338,335,338,336,338,336,338,335;508,335,508,335,508,335,507,335,507,335,507,334,506,334,506,334,506,334,505,334,505,333,505,333,504,332,504,332,504,332,503,332,503,332,503,332,502,331,502,331,501,331,501,331,500,331,500,330,500,330,499,330,499,330,498,330,498,329,498,329,498,328,498,328,500,328,500,328,501,328,501,328,501,328,501,328,502,328,502,328,502,327,502,327,502,327,503,327,504,327,504,327,505,327,505,327,505,326,510,326,510,327,511,327,511,329,511,329,510,329,510,330,510,331,510,331,510,332,510,332,510,332,510,333,510,333,510,334,509,335,509,335,508,336,508,336,508,335;42,330,42,328,43,328,43,328,43,327,43,327,43,325,43,325,44,325,44,325,44,325,44,325,44,325,45,326,45,326,46,326,47,326,47,326,47,327,48,327,48,327,49,327,50,328,50,329,50,329,49,330,48,330,47,330,46,330,46,330,46,330,46,330,45,330,44,330,44,330,44,331,44,331,43,331,43,330;213,330,213,328,213,328,213,328,214,327,214,327,214,325,214,325,214,325,215,325,215,325,215,325,215,325,215,326,216,326,217,326,217,326,218,326,218,327,219,327,219,327,219,327,220,328,220,329,220,329,220,330,219,330,218,330,217,330,217,330,217,330,216,330,216,330,215,330,214,330,214,331,214,331,214,331,213,330;383,330,383,328,384,328,384,328,384,327,384,327,384,325,384,325,385,325,385,325,386,325,386,325,386,325,386,326,387,326,388,326,388,326,389,326,389,327,389,327,389,327,390,327,391,328,391,329,391,329,391,330,389,330,388,330,388,330,388,330,388,330,387,330,386,330,385,330,385,330,385,331,385,331,384,331,384,330;8,328,7,328,7,328,6,328,6,328,6,327,6,326,5,326,5,326,5,326,5,325,5,324,6,323,7,323,7,324,7,324,7,324,8,324,8,324,8,324,8,325,8,325,10,327,10,327,11,327,11,327,11,328,11,328,11,328,10,328,9,328,9,328,9,329,9,329,9,329,8,329,8,329,8,329,8,329;178,328,178,328,177,328,176,328,176,328,176,327,176,326,176,326,176,326,175,326,175,325,176,324,177,323,178,323,178,324,178,324,178,324,178,324,179,324,179,324,179,325,179,325,179,326,180,326,180,326,181,327,181,327,181,327,182,327,182,328,182,328,181,328,181,328,180,328,180,328,180,329,180,329,179,329,179,329,178,329,178,329,178,329;349,328,348,328,348,328,347,328,347,328,347,327,347,326,347,326,347,326,346,326,346,325,347,324,347,323,348,323,348,324,348,324,348,324,349,324,349,324,350,324,350,325,350,325,350,326,350,326,351,326,351,327,352,327,352,327,352,327,352,328,352,328,352,328,351,328,351,328,350,328,350,329,350,329,350,329,350,329,349,329,349,329,349,329;125,326,125,324,125,324,126,324,126,322,125,322,124,322,124,321,124,321,124,320,124,320,124,320,123,320,123,319,124,319,124,318,126,318,129,318,132,318,134,318,134,318,134,318,135,318,135,318,136,318,136,317,136,317,136,317,138,317,142,317,145,317,148,317,148,317,148,316,148,316,150,316,151,316,152,316,152,316,152,316,152,316,152,316,153,316,154,315,154,315,154,315,154,315,154,315,155,316,155,316,152,318,150,320,150,321,150,322,150,322,149,323,149,323,148,323,148,324,148,324,148,326,147,326,145,326,144,326,144,326,144,327,144,327,142,327,140,327,137,327,136,327,136,327,136,327,134,327,131,327,127,327,126,327,126,327;152,327,152,327,152,327,151,327,151,326,150,326,149,325,149,324,150,324,150,324,150,324,150,324,150,323,150,323,151,323,151,323,151,322,151,322,151,321,154,318,155,318,155,318,156,317,156,317,156,316,157,316,159,316,160,316,162,316,162,317,162,317,162,317,164,317,165,317,166,317,166,317,166,317,166,318,167,318,168,318,168,318,168,318,168,319,168,319,169,319,169,319,169,320,169,321,169,322,169,323,169,323,169,323,170,323,170,324,170,324,169,324,169,324,168,324,168,324,168,325,168,325,167,325,166,325,164,325,163,325,163,325,163,325,162,326,162,326,161,326,160,326,160,326,159,327,159,327,158,327,157,327,157,327,157,327,157,327,156,328,155,328,153,328,152,327,152,327;295,326,295,324,296,324,296,324,296,322,296,322,295,322,295,321,295,321,295,320,295,320,295,320,294,320,294,319,295,319,295,318,296,318,300,318,303,318,305,318,305,318,305,318,305,318,306,318,306,318,307,317,307,317,307,317,309,317,313,317,316,317,318,317,318,317,318,316,319,316,320,316,321,316,322,316,322,316,322,316,323,316,323,316,324,316,324,315,324,315,324,315,325,315,325,315,326,316,325,316,323,318,321,320,320,321,320,322,320,322,320,323,320,323,319,323,319,324,319,324,319,326,318,326,316,326,315,326,314,326,314,327,314,327,313,327,310,327,308,327,306,327,306,327,306,327,304,327,302,327,297,327,297,327,296,327;323,327,323,327,322,327,322,327,321,326,321,326,320,325,320,324,321,324,321,324,321,324,321,324,321,323,321,323,321,323,321,323,322,322,322,322,322,321,325,318,326,318,326,318,326,317,327,317,327,316,327,316,330,316,331,316,332,316,332,317,332,317,333,317,334,317,335,317,336,317,336,317,336,317,337,318,338,318,339,318,339,318,339,318,339,319,339,319,339,319,339,319,340,320,340,321,340,322,340,323,340,323,340,323,340,323,340,324,340,324,340,324,340,324,339,324,339,324,339,325,339,325,338,325,336,325,335,325,334,325,334,325,334,325,333,326,332,326,331,326,331,326,331,326,330,327,330,327,329,327,328,327,328,327,328,327,328,327,327,328,325,328,324,328,323,327,323,327;466,326,466,324,467,324,467,324,467,322,466,322,466,322,466,321,466,321,466,320,465,320,465,320,465,320,465,319,465,319,466,318,467,318,471,318,474,318,476,318,476,318,476,318,476,318,477,318,477,318,478,317,478,317,478,317,480,317,483,317,487,317,489,317,489,317,489,316,490,316,491,316,492,316,493,316,493,316,493,316,493,316,494,316,494,316,495,315,495,315,495,315,495,315,496,315,496,316,496,316,494,318,492,320,491,321,491,322,491,322,491,323,490,323,490,323,490,324,490,324,490,326,489,326,487,326,486,326,485,326,485,327,485,327,483,327,481,327,478,327,477,327,477,327,477,327,475,327,472,327,468,327,468,327,467,327;494,327,493,327,493,327,493,327,492,326,492,326,491,325,491,324,491,324,491,324,492,324,492,324,492,323,492,323,492,323,492,323,492,322,492,322,492,321,495,318,496,318,496,318,497,317,497,317,498,316,498,316,500,316,502,316,503,316,503,317,503,317,504,317,505,317,506,317,507,317,507,317,507,317,507,318,508,318,509,318,510,318,510,318,510,319,510,319,510,319,510,319,510,320,510,321,510,322,510,323,511,323,511,323,511,323,511,324,511,324,511,324,510,324,510,324,510,324,510,325,510,325,508,325,507,325,505,325,504,325,504,325,504,325,504,326,503,326,502,326,502,326,501,326,501,327,500,327,499,327,499,327,498,327,498,327,498,327,497,328,496,328,495,328,494,327,494,327;0,318,0,318,1,318,1,318,2,318,2,318,2,318,2,318,3,318,4,318,4,321,4,323,4,324,4,324,4,324,4,325,4,326,4,327,4,327,3,327,2,327,1,327,1,326,1,326,1,326,1,326,0,328,0,326,0,322;13,326,13,326,12,326,11,326,10,323,12,322,12,322,12,321,12,321,12,320,15,318,16,318,16,318,16,317,16,317,16,317,16,317,17,317,17,317,18,317,18,317,18,316,18,316,18,316,19,316,19,316,19,316,19,316,19,316,20,316,20,316,21,315,21,315,21,315,21,315,22,315,22,315,23,315,23,315,23,314,23,314,24,314,24,314,24,314,24,314,24,314,25,314,26,314,27,314,28,313,28,313,28,313,28,313,28,313,29,313,29,313,29,313,29,313,29,314,29,314,30,314,31,314,31,315,31,316,31,316,32,317,32,317,32,317,32,318,32,318,32,319,33,319,33,319,33,320,32,321,32,321,31,322,31,322,31,322,30,322,30,322,30,322,29,322,28,322,27,322,26,322,26,323,26,323,25,323,25,323,25,323,24,323,24,324,24,324,23,324,23,324,22,324,21,324,21,325,21,325,20,326,20,326,20,326,19,326,19,326,19,327,18,327,16,327,14,327,13,327,13,327;55,326,54,326,54,326,53,326,53,326,53,326,53,326,52,326,52,326,51,326,51,325,49,324,47,322,47,322,46,322,44,322,43,321,44,320,44,320,44,320,44,319,44,319,44,318,45,318,45,318,45,317,45,316,45,315,45,314,45,314,44,314,44,313,44,312,44,311,44,311,43,311,42,311,42,310,42,310,42,309,42,309,42,309,43,308,44,308,44,310,44,311,44,311,45,311,45,311,46,311,47,312,48,313,48,314,50,314,51,314,51,314,52,314,52,315,53,315,53,315,54,315,54,315,54,315,54,315,55,316,56,316,57,316,58,316,58,316,58,316,58,316,58,316,59,316,59,316,59,317,59,317,59,317,60,317,60,317,61,317,61,317,61,317,61,318,61,318,62,318,63,318,63,319,63,319,63,320,64,320,65,321,64,323,63,323,63,323,62,323,62,324,62,324,61,324,60,324,59,324,59,324,58,326,57,326,56,327,56,327,55,327,55,327,55,327;72,326,71,326,71,326,70,326,70,325,70,325,70,325,70,325,70,325,69,325,69,324,68,324,68,323,68,323,68,320,68,318,70,316,71,314,72,314,72,313,72,311,73,310,74,310,74,310,75,309,75,309,75,309,75,309,76,309,76,309,76,309,76,309,76,309,77,310,78,310,78,310,79,310,79,310,79,310,79,310,80,310,80,310,80,310,80,311,80,311,80,311,81,311,81,311,82,311,82,311,82,312,82,312,82,313,83,313,83,313,83,314,83,314,83,314,84,315,84,315,84,315,84,316,84,316,84,317,85,317,85,317,85,317,85,318,85,318,85,318,85,318,85,318,86,319,86,320,86,320,86,321,86,321,86,321,86,321,86,322,86,322,86,322,87,322,87,322,87,323,87,323,87,324,87,324,86,324,86,324,86,324,86,325,86,325,85,325,84,325,83,325,83,325,83,325,83,325,83,326,82,326,82,326,82,326,82,326,82,326,81,326,81,326,80,326,80,326,80,327,80,327,78,327,76,327,73,327,72,327,72,326;171,318,171,318,172,318,172,318,172,318,172,318,172,318,173,318,173,318,174,318,174,321,174,323,174,324,175,324,175,324,175,325,175,326,175,327,175,327,174,327,173,327,172,327,172,326,172,326,172,326,172,326,171,328,171,326,171,322;184,326,183,326,183,326,181,326,181,323,182,322,183,322,183,321,183,321,183,320,186,318,186,318,187,318,187,317,187,317,187,317,187,317,188,317,188,317,188,317,188,317,188,316,188,316,189,316,189,316,190,316,190,316,190,316,190,316,191,316,191,316,192,315,192,315,192,315,192,315,193,315,193,315,194,315,194,315,194,314,194,314,194,314,195,314,195,314,195,314,195,314,196,314,197,314,197,314,198,313,198,313,198,313,198,313,199,313,199,313,200,313,200,313,200,313,200,314,200,314,201,314,202,314,202,315,202,316,202,316,202,317,203,317,203,317,203,318,203,318,203,319,203,319,204,319,204,320,203,321,203,321,202,322,202,322,201,322,201,322,201,322,201,322,200,322,199,322,197,322,196,322,196,323,196,323,196,323,196,323,195,323,195,323,195,324,194,324,194,324,193,324,193,324,192,324,192,325,192,325,191,326,191,326,191,326,190,326,190,326,189,327,189,327,186,327,185,327,184,327,184,327;226,326,225,326,225,326,224,326,224,326,224,326,224,326,223,326,223,326,222,326,221,325,220,324,218,322,218,322,216,322,215,322,214,321,214,320,215,320,215,320,215,319,215,319,215,318,215,318,215,318,216,317,216,316,216,315,215,314,215,314,215,314,215,313,215,312,215,311,215,311,214,311,213,311,212,310,212,310,212,309,212,309,213,309,214,308,215,308,215,310,215,311,215,311,215,311,216,311,216,311,217,312,218,313,219,314,220,314,222,314,222,314,223,314,223,315,223,315,224,315,224,315,225,315,225,315,225,315,226,316,227,316,227,316,228,316,228,316,228,316,228,316,229,316,229,316,230,316,230,317,230,317,230,317,231,317,231,317,232,317,232,317,232,317,232,318,232,318,233,318,234,318,234,319,234,319,234,320,234,320,235,321,235,323,233,323,233,323,233,323,233,324,232,324,232,324,231,324,230,324,229,324,229,326,228,326,227,327,226,327,226,327,226,327,226,327;242,326,242,326,241,326,241,326,241,325,241,325,241,325,241,325,240,325,240,325,239,324,239,324,238,323,238,323,238,320,238,318,240,316,242,314,242,314,242,313,242,311,243,310,245,310,245,310,246,309,246,309,246,309,246,309,246,309,247,309,247,309,247,309,247,309,247,310,248,310,249,310,250,310,250,310,250,310,250,310,250,310,251,310,251,310,251,311,251,311,251,311,252,311,252,311,252,311,252,311,252,312,252,312,253,313,253,313,254,313,254,314,254,314,254,314,254,315,255,315,255,315,255,316,255,316,255,317,255,317,255,317,256,317,256,318,256,318,256,318,256,318,256,318,256,319,256,320,256,320,256,321,257,321,257,321,257,321,257,322,257,322,257,322,257,322,257,322,258,323,258,323,258,324,257,324,257,324,256,324,256,324,256,325,256,325,256,325,255,325,254,325,254,325,254,325,254,325,253,326,253,326,252,326,252,326,252,326,252,326,252,326,251,326,251,326,250,326,250,327,250,327,249,327,247,327,243,327,243,327,243,326;342,318,342,318,342,318,343,318,343,318,343,318,343,318,343,318,344,318,345,318,345,321,345,323,345,324,345,324,345,324,346,325,346,326,346,327,345,327,344,327,343,327,343,327,343,326,343,326,342,326,342,326,342,328,342,326,342,322;354,326,354,326,354,326,352,326,352,323,353,322,353,322,354,321,354,321,354,320,356,318,357,318,357,318,358,317,358,317,358,317,358,317,358,317,359,317,359,317,359,317,359,316,359,316,360,316,360,316,360,316,360,316,360,316,361,316,361,316,362,316,362,315,362,315,362,315,363,315,363,315,364,315,364,315,364,315,364,314,364,314,365,314,365,314,366,314,366,314,366,314,366,314,367,314,368,314,369,313,369,313,369,313,369,313,370,313,370,313,370,313,370,313,370,313,370,314,371,314,371,314,372,314,372,315,372,316,372,316,373,317,373,317,374,317,374,318,374,318,374,319,374,319,374,319,374,320,374,321,373,321,373,322,372,322,372,322,372,322,372,322,372,322,371,322,369,322,368,322,367,322,367,323,367,323,367,323,366,323,366,323,365,323,365,324,365,324,364,324,364,324,363,324,363,324,363,325,362,325,362,326,362,326,361,326,361,326,361,326,360,327,360,327,357,327,355,327,354,327,354,327;396,326,396,326,395,326,395,326,394,326,394,326,394,326,394,326,393,326,393,326,392,325,391,324,389,322,388,322,387,322,386,322,384,321,385,320,385,320,386,320,386,319,386,319,386,318,386,318,386,318,386,317,386,316,386,315,386,314,386,314,386,314,386,313,386,312,386,311,385,311,385,311,384,311,383,310,383,310,383,309,383,309,383,309,384,308,386,308,386,310,386,311,386,311,386,311,386,311,387,311,388,312,389,313,389,314,391,314,392,314,393,314,393,314,393,315,394,315,395,315,395,315,396,315,396,315,396,315,396,316,397,316,398,316,399,316,399,316,399,316,399,316,400,316,400,316,400,316,400,317,400,317,401,317,401,317,402,317,402,317,402,317,402,317,402,318,403,318,403,318,404,318,404,319,404,319,404,320,405,320,406,321,405,323,404,323,404,323,403,323,403,324,403,324,402,324,402,324,401,324,400,324,399,326,398,326,398,327,397,327,397,327,396,327,396,327;413,326,412,326,412,326,412,326,412,325,412,325,412,325,411,325,411,325,411,325,410,324,410,324,409,323,409,323,409,320,409,318,411,316,413,314,413,314,413,313,413,311,414,310,415,310,416,310,416,309,416,309,416,309,416,309,417,309,417,309,418,309,418,309,418,309,418,310,419,310,420,310,420,310,420,310,420,310,420,310,421,310,421,310,422,310,422,311,422,311,422,311,422,311,423,311,423,311,423,311,423,312,423,312,424,313,424,313,424,313,424,314,424,314,424,314,425,315,425,315,426,315,426,316,426,316,426,317,426,317,426,317,426,317,426,318,426,318,426,318,427,318,427,318,427,319,427,320,427,320,427,321,427,321,427,321,428,321,428,322,428,322,428,322,428,322,428,322,428,323,428,323,428,324,428,324,428,324,427,324,427,324,427,325,427,325,426,325,426,325,425,325,424,325,424,325,424,325,424,326,424,326,423,326,423,326,423,326,423,326,422,326,422,326,421,326,421,326,421,327,421,327,419,327,417,327,414,327,414,327,413,326;91,324,91,324,90,324,90,324,88,323,88,322,88,322,88,322,88,322,88,322,88,320,88,318,88,316,88,314,88,314,88,314,88,314,88,313,88,312,89,312,91,312,92,312,92,312,93,313,94,314,99,314,102,314,104,314,104,314,104,314,104,314,105,314,105,314,106,314,106,315,106,315,106,315,106,315,106,315,107,315,107,316,107,316,108,316,108,316,109,316,110,317,110,318,110,318,110,318,110,319,111,319,111,319,111,319,111,320,112,321,113,322,114,323,115,324,115,324,115,324,113,324,111,324,108,324,106,324,106,324,106,324,106,324,106,324,105,324,105,324,105,324,105,324,104,324,103,324,102,324,101,324,101,325,101,325,101,325,100,325,100,325,100,325,100,325,100,324,98,324,96,324,93,324,92,324,92,325,92,325,91,325,91,325,91,325,91,325,91,325;262,324,261,324,261,324,261,324,260,324,260,323,259,323,259,322,259,322,259,322,259,322,259,322,258,322,258,320,258,318,258,316,258,314,259,314,259,314,259,314,259,313,259,312,260,312,261,312,262,312,263,312,264,313,264,314,269,314,272,314,274,314,274,314,274,314,275,314,275,314,276,314,276,314,276,315,276,315,276,315,277,315,277,315,278,315,278,316,278,316,279,316,279,316,279,316,280,317,280,318,280,318,280,318,281,319,281,319,282,319,282,319,282,320,282,321,284,322,285,323,286,324,286,324,286,324,284,324,281,324,279,324,277,324,277,324,277,324,277,324,276,324,276,324,276,324,276,324,276,324,275,324,274,324,272,324,272,324,272,325,272,325,271,325,271,325,270,325,270,325,270,325,270,324,269,324,266,324,264,324,262,324,262,325,262,325,262,325,262,325,262,325,262,325,262,325;432,324,432,324,432,324,431,324,431,324,430,323,430,323,430,322,430,322,430,322,429,322,429,322,429,322,429,320,429,318,429,316,429,314,429,314,429,314,430,314,430,313,430,312,430,312,432,312,433,312,433,312,434,313,435,314,440,314,443,314,445,314,445,314,445,314,445,314,446,314,446,314,447,314,447,315,447,315,447,315,447,315,448,315,448,315,449,316,449,316,449,316,449,316,450,316,451,317,451,318,451,318,451,318,452,319,452,319,452,319,452,319,452,320,453,321,454,322,455,323,456,324,456,324,456,324,454,324,452,324,449,324,448,324,448,324,448,324,447,324,447,324,446,324,446,324,446,324,446,324,445,324,444,324,443,324,442,324,442,325,442,325,442,325,442,325,441,325,441,325,441,325,441,324,439,324,437,324,434,324,433,324,433,325,433,325,433,325,433,325,432,325,432,325,432,325;116,324,116,324,116,324,115,324,114,323,114,322,114,322,114,321,113,321,113,320,112,320,112,319,112,319,112,318,112,318,111,317,111,316,112,315,113,314,113,314,116,314,119,314,120,314,120,315,120,315,120,316,121,316,121,316,121,316,121,316,121,317,121,317,121,317,121,317,122,317,122,318,122,318,122,319,122,319,123,319,123,320,123,321,123,321,123,322,124,322,124,322,124,323,124,324,123,324,116,324,116,324;287,324,287,324,286,324,286,324,285,323,285,322,285,322,284,321,284,321,283,320,283,320,283,319,283,319,283,318,282,318,281,317,281,316,283,315,284,314,284,314,287,314,290,314,291,314,291,315,291,315,291,316,291,316,291,316,292,316,292,316,292,317,292,317,292,317,292,317,292,317,292,318,292,318,292,319,293,319,293,319,294,320,294,321,294,321,294,322,294,322,295,322,295,323,294,324,294,324,287,324,287,324;458,324,457,324,457,324,456,324,456,323,456,322,456,322,455,321,455,321,454,320,454,320,454,319,454,319,453,318,453,318,452,317,452,316,453,315,454,314,454,314,458,314,461,314,462,314,462,315,462,315,462,316,462,316,462,316,462,316,462,316,462,317,462,317,463,317,463,317,463,317,463,318,463,318,463,319,464,319,464,319,464,320,464,321,464,321,464,322,465,322,466,322,466,323,465,324,464,324,458,324,458,324;5,321,5,320,5,319,5,319,5,318,4,318,4,318,4,318,5,317,5,317,6,317,7,317,7,317,8,317,8,317,8,316,8,316,9,316,9,316,10,316,10,316,10,315,11,315,11,315,11,315,12,314,13,313,14,312,15,311,16,311,16,311,17,312,17,312,17,313,17,313,17,313,18,313,18,315,17,316,17,316,16,316,16,316,15,316,14,317,13,319,11,320,10,322,9,322,9,322,9,322,9,322,9,322,8,322,8,322,7,322,6,322,6,321;176,321,176,320,176,319,176,319,175,318,175,318,175,318,175,318,175,317,176,317,176,317,177,317,178,317,179,317,179,317,179,316,179,316,179,316,180,316,180,316,181,316,181,315,181,315,181,315,182,315,183,314,184,313,185,312,186,311,186,311,187,311,188,312,188,312,188,313,188,313,188,313,188,313,188,315,188,316,187,316,187,316,187,316,186,316,185,317,183,319,182,320,180,322,180,322,180,322,180,322,180,322,180,322,179,322,178,322,177,322,177,322,176,321;346,321,346,320,346,319,346,319,346,318,346,318,345,318,345,318,346,317,346,317,347,317,348,317,349,317,350,317,350,317,350,316,350,316,350,316,350,316,351,316,351,316,351,315,352,315,352,315,352,315,353,314,355,313,356,312,357,311,357,311,357,311,358,312,358,312,358,313,358,313,359,313,359,313,359,315,358,316,358,316,358,316,357,316,357,316,355,317,354,319,352,320,351,322,351,322,350,322,350,322,350,322,350,322,350,322,349,322,348,322,347,322,347,321;39,321,38,321,37,321,36,321,36,321,35,320,34,319,34,318,34,318,34,318,33,318,33,318,33,318,33,317,33,317,33,316,33,316,33,316,32,316,32,316,32,316,32,315,32,315,32,315,31,315,31,312,32,312,33,311,33,311,37,311,39,311,41,311,41,311,41,311,41,312,41,312,42,312,43,312,43,313,43,313,43,314,43,314,43,314,44,315,44,316,44,317,43,318,43,318,43,318,43,318,43,319,43,319,42,320,41,320,41,320,41,320,41,321,40,322,39,322,39,321;210,321,209,321,208,321,207,321,206,321,205,320,205,319,204,318,204,318,204,318,204,318,204,318,204,318,204,317,204,317,204,316,203,316,203,316,203,316,203,316,203,316,203,315,203,315,203,315,202,315,202,312,203,312,204,311,204,311,208,311,210,311,212,311,212,311,212,311,212,312,212,312,212,312,213,312,213,312,213,312,214,313,214,313,214,313,214,314,214,314,214,314,214,315,214,316,214,317,214,318,214,318,214,318,214,318,214,319,214,319,213,320,212,320,212,320,211,320,211,321,211,322,210,322,210,321;380,321,379,321,379,321,377,321,377,321,376,320,375,319,375,318,375,318,375,318,375,318,375,318,374,318,374,317,374,317,374,316,374,316,374,316,374,316,374,316,374,316,374,315,373,315,373,315,372,315,373,312,374,312,374,311,375,311,378,311,381,311,382,311,382,311,382,311,382,312,383,312,383,312,383,312,384,312,384,312,384,313,384,313,384,313,384,314,385,314,385,314,385,315,385,316,385,317,385,318,385,318,384,318,384,318,384,319,384,319,383,320,383,320,383,320,382,320,382,321,381,322,380,322,380,321;64,316,64,316,63,316,62,316,60,315,61,315,61,315,62,314,62,314,62,313,62,313,62,313,63,313,63,313,63,313,63,312,64,312,65,312,67,312,68,312,68,312,68,312,68,312,68,312,70,312,71,314,69,316,68,317,68,317,66,317,65,317,64,317,64,317;124,316,123,316,123,316,122,316,122,315,122,315,122,315,121,314,121,314,120,314,120,313,120,313,120,312,119,311,118,311,118,311,118,311,118,310,118,309,117,309,117,309,117,309,117,309,117,308,117,308,117,308,117,308,117,308,118,307,118,307,118,307,118,306,118,306,119,306,119,305,119,305,119,304,119,304,122,304,124,304,125,304,125,305,125,305,126,305,128,305,129,305,130,305,130,305,130,305,131,306,131,306,132,306,132,310,132,314,132,315,130,315,130,315,129,315,129,316,129,316,128,316,127,316,126,316,126,316,126,317,126,317,125,317,125,317,124,317,124,317,124,317;170,316,170,316,170,316,169,316,169,316,169,316,168,315,168,315,167,315,166,315,166,315,166,315,166,314,165,314,164,314,163,314,163,314,163,314,163,314,161,314,159,314,155,314,155,313,155,312,155,311,155,311,155,311,154,311,154,311,154,310,154,310,154,310,154,310,154,310,154,309,154,309,154,308,153,307,153,307,153,307,153,307,153,307,153,307,154,307,154,306,154,306,155,304,156,304,156,304,156,304,156,304,156,304,157,304,158,304,159,304,160,303,160,303,160,303,161,303,162,303,163,303,164,303,164,303,164,302,164,302,164,302,165,302,165,302,165,302,165,302,166,302,167,302,168,302,169,301,169,301,169,301,169,301,170,301,170,301,171,301,171,301,171,301,171,302,172,302,172,302,172,302,172,302,172,302,173,302,174,302,175,302,176,302,176,303,176,303,176,303,178,303,179,303,180,303,180,303,180,303,180,304,181,304,181,304,182,303,182,303,182,303,184,303,185,303,185,304,186,304,186,305,186,305,186,306,186,306,187,306,187,307,187,307,187,307,187,308,186,308,186,308,186,309,186,309,186,310,182,314,181,314,181,314,181,314,181,314,180,315,180,315,179,315,179,315,179,315,179,315,179,315,178,316,177,316,176,316,175,316,175,316,175,316,174,316,173,316,172,316,171,316,171,317,171,317,171,317,171,317,170,317,170,317,170,317;235,316,234,316,234,316,232,316,231,315,232,315,232,315,232,314,232,314,232,313,232,313,233,313,233,313,234,313,234,313,234,312,235,312,236,312,237,312,238,312,238,312,238,312,239,312,239,312,241,312,241,314,240,316,239,317,238,317,237,317,236,317,235,317,235,317;294,316,294,316,294,316,293,316,292,315,292,315,292,315,292,314,292,314,291,314,291,313,291,313,291,312,289,311,289,311,288,311,288,311,288,310,288,309,288,309,288,309,288,309,288,309,288,308,288,308,288,308,288,308,288,308,288,307,288,307,288,307,288,306,289,306,289,306,290,305,290,305,290,304,290,304,293,304,294,304,296,304,296,305,296,305,297,305,298,305,300,305,301,305,301,305,301,305,301,306,302,306,303,306,303,310,303,314,303,315,301,315,301,315,300,315,300,316,299,316,299,316,298,316,297,316,296,316,296,317,296,317,296,317,295,317,295,317,294,317,294,317;341,316,341,316,340,316,340,316,339,316,339,316,339,315,338,315,337,315,337,315,336,315,336,315,336,314,336,314,335,314,334,314,334,314,334,314,334,314,332,314,330,314,326,314,326,313,326,312,326,311,325,311,325,311,325,311,325,311,325,310,325,310,325,310,325,310,324,310,324,309,324,309,324,308,324,307,324,307,323,307,323,307,324,307,324,307,324,307,324,306,324,306,326,304,326,304,327,304,327,304,327,304,327,304,328,304,329,304,330,304,331,303,331,303,331,303,332,303,333,303,333,303,334,303,334,303,334,302,334,302,335,302,335,302,336,302,336,302,336,302,336,302,338,302,339,302,340,301,340,301,340,301,340,301,341,301,341,301,342,301,342,301,342,301,342,302,342,302,343,302,343,302,343,302,343,302,344,302,345,302,345,302,346,302,346,303,346,303,347,303,348,303,349,303,350,303,350,303,350,303,351,304,351,304,352,304,352,303,352,303,352,303,355,303,356,303,356,304,356,304,356,305,356,305,356,306,357,306,357,306,358,307,358,307,358,307,357,308,357,308,356,308,356,309,356,309,356,310,353,314,352,314,352,314,351,314,351,314,351,315,350,315,350,315,350,315,350,315,350,315,350,315,349,316,348,316,346,316,346,316,346,316,346,316,345,316,344,316,342,316,342,316,342,317,342,317,341,317,341,317,341,317,341,317,341,317;406,316,405,316,404,316,403,316,402,315,402,315,403,315,403,314,403,314,403,313,403,313,404,313,404,313,404,313,404,313,404,312,405,312,407,312,408,312,409,312,409,312,409,312,409,312,410,312,412,312,412,314,410,316,409,317,409,317,407,317,406,317,406,317,406,317;465,316,465,316,464,316,464,316,463,315,463,315,463,315,463,314,462,314,462,314,462,313,462,313,462,312,460,311,459,311,459,311,459,311,459,310,459,309,459,309,459,309,458,309,458,309,458,308,458,308,458,308,459,308,459,308,459,307,459,307,459,307,459,306,460,306,460,306,460,305,460,305,460,304,461,304,463,304,465,304,466,304,466,305,466,305,467,305,469,305,470,305,472,305,472,305,472,305,472,306,473,306,474,306,474,310,474,314,473,315,472,315,471,315,471,315,471,316,470,316,470,316,468,316,468,316,467,316,467,317,467,317,466,317,466,317,465,317,465,317,465,317;512,316,511,316,511,316,511,316,510,316,510,316,509,315,509,315,508,315,507,315,507,315,507,315,507,314,506,314,506,314,505,314,504,314,504,314,504,314,503,314,501,314,497,314,496,313,496,312,496,311,496,311,496,311,496,311,496,311,496,310,496,310,495,310,495,310,495,310,495,309,495,309,495,308,495,307,494,307,494,307,494,307,494,307,495,307,495,307,495,306,495,306,496,304,497,304,497,304,498,304,498,304,498,304,498,304,500,304,501,304,502,303,502,303,502,303,502,303,503,303,504,303,505,303,505,303,505,302,505,302,506,302,506,302,506,302,506,302,506,302,507,302,508,302,509,302,510,301,510,301,510,301,511,301,511,301,512,301,512,301,512,301,512,301,512,302,513,302,513,302,514,302,514,302,514,302,514,302,515,302,516,302,517,302,517,303,517,303,518,303,519,303,520,303,521,303,521,303,521,303,521,304,522,304,522,304,523,303,523,303,523,303,526,303,526,303,527,304,527,304,527,305,527,305,527,306,528,306,528,306,528,307,528,307,528,307,528,308,528,308,527,308,527,309,527,309,527,310,524,314,523,314,523,314,522,314,522,314,522,315,521,315,521,315,520,315,520,315,520,315,520,315,519,316,518,316,517,316,516,316,516,316,516,316,515,316,514,316,513,316,512,316,512,317,512,317,512,317,512,317,512,317,512,317,512,317;132,316,132,316,133,316,133,316,134,316,134,316,134,316,133,316,133,316,132,316,132,316,132,316;303,316,303,316,304,316,304,316,304,316,304,316,304,316,304,316,304,316,303,316,303,316,303,316;474,316,474,316,474,316,475,316,475,316,475,316,475,316,475,316,474,316,474,316,474,316,474,316;135,315,135,315,134,315,134,315,134,315,134,310,134,307,133,306,133,306,133,306,133,305,133,304,134,303,137,303,137,304,137,304,139,304,142,304,147,304,147,304,148,305,148,305,149,306,149,306,149,306,151,307,151,308,151,308,151,309,152,309,152,309,152,310,152,311,152,312,152,312,153,312,153,312,153,313,153,313,152,313,152,313,152,313,152,314,151,315,149,315,148,315,148,315,148,315,148,315,145,316,141,316,137,316,135,315,135,315;306,315,305,315,305,315,304,315,304,315,304,310,304,307,304,306,304,306,303,306,303,305,304,304,305,303,308,303,308,304,308,304,309,304,313,304,318,304,318,304,319,305,319,305,319,306,319,306,320,306,322,307,322,308,322,308,322,309,322,309,323,309,323,310,323,311,323,312,323,312,323,312,324,312,324,313,323,313,323,313,323,313,323,313,323,314,322,315,320,315,319,315,318,315,318,315,318,315,316,316,312,316,308,316,306,315,306,315;476,315,476,315,476,315,475,315,475,315,475,310,475,307,475,306,475,306,474,306,474,305,475,304,475,303,478,303,478,304,478,304,480,304,483,304,488,304,489,304,489,305,489,305,490,306,490,306,491,306,492,307,492,308,492,308,492,309,493,309,493,309,494,310,494,311,494,312,494,312,494,312,494,312,494,313,494,313,494,313,494,313,494,313,494,314,493,315,491,315,490,315,489,315,489,315,489,315,487,316,483,316,479,316,476,315,476,315;57,314,56,314,56,314,55,314,55,314,55,313,55,312,57,312,61,312,61,313,60,314,59,315,59,315,58,315,57,315,57,315,57,315;228,314,227,314,227,314,226,314,226,314,226,313,226,312,228,312,231,312,232,313,231,314,230,315,229,315,229,315,228,315,228,315,228,315;398,314,398,314,397,314,396,314,396,314,396,313,396,312,399,312,402,312,403,313,401,314,401,315,400,315,399,315,399,315,398,315,398,315;19,313,19,313,19,313,19,313,19,312,18,312,18,311,18,311,18,309,18,308,18,308,18,308,18,308,18,307,18,307,18,306,18,306,19,306,19,306,19,306,19,306,19,305,22,302,23,302,24,302,24,301,25,301,25,300,25,300,26,300,26,300,26,300,27,301,27,301,27,302,28,302,28,302,28,302,29,302,29,303,29,303,29,303,31,303,31,304,31,307,31,311,31,312,29,312,29,312,28,312,28,312,28,312,27,312,26,312,25,312,24,312,24,313,24,313,24,313,24,313,23,313,23,313,23,313,23,313,22,314,22,314,21,314,20,314,20,314,20,314,20,314,19,314;190,313,190,313,190,313,190,313,189,312,189,312,188,311,188,311,188,309,188,308,188,308,189,308,189,308,189,307,189,307,189,306,189,306,189,306,189,306,190,306,190,306,190,305,193,302,194,302,194,302,195,301,195,301,195,300,196,300,196,300,196,300,197,300,197,301,197,301,198,302,198,302,198,302,199,302,199,302,199,303,200,303,200,303,201,303,202,304,202,307,202,311,201,312,200,312,199,312,199,312,199,312,199,312,198,312,197,312,196,312,195,312,195,313,195,313,195,313,194,313,194,313,194,313,194,313,194,313,193,314,192,314,191,314,191,314,191,314,191,314,190,314,190,314;360,313,360,313,360,313,360,313,360,312,360,312,359,311,359,311,359,309,359,308,359,308,359,308,359,308,360,307,360,307,360,306,360,306,360,306,360,306,360,306,360,306,360,305,364,302,365,302,365,302,366,301,366,301,366,300,367,300,367,300,367,300,368,300,368,301,368,301,369,302,369,302,369,302,370,302,370,302,370,303,371,303,371,303,372,303,372,304,372,307,372,311,372,312,370,312,370,312,370,312,370,312,370,312,369,312,368,312,366,312,366,312,366,313,366,313,365,313,365,313,364,313,364,313,364,313,364,313,364,314,363,314,362,314,362,314,362,314,362,314,361,314,361,314;100,312,99,312,97,312,94,312,94,312,93,311,93,311,92,310,92,310,92,310,92,310,92,310,91,310,91,309,91,309,90,308,90,308,91,308,91,308,91,307,91,307,91,306,91,306,92,306,92,306,92,305,92,305,92,305,93,305,93,305,94,305,94,305,94,305,94,304,95,304,96,304,97,304,98,304,98,304,98,304,99,304,99,304,100,304,100,303,100,303,100,303,100,303,101,303,101,303,102,303,102,303,102,302,102,302,102,302,102,302,103,302,104,301,104,300,105,300,106,300,107,300,108,300,108,300,108,300,109,300,110,300,113,300,114,300,114,301,114,301,114,302,114,302,114,302,114,302,114,302,114,303,114,303,115,303,115,303,115,304,115,305,115,305,115,306,115,306,115,306,116,307,116,307,116,308,116,309,116,309,116,309,116,309,116,309,115,310,115,311,116,311,117,311,115,312,114,312,114,312,114,312,114,313,114,313,111,313,107,313,103,313,100,313,100,313;271,312,270,312,268,312,265,312,264,312,264,311,263,311,263,310,263,310,263,310,263,310,262,310,262,310,262,309,261,309,261,308,261,308,261,308,261,308,262,307,262,307,262,306,262,306,262,306,263,306,263,305,263,305,263,305,263,305,264,305,264,305,265,305,265,305,265,304,266,304,267,304,268,304,269,304,269,304,269,304,269,304,270,304,270,304,271,303,271,303,271,303,271,303,272,303,272,303,272,303,272,303,272,302,272,302,273,302,273,302,274,302,274,301,275,300,275,300,277,300,278,300,279,300,279,300,279,300,280,300,281,300,283,300,284,300,284,301,284,301,284,302,285,302,285,302,285,302,285,302,285,303,285,303,285,303,285,303,286,304,286,305,286,305,286,306,286,306,286,306,286,307,286,307,286,308,286,309,287,309,287,309,287,309,287,309,286,310,286,311,287,311,287,311,286,312,285,312,285,312,284,312,284,313,284,313,282,313,278,313,273,313,271,313,271,313;442,312,440,312,438,312,435,312,435,312,434,311,434,311,434,310,434,310,434,310,433,310,433,310,433,310,432,309,432,309,431,308,431,308,432,308,432,308,432,307,432,307,432,306,432,306,433,306,433,306,434,305,434,305,434,305,434,305,435,305,435,305,436,305,436,305,436,304,436,304,438,304,439,304,440,304,440,304,440,304,440,304,441,304,441,304,442,303,442,303,442,303,442,303,442,303,443,303,443,303,443,303,443,302,443,302,443,302,444,302,444,302,445,301,446,300,446,300,448,300,449,300,450,300,450,300,450,300,450,300,452,300,454,300,455,300,455,301,455,301,455,302,455,302,455,302,456,302,456,302,456,303,456,303,456,303,456,303,456,304,456,305,456,305,456,306,457,306,457,306,457,307,457,307,457,308,457,309,457,309,458,309,458,309,457,309,457,310,457,311,457,311,458,311,457,312,456,312,455,312,455,312,455,313,455,313,452,313,448,313,444,313,442,313,442,313;46,310,46,310,46,309,46,309,45,309,45,309,44,308,44,308,44,307,44,307,44,307,44,307,44,307,44,307,44,306,44,306,44,306,44,306,44,306,44,305,44,304,44,303,45,302,47,302,47,302,48,301,48,301,48,301,48,301,49,301,50,301,51,301,51,301,51,300,52,300,53,300,54,300,55,300,55,300,55,300,56,300,58,300,59,300,60,299,60,299,60,299,66,299,67,299,68,300,68,305,67,306,67,306,67,306,67,306,68,307,68,309,68,310,67,310,67,310,66,310,65,310,65,310,65,311,65,311,63,311,60,311,55,311,55,311,55,312,54,312,54,312,51,312,48,312,48,312,47,311;217,310,216,310,216,309,216,309,216,309,216,309,215,308,215,308,215,307,215,307,215,307,215,307,214,307,214,307,214,306,214,306,214,306,215,306,215,306,215,305,215,304,215,303,216,302,217,302,218,302,218,301,218,301,218,301,219,301,220,301,221,301,222,301,222,301,222,300,222,300,224,300,225,300,226,300,226,300,226,300,227,300,228,300,230,300,231,299,231,299,231,299,237,299,238,299,238,300,238,305,238,306,237,306,238,306,238,306,239,307,239,309,238,310,238,310,237,310,237,310,236,310,236,310,236,311,236,311,234,311,231,311,226,311,226,311,225,312,225,312,224,312,222,312,218,312,218,312,217,311;387,310,387,310,387,309,387,309,387,309,386,309,386,308,386,308,386,307,386,307,385,307,385,307,385,307,385,307,385,306,385,306,385,306,385,306,385,306,386,305,386,304,386,303,387,302,388,302,388,302,389,301,389,301,389,301,390,301,391,301,391,301,392,301,392,301,392,300,393,300,394,300,395,300,396,300,396,300,396,300,397,300,399,300,400,300,402,299,402,299,402,299,408,299,408,299,409,300,409,305,408,306,408,306,408,306,409,306,410,307,410,309,409,310,409,310,408,310,407,310,407,310,406,310,406,311,406,311,404,311,401,311,397,311,396,311,396,312,395,312,395,312,392,312,389,312,389,312,388,311;82,310,82,310,82,310,81,310,81,309,81,309,81,309,81,309,80,309,80,309,80,309,80,309,80,308,79,308,78,308,77,308,77,308,77,308,77,308,77,308,76,308,76,308,75,307,75,306,75,306,75,306,75,306,74,306,74,305,74,305,74,304,74,304,75,304,75,304,75,304,75,304,75,303,75,303,76,303,76,303,76,303,76,302,76,301,77,301,78,301,79,301,80,301,80,301,80,300,80,300,82,300,83,300,84,300,84,301,84,301,84,301,85,301,85,301,86,301,86,301,86,301,86,302,87,302,89,302,90,303,90,305,90,307,89,308,88,308,88,308,88,308,88,309,88,309,87,309,87,309,86,309,86,309,86,309,86,309,86,310,85,310,84,310,84,310,84,310,84,310,83,310,83,310,82,310,82,310,82,310;253,310,253,310,252,310,252,310,252,309,252,309,252,309,251,309,251,309,250,309,250,309,250,309,250,308,250,308,249,308,248,308,248,308,248,308,248,308,247,308,247,308,247,308,246,307,246,307,246,307,246,306,246,306,246,306,245,306,245,306,245,306,245,305,245,305,245,304,245,304,245,304,245,304,246,304,246,304,246,303,246,303,246,303,247,303,247,303,247,302,247,301,248,301,249,301,250,301,250,301,250,301,250,300,251,300,252,300,253,300,254,300,254,301,254,301,255,301,255,301,256,301,256,301,256,301,256,301,257,302,257,302,259,302,260,303,260,305,260,307,260,308,259,308,258,308,258,308,258,309,258,309,258,309,258,309,257,309,257,309,257,309,257,309,256,310,256,310,255,310,254,310,254,310,254,310,254,310,254,310,253,310,253,310,253,310;424,310,423,310,423,310,422,310,422,309,422,309,422,309,422,309,422,309,421,309,421,309,421,309,421,308,420,308,420,308,419,308,418,308,418,308,418,308,418,308,418,308,417,308,417,307,417,307,416,307,416,306,416,306,416,306,416,306,416,306,416,306,416,305,416,305,416,304,416,304,416,304,416,304,416,304,416,304,416,303,416,303,417,303,417,303,418,303,418,302,418,301,418,301,420,301,420,301,421,301,421,301,421,300,422,300,423,300,424,300,425,300,425,301,425,301,425,301,426,301,426,301,427,301,427,301,427,301,427,302,428,302,430,302,431,303,431,305,431,307,430,308,429,308,429,308,429,308,429,309,429,309,429,309,428,309,428,309,428,309,428,309,428,309,427,310,426,310,425,310,425,310,425,310,425,310,425,310,424,310,424,310,424,310,424,310;34,309,34,309,34,309,33,309,32,308,32,306,32,303,33,303,34,303,35,303,36,303,36,303,36,302,42,302,42,303,43,303,43,306,43,306,42,306,42,306,42,307,42,308,42,308,41,308,41,308,40,308,40,309,39,309,39,310,37,310,35,310,34,309,34,309;205,309,205,309,204,309,203,309,203,308,203,306,203,303,203,303,205,303,206,303,206,303,206,303,206,302,212,302,213,303,214,303,214,306,213,306,213,306,213,306,213,307,213,308,213,308,212,308,211,308,211,308,211,309,210,309,210,310,207,310,206,310,205,309,205,309;376,309,375,309,375,309,374,309,374,308,374,306,374,303,374,303,376,303,376,303,377,303,377,303,377,302,383,302,384,303,384,303,384,306,384,306,384,306,384,306,384,307,384,308,383,308,383,308,382,308,381,308,381,309,381,309,380,310,378,310,377,310,376,309,376,309;150,305,149,304,149,304,148,304,148,304,148,304,148,303,148,303,149,303,149,303,150,303,150,303,150,303,150,304,151,304,152,304,153,304,153,304,153,304,153,305,153,305,152,306,151,306,150,305;320,305,320,304,319,304,319,304,319,304,319,304,319,303,319,303,320,303,320,303,320,303,320,303,320,303,321,304,322,304,323,304,323,304,324,304,324,304,324,305,323,305,322,306,322,306,321,305;491,305,490,304,490,304,490,304,490,304,490,304,490,303,490,303,490,303,491,303,491,303,491,303,491,303,492,304,492,304,493,304,494,304,494,304,495,304,495,305,494,305,493,306,493,306,492,305;68,300,68,300,69,300,69,300,70,300,70,301,70,301,71,301,72,301,74,301,74,302,74,303,74,303,74,303,73,303,73,303,73,304,72,304,72,304,72,304,71,304,71,304,71,305,70,305,70,306,69,306,68,306,68,303;239,300,239,300,240,300,240,300,240,300,240,301,240,301,241,301,243,301,245,301,245,302,245,303,245,303,244,303,244,303,243,303,243,304,243,304,242,304,242,304,242,304,241,304,241,305,241,305,240,306,240,306,239,306,239,303;410,300,410,300,410,300,411,300,411,300,411,301,411,301,412,301,413,301,416,301,416,302,416,303,415,303,415,303,415,303,414,303,414,304,414,304,413,304,413,304,413,304,412,304,412,305,412,305,411,306,410,306,410,306,410,303;16,303,17,302,18,302,19,302,19,302,19,303,19,304,19,304,18,304,18,304,18,304,18,305,18,305,17,305,17,305,16,305,16,305,16,304;187,304,187,303,187,303,188,302,188,302,189,302,189,302,190,302,190,303,190,304,189,304,189,304,188,304,188,304,188,305,188,305,188,305,188,305,187,305,187,305,187,304;358,304,358,303,358,303,358,302,359,302,359,302,360,302,360,302,360,303,360,304,360,304,360,304,359,304,359,304,359,305,359,305,359,305,358,305,358,305,358,305,358,304;90,303,90,303,90,303,91,303,91,302,91,302,91,300,91,300,96,300,100,300,100,300,100,301,100,301,99,302,98,302,98,302,98,302,98,303,98,303,97,303,96,303,95,303,94,303,94,303,94,303,94,304,93,304,93,304,92,304,92,304,92,304,91,304,91,304;261,303,261,303,261,303,261,303,262,302,262,302,262,300,262,300,267,300,270,300,271,300,271,301,271,301,270,302,269,302,269,302,268,302,268,303,268,303,267,303,267,303,266,303,265,303,265,303,265,303,264,304,264,304,263,304,263,304,263,304,263,304,262,304,261,304;431,303,431,303,432,303,432,303,432,302,432,302,432,300,433,300,437,300,441,300,442,300,442,301,442,301,441,302,440,302,439,302,439,302,439,303,439,303,438,303,437,303,436,303,436,303,436,303,436,303,435,304,435,304,434,304,434,304,434,304,434,304,432,304,432,304;116,302,116,302,116,301,116,301,115,301,115,301,115,301,115,300,116,299,116,299,116,298,116,298,116,298,116,298,117,298,117,298,118,297,118,297,118,297,118,297,118,297,119,298,119,298,119,299,119,301,119,301,118,302,117,303,117,303,116,302;130,302,130,302,127,302,125,302,124,301,123,300,122,299,122,299,122,298,122,297,122,296,122,296,122,296,122,296,122,296,122,295,121,295,121,295,120,294,120,294,120,291,120,288,121,288,122,288,122,288,122,287,122,287,122,287,124,287,126,287,129,287,129,287,130,288,130,288,131,288,132,288,132,288,133,288,133,289,133,289,133,289,134,289,134,289,135,289,135,289,135,289,136,290,137,290,137,290,138,290,138,290,138,290,139,290,139,290,140,290,140,290,140,291,140,291,141,291,142,291,143,291,144,291,144,293,144,293,144,294,145,294,145,294,145,294,145,296,145,297,145,298,145,298,144,298,144,298,144,298,144,299,144,299,144,299,143,299,143,299,143,299,143,299,142,300,142,300,141,300,140,300,140,300,139,301,139,301,137,301,136,301,136,301,136,301,136,301,135,302,134,302,133,302,133,302,133,302,133,303,133,303,132,303,131,303,131,303,131,302;141,302,141,302,141,302,142,302,142,301,143,301,143,300,144,300,145,301,145,302,145,302,145,302,145,303,144,303,143,303,141,303,141,303,141,302;155,302,154,302,152,302,151,302,150,302,150,302,150,302,149,302,148,302,147,302,147,301,147,301,147,301,147,300,146,300,145,299,145,298,147,297,148,296,148,296,149,296,150,296,151,296,151,296,151,296,151,296,152,296,153,296,154,296,154,297,154,297,154,297,154,297,155,297,155,297,155,297,155,297,155,298,156,298,156,298,157,298,157,298,157,298,159,298,161,298,164,298,166,298,166,299,166,299,166,299,168,299,169,299,170,299,170,300,170,300,169,300,167,300,166,300,165,300,165,301,165,301,165,301,164,301,164,301,164,301,164,301,164,301,163,302,162,302,161,302,160,302,160,302,160,302,159,302,158,302,157,302,156,302,156,303,156,303,156,303,156,303,155,303,155,303,155,303;286,302,286,302,286,301,286,301,286,301,286,301,285,301,285,300,286,299,287,299,287,298,287,298,287,298,287,298,287,298,288,298,288,297,288,297,288,297,289,297,289,297,289,298,290,298,290,299,290,301,289,301,289,302,288,303,287,303,287,302;301,302,300,302,298,302,295,302,295,301,294,300,293,299,293,299,293,298,293,297,293,296,293,296,292,296,292,296,292,296,292,295,292,295,292,295,291,294,291,294,291,291,291,288,291,288,292,288,293,288,293,287,293,287,293,287,294,287,296,287,300,287,300,287,301,288,301,288,301,288,302,288,303,288,304,288,304,289,304,289,304,289,305,289,305,289,306,289,306,289,306,289,306,290,307,290,308,290,309,290,309,290,309,290,309,290,310,290,310,290,311,290,311,291,311,291,312,291,312,291,314,291,315,291,315,293,315,293,315,294,315,294,315,294,316,294,316,296,316,297,315,298,315,298,315,298,315,298,315,298,315,299,315,299,314,299,314,299,314,299,314,299,314,299,313,300,312,300,311,300,311,300,311,300,310,301,310,301,308,301,307,301,306,301,306,301,306,301,306,302,305,302,304,302,304,302,304,302,304,303,303,303,303,303,302,303,301,303,301,302;312,302,312,302,312,302,312,302,313,301,313,301,314,300,314,300,315,301,316,302,316,302,316,302,315,303,315,303,313,303,312,303,312,303,312,302;326,302,324,302,323,302,321,302,320,302,320,302,320,302,320,302,319,302,318,302,318,301,318,301,318,301,317,300,317,300,316,299,316,298,317,297,318,296,319,296,320,296,321,296,322,296,322,296,322,296,322,296,323,296,324,296,324,296,324,297,324,297,324,297,325,297,325,297,326,297,326,297,326,297,326,298,327,298,327,298,328,298,328,298,328,298,329,298,332,298,335,298,336,298,336,299,336,299,337,299,338,299,340,299,340,299,340,300,340,300,340,300,338,300,337,300,336,300,336,301,336,301,335,301,335,301,334,301,334,301,334,301,334,301,333,302,333,302,332,302,331,302,331,302,331,302,330,302,329,302,328,302,327,302,327,303,327,303,327,303,326,303,326,303,326,303,326,303;457,302,457,302,457,301,457,301,457,301,457,301,456,301,456,300,457,299,457,299,458,298,458,298,458,298,458,298,458,298,458,298,459,297,459,297,459,297,459,297,460,297,460,298,460,298,460,299,460,301,460,301,459,302,458,303,458,303,457,302;471,302,471,302,469,302,466,302,466,301,465,300,464,299,464,299,464,298,464,297,463,296,463,296,463,296,463,296,463,296,463,295,463,295,462,295,462,294,462,294,462,291,462,288,462,288,463,288,463,288,464,287,464,287,464,287,465,287,467,287,470,287,471,287,471,288,472,288,472,288,473,288,474,288,474,288,474,289,474,289,475,289,475,289,476,289,476,289,476,289,476,289,477,290,478,290,479,290,480,290,480,290,480,290,480,290,481,290,481,290,482,290,482,291,482,291,482,291,483,291,485,291,486,291,486,293,486,293,486,294,486,294,486,294,486,294,486,296,486,297,486,298,486,298,486,298,486,298,486,298,486,299,485,299,485,299,484,299,484,299,484,299,484,299,484,300,483,300,482,300,482,300,481,300,481,301,480,301,479,301,478,301,477,301,477,301,477,301,476,302,476,302,474,302,474,302,474,302,474,303,474,303,473,303,473,303,472,303,472,302;482,302,482,302,483,302,483,302,484,301,484,301,484,300,485,300,486,301,487,302,487,302,486,302,486,303,485,303,484,303,482,303,482,303,482,302;496,302,495,302,494,302,492,302,491,302,491,302,491,302,490,302,490,302,488,302,488,301,488,301,488,301,488,300,488,300,487,299,487,298,488,297,489,296,489,296,491,296,491,296,492,296,492,296,492,296,493,296,494,296,494,296,495,296,495,297,495,297,495,297,496,297,496,297,496,297,496,297,496,297,497,298,497,298,498,298,498,298,498,298,498,298,500,298,503,298,505,298,507,298,507,299,507,299,508,299,509,299,511,299,511,299,511,300,511,300,511,300,509,300,507,300,506,300,506,301,506,301,506,301,506,301,505,301,505,301,505,301,505,301,504,302,503,302,502,302,502,302,502,302,502,302,501,302,500,302,498,302,498,302,498,303,498,303,497,303,497,303,496,303,496,303,496,303;9,302,8,302,7,302,6,302,5,301,5,301,5,301,4,301,4,301,2,301,1,299,2,299,3,298,3,298,3,298,3,297,3,297,4,297,4,296,4,296,4,296,4,295,4,295,5,295,5,294,6,294,6,294,6,293,8,291,8,291,9,291,9,291,9,291,9,290,9,290,10,290,10,290,10,290,10,290,10,290,11,290,11,290,13,290,14,289,14,288,14,288,14,287,15,287,15,287,16,287,16,288,16,288,17,288,17,288,17,288,18,288,18,289,18,289,19,290,20,290,21,290,22,290,22,290,22,290,22,290,23,290,23,290,24,291,24,291,25,292,25,292,25,295,25,297,25,298,25,298,24,298,24,298,24,299,24,299,24,300,24,300,23,300,23,300,23,300,23,300,22,300,22,300,21,300,21,300,21,301,21,301,20,301,19,301,18,301,17,301,17,301,17,301,16,302,14,302,13,302,12,302,12,302,12,302,11,302,10,302,9,302,9,302,9,302;180,302,179,302,178,302,176,302,176,301,176,301,176,301,175,301,174,301,172,301,172,299,173,299,173,298,174,298,174,298,174,297,174,297,174,297,175,296,175,296,175,296,175,295,175,295,176,295,176,294,176,294,176,294,176,293,178,291,179,291,179,291,180,291,180,291,180,290,180,290,180,290,181,290,181,290,181,290,181,290,181,290,182,290,183,290,184,289,184,288,184,288,185,287,186,287,186,287,186,287,187,288,187,288,187,288,188,288,188,288,188,288,189,289,189,289,189,290,191,290,192,290,193,290,193,290,193,290,193,290,193,290,194,290,194,291,195,291,195,292,196,292,196,295,196,297,195,298,195,298,195,298,195,298,195,299,195,299,195,300,194,300,194,300,194,300,194,300,194,300,193,300,193,300,192,300,192,300,192,301,192,301,191,301,190,301,188,301,188,301,188,301,188,301,186,302,185,302,183,302,182,302,182,302,182,302,182,302,181,302,180,302,180,302,180,302;350,302,349,302,348,302,347,302,346,301,346,301,346,301,346,301,345,301,343,301,342,299,344,299,344,298,344,298,344,298,344,297,344,297,345,297,345,296,346,296,346,296,346,295,346,295,346,295,347,294,347,294,347,294,347,293,349,291,350,291,350,291,350,291,350,291,350,290,350,290,351,290,351,290,352,290,352,290,352,290,352,290,353,290,354,290,355,289,355,288,355,288,356,287,356,287,356,287,357,287,357,288,357,288,358,288,358,288,358,288,359,288,359,289,360,289,360,290,362,290,363,290,364,290,364,290,364,290,364,290,364,290,364,290,365,291,365,291,366,292,366,292,366,295,366,297,366,298,366,298,366,298,366,298,366,299,366,299,365,300,365,300,364,300,364,300,364,300,364,300,364,300,363,300,363,300,362,300,362,301,362,301,361,301,360,301,359,301,358,301,358,301,358,301,357,302,356,302,354,302,353,302,353,302,353,302,352,302,352,302,351,302,350,302,350,302;30,301,30,301,29,301,29,301,28,301,28,301,28,300,28,300,28,300,27,300,27,300,27,300,27,299,27,299,27,299,26,299,26,298,26,297,26,296,26,296,27,296,27,296,27,295,27,294,27,292,28,291,29,291,30,291,30,291,31,290,31,290,31,290,33,290,35,290,36,289,36,289,36,289,36,289,36,289,37,289,37,289,37,289,37,288,38,288,41,288,45,288,45,289,45,290,45,290,46,291,47,291,47,292,47,293,47,294,47,294,48,295,49,296,50,297,50,297,50,297,50,298,50,298,50,298,50,298,50,299,50,299,50,300,49,300,48,300,47,300,47,300,47,300,46,300,46,300,45,300,45,300,45,301,45,301,43,301,40,301,37,301,35,301,35,301,35,301,34,302,33,302,31,302,30,301,30,301;201,301,200,301,200,301,199,301,199,301,199,301,199,300,199,300,198,300,198,300,198,300,198,300,198,299,197,299,197,299,197,299,197,298,197,297,197,296,197,296,197,296,197,296,198,295,198,294,198,292,199,291,200,291,200,291,201,291,201,290,202,290,202,290,204,290,205,290,206,289,206,289,206,289,206,289,207,289,207,289,208,289,208,289,208,288,209,288,212,288,216,288,216,289,216,290,216,290,217,291,217,291,218,292,218,293,218,294,218,294,219,295,220,296,220,297,220,297,220,297,220,298,221,298,221,298,221,298,221,299,221,299,221,300,219,300,218,300,218,300,218,300,218,300,217,300,217,300,216,300,216,300,216,301,216,301,214,301,211,301,207,301,206,301,206,301,206,301,205,302,203,302,202,302,201,301,201,301;372,301,371,301,371,301,370,301,370,301,370,301,370,300,369,300,369,300,368,300,368,300,368,300,368,299,368,299,368,299,368,299,368,298,368,297,368,296,368,296,368,296,368,296,368,295,368,294,368,292,369,291,371,291,371,291,372,291,372,290,372,290,373,290,375,290,376,290,377,289,377,289,377,289,377,289,378,289,378,289,378,289,378,289,378,288,380,288,382,288,386,288,386,289,386,290,387,290,387,291,388,291,388,292,388,293,388,294,388,294,390,295,390,296,391,297,391,297,391,297,391,298,391,298,391,298,392,298,392,299,392,299,391,300,390,300,389,300,388,300,388,300,388,300,388,300,387,300,387,300,386,300,386,301,386,301,384,301,381,301,378,301,376,301,376,301,376,301,375,302,374,302,373,302,372,301,372,301;68,297,67,297,66,297,65,297,65,296,64,296,64,296,65,295,65,295,66,294,66,294,66,294,66,293,66,293,67,293,67,292,67,292,67,292,67,292,67,292,68,292,68,291,69,291,70,290,70,290,71,290,72,290,72,289,72,289,72,289,73,289,73,289,74,289,74,289,74,289,74,288,77,288,78,289,78,289,78,289,78,289,78,289,78,290,78,291,78,292,77,292,77,292,77,292,77,293,77,295,77,296,77,297,77,297,78,297,78,298,77,299,77,299,76,300,72,300,68,300,68,298;84,299,83,299,82,299,80,299,79,298,79,297,79,297,79,296,79,296,78,296,78,295,78,294,78,293,78,292,79,292,79,292,79,291,79,290,79,288,79,288,80,288,80,288,81,288,81,289,81,289,82,289,84,289,86,289,87,289,87,289,87,289,89,290,93,290,100,290,100,290,101,290,101,291,102,291,102,295,102,298,101,299,101,299,101,300,100,300,100,299,100,299,92,299,92,299,92,299,91,300,88,300,85,300,84,299,84,299;103,298,103,290,103,290,103,290,104,289,104,287,104,286,104,285,104,285,105,284,107,284,107,285,107,285,107,285,108,285,108,285,108,285,108,285,108,285,109,286,110,286,111,286,112,286,112,286,112,286,113,286,114,286,117,286,118,287,118,288,118,288,118,288,118,289,119,289,119,289,119,292,119,294,119,295,118,295,118,296,117,296,116,296,116,296,115,297,115,297,114,298,114,298,111,298,109,298,108,298,108,299,108,299,107,299,106,299,105,299,104,299,104,299,104,300,104,300,103,299;239,297,237,297,236,297,236,297,235,296,235,296,235,296,235,295,236,295,236,294,236,294,236,294,236,293,237,293,237,293,238,292,238,292,238,292,238,292,238,292,238,292,239,291,240,291,240,290,241,290,242,290,242,290,243,289,243,289,243,289,243,289,244,289,244,289,245,289,245,289,245,288,248,288,248,289,249,289,249,289,249,289,248,289,248,290,248,291,248,292,248,292,248,292,248,292,248,293,248,295,248,296,248,297,248,297,248,297,248,298,248,299,247,299,246,300,243,300,239,300,239,298;254,299,253,299,252,299,250,299,250,298,250,297,250,297,249,296,249,296,249,296,249,295,249,294,249,293,249,292,249,292,249,292,250,291,250,290,250,288,250,288,251,288,251,288,252,288,252,289,252,289,253,289,255,289,256,289,258,289,258,289,258,289,260,290,264,290,270,290,271,290,271,290,272,291,272,291,272,295,272,298,272,299,272,299,271,300,271,300,271,299,271,299,263,299,263,299,263,299,261,300,259,300,256,300,254,299,254,299;273,298,273,290,274,290,274,290,274,289,274,287,274,286,274,285,275,285,275,284,278,284,278,285,278,285,278,285,278,285,279,285,279,285,279,285,279,285,280,286,281,286,282,286,283,286,283,286,283,286,284,286,285,286,287,286,288,287,288,288,288,288,288,288,289,289,289,289,290,289,290,292,290,294,289,295,289,295,288,296,288,296,287,296,287,296,286,297,286,297,285,298,284,298,282,298,280,298,279,298,279,299,279,299,278,299,277,299,276,299,275,299,275,299,275,300,274,300,274,299;410,297,408,297,407,297,406,297,406,296,405,296,405,296,406,295,407,295,407,294,407,294,407,294,407,293,408,293,408,293,408,292,408,292,408,292,408,292,409,292,409,292,410,291,410,291,411,290,411,290,412,290,413,290,414,289,414,289,414,289,414,289,415,289,415,289,416,289,416,289,416,288,418,288,419,289,420,289,420,289,419,289,419,289,419,290,419,291,419,292,419,292,419,292,418,292,418,293,418,295,418,296,418,297,419,297,419,297,419,298,418,299,418,299,417,300,414,300,410,300,410,298;425,299,424,299,423,299,421,299,420,298,420,297,420,297,420,296,420,296,420,296,420,295,420,294,420,293,420,292,420,292,420,292,420,291,420,290,420,288,420,288,421,288,422,288,422,288,422,289,422,289,423,289,425,289,427,289,428,289,428,289,428,289,431,290,435,290,441,290,441,290,442,290,443,291,443,291,443,295,443,298,443,299,442,299,442,300,442,300,442,299,441,299,434,299,434,299,434,299,432,300,429,300,427,300,425,299,425,299;444,298,444,290,445,290,445,290,445,289,445,287,445,286,445,285,445,285,446,284,448,284,448,285,448,285,448,285,449,285,449,285,450,285,450,285,450,285,450,286,452,286,453,286,454,286,454,286,454,286,454,286,456,286,458,286,459,287,459,288,459,288,459,288,460,289,460,289,460,289,460,292,460,294,460,295,459,295,459,296,458,296,458,296,457,296,457,297,456,297,455,298,455,298,452,298,451,298,450,298,450,299,450,299,449,299,448,299,446,299,446,299,446,299,446,300,445,300,445,299;52,298,52,298,52,297,52,297,52,297,52,297,52,297,52,296,52,296,52,294,52,294,53,294,53,294,54,293,54,293,54,292,55,292,55,292,55,292,56,292,56,292,56,291,57,291,57,291,57,291,58,291,58,291,58,290,58,290,59,290,59,290,60,290,60,291,60,291,60,291,61,291,62,291,63,291,63,291,63,290,65,290,65,291,66,292,65,293,65,293,64,294,64,294,64,295,64,295,64,295,64,295,64,295,64,296,64,297,63,298,62,298,61,298,61,298,61,298,61,298,60,298,58,298,57,298,56,298,56,299,56,299,53,299,53,298;223,298,223,298,223,297,223,297,223,297,223,297,222,297,222,296,222,296,222,294,223,294,224,294,224,294,224,293,225,293,225,292,225,292,226,292,226,292,226,292,227,292,227,291,227,291,228,291,228,291,228,291,228,291,228,290,229,290,229,290,230,290,230,290,230,291,230,291,231,291,232,291,233,291,234,291,234,291,234,290,235,290,236,291,237,292,236,293,235,293,235,294,235,294,235,295,235,295,235,295,234,295,234,295,234,296,234,296,234,297,234,297,233,297,233,298,232,298,232,298,232,298,232,298,232,298,230,298,229,298,227,298,226,298,226,299,226,299,224,299,223,298;394,298,394,298,394,297,394,297,393,297,393,297,393,297,393,296,393,296,393,294,393,294,394,294,394,294,395,293,395,293,395,292,396,292,396,292,396,292,397,292,397,292,397,291,398,291,398,291,399,291,399,291,399,291,399,290,399,290,400,290,400,290,401,290,401,291,401,291,402,291,403,291,403,291,404,291,404,291,404,290,406,290,407,291,408,292,407,293,406,293,406,294,406,294,406,295,405,295,405,295,405,295,405,295,405,296,405,296,405,297,404,297,404,297,403,298,403,298,403,298,402,298,402,298,402,298,401,298,400,298,398,298,397,298,397,299,397,299,394,299,394,298;162,297,161,297,160,297,158,297,158,297,158,297,158,296,157,296,156,296,155,296,155,296,155,296,155,296,155,296,154,296,154,296,154,295,154,295,154,295,153,295,153,295,152,295,152,295,152,295,152,294,150,294,149,294,146,294,146,293,146,291,145,290,144,290,144,290,144,290,144,289,144,288,144,288,144,288,145,288,145,288,145,288,145,288,146,288,147,288,149,288,150,287,150,287,150,287,151,287,153,287,154,287,156,287,156,287,156,286,156,286,157,287,158,287,158,287,157,287,157,287,157,288,157,289,157,289,157,290,159,290,160,290,161,290,161,290,161,291,162,291,163,291,163,291,164,291,164,291,164,291,164,292,165,292,166,292,166,292,166,292,166,292,167,292,167,292,169,292,170,293,170,294,170,294,170,294,170,294,171,294,171,294,171,296,171,298,166,298,163,298,162,297,162,297;332,297,331,297,330,297,329,297,328,297,328,297,328,296,328,296,327,296,326,296,326,296,326,296,326,296,325,296,325,296,324,296,324,295,324,295,324,295,324,295,323,295,323,295,322,295,322,295,322,294,321,294,319,294,316,294,316,293,316,291,316,290,315,290,314,290,314,290,314,289,314,288,314,288,315,288,315,288,316,288,316,288,316,288,317,288,318,288,319,288,320,287,320,287,320,287,321,287,323,287,325,287,326,287,326,287,326,286,327,286,328,287,328,287,328,287,328,287,328,287,328,288,328,289,328,289,328,290,329,290,331,290,331,290,332,290,332,291,333,291,333,291,334,291,334,291,334,291,334,291,335,292,336,292,336,292,337,292,337,292,337,292,337,292,338,292,339,292,340,293,340,294,340,294,340,294,341,294,341,294,342,294,342,296,342,298,337,298,334,298,332,297,332,297;503,297,502,297,501,297,500,297,499,297,499,297,499,296,498,296,498,296,497,296,496,296,496,296,496,296,496,296,496,296,495,296,495,295,495,295,495,295,494,295,494,295,493,295,493,295,493,295,493,294,492,294,490,294,487,294,487,293,487,291,486,290,485,290,485,290,485,290,485,289,485,288,485,288,486,288,486,288,486,288,486,288,486,288,487,288,489,288,490,288,491,287,491,287,491,287,492,287,494,287,496,287,497,287,497,287,497,286,498,286,498,287,499,287,499,287,499,287,498,287,498,288,498,289,498,289,498,290,500,290,502,290,502,290,503,290,503,291,503,291,504,291,504,291,505,291,505,291,505,291,505,292,506,292,507,292,508,292,508,292,508,292,508,292,509,292,510,292,511,293,511,294,511,294,511,294,512,294,512,294,512,294,512,296,512,298,508,298,505,298,503,297,503,297;48,291,48,291,47,291,47,291,47,291,47,290,47,290,47,289,46,289,46,289,46,289,47,289,47,288,48,288,51,288,53,288,54,288,54,289,54,289,54,289,55,289,55,289,56,289,56,290,56,291,55,291,55,291,54,291,54,291,54,291,54,291,54,292,54,292,53,292,53,292,53,292,53,292,52,292,51,292,49,292,49,292,49,292;219,291,218,291,218,291,218,291,218,291,218,290,218,290,217,289,217,289,217,289,217,289,217,289,218,288,218,288,221,288,223,288,225,288,225,289,225,289,225,289,226,289,226,289,226,289,226,290,226,291,226,291,226,291,225,291,225,291,225,291,225,291,225,292,224,292,224,292,224,292,224,292,224,292,223,292,222,292,220,292,220,292,219,292;390,291,389,291,389,291,388,291,388,291,388,290,388,290,388,289,388,289,387,289,387,289,388,289,388,288,389,288,392,288,394,288,396,288,396,289,396,289,396,289,396,289,397,289,397,289,397,290,397,291,397,291,396,291,396,291,396,291,396,291,396,291,395,292,395,292,394,292,394,292,394,292,394,292,393,292,392,292,391,292,390,292,390,292;170,290,169,290,167,290,166,290,165,289,165,289,165,289,164,289,163,289,161,289,160,289,160,289,160,288,160,288,160,288,159,288,159,288,159,286,159,284,159,283,159,283,159,283,160,283,160,282,160,282,160,282,160,282,160,282,160,281,160,281,160,280,160,279,161,279,161,279,162,278,162,278,162,277,162,277,162,277,163,276,163,276,163,275,163,275,163,275,165,275,167,275,168,275,168,275,168,275,168,276,169,276,169,276,170,276,170,276,170,276,170,276,170,276,171,276,171,276,171,277,171,277,171,278,172,278,172,278,173,278,173,278,173,279,174,279,174,279,175,279,175,279,175,279,175,279,175,280,176,280,176,280,176,280,176,280,176,280,177,280,177,280,179,280,180,281,180,282,180,282,180,283,181,283,181,283,182,284,182,284,182,284,182,285,182,285,183,286,183,286,183,287,183,288,183,288,182,288,181,288,181,288,181,289,181,289,180,289,180,289,179,289,179,289,179,289,179,289,177,290,175,290,172,290,171,290,171,290,171,290,171,290,170,290,170,290,170,290,170,290;340,290,339,290,338,290,337,290,336,289,336,289,336,289,335,289,333,289,332,289,331,289,331,289,331,288,331,288,330,288,330,288,330,288,330,286,330,284,330,283,330,283,330,283,330,283,330,282,330,282,330,282,331,282,331,282,331,281,331,281,331,280,331,279,332,279,332,279,332,278,332,278,332,277,332,277,333,277,333,276,334,276,334,275,334,275,334,275,336,275,337,275,338,275,338,275,338,275,339,276,339,276,340,276,340,276,340,276,340,276,340,276,341,276,341,276,342,276,342,277,342,277,342,278,342,278,343,278,344,278,344,278,344,279,345,279,345,279,345,279,346,279,346,279,346,279,346,280,346,280,347,280,347,280,347,280,347,280,347,280,348,280,349,280,351,281,351,282,351,282,351,283,352,283,352,283,352,284,352,284,352,284,352,285,353,285,353,286,354,286,354,287,354,288,353,288,353,288,352,288,352,288,352,289,352,289,351,289,351,289,350,289,350,289,350,289,350,289,348,290,346,290,343,290,342,290,342,290,342,290,341,290,341,290,340,290,340,290,340,290;511,290,510,290,509,290,507,290,506,289,506,289,506,289,505,289,504,289,503,289,502,289,502,289,502,288,501,288,501,288,500,288,500,288,500,286,500,284,500,283,501,283,501,283,501,283,501,282,501,282,501,282,501,282,501,282,502,281,502,281,502,280,502,279,502,279,503,279,503,278,503,278,503,277,503,277,504,277,504,276,504,276,504,275,504,275,504,275,507,275,508,275,509,275,509,275,509,275,509,276,510,276,510,276,511,276,511,276,511,276,511,276,512,276,512,276,512,276,512,277,512,277,512,278,513,278,514,278,514,278,515,278,515,279,515,279,516,279,516,279,516,279,516,279,516,279,516,280,517,280,517,280,518,280,518,280,518,280,518,280,519,280,520,280,522,281,522,282,522,282,522,283,522,283,523,283,523,284,523,284,523,284,523,285,524,285,524,286,524,286,524,287,524,288,524,288,523,288,523,288,522,288,522,289,522,289,522,289,521,289,521,289,520,289,520,289,520,289,519,290,516,290,514,290,512,290,512,290,512,290,512,290,512,290,511,290,511,290,511,290;60,287,60,286,60,286,60,286,60,286,60,285,60,285,59,284,59,284,59,284,59,283,59,283,59,282,59,281,59,281,58,281,58,280,58,280,58,278,61,278,62,278,64,278,64,278,64,278,64,278,64,278,64,278,65,277,65,277,65,276,66,276,66,276,67,276,67,276,67,276,67,276,67,276,68,276,68,276,69,275,72,272,76,268,76,268,77,268,79,268,79,272,79,274,79,275,79,275,79,275,80,277,80,280,80,286,78,286,76,286,76,286,75,286,75,287,74,287,74,287,74,287,74,287,74,287,74,287,73,288,73,288,72,288,72,288,72,288,72,288,71,288,71,288,70,288,69,288,69,289,69,289,68,290,66,290,64,290,63,289,63,289,63,289,62,289,62,289,62,289,62,290,61,290,60,290,60,289,60,288;231,287,231,286,231,286,230,286,230,286,230,285,230,285,230,284,230,284,230,284,230,283,230,283,230,282,229,281,229,281,229,281,229,280,229,280,229,278,232,278,233,278,234,278,234,278,234,278,234,278,235,278,235,278,236,277,236,277,236,276,237,276,237,276,237,276,238,276,238,276,238,276,238,276,238,276,239,276,240,275,243,272,246,268,247,268,248,268,250,268,250,272,250,274,250,275,250,275,250,275,250,277,250,280,250,286,248,286,247,286,246,286,246,286,246,287,245,287,245,287,244,287,244,287,244,287,244,287,244,288,243,288,243,288,242,288,242,288,242,288,242,288,241,288,241,288,240,288,240,289,239,289,239,290,236,290,234,290,233,289,233,289,233,289,233,289,233,289,233,289,232,290,232,290,231,290,231,289,231,288;402,287,401,286,401,286,401,286,401,286,401,285,401,285,401,284,401,284,400,284,400,283,400,283,400,282,400,281,400,281,400,281,400,280,400,280,400,278,402,278,404,278,405,278,405,278,405,278,405,278,405,278,406,278,406,277,407,277,407,276,407,276,408,276,408,276,408,276,408,276,408,276,409,276,409,276,410,276,411,275,414,272,417,268,417,268,419,268,420,268,420,272,420,274,420,275,421,275,421,275,421,277,421,280,421,286,419,286,417,286,417,286,417,286,416,287,416,287,415,287,415,287,415,287,415,287,415,287,414,288,414,288,413,288,413,288,413,288,413,288,412,288,412,288,411,288,411,288,411,289,410,289,410,290,407,290,405,290,404,289,404,289,404,289,404,289,404,289,404,289,403,290,402,290,402,290,402,289,402,288;22,288,21,288,20,288,19,288,19,288,19,288,19,288,19,288,18,288,18,288,18,287,18,287,18,287,17,287,17,287,16,287,16,287,16,286,16,285,16,285,17,285,17,284,18,284,18,283,18,283,18,282,18,282,18,282,18,282,18,282,18,281,18,281,19,281,19,281,19,280,19,280,19,279,19,279,19,279,20,279,20,279,21,278,21,278,21,278,22,278,22,278,22,277,23,277,23,276,23,276,24,276,24,276,24,276,25,276,25,275,25,275,26,275,26,275,27,275,27,275,27,274,27,274,28,274,28,274,28,274,28,274,28,273,29,272,30,272,31,272,32,272,32,272,32,272,32,272,33,272,34,272,34,272,34,272,34,272,34,272,35,272,35,272,37,274,37,274,37,275,37,275,37,275,37,275,38,275,38,275,38,276,38,276,38,277,39,277,39,277,39,278,39,279,39,280,39,280,38,280,38,280,38,280,38,281,38,281,38,281,38,281,38,281,38,282,38,283,37,284,37,284,37,284,37,284,37,285,37,286,37,287,36,287,35,288,35,288,33,288,31,288,30,288,30,289,30,289,29,289,26,289,23,289,22,289,22,289;192,288,192,288,191,288,190,288,190,288,190,288,190,288,189,288,189,288,188,288,188,287,188,287,188,287,188,287,188,287,187,287,187,287,187,286,187,285,187,285,188,285,188,284,188,284,188,283,188,283,188,282,189,282,189,282,189,282,189,282,189,281,189,281,189,281,189,281,190,280,190,280,190,279,190,279,190,279,190,279,191,279,191,278,191,278,192,278,192,278,192,278,193,277,193,277,193,276,194,276,194,276,194,276,195,276,195,276,195,275,196,275,197,275,197,275,198,275,198,275,198,274,198,274,198,274,199,274,199,274,199,274,199,273,200,272,201,272,202,272,202,272,202,272,202,272,203,272,204,272,204,272,205,272,205,272,205,272,205,272,205,272,206,272,206,273,207,273,207,273,208,274,208,274,208,275,208,275,208,275,208,275,208,275,208,275,208,276,208,276,209,277,209,277,210,277,210,278,210,279,209,280,209,280,209,280,209,280,209,280,209,281,209,281,209,281,208,281,208,281,208,282,208,283,208,284,208,284,208,284,208,284,208,285,208,286,207,287,207,287,206,288,206,288,203,288,202,288,201,288,201,289,201,289,199,289,197,289,194,289,192,289,192,289;363,288,362,288,362,288,361,288,360,288,360,288,360,288,360,288,360,288,359,288,359,287,359,287,359,287,359,287,358,287,358,287,358,287,358,286,358,285,358,285,358,285,359,284,359,284,359,283,359,283,359,282,359,282,359,282,360,282,360,282,360,281,360,281,360,281,360,281,360,280,360,280,360,279,360,279,361,279,361,279,362,279,362,278,362,278,363,278,363,278,363,278,364,277,364,277,364,276,365,276,365,276,365,276,366,276,366,276,366,275,367,275,367,275,368,275,368,275,368,275,368,274,368,274,369,274,369,274,370,274,370,274,370,273,370,272,372,272,372,272,373,272,373,272,373,272,373,272,374,272,375,272,376,272,376,272,376,272,376,272,376,272,376,272,377,273,377,273,378,273,378,274,378,274,378,275,378,275,379,275,379,275,379,275,379,275,379,276,379,276,380,277,380,277,380,277,380,278,380,279,380,280,380,280,380,280,380,280,380,280,380,281,379,281,379,281,379,281,379,281,379,282,379,283,379,284,379,284,378,284,378,284,378,285,378,286,378,287,377,287,377,288,376,288,374,288,373,288,372,288,372,289,372,289,370,289,367,289,365,289,363,289,363,289;56,288,55,288,54,288,53,288,52,287,52,287,52,287,50,287,48,287,45,287,45,287,45,286,44,286,44,286,43,286,42,286,42,285,42,285,42,285,41,285,41,285,40,285,40,285,39,284,39,284,39,282,39,282,39,282,40,281,40,281,40,280,40,280,40,280,40,280,40,279,40,279,40,279,40,278,41,278,41,278,41,278,40,277,39,276,39,276,39,275,39,275,39,275,38,275,38,274,38,274,38,273,38,272,40,272,42,272,43,272,43,272,43,271,44,271,45,271,45,271,46,271,46,271,46,270,47,270,48,270,49,270,50,270,50,271,50,271,50,271,51,271,51,271,52,272,53,273,55,274,55,275,55,276,55,277,55,277,56,278,56,278,56,279,56,279,56,280,56,280,57,280,57,280,57,280,57,281,57,281,57,282,57,282,57,282,58,282,58,283,58,284,58,284,58,284,58,284,58,285,58,285,58,286,58,286,59,286,59,286,59,287,58,288,58,288,56,288,56,288;227,288,226,288,225,288,223,288,222,287,222,287,222,287,221,287,219,287,216,287,216,287,215,286,215,286,214,286,213,286,213,286,212,285,212,285,212,285,212,285,211,285,211,285,210,285,210,284,209,284,209,282,210,282,210,282,210,281,210,281,210,280,210,280,211,280,211,280,211,279,211,279,211,279,211,278,211,278,212,278,211,278,211,277,210,276,210,276,210,275,210,275,209,275,209,275,208,274,208,274,208,273,208,272,211,272,213,272,213,272,214,272,214,271,215,271,215,271,216,271,216,271,216,271,216,270,217,270,219,270,220,270,221,270,221,271,221,271,221,271,221,271,222,271,223,272,224,273,225,274,226,275,226,276,226,277,226,277,226,278,227,278,227,279,227,279,227,280,227,280,227,280,227,280,228,280,228,281,228,281,228,282,228,282,228,282,228,282,228,283,228,284,228,284,229,284,229,284,229,285,229,285,229,286,229,286,229,286,230,286,230,287,229,288,228,288,227,288,227,288;398,288,397,288,395,288,394,288,393,287,393,287,393,287,392,287,390,287,387,287,386,287,386,286,385,286,385,286,384,286,383,286,383,285,383,285,383,285,382,285,382,285,382,285,381,285,381,284,380,284,380,282,381,282,381,282,381,281,381,281,381,280,381,280,381,280,381,280,382,279,382,279,382,279,382,278,382,278,382,278,382,278,381,277,381,276,380,276,380,275,380,275,380,275,380,275,379,274,379,274,379,273,379,272,381,272,384,272,384,272,385,272,385,271,385,271,386,271,386,271,387,271,387,271,387,270,388,270,389,270,391,270,392,270,392,271,392,271,392,271,392,271,392,271,393,272,394,273,396,274,396,275,396,276,396,277,396,277,397,278,397,278,398,279,398,279,398,280,398,280,398,280,398,280,398,280,398,281,398,281,398,282,399,282,399,282,399,282,399,283,399,284,399,284,399,284,399,284,400,285,400,285,400,286,400,286,400,286,400,286,400,287,400,288,399,288,398,288,398,288;82,285,82,284,82,281,82,277,82,277,83,276,83,276,84,276,84,276,85,276,85,275,85,275,85,275,87,275,91,275,95,275,97,275,97,275,97,275,97,276,98,276,98,276,99,276,99,276,99,276,100,276,101,276,102,276,103,276,103,277,104,277,104,277,103,277,103,278,103,278,103,279,103,280,103,281,103,281,102,281,102,282,102,283,102,284,102,285,102,286,101,286,100,286,92,286,84,286,83,285;253,285,253,284,253,281,253,277,253,277,254,276,254,276,255,276,255,276,255,276,256,275,256,275,256,275,258,275,262,275,265,275,268,275,268,275,268,275,268,276,269,276,269,276,270,276,270,276,270,276,270,276,271,276,273,276,273,276,274,277,274,277,274,277,274,277,274,278,274,278,274,279,274,280,273,281,273,281,273,281,273,282,273,283,273,284,273,285,272,286,272,286,270,286,263,286,254,286,254,285;424,285,424,284,424,281,424,277,424,277,424,276,425,276,425,276,426,276,426,276,426,275,426,275,426,275,428,275,432,275,436,275,438,275,438,275,438,275,439,276,439,276,440,276,440,276,440,276,440,276,441,276,442,276,443,276,444,276,444,277,445,277,445,277,445,277,444,278,444,278,444,279,444,280,444,281,444,281,444,281,444,282,444,283,444,284,443,285,443,286,443,286,441,286,434,286,425,286,424,285;12,284,12,283,13,283,14,282,15,282,15,284,15,286,14,286,13,285;121,285,119,285,116,285,113,285,112,285,112,285,112,284,111,284,110,284,109,284,109,284,109,284,108,283,108,283,107,283,107,283,106,282,105,282,104,281,104,280,104,279,104,278,104,277,105,277,105,277,105,276,105,274,105,271,105,270,106,270,106,269,107,269,109,269,111,269,112,269,112,269,112,269,113,270,114,270,115,270,116,270,116,270,116,270,116,270,116,270,117,270,117,270,117,271,117,271,117,271,118,271,118,271,119,271,119,271,119,271,119,272,120,272,120,272,121,272,121,272,121,272,122,272,123,272,123,272,124,272,124,273,124,273,125,273,125,273,126,273,126,273,126,273,126,273,127,274,127,274,128,274,128,274,129,274,129,275,129,275,130,275,130,275,130,275,130,276,130,276,130,277,131,277,131,277,131,279,131,281,131,286,126,286,123,286,121,285,121,285;143,285,142,285,140,285,138,285,136,285,136,285,136,284,135,284,134,284,132,284,132,281,132,278,132,277,132,277,132,277,132,277,132,276,132,276,132,276,132,276,133,276,133,275,133,275,133,275,133,275,134,275,134,275,135,274,136,274,136,273,137,273,137,273,137,273,138,273,139,274,139,275,140,276,140,276,141,276,141,276,141,276,141,276,141,276,142,276,143,276,144,276,144,277,144,277,144,277,145,277,145,277,146,277,146,277,146,277,147,278,148,278,149,278,150,277,150,277,150,277,151,277,153,277,154,277,156,277,156,277,156,276,157,276,158,276,160,276,160,276,160,277,160,278,160,278,160,279,159,279,159,279,159,280,159,280,159,281,159,281,158,281,158,281,158,282,158,282,158,283,158,283,158,283,158,283,158,284,158,284,157,284,157,284,156,284,156,284,156,285,156,285,156,285,155,285,155,285,154,285,154,285,154,285,152,286,149,286,145,286,143,285,143,285;183,284,183,283,183,283,184,282,186,282,186,284,186,286,185,286,184,285;292,285,290,285,287,285,284,285,282,285,282,285,282,284,282,284,281,284,280,284,280,284,279,284,279,283,278,283,278,283,277,283,277,282,276,282,275,281,275,280,275,279,275,278,275,277,275,277,275,277,276,276,276,274,276,271,276,270,276,270,277,269,277,269,280,269,282,269,283,269,283,269,283,269,284,270,285,270,285,270,286,270,286,270,286,270,286,270,287,270,287,270,288,270,288,271,288,271,288,271,289,271,289,271,290,271,290,271,290,271,290,272,291,272,291,272,292,272,292,272,292,272,292,272,293,272,294,272,295,272,295,273,295,273,295,273,296,273,296,273,297,273,297,273,297,273,297,274,298,274,298,274,299,274,299,274,299,275,300,275,300,275,301,275,301,275,301,276,301,276,301,277,301,277,301,277,302,279,302,281,302,286,297,286,293,286,292,285,292,285;314,285,312,285,310,285,308,285,307,285,307,285,307,284,306,284,305,284,303,284,303,281,303,278,303,277,303,277,302,277,302,277,302,276,302,276,302,276,303,276,303,276,304,275,304,275,304,275,304,275,304,275,305,275,306,274,306,274,307,273,307,273,307,273,308,273,308,273,309,274,310,275,311,276,311,276,311,276,312,276,312,276,312,276,312,276,313,276,314,276,314,276,314,277,314,277,315,277,315,277,316,277,316,277,316,277,316,277,317,278,319,278,320,278,321,277,321,277,321,277,322,277,324,277,325,277,326,277,326,277,326,276,327,276,329,276,331,276,331,276,331,277,331,278,331,278,330,279,330,279,330,279,330,280,330,280,329,281,329,281,329,281,329,281,329,282,329,282,329,283,329,283,328,283,328,283,328,284,328,284,328,284,328,284,327,284,327,284,327,285,327,285,326,285,326,285,325,285,325,285,325,285,325,285,323,286,319,286,316,286,314,285,314,285;353,284,353,283,354,283,355,282,356,282,356,284,356,286,355,286,354,285;462,285,460,285,458,285,455,285,453,285,453,285,453,284,452,284,452,284,451,284,450,284,450,284,450,283,449,283,449,283,448,283,447,282,447,282,446,281,446,280,446,279,446,278,446,277,446,277,446,277,446,276,446,274,446,271,446,270,447,270,448,269,448,269,451,269,452,269,454,269,454,269,454,269,454,270,455,270,456,270,457,270,457,270,457,270,457,270,458,270,458,270,458,270,458,271,458,271,459,271,459,271,460,271,460,271,460,271,460,271,461,272,461,272,462,272,462,272,462,272,462,272,463,272,464,272,465,272,466,272,466,273,466,273,466,273,467,273,467,273,468,273,468,273,468,273,468,274,468,274,469,274,470,274,470,274,470,275,471,275,471,275,471,275,472,275,472,276,472,276,472,277,472,277,472,277,472,279,472,281,472,286,467,286,464,286,462,285,462,285;484,285,483,285,481,285,479,285,478,285,478,285,478,284,477,284,476,284,474,284,474,281,474,278,473,277,473,277,473,277,473,277,473,276,473,276,473,276,474,276,474,276,474,275,474,275,474,275,475,275,475,275,476,275,476,274,477,274,477,273,478,273,478,273,478,273,479,273,480,274,481,275,481,276,482,276,482,276,482,276,482,276,482,276,483,276,484,276,484,276,485,276,485,277,485,277,485,277,486,277,486,277,487,277,487,277,487,277,488,278,489,278,491,278,492,277,492,277,492,277,493,277,494,277,496,277,497,277,497,277,497,276,498,276,499,276,501,276,502,276,502,277,502,278,501,278,501,279,500,279,500,279,500,280,500,280,500,281,500,281,500,281,500,281,500,282,500,282,499,283,499,283,499,283,499,283,499,284,499,284,499,284,498,284,498,284,498,284,498,285,498,285,497,285,497,285,496,285,496,285,496,285,496,285,493,286,490,286,486,286,484,285,484,285;11,280,11,280,10,280,10,280,8,279,8,278,8,278,8,277,8,277,7,277,7,276,7,276,7,275,7,275,8,275,8,275,8,275,8,275,8,274,9,274,11,274,12,274,13,274,13,274,13,274,14,274,15,274,17,274,17,275,17,276,17,276,17,276,16,276,16,276,16,277,16,277,13,280,13,280,12,280,12,280,12,281,12,281,12,281,12,281,11,281,11,281,11,281;182,280,181,280,181,280,180,280,179,279,179,278,179,278,179,277,178,277,178,277,178,276,178,276,178,275,178,275,178,275,179,275,179,275,179,275,179,274,180,274,181,274,183,274,184,274,184,274,184,274,184,274,186,274,188,274,188,275,188,276,187,276,187,276,187,276,187,276,187,277,187,277,186,278,185,279,185,279,184,280,183,280,183,280,183,280,183,281,183,281,183,281,182,281,182,281,182,281,182,281;352,280,352,280,352,280,351,280,350,279,350,278,350,278,349,277,349,277,348,277,348,276,348,276,348,275,348,275,349,275,349,275,350,275,350,275,350,274,351,274,352,274,353,274,354,274,354,274,354,274,355,274,356,274,358,274,358,275,358,276,358,276,358,276,358,276,358,276,358,277,358,277,357,278,356,279,355,279,354,280,354,280,354,280,354,280,354,281,354,281,353,281,353,281,352,281,352,281,352,281;16,278,16,278,17,278,17,278,18,277,18,277,18,277,18,276,18,276,19,276,19,275,19,274,19,274,19,274,19,274,19,274,20,274,20,274,20,274,20,274,21,274,21,274,22,274,22,275,23,275,23,275,22,276,22,276,22,276,21,276,21,276,21,276,21,277,20,277,20,278,20,278,19,278,19,278,19,278,18,279,16,279,16,279;187,278,187,278,188,278,188,278,188,277,188,277,188,277,188,276,189,276,189,276,190,275,190,274,190,274,190,274,190,274,190,274,190,274,190,274,190,274,191,274,191,274,192,274,193,274,193,275,193,275,193,275,193,276,193,276,192,276,192,276,192,276,191,276,191,277,191,277,190,278,190,278,190,278,189,278,189,278,189,279,187,279,187,279;358,278,358,278,358,278,359,278,359,277,359,277,359,277,359,276,360,276,360,276,360,275,360,274,360,274,360,274,361,274,361,274,361,274,361,274,361,274,361,274,362,274,363,274,363,274,364,275,364,275,364,275,364,276,363,276,363,276,363,276,363,276,362,276,362,277,362,277,361,278,361,278,361,278,360,278,360,278,359,279,358,279,358,279;5,278,4,278,4,278,3,278,2,276,2,275,2,275,2,275,2,275,3,275,3,275,3,275,3,275,3,276,4,276,4,276,4,276,4,276,4,276,4,276,5,276,5,276,6,276,6,277,6,278,5,278,5,278,5,278,5,278,5,278;176,278,175,278,175,278,174,278,172,276,172,275,172,275,172,275,173,275,173,275,174,275,174,275,174,275,174,276,174,276,175,276,175,276,175,276,175,276,175,276,176,276,176,276,176,276,176,277,176,278,176,278,176,278,176,278,176,278,176,278;346,278,346,278,345,278,344,278,343,276,343,275,343,275,343,275,344,275,344,275,344,275,344,275,344,275,344,276,345,276,345,276,346,276,346,276,346,276,346,276,346,276,347,276,347,276,347,277,347,278,347,278,347,278,346,278,346,278,346,278;146,276,145,276,145,276,144,276,144,275,144,275,144,275,143,275,142,275,141,275,141,275,141,274,140,274,140,274,139,274,139,274,139,273,139,273,139,272,139,271,138,271,138,271,138,270,138,270,138,269,137,269,137,269,137,269,137,268,137,268,137,268,138,267,138,267,138,265,138,265,138,265,139,264,139,264,139,263,139,263,139,263,139,263,140,263,140,263,141,262,141,262,141,262,142,262,142,262,142,261,142,261,142,261,142,261,143,261,143,261,144,260,146,259,147,257,148,256,148,256,149,256,149,256,149,256,149,256,149,256,150,256,151,256,152,256,154,258,155,259,156,261,156,261,156,261,156,262,157,262,157,262,158,263,158,263,158,263,158,264,158,264,158,264,158,264,158,264,158,265,158,265,159,265,159,265,159,265,159,265,159,266,159,266,160,267,160,267,160,267,160,268,160,268,160,268,161,268,161,268,161,268,161,269,161,269,161,270,161,270,161,270,162,270,162,270,162,271,162,272,162,272,163,272,163,273,162,274,161,275,161,275,159,275,158,275,157,275,157,275,157,275,156,276,154,276,152,276,151,276,151,276,151,276,150,276,148,276,147,276,146,276,146,276;316,276,316,276,315,276,315,276,314,275,314,275,314,275,314,275,313,275,312,275,312,275,311,274,311,274,310,274,310,274,310,274,310,273,310,273,310,272,309,271,309,271,308,271,308,270,308,270,308,269,308,269,308,269,307,269,307,268,308,268,308,268,308,267,308,267,308,265,308,265,309,265,309,264,310,264,310,263,310,263,310,263,310,263,310,263,311,263,311,262,311,262,312,262,312,262,313,262,313,261,313,261,313,261,313,261,313,261,314,261,315,260,316,259,317,257,319,256,319,256,319,256,320,256,320,256,320,256,320,256,321,256,322,256,322,256,324,258,326,259,327,261,327,261,327,261,327,262,328,262,328,262,328,263,328,263,328,263,328,264,329,264,329,264,329,264,329,264,329,265,329,265,329,265,329,265,330,265,330,265,330,266,330,266,330,267,331,267,331,267,331,268,331,268,331,268,331,268,331,268,332,268,332,269,332,269,332,270,332,270,332,270,332,270,332,270,332,271,332,272,333,272,334,272,334,273,333,274,332,275,332,275,330,275,328,275,328,275,328,275,328,275,326,276,325,276,323,276,322,276,322,276,322,276,320,276,319,276,317,276,316,276,316,276;487,276,486,276,486,276,485,276,485,275,485,275,485,275,484,275,484,275,483,275,482,275,482,274,482,274,481,274,481,274,480,274,480,273,480,273,480,272,480,271,480,271,479,271,479,270,479,270,479,269,479,269,478,269,478,269,478,268,478,268,479,268,479,267,479,267,479,265,479,265,480,265,480,264,480,264,480,263,480,263,480,263,481,263,481,263,482,263,482,262,482,262,483,262,483,262,483,262,484,261,484,261,484,261,484,261,484,261,484,261,486,260,487,259,488,257,489,256,490,256,490,256,490,256,490,256,490,256,491,256,491,256,492,256,493,256,495,258,496,259,498,261,498,261,498,261,498,262,498,262,499,262,499,263,499,263,499,263,499,264,499,264,499,264,500,264,500,264,500,265,500,265,500,265,500,265,500,265,500,265,500,266,500,266,501,267,501,267,502,267,502,268,502,268,502,268,502,268,502,268,502,268,502,269,502,269,502,270,503,270,503,270,503,270,503,270,503,271,503,272,504,272,504,272,504,273,503,274,503,275,502,275,500,275,499,275,498,275,498,275,498,275,497,276,495,276,493,276,492,276,492,276,492,276,491,276,490,276,488,276,487,276,487,276;58,274,58,274,57,274,56,274,55,272,55,271,55,271,55,271,55,271,54,271,54,271,54,270,54,270,54,270,56,270,57,270,58,269,58,269,58,269,58,269,59,269,60,269,60,269,60,269,60,269,61,270,63,270,64,270,65,270,65,270,65,270,66,270,67,270,68,270,69,270,69,271,69,271,69,271,70,271,71,271,71,271,71,271,71,272,69,274,69,274,68,274,68,274,68,274,68,274,68,274,68,274,67,274,67,274,67,275,67,275,65,275,63,275,59,275,59,275,59,274;82,274,82,273,82,272,82,269,82,269,83,268,84,267,84,267,86,267,87,267,88,267,88,267,88,266,88,266,89,266,91,266,91,266,92,267,92,267,93,268,95,268,96,268,98,268,98,268,98,268,98,268,99,268,101,268,101,268,102,269,103,270,104,271,104,272,104,273,103,274,103,274,103,274,103,274,103,274,103,275,103,275,101,275,100,275,100,275,100,275,100,274,99,274,98,274,97,274,97,274,97,274,97,274,95,274,92,274,88,274,86,274,86,274,86,274,85,274,85,274,84,274,83,274,83,275,83,275,82,275,82,274;128,273,128,272,127,272,127,272,126,272,126,272,126,272,126,272,125,272,125,272,124,271,124,271,124,271,123,271,123,271,121,271,121,271,121,270,121,269,121,269,121,269,121,269,122,268,122,268,122,267,122,266,122,266,122,266,122,266,122,266,122,265,122,265,123,265,123,265,123,264,123,264,123,263,124,262,125,262,126,262,126,262,126,262,126,262,127,262,128,262,129,262,130,261,130,261,130,261,130,261,131,261,132,261,132,261,132,261,132,261,132,262,133,262,133,262,134,262,134,262,134,262,134,262,135,262,135,262,136,262,136,263,136,263,136,263,136,263,137,263,137,263,137,264,137,264,137,265,137,265,136,265,136,266,136,267,136,269,136,270,136,270,136,270,136,270,136,271,136,272,135,272,135,272,135,272,135,272,135,273,135,273,135,274,134,274,133,274,133,274,133,274,133,274,133,274,132,274,132,274,132,274,132,275,132,275,130,275,129,274;229,274,228,274,228,274,227,274,226,272,226,271,226,271,225,271,225,271,225,271,225,271,225,270,225,270,225,270,227,270,227,270,228,269,228,269,228,269,229,269,230,269,230,269,231,269,231,269,231,269,232,270,233,270,235,270,236,270,236,270,236,270,236,270,238,270,239,270,240,270,240,271,240,271,240,271,241,271,242,271,242,272,241,273,240,273,240,274,239,274,239,274,239,274,239,274,239,274,239,274,238,274,238,274,238,274,238,275,238,275,236,275,234,275,230,275,230,275,229,274;252,274,252,273,252,272,252,269,252,269,253,268,254,267,255,267,256,267,257,267,258,267,258,267,258,266,259,266,260,266,262,266,262,266,263,267,263,267,263,268,266,268,267,268,268,268,268,268,268,268,269,268,270,268,272,268,272,268,273,269,274,270,274,271,274,272,274,273,274,274,274,274,274,274,274,274,274,274,274,275,273,275,272,275,271,275,270,275,270,275,270,274,270,274,269,274,268,274,268,274,268,274,268,274,266,274,262,274,259,274,257,274,257,274,257,274,256,274,255,274,254,274,254,274,254,275,254,275,253,275,253,274;299,273,298,272,298,272,297,272,297,272,297,272,297,272,296,272,296,272,295,272,295,271,295,271,295,271,294,271,293,271,292,271,292,271,292,270,292,269,292,269,292,269,292,269,292,268,292,268,292,267,292,266,293,266,293,266,293,266,293,266,293,265,293,265,293,265,293,265,294,264,294,264,294,263,294,262,296,262,296,262,297,262,297,262,297,262,298,262,299,262,299,262,300,261,300,261,300,261,301,261,302,261,302,261,303,261,303,261,303,261,303,262,304,262,304,262,304,262,304,262,304,262,305,262,305,262,306,262,306,262,306,263,306,263,306,263,307,263,307,263,308,263,308,264,308,264,307,265,307,265,307,265,307,266,307,267,307,269,307,270,307,270,306,270,306,270,306,271,306,272,306,272,306,272,306,272,306,272,306,273,306,273,305,274,305,274,304,274,304,274,304,274,304,274,303,274,303,274,302,274,302,274,302,275,302,275,301,275,300,274;400,274,399,274,399,274,398,274,396,272,396,271,396,271,396,271,396,271,396,271,396,271,396,270,396,270,396,270,397,270,398,270,399,269,399,269,399,269,399,269,400,269,401,269,402,269,402,269,402,269,403,270,404,270,405,270,406,270,406,270,406,270,407,270,408,270,409,270,410,270,410,271,410,271,411,271,411,271,412,271,412,272,411,273,411,273,410,274,410,274,410,274,410,274,410,274,410,274,409,274,409,274,408,274,408,274,408,275,408,275,407,275,404,275,401,275,400,275,400,274;423,274,423,273,423,272,423,269,423,269,424,268,425,267,425,267,427,267,428,267,429,267,429,267,429,266,430,266,431,266,432,266,433,266,433,267,434,267,434,268,436,268,438,268,439,268,439,268,439,268,440,268,441,268,442,268,443,268,444,269,445,270,445,271,445,272,445,273,445,274,445,274,444,274,444,274,444,274,444,275,444,275,443,275,442,275,441,275,441,275,441,274,440,274,440,274,439,274,438,274,438,274,438,274,436,274,433,274,430,274,428,274,428,274,428,274,427,274,426,274,425,274,424,274,424,275,424,275,424,275,423,274;470,273,469,272,468,272,468,272,468,272,468,272,468,272,467,272,467,272,466,272,466,271,466,271,466,271,465,271,464,271,462,271,462,271,462,270,462,269,462,269,463,269,463,269,463,268,463,268,463,267,463,266,463,266,463,266,464,266,464,266,464,265,464,265,464,265,464,265,464,264,464,264,464,263,465,262,466,262,467,262,468,262,468,262,468,262,468,262,469,262,470,262,471,261,471,261,471,261,471,261,472,261,473,261,474,261,474,261,474,261,474,262,474,262,475,262,475,262,475,262,475,262,475,262,476,262,476,262,477,262,477,263,477,263,477,263,478,263,478,263,478,263,478,264,478,264,478,265,478,265,478,265,478,266,478,267,478,269,477,270,477,270,477,270,477,270,477,271,477,272,477,272,477,272,476,272,476,272,476,273,476,273,476,274,475,274,475,274,474,274,474,274,474,274,474,274,474,274,473,274,473,274,473,275,473,275,472,275,471,274;173,274,172,274,171,274,170,274,169,273,169,273,169,273,168,273,167,273,165,273,165,273,164,272,163,271,163,270,163,270,163,269,163,269,162,269,162,268,162,268,162,268,162,267,161,267,161,267,160,266,160,266,160,264,160,262,161,262,162,262,163,262,163,262,164,263,164,263,166,263,167,263,168,263,168,263,168,263,169,264,170,264,170,264,171,264,171,264,171,264,172,264,172,264,174,264,175,265,175,266,175,266,175,267,175,267,175,267,176,267,176,268,176,268,176,268,176,268,176,268,176,269,176,270,176,270,176,271,177,271,177,271,177,271,177,272,177,272,177,272,177,272,177,272,178,272,178,273,178,273,177,274,177,274,176,274,176,274,176,274,176,274,175,274,175,274,174,274,173,274,173,274;344,274,343,274,342,274,340,274,340,273,340,273,340,273,339,273,338,273,336,273,336,273,335,272,334,271,334,270,334,270,334,269,333,269,333,269,332,268,332,268,332,268,332,267,332,267,332,267,331,266,331,266,331,264,331,262,332,262,333,262,333,262,334,262,334,263,335,263,337,263,338,263,339,263,339,263,339,263,339,264,340,264,341,264,342,264,342,264,342,264,342,264,343,264,345,264,346,265,346,266,346,266,346,267,346,267,346,267,346,267,346,268,346,268,346,268,347,268,347,268,347,269,347,270,347,270,347,271,347,271,347,271,348,271,348,272,348,272,348,272,348,272,348,272,348,272,348,273,348,273,348,274,348,274,347,274,347,274,347,274,347,274,346,274,345,274,344,274,344,274,344,274;514,274,513,274,512,274,511,274,510,273,510,273,510,273,509,273,508,273,507,273,506,273,505,272,505,271,504,270,504,270,504,269,504,269,504,269,503,268,503,268,503,268,503,267,503,267,502,267,502,266,502,266,502,264,502,262,503,262,504,262,504,262,505,262,505,263,505,263,507,263,509,263,510,263,510,263,510,263,510,264,511,264,512,264,512,264,512,264,512,264,513,264,514,264,515,264,516,265,516,266,516,266,516,267,517,267,517,267,517,267,517,268,517,268,517,268,517,268,517,268,518,269,518,270,518,270,518,271,518,271,518,271,518,271,518,272,518,272,518,272,519,272,519,272,519,272,519,273,519,273,519,274,518,274,518,274,518,274,518,274,518,274,517,274,516,274,515,274,514,274,514,274;7,271,7,270,7,269,7,269,7,268,7,268,6,268,6,268,6,268,6,267,6,267,6,267,6,267,6,266,6,265,6,263,5,262,5,262,5,262,5,262,5,261,5,261,5,260,5,260,5,260,6,260,6,260,6,259,6,259,6,259,7,259,8,260,8,260,8,261,9,262,10,262,11,262,12,262,12,262,12,262,12,262,13,262,13,262,14,262,14,263,14,263,15,263,17,263,18,263,20,263,20,263,20,263,20,264,21,264,22,264,23,264,23,264,23,264,24,264,26,264,28,264,28,267,28,268,28,269,28,269,28,269,28,269,28,270,28,270,27,271,27,271,27,271,27,271,27,271,27,273,26,273,22,273,20,273,18,273,18,273,18,272,17,272,16,272,15,272,14,272,14,273,14,273,13,273,12,273,9,273,9,273,8,272;178,271,178,270,178,269,178,269,177,268,177,268,177,268,177,268,177,268,177,267,177,267,177,267,176,267,176,266,176,265,176,263,176,262,176,262,176,262,176,262,176,261,176,261,176,260,176,260,176,260,176,260,176,260,176,259,176,259,177,259,178,259,179,260,179,260,179,261,180,262,181,262,182,262,182,262,182,262,182,262,183,262,183,262,184,262,184,262,184,263,184,263,185,263,187,263,189,263,190,263,190,263,190,263,191,264,192,264,193,264,194,264,194,264,194,264,195,264,196,264,199,264,199,267,199,268,199,269,199,269,198,269,198,269,198,270,198,270,198,271,198,271,198,271,198,271,198,271,198,273,197,273,193,273,190,273,189,273,189,273,189,272,188,272,187,272,186,272,185,272,185,273,185,273,184,273,182,273,180,273,180,273,179,272;348,271,348,270,348,269,348,269,348,268,348,268,348,268,348,268,348,268,348,267,347,267,347,267,347,267,347,266,347,265,347,263,347,262,347,262,346,262,346,262,346,261,346,261,346,260,347,260,347,260,347,260,347,260,347,259,347,259,348,259,349,259,350,260,350,260,350,261,350,262,352,262,352,262,353,262,353,262,353,262,353,262,354,262,354,262,355,262,355,263,355,263,356,263,358,263,360,263,361,263,361,263,361,263,362,264,363,264,363,264,364,264,364,264,364,264,365,264,367,264,370,264,370,267,370,268,369,269,369,269,369,269,369,269,369,270,369,270,369,271,369,271,368,271,368,271,368,271,368,273,367,273,363,273,361,273,360,273,360,273,360,272,359,272,358,272,356,272,356,272,356,273,356,273,354,273,353,273,350,273,350,273,349,272;32,270,32,270,32,270,31,270,31,269,31,268,31,267,31,267,31,267,30,267,30,264,31,263,31,263,32,263,32,263,32,263,33,263,33,263,33,262,34,262,35,262,35,262,36,262,36,262,36,262,38,262,42,262,45,262,48,261,48,261,48,261,49,261,52,261,54,261,56,261,56,261,56,260,57,260,58,261,58,261,58,262,58,264,58,267,57,267,57,267,56,267,56,267,56,267,55,268,53,268,51,268,50,268,50,268,50,268,48,268,47,268,45,268,44,268,44,269,44,269,43,269,42,269,41,269,40,269,40,269,40,269,38,270,37,270,35,270,34,270,34,270,34,270,34,270,33,270,33,270,32,270,32,270;203,270,203,270,202,270,202,270,202,269,202,268,202,267,201,267,201,267,201,267,201,264,201,263,202,263,202,263,203,263,203,263,204,263,204,263,204,262,204,262,205,262,206,262,207,262,207,262,207,262,209,262,213,262,216,262,218,261,218,261,218,261,220,261,222,261,225,261,226,261,226,261,226,260,228,260,228,261,229,261,229,262,229,264,229,267,228,267,227,267,227,267,227,267,227,267,226,268,224,268,222,268,220,268,220,268,220,268,219,268,218,268,216,268,215,268,215,269,215,269,214,269,213,269,211,269,210,269,210,269,210,269,209,270,208,270,206,270,205,270,205,270,205,270,204,270,204,270,203,270,203,270,203,270;374,270,373,270,373,270,372,270,372,269,372,268,372,267,372,267,372,267,371,267,371,264,372,263,372,263,373,263,373,263,374,263,374,263,374,263,374,262,375,262,376,262,377,262,378,262,378,262,378,262,380,262,383,262,387,262,389,261,389,261,389,261,390,261,393,261,395,261,397,261,397,261,397,260,398,260,399,261,399,261,400,262,400,264,400,267,399,267,398,267,398,267,398,267,398,267,396,268,394,268,392,268,391,268,391,268,391,268,390,268,388,268,387,268,386,268,386,269,386,269,385,269,383,269,382,269,381,269,381,269,381,269,380,270,378,270,377,270,376,270,376,270,376,270,375,270,375,270,374,270,374,270,374,270;118,268,118,268,117,268,117,268,116,268,116,268,116,268,116,268,115,268,115,268,114,267,114,267,114,267,113,267,112,267,110,267,109,267,109,267,109,266,107,266,103,266,100,266,98,266,98,267,98,267,97,267,97,267,96,267,96,267,96,267,96,266,95,266,95,266,94,266,94,266,94,265,94,264,94,264,96,264,96,264,97,264,97,264,97,264,97,264,98,264,98,264,98,263,98,263,98,263,99,263,100,263,100,263,101,263,101,263,101,262,101,262,102,262,102,262,102,262,102,262,102,262,103,262,104,262,104,262,105,261,105,261,105,261,105,261,106,261,106,261,106,261,106,261,106,260,107,260,108,260,108,260,109,260,109,260,109,260,109,260,110,260,110,260,110,259,110,259,110,259,111,259,112,259,113,259,114,259,114,259,114,258,114,258,114,258,115,258,115,258,115,259,115,259,115,259,116,259,116,259,117,259,117,260,117,260,118,260,118,260,119,260,122,262,122,263,122,264,121,264,121,264,121,264,121,264,121,265,121,265,121,266,121,266,120,266,120,266,120,267,120,268,120,268,120,268,119,268,119,268,119,269,119,269,119,269,119,269,118,269,118,269,118,269;289,268,288,268,288,268,287,268,287,268,287,268,287,268,286,268,286,268,285,268,285,267,285,267,285,267,284,267,282,267,281,267,280,267,280,267,280,266,277,266,274,266,270,266,268,266,268,267,268,267,268,267,267,267,267,267,266,267,266,267,266,266,266,266,266,266,265,266,265,266,265,265,265,264,265,264,266,264,267,264,268,264,268,264,268,264,268,264,268,264,269,264,269,263,269,263,269,263,269,263,270,263,271,263,272,263,272,263,272,262,272,262,272,262,273,262,273,262,273,262,273,262,273,262,274,262,275,262,276,261,276,261,276,261,276,261,276,261,277,261,277,261,277,261,277,260,277,260,278,260,279,260,280,260,280,260,280,260,280,260,280,260,281,260,281,259,281,259,281,259,282,259,283,259,283,259,284,259,284,259,284,258,284,258,285,258,285,258,286,258,286,259,286,259,286,259,286,259,287,259,288,259,288,260,288,260,289,260,289,260,290,260,292,262,292,263,292,264,292,264,292,264,292,264,292,264,292,265,292,265,291,266,291,266,291,266,291,266,291,267,291,268,291,268,290,268,290,268,290,268,290,269,290,269,289,269,289,269,289,269,289,269,289,269;460,268,459,268,459,268,458,268,458,268,458,268,458,268,457,268,457,268,456,268,456,267,456,267,456,267,454,267,453,267,451,267,450,267,450,267,450,266,448,266,445,266,441,266,439,266,439,267,439,267,438,267,438,267,437,267,437,267,437,267,437,266,437,266,436,266,436,266,436,266,436,265,436,264,436,264,437,264,438,264,438,264,438,264,438,264,438,264,439,264,439,264,440,263,440,263,440,263,440,263,441,263,442,263,442,263,442,263,442,262,442,262,443,262,443,262,444,262,444,262,444,262,444,262,445,262,446,262,446,261,446,261,446,261,446,261,447,261,447,261,448,261,448,261,448,260,448,260,449,260,450,260,450,260,450,260,450,260,450,260,451,260,451,260,452,259,452,259,452,259,452,259,453,259,454,259,455,259,455,259,455,258,455,258,456,258,456,258,456,258,456,259,456,259,457,259,457,259,458,259,458,259,459,260,459,260,459,260,460,260,461,260,463,262,463,263,463,264,463,264,463,264,462,264,462,264,462,265,462,265,462,266,462,266,462,266,462,266,462,267,462,268,461,268,461,268,460,268,460,268,460,269,460,269,460,269,460,269,460,269,460,269,460,269;73,266,72,266,70,266,68,266,66,266,66,266,66,266,65,266,64,266,61,266,60,265,60,262,60,260,61,260,64,260,66,260,68,260,68,260,68,260,69,260,70,260,72,260,73,260,73,260,73,260,73,260,74,260,76,260,76,261,76,264,76,265,76,266,76,266,75,267,73,267,73,267;244,266,242,266,240,266,238,266,237,266,237,266,237,266,236,266,235,266,232,266,231,265,231,262,231,260,231,260,235,260,237,260,238,260,238,260,238,260,239,260,241,260,242,260,244,260,244,260,244,260,244,260,245,260,246,260,247,261,247,264,247,265,247,266,246,266,246,267,244,267,244,267;414,266,413,266,411,266,409,266,408,266,408,266,408,266,407,266,405,266,403,266,402,265,402,262,402,260,402,260,406,260,408,260,409,260,409,260,409,260,410,260,412,260,413,260,414,260,414,260,414,260,415,260,415,260,417,260,418,261,418,264,418,265,417,266,417,266,416,267,414,267,414,267;77,263,78,260,80,260,80,260,81,260,81,260,81,260,81,260,82,260,82,260,83,259,83,259,83,259,84,259,85,259,85,259,86,259,86,259,86,258,86,258,87,258,87,258,88,258,88,259,88,259,88,259,88,259,89,259,90,259,90,260,91,260,91,261,91,262,91,265,91,265,84,265,80,265,78,265,78,264;247,263,249,260,251,260,251,260,252,260,252,260,252,260,252,260,253,260,253,260,254,259,254,259,254,259,254,259,255,259,256,259,257,259,257,259,257,258,257,258,258,258,258,258,258,258,258,259,258,259,259,259,259,259,259,259,260,259,261,260,261,260,262,261,262,262,262,265,261,265,255,265,250,265,249,265,249,264;418,263,419,260,421,260,422,260,422,260,422,260,422,260,423,260,423,260,424,260,424,259,424,259,424,259,425,259,426,259,427,259,428,259,428,259,428,258,428,258,428,258,429,258,429,258,429,259,429,259,429,259,430,259,430,259,431,259,431,260,432,260,432,261,432,262,432,265,432,265,425,265,421,265,420,265,419,264;92,261,92,261,93,261,93,261,94,261,94,261,94,261,94,262,95,262,95,262,96,262,96,262,96,263,95,263,95,263,94,263,94,263,94,263,94,263,94,264,93,264,92,264,92,263,92,262;263,261,263,261,264,261,264,261,264,261,264,261,264,261,265,262,265,262,266,262,266,262,266,262,266,263,266,263,266,263,265,263,265,263,265,263,265,263,264,264,264,264,263,264,263,263,263,262;434,261,434,261,434,261,435,261,435,261,435,261,435,261,435,262,436,262,437,262,437,262,437,262,437,263,437,263,436,263,436,263,436,263,436,263,436,263,435,264,435,264,434,264,434,263,434,262;1,262,1,261,1,260,2,260,2,260,3,260,3,261,4,262,4,262,4,263,3,263,3,263,2,263,1,263,1,262;171,262,171,261,172,260,172,260,173,260,173,260,174,261,174,262,174,262,174,263,174,263,173,263,173,263,172,263,172,262;342,262,342,261,343,260,343,260,343,260,344,260,344,261,345,262,345,262,345,263,345,263,344,263,343,263,343,263,343,262;168,262,167,262,166,262,165,262,164,261,164,261,164,261,164,261,164,261,163,261,163,261,163,261,163,260,162,260,162,260,160,260,160,258,160,257,160,256,161,256,162,255,162,255,165,255,167,255,169,255,169,255,169,254,170,254,171,254,171,254,172,254,172,255,172,255,173,255,175,255,177,255,178,255,178,257,178,257,178,258,178,258,177,258,177,258,177,258,177,258,176,258,174,258,171,258,171,260,171,262,170,262,169,262,168,262,168,262;339,262,338,262,337,262,336,262,335,261,335,261,335,261,335,261,334,261,334,261,334,261,334,261,334,260,333,260,332,260,331,260,331,258,331,257,331,256,332,256,332,255,333,255,336,255,338,255,340,255,340,255,340,254,340,254,341,254,342,254,343,254,343,255,343,255,344,255,345,255,348,255,349,255,349,257,349,257,349,258,348,258,348,258,348,258,348,258,348,258,346,258,345,258,342,258,342,260,342,262,340,262,339,262,339,262,339,262;510,262,509,262,508,262,506,262,506,261,506,261,506,261,505,261,505,261,504,261,504,261,504,261,504,260,504,260,503,260,502,260,502,258,502,257,502,256,502,256,503,255,503,255,507,255,509,255,510,255,510,255,510,254,511,254,512,254,513,254,514,254,514,255,514,255,515,255,516,255,519,255,520,255,520,257,520,257,519,258,519,258,518,258,518,258,518,258,518,258,517,258,515,258,512,258,512,260,512,262,511,262,510,262,510,262,510,262;14,261,13,261,13,261,12,261,12,261,12,261,12,260,12,260,11,260,10,260,10,258,10,256,10,255,13,255,13,255,14,255,14,255,14,254,17,254,23,254,28,254,31,254,31,254,31,254,32,254,34,254,36,254,37,254,37,254,37,254,37,254,37,254,38,254,38,254,38,255,39,255,39,255,37,257,36,258,35,259,35,260,35,260,35,260,34,260,34,260,34,260,34,261,34,261,31,261,27,261,22,261,20,261,20,261,20,261,18,262,17,262,15,262,14,261,14,261;98,261,98,261,98,261,99,260,99,260,99,260,99,259,100,258,101,258,102,258,102,258,102,259,102,259,103,259,103,259,104,259,104,259,104,260,104,260,104,260,103,260,102,260,102,260,101,261,101,261,100,262,99,262,98,262,98,261,98,261;136,261,136,261,135,261,135,261,134,261,134,261,134,260,134,260,134,260,132,260,132,257,133,256,133,255,134,255,135,255,135,255,136,255,136,255,136,254,137,254,139,254,140,254,142,254,142,254,142,254,142,254,142,254,143,254,143,254,143,254,143,254,143,254,144,254,144,254,145,254,145,255,145,255,145,255,146,255,147,255,147,255,147,255,147,256,144,259,143,259,143,259,143,259,143,259,143,259,143,260,142,260,142,260,142,260,142,260,142,260,140,260,140,260,140,259,140,259,140,260,140,260,139,260,139,260,138,260,138,260,138,261,138,261,138,261,138,261,137,261,137,261,137,261,137,261,137,262,137,262,136,262,136,261,136,261;184,261,184,261,184,261,183,261,183,261,183,261,183,260,182,260,182,260,180,260,180,258,180,256,181,255,183,255,184,255,185,255,185,255,185,254,188,254,193,254,199,254,202,254,202,254,202,254,203,254,205,254,206,254,208,254,208,254,208,254,208,254,208,254,208,254,209,254,209,255,209,255,209,255,208,257,206,258,206,259,206,260,206,260,205,260,205,260,204,260,204,260,204,261,204,261,202,261,197,261,193,261,190,261,190,261,190,261,189,262,187,262,185,262,184,261,184,261;268,261,268,261,269,261,269,260,270,260,270,260,270,259,270,258,272,258,272,258,273,258,273,259,273,259,273,259,274,259,275,259,275,259,275,260,275,260,275,260,274,260,273,260,272,260,272,261,271,261,271,262,270,262,269,262,268,261,268,261;307,261,306,261,306,261,305,261,305,261,305,261,305,260,305,260,304,260,303,260,302,257,304,256,304,255,305,255,305,255,306,255,306,255,306,255,306,254,307,254,309,254,311,254,312,254,312,254,312,254,312,254,313,254,313,254,314,254,314,254,314,254,314,254,315,254,315,254,316,254,316,255,316,255,316,255,317,255,318,255,318,256,316,257,315,258,314,259,314,259,314,259,314,259,314,259,314,259,313,260,313,260,312,260,312,260,312,260,312,260,311,260,311,260,311,259,310,259,310,260,310,260,310,260,309,260,309,260,309,260,309,261,309,261,309,261,308,261,308,261,308,261,308,261,308,261,307,262,307,262,307,262,307,261,307,261;355,261,355,261,354,261,354,261,354,261,354,261,354,260,353,260,352,260,351,260,351,258,351,256,352,255,354,255,355,255,356,255,356,255,356,254,359,254,364,254,369,254,372,254,372,254,372,254,373,254,375,254,377,254,378,254,378,254,378,254,378,254,379,254,379,254,379,254,380,255,380,255,380,255,378,257,377,258,376,259,376,260,376,260,376,260,376,260,375,260,375,260,375,261,375,261,372,261,368,261,363,261,361,261,361,261,361,261,360,262,358,262,356,262,355,261,355,261;439,261,439,261,440,261,440,260,440,260,440,260,440,259,441,258,442,258,443,258,444,258,444,259,444,259,444,259,445,259,445,259,446,259,446,260,446,260,445,260,444,260,443,260,443,260,443,261,442,261,442,262,440,262,440,262,439,261,439,261;478,261,477,261,477,261,476,261,476,261,476,261,476,260,475,260,475,260,473,260,473,257,474,256,475,255,476,255,476,255,476,255,477,255,477,255,477,254,478,254,480,254,482,254,483,254,483,254,483,254,483,254,484,254,484,254,484,254,484,254,484,254,485,254,485,254,486,254,486,254,486,255,486,255,487,255,487,255,489,255,488,256,487,257,486,258,485,259,485,259,484,259,484,259,484,259,484,259,484,260,484,260,483,260,483,260,483,260,483,260,482,260,481,260,481,259,481,259,481,260,481,260,480,260,480,260,480,260,480,260,480,261,480,261,479,261,479,261,478,261,478,261,478,261,478,261,478,262,478,262,478,262,478,261,478,261;94,259,93,259,92,259,92,259,91,259,91,258,91,258,90,258,90,258,89,258,89,257,89,257,88,256,88,256,87,256,87,256,87,256,87,256,87,255,86,255,86,254,85,253,84,252,84,252,84,252,83,251,83,251,82,251,82,250,82,249,82,249,81,249,81,249,81,249,81,249,81,248,81,248,81,248,83,248,83,248,84,248,84,248,84,248,85,248,86,248,86,248,87,248,87,249,87,249,87,249,88,249,88,249,88,249,88,249,88,249,91,250,97,250,105,250,105,250,106,250,106,251,107,251,108,251,108,251,109,251,109,252,109,252,110,252,111,252,111,252,112,252,112,253,112,254,111,254,110,254,109,254,108,254,108,254,108,254,107,254,105,254,101,254,100,255,99,255,99,256,99,256,99,256,99,257,98,257,98,257,98,258,98,259,98,259,97,260,97,260,97,260,97,260,97,260,97,261,95,261,94,260;264,259,264,259,263,259,263,259,262,259,262,258,262,258,261,258,261,258,260,258,259,257,259,257,259,256,258,256,258,256,258,256,258,256,258,256,258,255,257,255,256,254,255,253,255,252,255,252,255,252,254,251,254,251,253,251,252,250,252,249,252,249,252,249,252,249,252,249,252,249,252,248,252,248,252,248,253,248,254,248,255,248,255,248,255,248,255,248,256,248,257,248,258,248,258,249,258,249,258,249,258,249,259,249,259,249,259,249,259,249,262,250,267,250,276,250,276,250,277,250,277,251,277,251,278,251,279,251,280,251,280,252,280,252,281,252,281,252,282,252,282,252,282,253,282,254,282,254,281,254,280,254,279,254,279,254,279,254,277,254,275,254,272,254,271,255,270,255,270,256,270,256,270,256,269,257,269,257,268,257,268,258,268,259,268,259,268,260,268,260,268,260,268,260,268,260,268,261,266,261,265,260;435,259,434,259,434,259,433,259,433,259,433,258,432,258,432,258,431,258,431,258,430,257,430,257,430,256,429,256,429,256,428,256,428,256,428,256,428,255,428,255,427,254,426,253,426,252,426,252,426,252,425,251,424,251,424,251,423,250,423,249,423,249,423,249,423,249,422,249,422,249,422,248,422,248,422,248,424,248,425,248,426,248,426,248,426,248,426,248,427,248,428,248,428,248,428,249,428,249,428,249,429,249,429,249,430,249,430,249,430,249,433,250,438,250,446,250,447,250,447,250,447,251,448,251,449,251,450,251,450,251,451,252,451,252,451,252,452,252,453,252,453,252,453,253,453,254,453,254,451,254,450,254,450,254,450,254,450,254,448,254,446,254,442,254,441,255,441,255,440,256,440,256,440,256,440,257,440,257,439,257,439,258,439,259,439,259,439,260,439,260,438,260,438,260,438,260,438,261,437,261,436,260;53,260,51,260,49,260,47,260,46,259,46,259,46,259,44,259,42,259,39,259,38,259,38,258,38,258,38,258,38,257,39,256,39,256,41,256,42,256,42,256,43,256,43,255,43,255,45,255,45,255,46,255,46,255,46,254,48,254,50,254,52,254,53,254,53,255,53,255,53,255,54,255,55,255,56,255,56,255,56,255,56,256,56,256,57,256,57,256,57,256,57,256,57,256,58,256,58,256,58,256,58,257,58,257,58,258,58,258,57,258,57,258,57,258,56,259,56,259,56,259,55,259,55,259,55,260,54,260,53,260,53,260;224,260,222,260,220,260,218,260,216,259,216,259,216,259,215,259,213,259,210,259,209,259,209,258,208,258,208,258,209,257,210,256,210,256,211,256,212,256,213,256,213,256,214,255,214,255,215,255,216,255,217,255,217,255,217,254,218,254,220,254,222,254,224,254,224,255,224,255,224,255,225,255,226,255,226,255,226,255,226,255,226,256,227,256,227,256,228,256,228,256,228,256,228,256,228,256,229,256,229,256,229,257,229,257,229,258,228,258,228,258,227,258,227,258,227,259,226,259,226,259,226,259,225,259,225,260,225,260,224,260,224,260;394,260,393,260,391,260,388,260,387,259,387,259,387,259,385,259,383,259,381,259,380,259,379,258,379,258,379,258,380,257,380,256,381,256,382,256,383,256,383,256,384,256,384,255,385,255,386,255,387,255,388,255,388,255,388,254,389,254,391,254,393,254,394,254,394,255,394,255,395,255,396,255,396,255,397,255,397,255,397,255,397,256,398,256,398,256,398,256,398,256,398,256,398,256,399,256,399,256,400,256,400,257,400,257,399,258,399,258,399,258,398,258,398,258,398,259,397,259,397,259,397,259,396,259,396,260,395,260,394,260,394,260;60,258,60,255,61,254,61,254,63,254,69,254,77,254,78,254,78,254,78,254,78,255,78,255,79,256,79,256,79,257,79,258,74,258,71,258,69,258,69,259,69,259,61,259,61,258;231,258,231,255,231,254,232,254,233,254,240,254,248,254,248,254,248,254,248,254,248,255,249,255,249,256,250,256,250,257,250,258,245,258,241,258,240,258,240,259,240,259,232,259,231,258;401,258,401,255,402,254,402,254,404,254,411,254,418,254,419,254,419,254,419,254,419,255,420,255,420,256,420,256,420,257,420,258,415,258,412,258,410,258,410,259,410,259,402,259,402,258;81,257,80,256,80,256,80,256,80,255,80,255,79,255,79,254,79,253,79,252,79,252,78,252,78,252,77,251,77,251,76,250,76,250,76,248,76,246,76,246,77,246,78,246,79,247,79,248,79,249,80,251,81,251,81,251,82,252,83,253,85,255,86,255,86,256,86,257,85,258,84,258,83,258,83,258,83,258,83,258,82,258,81,257;106,258,105,258,104,258,103,258,102,257,102,257,102,257,102,257,102,257,101,257,101,257,101,256,100,256,100,256,101,255,101,255,102,255,106,255,110,255,111,255,111,256,112,256,112,257,112,257,111,257,111,258,109,258,108,258,108,258,108,258,108,258,107,258,107,258,106,258,106,258,106,258;251,257,251,256,251,256,251,256,251,255,250,255,250,255,250,254,250,253,250,252,249,252,249,252,249,252,248,251,248,251,247,250,247,250,247,248,247,246,247,246,247,246,248,246,250,247,250,248,250,249,251,251,251,251,252,251,253,252,254,253,256,255,256,255,256,256,256,257,256,258,255,258,254,258,254,258,254,258,254,258,252,258,252,257;277,258,276,258,275,258,274,258,273,257,273,257,273,257,273,257,272,257,272,257,272,257,271,256,271,256,271,256,271,255,272,255,273,255,276,255,281,255,281,255,282,256,283,256,283,257,282,257,282,257,281,258,280,258,279,258,278,258,278,258,278,258,278,258,278,258,277,258,277,258,277,258;422,257,422,256,422,256,422,256,421,255,421,255,420,255,420,254,420,253,420,252,420,252,420,252,419,252,419,251,418,251,418,250,418,250,418,248,418,246,418,246,418,246,419,246,420,247,420,248,420,249,421,251,422,251,422,251,423,252,425,253,427,255,427,255,427,256,427,257,427,258,426,258,425,258,424,258,424,258,424,258,423,258,422,257;448,258,447,258,446,258,444,258,444,257,444,257,444,257,443,257,443,257,443,257,442,257,442,256,442,256,442,256,442,255,442,255,443,255,447,255,452,255,452,255,453,256,453,256,453,257,453,257,453,257,452,258,451,258,450,258,449,258,449,258,449,258,449,258,448,258,448,258,448,258,448,258;114,256,114,256,114,256,114,256,114,256,114,256,114,256,114,256,114,256,114,256,114,256,114,256;284,256,284,256,285,256,285,256,285,256,285,256,285,256,285,256,285,256,284,256,284,256,284,256;455,256,455,256,455,256,455,256,456,256,456,256,456,256,455,256,455,256,455,256,455,256,455,256;151,254,150,254,150,254,149,254,149,254,149,254,149,254,148,254,147,254,146,254,145,253,145,253,145,253,143,253,141,253,138,253,136,253,136,253,136,252,136,252,136,252,135,252,135,252,135,252,134,251,134,249,135,249,135,249,135,248,135,248,135,247,135,247,135,247,135,247,136,246,136,245,136,244,135,244,135,244,135,244,135,242,135,240,135,236,135,236,136,236,136,236,136,236,136,236,136,236,136,236,137,236,137,236,138,235,138,235,138,235,138,235,139,235,140,235,140,235,140,235,140,234,142,234,144,234,146,234,147,234,147,235,147,235,148,235,149,235,150,235,151,235,151,235,151,235,151,236,152,236,152,236,152,236,152,236,152,236,152,236,153,236,153,236,154,236,154,237,154,237,155,238,155,238,155,238,156,238,156,238,157,239,157,239,157,242,157,244,157,246,157,246,158,246,158,246,157,246,157,246,157,247,157,249,157,252,157,253,156,253,156,254,155,254,155,254,154,254,154,254,154,255,154,255,153,255,153,255,152,255,151,255,151,255;322,254,321,254,321,254,320,254,320,254,320,254,320,254,319,254,318,254,316,254,316,253,316,253,316,253,314,253,311,253,309,253,307,253,307,253,307,252,307,252,306,252,306,252,306,252,305,252,305,251,305,249,305,249,305,249,306,248,306,248,306,247,306,247,306,247,306,247,306,246,306,245,306,244,306,244,306,244,306,244,306,242,306,240,306,236,306,236,306,236,307,236,307,236,307,236,307,236,307,236,308,236,308,236,308,235,308,235,308,235,309,235,310,235,310,235,311,235,311,235,311,234,312,234,314,234,316,234,318,234,318,235,318,235,318,235,320,235,321,235,322,235,322,235,322,235,322,236,322,236,323,236,323,236,323,236,323,236,323,236,323,236,324,236,324,236,325,237,325,237,325,238,325,238,326,238,326,238,327,238,327,239,328,239,328,242,328,244,328,246,328,246,328,246,328,246,328,246,328,246,328,247,328,249,328,252,327,253,327,253,326,254,326,254,325,254,325,254,325,254,325,255,325,255,324,255,323,255,322,255,322,255,322,255;492,254,492,254,491,254,491,254,490,254,490,254,490,254,489,254,488,254,487,254,486,253,486,253,486,253,485,253,482,253,479,253,478,253,478,253,478,252,477,252,477,252,477,252,476,252,476,252,475,251,475,249,476,249,476,249,476,248,476,248,476,247,476,247,477,247,477,247,477,246,477,245,477,244,477,244,477,244,476,244,476,242,476,240,476,236,476,236,477,236,477,236,478,236,478,236,478,236,478,236,478,236,479,236,479,235,479,235,479,235,479,235,480,235,481,235,482,235,482,235,482,234,483,234,485,234,487,234,488,234,488,235,488,235,489,235,490,235,491,235,492,235,492,235,492,235,492,236,493,236,493,236,494,236,494,236,494,236,494,236,494,236,494,236,495,236,495,237,495,237,496,238,496,238,496,238,497,238,497,238,498,239,498,239,498,242,498,244,498,246,499,246,499,246,499,246,499,246,498,246,498,247,498,249,498,252,498,253,497,253,497,254,496,254,496,254,496,254,496,254,496,255,496,255,495,255,494,255,493,255,492,255,492,255;40,252,39,252,39,252,38,252,37,252,37,252,37,251,36,251,36,251,35,251,35,251,35,250,35,250,35,250,35,250,34,250,34,248,34,247,34,245,34,244,34,244,34,244,34,244,34,244,34,243,34,243,34,243,34,243,34,243,34,242,34,242,34,242,35,242,35,242,35,241,35,241,35,240,36,240,40,240,43,240,44,240,44,240,44,240,44,240,45,240,45,240,47,242,47,242,47,242,47,243,48,243,48,243,48,244,48,244,48,245,48,245,49,245,49,245,49,245,49,246,49,246,49,247,49,247,48,247,48,247,48,248,48,248,48,249,48,249,47,249,47,249,48,249,48,249,48,250,48,250,48,250,48,251,49,251,50,252,50,252,49,252,49,253,48,253,48,253,47,253,47,253,47,253,47,253,46,254,44,254,41,254,40,253,40,253;174,253,172,253,170,253,168,253,166,253,166,253,166,252,165,252,163,252,160,252,159,252,159,252,158,251,158,246,159,246,159,246,159,246,159,245,159,245,159,244,160,244,160,244,160,243,160,243,160,243,160,242,161,242,161,242,162,241,162,241,162,240,162,240,162,240,163,240,163,240,163,241,163,241,163,241,164,241,164,241,164,241,164,241,164,241,164,242,165,242,165,242,166,242,166,242,166,242,166,242,167,242,168,242,169,242,169,242,169,242,169,242,170,242,170,242,170,241,170,241,169,240,168,240,168,241,168,241,167,241,167,241,166,241,166,241,166,241,166,240,165,240,165,240,164,240,164,240,164,240,164,239,164,239,165,239,165,238,166,238,166,238,166,237,166,236,167,236,168,236,168,236,169,235,169,235,170,234,170,234,171,234,171,234,171,231,171,228,173,228,174,228,175,228,176,229,176,229,176,231,176,231,176,231,176,232,176,234,176,236,176,238,176,238,176,238,176,239,176,242,176,244,176,246,177,246,177,246,177,246,177,247,177,248,177,248,177,248,176,248,176,249,176,250,176,251,176,252,177,252,177,252,177,252,176,253,176,254,174,254,174,253;210,252,210,252,209,252,209,252,208,252,208,252,208,251,207,251,206,251,206,251,206,251,206,250,206,250,205,250,205,250,205,250,205,248,205,247,205,245,205,244,205,244,204,244,204,244,204,244,204,243,204,243,205,243,205,243,205,243,205,242,205,242,205,242,205,242,205,242,206,241,206,241,206,240,206,240,211,240,213,240,215,240,215,240,215,240,215,240,215,240,216,240,218,242,218,242,218,242,218,243,218,243,219,243,219,244,219,244,219,245,219,245,219,245,219,245,220,245,220,246,220,246,219,247,219,247,219,247,219,247,219,248,219,248,219,249,218,249,218,249,218,249,218,249,219,249,219,250,219,250,219,250,219,251,220,251,220,252,220,252,220,252,219,253,219,253,218,253,218,253,218,253,218,253,218,253,216,254,214,254,211,254,211,253,211,253;344,253,343,253,341,253,338,253,337,253,337,253,337,252,335,252,333,252,331,252,330,252,329,252,329,251,329,246,329,246,329,246,330,246,330,245,330,245,330,244,330,244,331,244,331,243,331,243,331,243,331,242,332,242,332,242,332,241,332,241,332,240,332,240,333,240,333,240,334,240,334,241,334,241,334,241,334,241,335,241,335,241,335,241,335,241,335,242,336,242,336,242,336,242,336,242,336,242,337,242,338,242,339,242,340,242,340,242,340,242,340,242,340,242,341,242,341,241,340,241,340,240,338,240,338,241,338,241,338,241,337,241,337,241,336,241,336,241,336,240,336,240,336,240,335,240,335,240,335,240,335,239,335,239,336,239,336,238,336,238,336,238,336,237,337,236,338,236,338,236,339,236,340,235,340,235,341,234,341,234,341,234,342,234,342,231,342,228,344,228,345,228,346,228,346,229,347,229,347,231,347,231,346,231,346,232,346,234,346,236,346,238,347,238,347,238,347,239,347,242,347,244,347,246,347,246,347,246,348,246,348,247,348,248,347,248,347,248,347,248,347,249,347,250,347,251,347,252,347,252,348,252,348,252,347,253,346,254,344,254,344,253;381,252,380,252,380,252,379,252,379,252,379,252,378,251,378,251,377,251,376,251,376,251,376,250,376,250,376,250,376,250,376,250,376,248,376,247,376,245,375,244,375,244,375,244,375,244,375,244,375,243,375,243,375,243,375,243,376,243,376,242,376,242,376,242,376,242,376,242,376,241,376,241,376,240,377,240,381,240,384,240,386,240,386,240,386,240,386,240,386,240,387,240,388,242,388,242,388,242,388,243,389,243,389,243,390,244,390,244,390,245,390,245,390,245,390,245,390,245,390,246,390,246,390,247,390,247,390,247,390,247,390,248,390,248,389,249,389,249,389,249,389,249,389,249,389,249,390,250,390,250,390,250,390,251,390,251,391,252,391,252,390,252,390,253,389,253,389,253,389,253,388,253,388,253,388,253,387,254,385,254,382,254,382,253,381,253;515,253,513,253,511,253,509,253,508,253,508,253,508,252,506,252,504,252,501,252,500,252,500,252,499,251,499,246,500,246,500,246,500,246,500,245,500,245,500,244,501,244,501,244,502,243,502,243,502,243,502,242,502,242,503,242,503,241,503,241,503,240,503,240,504,240,504,240,504,240,504,241,504,241,504,241,505,241,505,241,506,241,506,241,506,241,506,242,506,242,507,242,507,242,507,242,507,242,508,242,509,242,509,242,510,242,510,242,510,242,510,242,511,242,512,242,512,241,511,241,510,240,509,240,509,241,509,241,508,241,508,241,507,241,507,241,507,241,507,240,507,240,506,240,506,240,506,240,506,240,506,239,506,239,506,239,507,238,507,238,507,238,507,237,508,236,509,236,509,236,510,236,510,235,511,235,511,234,512,234,512,234,512,234,512,231,512,228,514,228,516,228,517,228,517,229,518,229,518,231,517,231,517,231,517,232,517,234,517,236,517,238,517,238,517,238,518,239,518,242,518,244,518,246,518,246,518,246,518,246,518,247,518,248,518,248,518,248,518,248,518,249,518,250,518,251,518,252,518,252,518,252,518,252,518,253,517,254,515,254,515,253;50,251,50,250,50,250,50,249,49,249,49,249,49,249,49,248,49,248,49,248,50,247,50,246,50,244,50,244,50,244,50,244,50,243,50,243,50,242,50,242,51,242,51,242,51,242,51,241,51,241,51,240,51,240,51,240,52,240,52,239,52,238,52,238,52,238,52,238,52,237,52,237,52,236,52,236,55,236,56,236,58,236,58,237,58,237,60,237,64,237,67,237,70,237,70,237,70,237,70,238,70,238,71,238,72,238,72,239,72,239,72,240,73,240,73,240,74,241,74,241,74,241,74,242,74,242,75,242,75,243,75,246,75,250,75,250,76,251,76,251,76,251,76,252,76,252,75,252,64,252,51,252,50,251;114,252,114,252,113,252,113,252,112,251,112,251,112,251,112,251,111,251,111,251,110,251,110,251,110,250,110,250,110,250,109,250,109,250,109,250,109,250,108,250,108,250,107,250,107,249,107,249,107,248,107,248,107,248,106,248,106,248,106,247,106,247,106,246,107,246,107,246,107,245,107,245,107,244,107,243,107,243,107,243,108,242,108,242,108,241,108,240,108,240,108,240,108,240,108,240,108,239,109,238,111,238,111,238,112,238,112,239,112,239,113,239,113,239,114,239,115,239,115,240,116,240,116,240,117,240,118,240,118,240,118,241,118,241,119,241,119,241,120,241,120,241,120,241,120,241,121,242,122,242,122,242,123,241,123,241,123,241,124,241,125,241,126,241,127,241,127,241,127,241,128,242,129,242,130,242,131,242,131,242,131,242,131,242,132,242,133,242,134,243,134,244,134,244,134,244,134,244,134,244,134,245,134,245,134,246,134,246,134,246,134,246,134,247,134,247,134,248,133,249,133,249,132,249,132,250,132,250,132,251,132,251,132,251,131,251,131,251,131,251,131,251,129,252,126,252,123,252,121,252,121,252,121,252,120,252,118,252,116,252,114,252,114,252;221,251,220,250,220,250,220,249,220,249,220,249,219,249,219,248,220,248,220,248,220,247,220,246,220,244,220,244,221,244,221,244,221,243,221,243,221,242,221,242,221,242,221,242,222,242,222,241,222,241,222,240,222,240,222,240,222,240,222,239,222,238,222,238,223,238,223,238,223,237,223,237,223,236,223,236,226,236,227,236,228,236,228,237,228,237,230,237,234,237,238,237,240,237,240,237,240,237,241,238,241,238,242,238,243,238,243,239,243,239,243,240,244,240,244,240,244,241,244,241,244,241,244,242,245,242,245,242,246,243,246,246,246,250,246,250,246,251,247,251,247,251,247,252,247,252,246,252,234,252,222,252,221,251;285,252,284,252,284,252,283,252,283,251,283,251,283,251,282,251,282,251,281,251,281,251,281,251,281,250,281,250,280,250,280,250,280,250,280,250,280,250,279,250,279,250,278,250,278,249,278,249,278,248,277,248,277,248,277,248,277,248,277,247,277,247,277,246,277,246,277,246,278,245,278,245,278,244,278,243,278,243,278,243,278,242,278,242,278,241,278,240,279,240,279,240,279,240,279,240,279,239,280,238,281,238,282,238,283,238,283,239,283,239,283,239,284,239,285,239,285,239,286,240,286,240,287,240,288,240,288,240,289,240,289,241,289,241,289,241,290,241,290,241,291,241,291,241,291,241,291,242,292,242,293,242,294,241,294,241,294,241,294,241,296,241,297,241,298,241,298,241,298,241,298,242,300,242,301,242,302,242,302,242,302,242,302,242,302,242,303,242,304,243,304,244,304,244,304,244,305,244,305,244,305,245,305,245,305,246,305,246,305,246,304,246,304,247,304,247,304,248,304,249,304,249,303,249,303,250,303,250,303,251,303,251,302,251,302,251,302,251,302,251,302,251,300,252,297,252,293,252,292,252,292,252,292,252,290,252,288,252,286,252,285,252,285,252;391,251,391,250,391,250,391,249,391,249,390,249,390,249,390,248,390,248,391,248,391,247,391,246,391,244,391,244,391,244,391,244,392,243,392,243,392,242,392,242,392,242,392,242,392,242,392,241,392,241,392,240,393,240,393,240,393,240,393,239,393,238,393,238,393,238,393,238,394,237,394,237,394,236,394,236,396,236,398,236,399,236,399,237,399,237,401,237,405,237,409,237,411,237,411,237,411,237,411,238,412,238,413,238,414,238,414,239,414,239,414,240,414,240,415,240,415,241,415,241,415,241,415,242,416,242,416,242,416,243,416,246,416,250,416,250,417,251,417,251,418,251,418,252,418,252,417,252,405,252,392,252,392,251;456,252,455,252,455,252,454,252,454,251,454,251,454,251,453,251,453,251,452,251,452,251,452,251,452,250,451,250,451,250,450,250,450,250,450,250,450,250,450,250,449,250,448,250,448,249,448,249,448,248,448,248,448,248,448,248,448,248,448,247,448,247,448,246,448,246,448,246,448,245,448,245,448,244,448,243,449,243,449,243,449,242,449,242,449,241,449,240,449,240,449,240,450,240,450,240,450,239,450,238,452,238,453,238,454,238,454,239,454,239,454,239,455,239,456,239,456,239,457,240,457,240,457,240,458,240,459,240,460,240,460,241,460,241,460,241,461,241,461,241,462,241,462,241,462,241,462,242,463,242,464,242,464,241,464,241,464,241,465,241,466,241,467,241,468,241,468,241,468,241,469,242,470,242,471,242,472,242,472,242,472,242,473,242,473,242,474,242,475,243,475,244,475,244,475,244,475,244,475,244,476,245,476,245,476,246,475,246,475,246,475,246,475,247,475,247,475,248,475,249,474,249,474,249,474,250,474,250,474,251,473,251,473,251,472,251,472,251,472,251,472,251,470,252,467,252,464,252,462,252,462,252,462,252,461,252,459,252,457,252,456,252,456,252;10,251,10,251,10,251,9,251,8,250,8,249,8,248,8,248,9,248,9,248,10,248,10,248,10,247,11,247,11,247,11,247,12,247,12,246,12,246,13,246,13,246,13,246,14,245,14,245,14,244,15,244,15,244,15,244,16,244,16,244,16,243,17,243,17,243,17,243,18,243,18,242,18,242,19,242,19,242,19,242,20,241,20,241,20,240,21,240,21,240,21,240,22,240,22,240,22,239,23,239,23,239,24,239,24,239,25,238,25,238,25,238,25,238,26,238,27,238,27,239,27,239,27,240,27,240,27,240,28,240,28,240,28,241,28,241,28,241,28,241,28,241,28,242,28,242,28,243,29,243,29,243,30,244,30,245,30,245,30,246,30,246,30,246,30,246,30,246,30,247,30,247,31,247,31,247,31,247,31,248,31,248,31,249,32,249,32,250,32,250,32,251,31,251,29,252,21,252,14,252,10,251,10,251;181,251,181,251,180,251,180,251,179,250,179,249,179,248,179,248,179,248,180,248,180,248,181,248,181,247,181,247,182,247,182,247,182,247,183,246,183,246,183,246,184,246,184,246,184,245,185,245,185,244,185,244,186,244,186,244,186,244,187,244,187,243,187,243,188,243,188,243,188,243,189,242,189,242,189,242,190,242,190,242,190,241,191,241,191,240,191,240,192,240,192,240,192,240,193,240,193,239,193,239,194,239,194,239,195,239,195,238,195,238,196,238,196,238,197,238,198,238,198,239,198,239,198,240,198,240,198,240,198,240,198,240,198,241,198,241,199,241,199,241,199,241,199,242,199,242,199,243,200,243,200,243,200,244,200,245,200,245,200,246,201,246,201,246,201,246,201,246,201,247,201,247,201,247,201,247,202,247,202,248,202,248,202,249,202,249,203,250,203,250,202,251,202,251,200,252,191,252,185,252,181,251,181,251;352,251,351,251,351,251,350,251,350,250,350,249,350,248,350,248,350,248,350,248,351,248,351,248,351,247,352,247,352,247,352,247,353,247,353,246,353,246,354,246,354,246,354,246,355,245,355,245,355,244,356,244,356,244,356,244,357,244,357,244,357,243,358,243,358,243,358,243,359,243,359,242,359,242,360,242,360,242,360,242,361,241,361,241,361,240,362,240,362,240,362,240,363,240,363,240,363,239,364,239,365,239,365,239,366,239,366,238,366,238,367,238,367,238,367,238,368,238,368,239,368,239,368,240,369,240,369,240,369,240,369,240,369,241,369,241,369,241,369,241,370,241,370,242,370,242,370,243,370,243,371,243,371,244,371,245,371,245,371,246,371,246,371,246,372,246,372,246,372,247,372,247,372,247,372,247,372,247,372,248,372,248,372,249,373,249,374,250,374,250,373,251,373,251,371,252,362,252,355,252,352,251,352,251;90,247,90,247,91,247,92,247,93,247,93,247,93,246,94,246,95,246,96,246,97,246,97,246,97,246,98,246,100,246,102,246,103,245,103,245,103,245,103,245,104,246,105,247,105,247,104,248,104,248,102,248,97,248,90,248,90,248,90,248;260,247,260,247,262,247,263,247,264,247,264,247,264,246,264,246,266,246,267,246,268,246,268,246,268,246,269,246,270,246,273,246,273,245,274,245,274,245,274,245,275,246,276,247,276,247,275,248,275,248,273,248,267,248,260,248,260,248,260,248;431,247,431,247,433,247,433,247,434,247,434,247,434,246,435,246,436,246,437,246,438,246,438,246,438,246,439,246,441,246,443,246,444,245,444,245,444,245,445,245,445,246,446,247,446,247,446,248,445,248,444,248,438,248,431,248,431,248,431,248;7,239,7,238,9,238,10,238,10,238,10,238,10,238,12,238,14,238,17,238,17,238,18,238,18,239,19,239,19,239,19,239,20,239,20,240,20,240,19,240,19,240,19,240,18,240,18,241,18,241,17,242,17,242,17,242,16,242,16,242,16,243,15,243,15,243,15,243,14,243,14,244,14,244,13,244,13,244,13,244,12,244,12,245,12,245,11,246,11,246,11,246,10,246,10,246,9,247,9,247,8,247,7,247,7,243;178,239,178,238,180,238,180,238,181,238,181,238,181,238,182,238,184,238,188,238,188,238,189,238,189,239,189,239,190,239,190,239,190,239,190,240,190,240,190,240,190,240,189,240,189,240,189,241,188,241,188,242,188,242,187,242,187,242,187,242,186,243,186,243,186,243,185,243,185,243,185,244,184,244,184,244,184,244,183,244,183,244,183,245,182,245,182,246,182,246,181,246,181,246,181,246,180,247,180,247,179,247,178,247,178,243;348,239,348,238,350,238,351,238,352,238,352,238,352,238,353,238,355,238,358,238,359,238,359,238,359,239,360,239,360,239,361,239,361,239,361,240,361,240,361,240,360,240,360,240,359,240,359,241,359,241,358,242,358,242,358,242,357,242,357,242,357,243,356,243,356,243,356,243,355,243,355,244,355,244,354,244,354,244,354,244,353,244,353,245,353,245,352,246,352,246,352,246,351,246,351,246,351,247,350,247,349,247,348,247,348,243;30,242,30,241,30,241,30,241,29,240,29,240,29,240,29,240,29,240,29,239,29,239,30,239,30,239,31,239,31,239,31,239,31,240,32,240,33,240,34,240,34,241,34,241,31,244,31,243,31,243,31,243,30,243;201,242,200,241,200,241,200,241,200,240,200,240,200,240,200,240,200,240,200,239,200,239,201,239,201,239,202,239,202,239,202,239,202,240,202,240,203,240,204,240,204,241,204,241,202,244,202,243,202,243,201,243,201,243;371,242,371,241,371,241,371,241,371,240,371,240,370,240,370,240,370,240,370,239,370,239,371,239,372,239,372,239,372,239,372,239,373,240,373,240,374,240,375,240,375,241,375,241,373,244,372,243,372,243,372,243,372,243;131,240,130,240,130,240,128,240,128,240,128,239,128,238,130,236,132,236,133,236,134,237,134,239,134,239,133,240,133,240,132,241,131,241,131,241;302,240,301,240,300,240,299,240,299,240,299,239,299,238,301,236,302,236,304,236,304,237,304,239,304,239,304,240,304,240,303,241,302,241,302,241;472,240,472,240,471,240,470,240,470,240,470,239,470,238,472,236,473,236,474,236,475,237,475,239,475,239,475,240,474,240,474,241,472,241,472,241;160,239,159,239,159,239,159,239,158,239,158,238,158,238,157,238,157,238,157,238,156,237,156,237,155,236,154,236,154,236,154,236,154,235,154,235,154,235,153,235,153,235,152,235,152,235,152,235,152,234,152,234,151,234,151,234,150,234,150,234,150,234,150,234,150,234,149,234,147,231,147,231,147,230,147,230,147,230,147,230,148,230,148,230,148,229,148,229,148,229,148,229,148,228,148,228,148,227,148,227,149,227,149,227,150,227,150,226,150,226,151,226,152,226,154,226,154,226,155,226,155,227,155,227,156,227,157,227,158,227,158,228,158,228,159,228,159,228,159,228,160,229,161,230,161,230,162,231,162,231,162,231,163,231,163,232,164,232,164,233,164,235,164,238,164,239,162,239,162,239,162,239,162,239,162,239,161,240,161,240,160,240,160,239,160,239;330,239,330,239,330,239,329,239,329,239,329,238,328,238,328,238,328,238,327,238,327,237,326,237,326,236,325,236,325,236,324,236,324,235,324,235,324,235,324,235,324,235,323,235,323,235,323,235,323,234,322,234,322,234,321,234,321,234,321,234,321,234,321,234,320,234,320,234,319,233,319,232,318,231,317,230,318,230,318,230,318,230,318,230,318,229,318,229,319,229,319,229,319,228,319,228,319,227,319,227,319,227,320,227,320,227,321,226,321,226,321,226,323,226,324,226,325,226,325,226,325,227,326,227,327,227,328,227,328,227,329,228,329,228,329,228,329,228,330,228,330,229,331,230,332,230,333,231,333,231,333,231,334,231,334,232,335,232,335,233,335,235,335,238,334,239,333,239,333,239,332,239,332,239,332,239,332,240,331,240,331,240,330,239,330,239;501,239,501,239,500,239,500,239,499,239,499,238,499,238,498,238,498,238,498,238,497,237,497,237,496,236,496,236,495,236,495,236,495,235,495,235,495,235,495,235,494,235,494,235,494,235,494,235,494,234,493,234,493,234,492,234,492,234,492,234,492,234,491,234,491,234,491,234,490,233,489,232,488,231,488,230,489,230,489,230,489,230,489,230,489,229,489,229,489,229,489,229,490,228,490,228,490,227,490,227,490,227,490,227,491,227,491,226,492,226,492,226,494,226,495,226,495,226,496,226,496,227,497,227,498,227,498,227,499,227,499,228,499,228,500,228,500,228,500,228,501,229,502,230,503,230,503,231,503,231,504,231,504,231,505,232,505,232,506,233,506,235,506,238,505,239,504,239,503,239,503,239,503,239,503,239,502,240,502,240,501,240,501,239,501,239;46,238,43,238,38,238,33,238,30,238,30,238,30,238,29,238,29,238,27,238,27,234,27,232,27,230,27,230,27,230,28,230,28,230,28,229,29,228,30,228,30,228,31,228,31,228,31,228,31,228,32,228,33,228,34,228,34,229,34,229,34,229,34,229,34,228,35,228,36,228,38,228,38,228,39,228,39,227,39,227,40,227,40,227,41,227,41,226,42,225,44,225,44,226,44,227,45,228,46,228,46,228,46,228,46,228,46,228,47,228,48,228,49,228,50,228,50,229,50,229,50,230,50,230,50,230,50,230,50,230,50,230,50,231,50,232,50,233,50,233,50,234,51,234,51,235,51,235,51,235,51,236,51,236,52,236,52,236,51,236,51,236,51,236,51,237,51,237,50,238,50,238,49,239,49,239,47,239,46,239,46,239,46,239;99,238,98,238,98,238,97,238,96,238,96,238,96,238,95,238,95,238,94,238,93,237,93,237,93,237,93,237,92,237,92,237,92,237,92,237,92,236,91,236,91,236,90,236,90,236,90,236,90,235,89,235,89,235,89,235,89,235,89,234,89,234,89,234,89,234,89,234,90,233,90,232,90,231,90,231,90,231,91,230,91,230,91,230,91,229,91,229,92,229,92,228,92,228,92,228,92,227,92,227,93,227,93,226,94,226,94,226,94,225,94,225,94,225,95,224,95,224,95,224,95,223,98,220,98,220,99,220,99,220,99,220,99,219,100,220,101,221,101,221,102,222,102,222,103,222,104,223,104,224,104,224,104,225,105,225,105,225,106,226,106,227,106,227,106,228,106,228,107,228,107,229,107,229,107,229,107,230,108,230,108,230,108,231,108,233,108,235,108,235,108,235,107,235,107,235,107,236,106,236,106,236,105,236,104,236,103,236,103,237,103,237,102,238,102,238,102,238,101,238,101,238,101,239,99,239,99,239;216,238,213,238,209,238,204,238,201,238,201,238,201,238,200,238,199,238,198,238,198,234,198,232,198,230,198,230,198,230,198,230,198,230,198,229,200,228,201,228,201,228,202,228,202,228,202,228,202,228,203,228,204,228,204,228,204,229,204,229,205,229,205,229,205,228,206,228,207,228,208,228,209,228,209,228,209,227,210,227,211,227,211,227,212,227,212,226,212,225,215,225,215,226,215,226,215,227,215,227,216,227,216,228,216,228,217,228,217,228,217,228,217,228,218,228,219,228,220,228,220,228,220,229,220,229,220,230,221,230,221,230,221,230,221,230,220,230,220,231,220,232,220,233,220,233,221,234,221,234,222,235,222,235,222,235,222,236,222,236,222,236,222,236,222,236,222,236,222,236,222,237,222,237,221,238,221,238,220,239,220,239,218,239,217,239,216,239,216,239;270,238,269,238,268,238,267,238,267,238,267,238,267,238,266,238,265,238,264,238,264,237,264,237,264,237,263,237,263,237,262,237,262,237,262,237,262,236,262,236,261,236,260,236,260,236,260,236,260,235,260,235,260,235,260,235,260,235,260,234,260,234,260,234,260,234,260,234,260,233,260,232,260,231,260,231,261,231,261,230,262,230,262,230,262,229,262,229,262,229,263,228,263,228,263,228,263,227,263,227,264,227,264,226,264,226,264,226,264,225,264,225,265,225,265,224,266,224,266,224,266,223,268,220,269,220,269,220,270,220,270,220,270,219,271,220,272,221,272,221,273,222,273,222,273,222,275,223,275,224,275,224,275,225,276,225,276,225,276,226,276,227,276,227,276,228,277,228,277,228,278,229,278,229,278,229,278,230,278,230,279,230,279,231,279,233,279,235,279,235,278,235,278,235,277,235,277,236,277,236,276,236,276,236,275,236,274,236,274,237,274,237,273,238,273,238,273,238,272,238,272,238,271,239,270,239,270,239;387,238,384,238,379,238,374,238,372,238,372,238,372,238,371,238,370,238,368,238,368,234,368,232,368,230,369,230,369,230,369,230,369,230,369,229,370,228,371,228,372,228,372,228,372,228,372,228,373,228,373,228,374,228,375,228,375,229,375,229,375,229,375,229,375,228,376,228,377,228,379,228,379,228,380,228,380,227,381,227,381,227,382,227,382,227,383,226,383,225,386,225,386,226,386,226,386,227,386,227,386,227,387,228,387,228,387,228,388,228,388,228,388,228,388,228,389,228,391,228,391,228,391,229,391,229,391,230,391,230,392,230,392,230,391,230,391,230,391,231,391,232,391,233,391,233,392,234,392,234,392,235,392,235,392,235,392,236,393,236,393,236,393,236,393,236,392,236,392,236,392,237,392,237,392,238,391,238,391,239,390,239,389,239,388,239,387,239,387,239;440,238,440,238,439,238,438,238,438,238,438,238,438,238,437,238,436,238,435,238,434,237,434,237,434,237,434,237,434,237,433,237,433,237,433,237,433,236,432,236,432,236,431,236,431,236,431,236,431,235,431,235,431,235,430,235,430,235,430,234,430,234,430,234,431,234,431,234,431,233,431,232,431,231,431,231,432,231,432,230,432,230,432,230,432,229,432,229,433,229,433,228,434,228,434,228,434,227,434,227,434,227,435,226,435,226,435,226,435,225,435,225,436,225,436,224,436,224,436,224,436,223,439,220,440,220,440,220,440,220,440,220,440,219,441,220,442,221,443,221,443,222,443,222,444,222,446,223,446,224,446,224,446,225,446,225,447,225,447,226,447,227,447,227,447,228,448,228,448,228,448,229,448,229,448,229,448,230,449,230,449,230,450,231,450,233,450,235,449,235,449,235,449,235,448,235,448,236,448,236,447,236,446,236,445,236,445,236,445,237,444,237,444,238,444,238,443,238,443,238,443,238,442,239,440,239,440,239;18,236,18,236,18,231,18,227,19,227,21,227,21,227,22,228,22,228,23,229,23,229,23,229,23,230,24,230,24,230,24,231,24,231,24,232,24,232,25,232,25,232,25,232,25,233,25,233,25,234,25,234,24,234,24,234,24,234,24,235,24,235,25,235,25,235,25,235,25,236,25,236,25,236,25,236,24,236,24,236,24,237,24,237,24,237,22,237,19,237,19,237,18,237;188,236,188,236,188,231,188,227,190,227,192,227,192,227,193,228,193,228,194,229,194,229,194,229,194,230,194,230,195,230,195,231,195,231,195,232,195,232,195,232,195,232,196,232,196,233,196,233,195,234,195,234,195,234,195,234,195,234,195,235,195,235,195,235,195,235,196,235,196,236,196,236,195,236,195,236,195,236,195,236,195,237,195,237,195,237,192,237,190,237,190,237,189,237;359,236,359,236,359,231,359,227,361,227,362,227,363,227,363,228,364,228,364,229,364,229,364,229,364,230,365,230,365,230,366,231,366,231,366,232,366,232,366,232,366,232,366,232,366,233,366,233,366,234,366,234,366,234,366,234,366,234,366,235,366,235,366,235,366,235,366,235,366,236,366,236,366,236,366,236,366,236,366,236,366,237,366,237,365,237,363,237,361,237,360,237,360,237;6,235,6,235,6,233,6,232,6,232,7,232,7,232,7,231,7,231,7,230,7,230,9,230,9,230,10,229,10,229,10,229,10,229,11,229,11,229,12,229,12,229,12,228,13,228,14,228,16,228,16,232,16,236,16,236,13,236,12,236,12,236,12,237,12,237,11,237,10,237,8,237,8,237,7,236;117,236,117,236,116,236,116,236,115,236,115,236,115,235,114,235,114,235,114,235,113,234,113,234,111,232,113,230,115,230,116,230,116,229,116,229,116,229,116,229,117,229,117,229,118,229,118,229,118,228,118,228,118,228,118,228,119,228,119,228,119,227,120,227,120,227,121,227,121,227,121,227,121,226,121,226,122,226,122,226,122,226,122,226,122,226,123,226,124,226,125,226,126,225,126,225,126,225,126,225,126,225,126,225,127,226,127,226,129,226,131,227,131,229,131,230,131,230,131,230,132,230,132,231,131,232,130,232,130,233,129,233,129,233,129,233,129,233,129,233,129,234,128,234,128,234,127,234,127,235,126,236,125,236,125,236,124,236,124,236,124,237,124,237,123,237,121,237,118,237,117,237,117,237;177,235,177,235,177,233,177,232,177,232,177,232,177,232,178,231,178,231,178,230,178,230,179,230,180,230,181,229,181,229,181,229,181,229,182,229,182,229,182,229,182,229,182,228,183,228,185,228,187,228,187,232,187,236,187,236,184,236,183,236,182,236,182,237,182,237,181,237,180,237,179,237,178,237,178,236;288,236,287,236,287,236,287,236,286,236,286,236,286,235,285,235,285,235,285,235,284,234,284,234,282,232,283,230,286,230,286,230,287,229,287,229,287,229,287,229,288,229,288,229,288,229,288,229,288,228,288,228,289,228,289,228,290,228,290,228,290,227,291,227,291,227,291,227,292,227,292,227,292,226,292,226,292,226,293,226,293,226,293,226,293,226,294,226,294,226,295,226,296,225,296,225,296,225,297,225,297,225,297,225,297,226,298,226,300,226,302,227,302,229,302,230,302,230,302,230,302,230,302,231,301,232,301,232,300,233,300,233,300,233,300,233,300,233,300,233,299,234,299,234,299,234,298,234,297,235,296,236,296,236,295,236,295,236,295,236,295,237,295,237,293,237,291,237,289,237,288,237,288,237;348,235,348,235,348,233,348,232,348,232,348,232,348,232,348,231,348,231,348,230,348,230,350,230,351,230,352,229,352,229,352,229,352,229,352,229,353,229,353,229,353,229,353,228,354,228,355,228,358,228,358,232,358,236,357,236,355,236,354,236,353,236,353,237,353,237,352,237,351,237,349,237,349,237,348,236;458,236,458,236,458,236,457,236,457,236,457,236,456,235,456,235,456,235,455,235,455,234,454,234,453,232,454,230,456,230,457,230,458,229,458,229,458,229,458,229,458,229,459,229,459,229,459,229,459,228,459,228,459,228,460,228,460,228,461,228,461,227,461,227,462,227,462,227,462,227,462,227,462,226,462,226,463,226,463,226,464,226,464,226,464,226,464,226,465,226,466,226,467,225,467,225,467,225,467,225,467,225,467,225,468,226,469,226,470,226,472,227,472,229,472,230,472,230,473,230,473,230,473,231,472,232,472,232,471,233,471,233,470,233,470,233,470,233,470,233,470,234,470,234,469,234,469,234,468,235,467,236,466,236,466,236,466,236,466,236,466,237,466,237,464,237,462,237,460,237,458,237,458,237;74,235,72,235,68,235,64,235,62,235,62,234,61,234,61,233,62,233,62,233,62,233,62,232,62,232,65,229,66,229,66,229,66,229,66,229,66,228,67,228,67,228,68,228,68,228,69,228,69,227,69,227,70,227,70,227,71,227,71,226,72,226,72,226,74,226,75,226,76,225,76,225,76,225,77,225,78,225,79,225,80,225,80,225,80,224,81,224,82,224,82,224,83,224,83,224,83,224,83,224,84,224,84,224,84,223,84,223,84,223,87,223,88,223,88,224,88,224,88,225,88,225,88,226,89,226,89,226,89,226,89,227,89,228,89,228,89,228,90,228,90,230,89,231,88,231,88,231,88,232,88,232,88,233,88,233,88,233,88,233,88,233,88,234,87,234,87,235,86,235,86,236,80,236,76,236,74,235,74,235;245,235,243,235,239,235,234,235,233,235,233,234,232,234,232,233,233,233,233,233,233,233,233,232,233,232,234,231,234,230,235,230,236,229,236,229,237,229,237,229,237,229,237,228,237,228,238,228,238,228,239,228,239,228,239,227,240,227,241,227,241,227,242,227,242,226,242,226,243,226,244,226,245,226,246,225,246,225,246,225,247,225,249,225,250,225,251,225,251,225,251,224,251,224,252,224,253,224,254,224,254,224,254,224,254,224,254,224,255,224,255,223,255,223,255,223,258,223,258,223,259,224,259,224,259,225,259,225,259,226,259,226,259,226,260,226,260,227,260,228,260,228,260,228,260,228,260,230,260,231,259,231,259,231,259,232,259,232,259,233,259,233,258,233,258,233,258,233,258,234,258,234,257,235,257,235,256,236,251,236,247,236,245,235,245,235;416,235,413,235,410,235,405,235,404,235,403,234,403,234,403,233,403,233,403,233,404,233,404,232,404,232,404,231,405,230,406,230,407,229,407,229,407,229,408,229,408,229,408,228,408,228,408,228,409,228,410,228,410,228,410,227,411,227,411,227,412,227,412,227,413,226,413,226,413,226,415,226,416,226,417,225,417,225,417,225,418,225,419,225,421,225,422,225,422,225,422,224,422,224,423,224,424,224,424,224,424,224,424,224,424,224,425,224,425,224,426,223,426,223,426,223,428,223,429,223,429,224,430,224,430,225,430,225,430,226,430,226,430,226,430,226,430,227,430,228,430,228,431,228,431,228,431,230,430,231,430,231,430,231,430,232,430,232,429,233,429,233,429,233,429,233,429,233,429,234,428,234,428,235,427,235,427,236,421,236,418,236,416,235,416,235;51,232,51,230,52,229,52,229,53,228,53,228,53,228,54,227,55,226,57,224,59,224,61,224,62,224,62,225,62,225,62,225,62,225,63,225,63,225,63,225,63,225,64,226,65,226,67,226,68,226,68,226,68,227,67,227,67,227,67,227,65,228,64,230,62,231,61,232,61,232,61,232,60,232,60,233,60,233,59,234,59,234,58,234,58,234,58,234,58,234,57,234,55,234,53,234,52,234,52,233;221,232,221,230,222,229,223,229,223,228,224,228,224,228,225,227,226,226,228,224,230,224,231,224,232,224,232,225,232,225,232,225,233,225,233,225,234,225,234,225,234,225,235,226,236,226,238,226,238,226,238,226,238,227,238,227,238,227,237,227,236,228,235,230,233,231,232,232,231,232,231,232,231,232,231,233,230,233,230,234,229,234,229,234,229,234,229,234,229,234,228,234,226,234,223,234,223,234,222,233;392,232,392,230,393,229,393,229,394,228,394,228,394,228,395,227,397,226,398,224,401,224,402,224,403,224,403,225,403,225,403,225,404,225,404,225,404,225,404,225,404,225,405,226,407,226,409,226,409,226,409,226,409,227,409,227,408,227,408,227,407,228,405,230,404,231,402,232,402,232,402,232,401,232,401,233,401,233,400,234,400,234,400,234,400,234,400,234,400,234,398,234,397,234,394,234,394,234,393,233;146,233,146,233,145,233,144,233,144,233,143,232,143,232,143,232,143,231,144,231,146,231,146,231,146,232,146,232,146,233,147,233,147,234,147,234,146,234,146,233,146,233;167,232,166,232,166,232,166,232,165,232,165,231,164,230,163,230,163,230,163,230,162,229,161,228,160,227,160,227,159,227,159,227,159,226,159,225,159,223,159,222,160,222,161,222,163,224,163,225,163,225,163,226,163,226,163,226,164,226,164,226,164,227,164,227,166,227,167,227,168,227,168,227,168,227,168,228,168,228,169,228,170,229,170,230,170,231,170,232,170,232,170,232,170,232,170,233,170,233,169,234,169,234,168,234,167,233,167,233;317,233,316,233,316,233,315,233,314,233,314,232,314,232,314,232,314,231,315,231,316,231,316,231,316,232,316,232,317,233,318,233,318,234,317,234,317,234,317,233,317,233;338,232,337,232,337,232,337,232,336,232,335,231,334,230,334,230,334,230,333,230,333,229,332,228,331,227,330,227,330,227,330,227,330,226,330,225,330,223,330,222,331,222,331,222,334,224,334,225,334,225,334,226,334,226,334,226,334,226,334,226,334,227,334,227,336,227,337,227,338,227,338,227,338,227,338,228,339,228,340,228,341,229,341,230,341,231,341,232,341,232,340,232,340,232,340,233,340,233,340,234,339,234,339,234,338,233,338,233;488,233,487,233,486,233,486,233,485,233,485,232,484,232,484,232,485,231,485,231,487,231,487,231,487,232,487,232,488,233,488,233,488,234,488,234,488,234,488,233,488,233;508,232,508,232,508,232,507,232,507,232,506,231,505,230,504,230,504,230,504,230,503,229,503,228,502,227,501,227,501,227,500,227,500,226,500,225,500,223,501,222,501,222,502,222,504,224,504,225,504,225,504,226,505,226,505,226,505,226,505,226,505,227,505,227,507,227,508,227,509,227,509,227,509,227,509,228,509,228,510,228,512,229,512,230,512,231,511,232,511,232,511,232,511,232,511,233,511,233,511,234,510,234,509,234,509,233,509,233;136,232,135,232,135,232,134,232,133,231,133,230,133,230,133,230,133,230,132,230,132,229,132,229,132,228,132,227,132,227,131,227,131,227,132,227,132,227,132,227,132,226,132,225,135,223,136,223,136,223,137,223,137,223,137,222,137,222,138,222,139,222,140,222,140,222,140,222,140,222,141,222,143,222,143,222,143,222,143,223,143,223,143,223,143,223,144,224,144,226,144,228,143,230,143,230,143,230,143,230,143,230,143,231,141,232,140,232,140,232,140,232,140,233,140,233,139,233,138,233,136,233,136,233,136,233;306,232,306,232,305,232,305,232,304,232,304,232,304,231,304,231,304,230,304,230,303,230,303,230,303,230,303,229,303,229,303,228,303,227,302,227,302,227,302,227,302,227,303,227,303,227,303,226,303,225,306,223,307,223,307,223,308,223,308,223,308,222,308,222,309,222,310,222,310,222,310,222,310,222,311,222,312,222,313,222,314,222,314,222,314,223,314,223,314,223,314,223,314,224,314,226,314,228,314,230,314,230,314,230,314,230,314,230,314,231,312,232,311,232,311,232,310,232,310,233,310,233,309,233,308,233,307,233,306,233,306,233;477,232,476,232,476,232,476,232,475,232,475,232,474,231,474,231,474,230,474,230,474,230,474,230,474,230,474,229,474,229,474,228,473,227,473,227,473,227,473,227,473,227,473,227,474,227,474,226,474,225,476,223,477,223,478,223,478,223,478,223,478,222,479,222,480,222,480,222,481,222,481,222,481,222,482,222,483,222,484,222,484,222,484,222,484,223,484,223,485,223,485,223,485,224,485,226,485,228,485,230,485,230,484,230,484,230,484,230,484,231,483,232,482,232,481,232,481,232,481,233,481,233,480,233,479,233,478,233,477,233,477,233;51,228,51,228,50,228,50,228,50,227,50,227,50,227,49,227,48,227,47,227,47,227,47,226,46,226,46,226,46,226,45,226,44,225,44,224,44,224,44,224,44,224,44,224,44,223,44,221,44,220,44,219,44,219,44,219,44,219,44,218,44,218,45,217,45,217,46,216,46,216,50,216,53,216,54,216,54,217,54,217,54,217,55,217,55,217,56,217,56,217,56,217,56,218,57,218,57,218,58,218,58,218,58,218,58,219,58,219,59,219,59,220,59,220,59,221,58,222,58,222,57,222,55,224,55,225,55,225,55,226,54,226,54,226,53,226,53,227,51,228,51,228,51,228;107,227,107,227,107,226,107,225,107,225,106,224,105,224,105,224,106,223,107,223,110,223,110,223,110,223,110,224,112,224,113,224,114,224,114,224,114,224,114,224,114,224,115,224,115,224,115,225,115,226,114,227,113,227,113,227,112,227,112,227,112,227,112,228,112,228,111,228,111,228,111,228,111,228,108,228,107,228;116,228,116,228,116,228,116,228,116,228,116,228,116,228,116,228,116,228,116,228,116,228,116,228;145,227,145,225,145,225,146,224,146,224,147,224,149,224,149,225,148,226,147,227,147,227,147,228,147,228,146,228,145,228;222,228,221,228,221,228,220,228,220,227,220,227,220,227,220,227,219,227,218,227,218,227,217,226,217,226,216,226,216,226,216,226,215,225,215,224,215,224,215,224,215,224,214,224,214,223,214,221,214,220,214,219,215,219,215,219,215,219,215,218,215,218,215,217,216,217,216,216,217,216,221,216,223,216,225,216,225,217,225,217,225,217,226,217,226,217,226,217,226,217,226,217,227,218,227,218,228,218,228,218,228,218,228,218,228,219,229,219,229,219,230,220,230,220,230,221,229,222,228,222,227,222,226,224,226,225,226,225,225,226,225,226,225,226,224,226,223,227,222,228,222,228,222,228;278,227,278,227,278,226,278,225,277,225,277,224,276,224,276,224,277,223,277,223,280,223,280,223,280,223,281,224,282,224,283,224,284,224,284,224,284,224,284,224,285,224,286,224,286,226,285,226,285,227,284,227,284,227,283,227,283,227,283,227,283,227,283,228,282,228,282,228,282,228,282,228,282,228,278,228,278,228;286,228,286,228,287,228,287,228,287,228,287,228,287,228,287,228,287,228,286,228,286,228,286,228;315,227,315,225,316,225,316,224,317,224,318,224,320,224,320,225,319,226,318,227,318,227,318,228,318,228,316,228,316,228;392,228,392,228,392,228,391,228,391,227,391,227,391,227,390,227,390,227,389,227,388,227,388,226,388,226,387,226,387,226,386,226,386,225,386,224,386,224,385,224,385,224,385,224,385,223,385,221,385,220,385,219,385,219,385,219,386,219,386,218,386,218,386,217,386,217,387,216,387,216,391,216,394,216,396,216,396,217,396,217,396,217,396,217,397,217,397,217,397,217,397,217,397,218,398,218,399,218,399,218,399,218,399,218,399,219,400,219,400,219,400,220,400,220,400,221,399,222,399,222,398,222,396,224,396,225,396,225,396,226,396,226,395,226,395,226,394,227,393,228,392,228,392,228;448,227,448,227,448,226,448,225,448,225,447,224,447,224,447,224,447,223,448,223,451,223,451,223,451,223,452,224,453,224,454,224,455,224,455,224,455,224,455,224,456,224,456,224,456,226,456,226,455,227,455,227,454,227,454,227,454,227,454,227,454,227,453,228,453,228,452,228,452,228,452,228,452,228,449,228,449,228;457,228,457,228,457,228,457,228,458,228,458,228,458,228,457,228,457,228,457,228,457,228,457,228;486,227,486,225,487,225,487,224,488,224,489,224,490,224,491,225,489,226,489,227,488,227,488,228,488,228,487,228,487,228;-1,226,-1,226,-2,226,-3,226,-3,226,-3,226,-3,226,-4,226,-5,226,-6,226,-7,225,-7,225,-7,225,-7,224,-7,224,-8,224,-8,223,-8,223,-8,223,-9,222,-10,221,-11,219,-11,219,-11,218,-11,217,-11,216,-11,216,-11,216,-11,216,-11,216,-11,215,-10,215,-10,215,-9,215,-9,215,-9,215,-9,214,-7,214,-4,214,0,214,2,214,2,214,2,214,2,214,2,214,3,214,4,213,4,213,4,212,5,212,6,212,7,212,8,212,8,213,8,213,8,213,9,213,10,213,10,213,10,213,10,213,11,214,12,214,13,214,13,214,14,214,14,215,15,215,16,215,16,215,17,215,17,215,17,215,17,216,18,216,18,216,18,216,18,216,18,216,19,216,19,216,19,216,20,217,21,217,21,218,22,218,22,220,22,223,21,224,20,224,19,224,19,224,19,224,19,224,18,224,16,224,13,224,12,224,12,225,11,225,11,226,10,226,9,226,8,226,8,226,8,226,8,226,8,226,7,226,7,226,7,227,7,227,5,227,3,227,1,227,-1,227,-1,227;31,226,30,226,29,226,28,226,27,226,27,226,27,226,26,226,26,226,24,226,24,225,24,223,24,223,23,222,23,222,23,222,23,222,23,221,23,220,23,220,24,219,25,218,25,218,26,218,26,218,27,217,27,217,28,216,28,216,30,216,32,216,33,216,33,216,33,216,34,216,35,216,35,216,36,215,36,215,36,215,37,215,38,215,38,215,39,215,39,215,39,215,40,216,40,216,43,216,43,216,43,219,43,220,43,222,43,222,42,222,42,222,42,222,42,223,40,226,39,226,39,226,39,226,39,226,38,227,38,227,34,227,32,227,31,227,31,227;116,226,116,225,117,224,117,223,120,223,120,224,121,224,121,225,120,226,118,227,117,227,117,226;170,226,170,226,169,226,168,226,168,226,168,226,168,226,167,226,166,226,164,226,164,225,164,225,164,225,164,224,164,224,163,224,163,223,163,223,163,223,162,222,161,221,160,219,160,219,160,218,160,217,160,216,160,216,160,216,160,216,160,216,160,215,160,215,161,215,162,215,162,215,162,215,162,214,164,214,167,214,170,214,172,214,172,214,172,214,173,214,173,214,174,214,174,213,175,213,175,212,175,212,177,212,177,212,178,212,178,213,178,213,179,213,180,213,180,213,181,213,181,213,181,213,182,214,182,214,184,214,184,214,185,214,185,215,185,215,186,215,187,215,188,215,188,215,188,215,188,216,188,216,189,216,189,216,189,216,189,216,189,216,190,216,190,216,191,217,191,217,192,218,192,218,192,220,192,223,192,224,190,224,190,224,190,224,190,224,190,224,188,224,186,224,183,224,183,224,183,225,182,225,182,226,180,226,180,226,179,226,179,226,179,226,179,226,178,226,178,226,178,226,178,227,178,227,176,227,174,227,172,227,170,227,170,227;202,226,201,226,200,226,198,226,198,226,198,226,198,226,197,226,196,226,196,226,195,225,195,225,194,225,194,224,194,223,194,223,194,222,194,222,194,222,194,222,194,221,194,220,194,220,195,219,195,218,196,218,197,218,197,218,198,217,198,217,198,216,199,216,201,216,202,216,204,216,204,216,204,216,204,216,205,216,206,216,207,215,207,215,207,215,207,215,208,215,209,215,210,215,210,215,210,215,210,216,211,216,213,216,214,216,214,219,214,220,213,222,213,222,213,222,213,222,213,222,213,223,211,226,210,226,210,226,209,226,209,226,209,227,208,227,205,227,203,227,202,227,202,227;287,226,287,225,287,224,288,223,290,223,291,224,291,224,291,225,290,226,289,227,288,227,287,226;341,226,340,226,340,226,339,226,338,226,338,226,338,226,337,226,337,226,335,226,335,225,335,225,335,225,335,224,334,224,334,224,334,223,334,223,334,223,333,222,332,221,330,219,330,219,330,218,330,217,330,216,331,216,331,216,331,216,331,216,331,215,331,215,332,215,332,215,333,215,333,215,333,214,335,214,338,214,341,214,343,214,343,214,343,214,343,214,344,214,344,214,345,213,345,213,346,212,346,212,347,212,348,212,349,212,349,213,349,213,349,213,350,213,351,213,352,213,352,213,352,213,352,214,353,214,354,214,355,214,355,214,356,215,356,215,357,215,358,215,358,215,358,215,358,215,358,216,359,216,359,216,360,216,360,216,360,216,360,216,360,216,361,216,362,217,362,217,363,218,363,218,363,220,363,223,362,224,361,224,361,224,360,224,360,224,360,224,359,224,357,224,354,224,354,224,353,225,353,225,352,226,351,226,350,226,350,226,350,226,350,226,349,226,349,226,348,226,348,226,348,227,348,227,347,227,345,227,342,227,341,227,341,227;372,226,371,226,370,226,369,226,368,226,368,226,368,226,368,226,367,226,366,226,366,225,365,225,365,225,365,224,365,223,365,223,365,222,365,222,364,222,364,222,364,221,364,220,364,220,365,219,366,218,367,218,367,218,368,218,368,217,369,217,369,216,369,216,372,216,373,216,374,216,374,216,374,216,375,216,376,216,377,216,378,215,378,215,378,215,378,215,379,215,380,215,380,215,380,215,380,215,381,216,382,216,384,216,384,216,384,219,384,220,384,222,384,222,384,222,384,222,384,222,384,223,382,226,381,226,381,226,380,226,380,226,379,227,379,227,376,227,374,227,372,227,372,227;457,226,457,225,458,224,459,223,461,223,462,224,462,224,462,225,461,226,460,227,459,227,458,226;129,225,129,224,129,224,129,224,130,224,130,224,130,223,130,223,131,222,132,221,132,220,132,220,132,219,133,219,134,220,135,221,135,222,133,224,131,226,130,226,129,225;154,224,154,224,153,224,152,224,152,224,152,224,152,224,151,224,151,224,150,224,150,223,150,223,150,223,149,223,148,223,147,223,146,223,146,223,146,222,146,222,145,222,144,222,144,220,144,218,144,218,145,217,145,217,146,216,146,216,146,216,146,215,146,215,147,215,147,214,147,214,147,213,148,212,150,212,152,212,153,212,153,213,153,213,154,214,154,214,154,214,155,214,155,214,155,215,156,215,156,215,157,215,157,215,157,216,157,216,157,216,157,216,157,216,158,216,158,217,158,217,158,218,158,218,158,218,158,219,158,220,158,222,158,223,158,223,158,223,158,223,158,224,158,225,157,226,156,226,155,226,155,225,155,225;299,225,299,224,300,224,300,224,300,224,300,224,300,223,301,223,302,222,302,221,303,220,303,220,303,219,304,219,305,220,306,221,306,222,304,224,302,226,301,226,300,225;325,224,324,224,323,224,323,224,322,224,322,224,322,224,322,224,321,224,321,224,320,223,320,223,320,223,319,223,319,223,318,223,317,223,317,223,317,222,316,222,316,222,315,222,315,220,315,218,315,218,316,217,316,217,316,216,316,216,316,216,316,215,317,215,317,215,318,214,318,214,318,213,318,212,321,212,323,212,323,212,324,213,324,213,325,214,325,214,325,214,326,214,326,214,326,215,327,215,327,215,327,215,328,215,328,216,328,216,328,216,328,216,328,216,328,216,328,217,328,217,328,218,329,218,329,218,329,219,329,220,329,222,329,223,329,223,328,223,328,223,328,224,328,225,328,226,327,226,326,226,326,225,325,225;470,225,470,224,470,224,471,224,471,224,471,224,471,223,471,223,472,222,473,221,474,220,474,220,474,219,474,219,475,220,477,221,476,222,474,224,472,226,471,226,471,225;495,224,495,224,494,224,493,224,493,224,493,224,493,224,492,224,492,224,491,224,491,223,491,223,491,223,490,223,489,223,488,223,488,223,488,223,488,222,487,222,487,222,486,222,486,220,486,218,486,218,486,217,487,217,487,216,487,216,487,216,487,215,488,215,488,215,488,214,488,214,488,213,489,212,492,212,494,212,494,212,495,213,495,213,495,214,496,214,496,214,496,214,497,214,497,215,497,215,498,215,498,215,498,215,498,216,498,216,498,216,499,216,499,216,499,216,499,217,499,217,499,218,499,218,499,218,500,219,500,220,500,222,499,223,499,223,499,223,499,223,499,224,499,225,499,226,498,226,497,226,496,225,496,225;63,224,63,224,62,224,62,224,62,223,62,223,62,223,61,223,60,223,59,223,59,223,59,222,59,222,59,221,60,221,60,221,60,220,60,220,60,220,60,220,61,220,61,220,61,219,61,219,61,218,61,218,61,218,61,218,62,217,62,216,62,215,62,214,62,214,63,214,63,213,63,213,63,212,64,211,64,212,64,212,65,212,66,212,67,212,68,212,68,213,68,213,69,213,69,213,70,213,70,213,70,213,70,213,71,214,71,214,72,214,73,214,73,214,73,215,74,215,75,215,75,215,76,215,76,215,76,215,76,216,77,216,78,216,79,216,79,216,79,216,80,216,82,216,86,216,86,218,86,220,85,220,84,221,84,222,83,222,83,222,82,222,82,222,82,223,82,223,80,223,77,223,74,223,72,223,72,223,72,223,72,224,72,224,71,224,71,224,71,224,71,224,69,224,67,224,64,224,63,224,63,224;124,224,124,224,124,224,123,224,123,223,123,223,123,223,122,223,122,223,121,223,121,223,121,223,121,222,120,222,119,222,117,222,116,222,116,223,116,223,115,223,115,223,114,223,113,223,113,223,113,222,112,222,111,222,110,222,110,222,110,222,110,222,109,222,108,222,107,222,107,221,107,221,107,221,107,220,106,220,106,220,106,220,106,220,107,220,107,219,107,219,107,219,107,218,108,218,108,218,108,217,108,217,108,216,108,216,109,216,109,216,109,215,109,213,109,211,109,210,109,210,110,209,111,209,111,210,112,211,112,211,113,211,114,211,115,211,115,211,115,211,116,212,117,212,119,212,120,212,120,212,120,212,120,212,122,212,123,212,124,212,124,213,124,213,124,213,125,213,125,213,126,213,126,213,126,213,127,214,128,214,131,214,131,215,131,215,131,216,131,216,131,216,132,216,132,217,132,218,131,218,131,218,131,218,131,219,131,219,131,220,131,220,131,220,130,220,130,220,130,221,130,221,129,222,129,223,127,224,127,224,126,224,125,224,124,224,124,224;234,224,233,224,233,224,232,224,232,223,232,223,232,223,232,223,231,223,230,223,230,223,230,222,230,222,230,221,230,221,231,221,231,220,231,220,231,220,231,220,231,220,231,220,232,219,232,219,232,218,232,218,232,218,232,218,232,217,232,216,232,215,232,214,233,214,233,214,234,213,234,213,234,212,235,211,235,212,235,212,236,212,237,212,238,212,239,212,239,213,239,213,239,213,240,213,240,213,241,213,241,213,241,213,241,214,242,214,243,214,243,214,244,214,244,215,245,215,245,215,246,215,246,215,246,215,246,215,247,216,248,216,249,216,250,216,250,216,250,216,251,216,253,216,256,216,256,218,256,220,256,220,255,221,254,222,254,222,253,222,253,222,253,222,253,223,253,223,251,223,248,223,245,223,243,223,243,223,243,223,243,224,242,224,242,224,242,224,242,224,242,224,240,224,238,224,235,224,234,224,234,224;295,224,295,224,294,224,294,224,294,223,294,223,294,223,293,223,293,223,292,223,292,223,292,223,292,222,291,222,289,222,288,222,287,222,287,223,287,223,286,223,285,223,284,223,284,223,284,223,284,222,283,222,282,222,281,222,280,222,280,222,280,222,280,222,279,222,278,222,278,221,278,221,278,221,277,220,277,220,277,220,277,220,277,220,277,220,278,219,278,219,278,219,278,218,278,218,279,218,279,217,279,217,279,216,279,216,279,216,279,216,280,215,280,213,280,211,280,210,280,210,281,209,281,209,282,210,282,211,283,211,284,211,285,211,286,211,286,211,286,211,287,212,288,212,289,212,290,212,290,212,290,212,291,212,292,212,293,212,294,212,294,213,294,213,295,213,295,213,296,213,296,213,296,213,296,213,297,214,299,214,302,214,302,215,302,215,302,216,302,216,302,216,302,216,302,217,302,218,302,218,302,218,302,218,302,219,302,219,302,220,301,220,301,220,301,220,301,220,301,221,301,221,300,222,299,223,298,224,298,224,296,224,296,224,295,224,295,224;404,224,404,224,404,224,403,224,403,223,403,223,403,223,402,223,402,223,400,223,400,223,400,222,400,222,400,221,401,221,401,221,402,220,402,220,402,220,402,220,402,220,402,220,402,219,402,219,402,218,402,218,403,218,403,218,403,217,403,216,403,215,403,214,404,214,404,214,404,213,404,213,404,212,405,211,405,212,406,212,406,212,408,212,409,212,410,212,410,213,410,213,410,213,411,213,411,213,412,213,412,213,412,213,412,214,413,214,414,214,414,214,415,214,415,215,415,215,416,215,416,215,417,215,417,215,417,215,418,216,419,216,419,216,420,216,420,216,420,216,422,216,424,216,427,216,427,218,427,220,427,220,426,221,425,222,424,222,424,222,424,222,424,222,424,223,424,223,422,223,419,223,415,223,414,223,414,223,414,223,413,224,413,224,412,224,412,224,412,224,412,224,411,224,408,224,406,224,404,224,404,224;466,224,465,224,465,224,464,224,464,223,464,223,464,223,464,223,463,223,463,223,462,223,462,223,462,222,461,222,460,222,459,222,458,222,458,223,458,223,457,223,456,223,455,223,454,223,454,223,454,222,453,222,453,222,452,222,451,222,451,222,451,222,450,222,450,222,448,222,448,221,448,221,448,221,448,220,448,220,447,220,447,220,448,220,448,220,448,219,448,219,448,219,448,218,449,218,449,218,450,217,450,217,450,216,450,216,450,216,450,216,450,215,450,213,450,211,450,210,451,210,451,209,452,209,453,210,453,211,453,211,455,211,455,211,456,211,456,211,456,211,457,212,459,212,460,212,461,212,461,212,461,212,462,212,463,212,464,212,465,212,465,213,465,213,465,213,466,213,466,213,467,213,467,213,467,213,468,214,470,214,472,214,472,215,472,215,472,216,473,216,473,216,473,216,473,217,473,218,473,218,473,218,472,218,472,219,472,219,472,220,472,220,472,220,472,220,472,220,472,221,472,221,471,222,470,223,469,224,468,224,467,224,466,224,466,224,466,224;94,221,93,221,92,221,90,221,90,221,90,221,90,220,89,220,89,220,87,220,87,219,87,218,87,217,87,217,87,217,86,217,86,217,86,216,86,216,86,216,87,216,87,216,87,215,87,215,87,214,87,214,88,214,88,214,88,213,88,213,88,213,90,213,93,213,96,213,98,213,98,213,98,213,99,214,99,214,100,214,102,215,102,215,102,216,99,219,98,219,98,219,97,219,97,220,97,220,96,220,96,220,96,220,95,220,95,221,95,222,94,222,94,221;264,221,263,221,262,221,261,221,260,221,260,221,260,220,260,220,259,220,258,220,258,219,258,218,258,217,257,217,257,217,257,217,257,217,257,216,257,216,257,216,257,216,257,216,258,215,258,215,258,214,258,214,258,214,259,214,259,213,259,213,259,213,261,213,264,213,267,213,269,213,269,213,269,213,269,214,270,214,271,214,272,215,272,215,272,216,269,219,269,219,269,219,268,219,268,220,268,220,267,220,267,220,267,220,266,220,266,221,265,222,264,222,264,221;435,221,434,221,433,221,432,221,431,221,431,221,431,220,430,220,430,220,429,220,428,219,428,218,428,217,428,217,428,217,428,217,428,217,428,216,428,216,428,216,428,216,428,216,428,215,428,215,428,214,428,214,429,214,429,214,430,213,430,213,430,213,431,213,435,213,438,213,440,213,440,213,440,213,440,214,440,214,441,214,443,215,443,215,443,216,440,219,439,219,439,219,439,219,439,220,438,220,438,220,438,220,437,220,437,220,437,221,436,222,435,222,435,221;134,217,133,216,133,216,133,216,133,216,133,216,132,216,132,215,132,214,132,213,132,212,133,212,133,212,134,211,134,211,134,210,134,210,136,210,136,210,137,210,138,211,139,212,139,212,140,212,141,212,142,212,142,213,142,214,142,214,142,214,142,214,142,215,142,215,142,216,142,216,143,216,143,216,143,218,142,219,142,219,142,220,141,220,141,220,141,220,141,220,141,220,140,220,139,220,136,220,135,218;304,217,304,216,304,216,304,216,303,216,303,216,303,216,303,215,303,214,303,213,303,212,304,212,304,212,304,211,304,211,304,210,305,210,306,210,307,210,308,210,309,211,310,212,310,212,311,212,312,212,312,212,312,213,312,214,312,214,313,214,313,214,313,215,313,215,313,216,313,216,313,216,314,216,314,218,313,219,313,219,312,220,312,220,312,220,312,220,312,220,312,220,311,220,309,220,307,220,305,218;475,217,474,216,474,216,474,216,474,216,474,216,474,216,474,215,474,214,474,213,474,212,474,212,475,212,475,211,475,211,475,210,476,210,477,210,478,210,478,210,479,211,480,212,481,212,482,212,483,212,483,212,483,213,483,214,483,214,483,214,483,214,484,215,484,215,484,216,484,216,484,216,484,216,484,218,484,219,483,219,483,220,483,220,482,220,482,220,482,220,482,220,481,220,480,220,478,220,476,218;105,216,104,215,104,214,104,214,105,212,105,213,105,213,106,214,106,214,106,214,107,214,107,214,108,215,108,216,107,216,107,216,107,216,107,216,107,217,106,217,105,216;275,216,275,215,275,214,275,214,276,212,276,213,276,213,276,214,277,214,277,214,277,214,278,214,278,215,278,216,278,216,278,216,278,216,278,216,278,217,277,217,276,216;446,216,446,215,446,214,446,214,447,212,447,213,447,213,447,214,447,214,448,214,448,214,448,214,449,215,449,216,449,216,448,216,448,216,448,216,448,217,447,217,446,216;156,214,156,214,157,213,157,213,158,213,158,213,159,213,160,213,160,214,160,215,159,215,159,215,158,215,158,215,158,215,158,216,158,216,157,215;327,214,327,214,327,213,328,213,328,213,329,213,330,213,330,213,330,214,330,215,330,215,330,215,329,215,329,215,329,215,329,216,328,216,328,215;498,214,498,214,498,213,498,213,499,213,500,213,501,213,501,213,501,214,501,215,501,215,500,215,500,215,500,215,500,215,500,216,499,216,498,215;17,214,17,214,16,214,15,214,15,213,15,213,15,213,15,213,14,213,14,213,14,213,14,213,14,212,13,212,12,212,11,212,10,212,10,212,10,212,10,212,10,212,9,212,7,210,8,210,8,210,8,209,8,209,8,208,9,207,10,207,10,207,11,207,11,206,11,206,12,206,13,206,13,206,14,205,14,205,14,204,15,204,16,204,17,204,18,204,18,204,18,204,20,204,24,204,28,204,30,204,30,204,30,204,32,204,34,204,36,204,37,204,37,205,37,205,37,205,37,205,38,205,39,206,39,207,39,208,39,209,39,209,40,209,40,209,39,209,39,209,39,210,39,210,39,210,39,211,38,211,38,211,38,212,38,212,38,213,37,214,36,214,36,214,36,214,36,214,36,214,35,214,34,214,33,214,32,214,32,215,32,215,31,215,29,215,27,215,26,215,26,215,26,214,25,214,25,214,24,214,24,214,24,215,24,215,23,215,21,215,19,215,18,215,18,214;44,214,43,214,43,214,42,214,41,214,41,214,40,213,40,210,41,210,41,210,41,210,41,210,40,210,40,209,40,207,40,204,41,204,42,204,42,204,43,203,43,203,43,203,44,203,45,203,46,203,47,203,47,203,47,202,47,202,48,202,48,202,49,202,49,202,49,202,50,202,51,202,53,202,54,201,54,201,54,201,55,201,57,201,58,201,60,201,60,201,60,201,60,202,60,202,60,202,61,202,61,202,61,203,62,203,62,203,63,203,63,203,63,204,63,204,63,205,63,205,63,205,64,205,64,206,64,207,63,208,63,208,63,208,63,208,63,208,63,209,62,211,61,211,61,211,60,211,60,212,59,212,59,212,58,212,57,212,57,212,57,213,57,213,57,213,56,213,56,213,56,213,56,213,56,213,55,214,54,214,53,214,53,214,53,214,53,214,52,214,51,214,49,214,48,214,48,215,48,215,47,215,46,215,45,215,44,215,44,215;79,214,78,214,78,214,77,214,76,214,76,214,76,214,76,214,76,214,75,214,75,213,75,213,75,212,75,212,77,212,77,212,78,212,78,212,78,212,79,212,80,212,81,212,82,211,82,211,82,211,83,211,83,211,84,211,84,211,84,211,84,212,84,212,85,213,85,213,86,213,86,214,86,215,82,215,80,215,79,215,79,215;188,214,188,214,187,214,186,214,186,213,186,213,186,213,185,213,185,213,184,213,184,213,184,213,184,212,183,212,183,212,182,212,181,212,181,212,181,212,181,212,180,212,180,212,178,210,178,210,179,210,179,209,179,209,179,208,180,207,181,207,181,207,182,207,182,206,182,206,183,206,183,206,184,206,184,205,185,205,185,204,185,204,187,204,188,204,189,204,189,204,189,204,191,204,195,204,199,204,201,204,201,204,201,204,202,204,204,204,206,204,208,204,208,205,208,205,208,205,208,205,209,205,210,206,210,207,210,208,210,209,210,209,210,209,210,209,210,209,210,209,210,210,210,210,210,210,209,211,209,211,208,211,208,212,208,212,208,213,207,214,207,214,206,214,206,214,206,214,206,214,205,214,205,214,204,214,203,214,203,215,203,215,202,215,200,215,198,215,196,215,196,215,196,214,196,214,196,214,195,214,195,214,195,215,195,215,194,215,192,215,189,215,189,215,189,214;215,214,214,214,213,214,212,214,212,214,211,214,211,213,211,210,211,210,212,210,212,210,211,210,211,210,211,209,211,207,211,204,211,204,213,204,213,204,214,203,214,203,214,203,214,203,216,203,217,203,218,203,218,203,218,202,218,202,219,202,219,202,220,202,220,202,220,202,221,202,222,202,223,202,224,201,224,201,224,201,225,201,227,201,229,201,230,201,230,201,230,201,230,202,231,202,231,202,232,202,232,202,232,203,233,203,233,203,233,203,234,203,234,204,234,204,234,205,234,205,234,205,234,205,234,206,234,207,234,208,234,208,234,208,234,208,234,208,234,209,232,211,231,211,231,211,231,211,231,212,230,212,230,212,229,212,228,212,228,212,228,213,228,213,227,213,227,213,226,213,226,213,226,213,226,213,226,214,225,214,224,214,224,214,224,214,224,214,223,214,221,214,220,214,219,214,219,215,219,215,218,215,217,215,216,215,215,215,215,215;250,214,249,214,248,214,247,214,247,214,247,214,247,214,247,214,246,214,246,214,246,213,246,213,246,212,246,212,247,212,248,212,249,212,249,212,249,212,250,212,251,212,252,212,253,211,253,211,253,211,253,211,254,211,255,211,255,211,255,211,255,212,255,212,256,213,256,213,256,213,256,214,256,215,253,215,251,215,250,215,250,215;359,214,358,214,357,214,357,214,356,213,356,213,356,213,356,213,356,213,355,213,355,213,355,213,355,212,354,212,353,212,352,212,352,212,352,212,352,212,351,212,351,212,350,212,349,210,349,210,349,210,350,209,350,209,350,208,350,207,351,207,352,207,352,207,353,206,353,206,353,206,354,206,354,206,355,205,355,205,356,204,356,204,358,204,359,204,360,204,360,204,360,204,362,204,366,204,369,204,372,204,372,204,372,204,373,204,375,204,377,204,378,204,378,205,378,205,378,205,379,205,380,205,380,206,380,207,380,208,380,209,381,209,381,209,381,209,381,209,380,209,380,210,380,210,380,210,380,211,380,211,379,211,379,212,379,212,379,213,378,214,377,214,377,214,377,214,377,214,377,214,376,214,375,214,374,214,374,214,374,215,374,215,372,215,370,215,368,215,367,215,367,215,367,214,367,214,366,214,366,214,366,214,366,215,366,215,364,215,363,215,360,215,360,215,359,214;386,214,385,214,384,214,383,214,382,214,382,214,381,213,381,210,382,210,382,210,382,210,382,210,382,210,382,209,382,207,382,204,382,204,383,204,384,204,384,203,384,203,384,203,385,203,386,203,387,203,388,203,388,203,388,202,389,202,389,202,390,202,390,202,390,202,390,202,391,202,393,202,394,202,395,201,395,201,395,201,396,201,398,201,400,201,401,201,401,201,401,201,401,202,401,202,402,202,402,202,403,202,403,203,403,203,404,203,404,203,404,203,404,204,404,204,404,205,405,205,405,205,405,205,405,206,405,207,405,208,405,208,404,208,404,208,404,208,404,209,403,211,402,211,402,211,401,211,401,212,401,212,400,212,399,212,399,212,398,212,398,213,398,213,398,213,398,213,397,213,397,213,397,213,397,213,396,214,396,214,395,214,394,214,394,214,394,214,393,214,392,214,391,214,390,214,390,215,390,215,389,215,388,215,386,215,386,215,386,215;420,214,420,214,419,214,418,214,418,214,418,214,418,214,417,214,417,214,416,214,416,213,416,213,416,212,416,212,418,212,419,212,420,212,420,212,420,212,420,212,422,212,423,212,424,211,424,211,424,211,424,211,425,211,425,211,426,211,426,211,426,212,426,212,426,213,427,213,427,213,427,214,427,215,424,215,422,215,420,215,420,215;0,212,0,212,0,212,-1,212,-1,212,-2,211,-3,210,-3,210,-3,208,-3,207,-3,206,-3,206,-3,206,-3,205,-3,205,-3,203,-1,203,0,203,0,199,0,194,0,194,1,194,1,194,2,194,2,194,2,194,2,194,2,194,3,194,3,193,3,193,3,193,4,193,5,193,7,193,8,193,8,193,8,192,9,192,13,192,18,192,19,193,20,195,21,196,20,197,19,197,19,198,19,198,19,199,19,199,19,199,18,199,18,199,18,199,18,200,18,200,17,201,17,201,16,202,16,202,16,203,16,203,15,203,15,203,14,203,14,203,14,203,14,204,14,204,13,204,13,204,13,204,13,204,12,204,12,204,11,204,11,204,11,205,10,205,10,206,7,206,5,206,4,205,4,205,4,205,4,205,4,205,3,205,3,205,3,205,3,204,2,204,2,204,0,204,0,204,0,205,0,205,0,206,1,206,2,206,3,206,3,207,3,207,3,208,3,208,3,208,4,208,4,208,4,209,3,209,3,209,3,209,3,209,3,210,3,211,2,212,1,212,1,212,1,212,1,213,1,213,1,213,1,213,0,213,0,213,0,213;171,212,171,212,170,212,170,212,169,212,169,211,168,210,168,210,168,208,168,207,168,206,168,206,168,206,168,205,168,205,168,203,170,203,171,203,171,199,171,194,171,194,172,194,172,194,172,194,172,194,172,194,172,194,173,194,173,194,174,193,174,193,174,193,175,193,176,193,177,193,178,193,178,193,178,192,180,192,183,192,189,192,190,193,191,195,191,196,190,197,190,197,190,198,190,198,190,199,189,199,189,199,189,199,189,199,189,199,189,200,188,200,188,201,187,201,187,202,187,202,187,203,187,203,186,203,185,203,185,203,185,203,185,203,185,204,184,204,184,204,184,204,184,204,184,204,183,204,183,204,182,204,181,204,181,205,181,205,180,206,178,206,176,206,175,205,175,205,175,205,175,205,174,205,174,205,174,205,174,205,174,204,173,204,172,204,171,204,171,204,171,205,171,205,171,206,172,206,173,206,174,206,174,207,174,207,174,208,174,208,174,208,174,208,174,208,174,209,174,209,174,209,174,209,174,209,174,210,174,211,173,212,172,212,172,212,172,212,172,213,172,213,171,213,171,213,171,213,171,213,171,213;342,212,341,212,341,212,341,212,340,212,339,211,338,210,338,210,338,208,338,207,338,206,339,206,339,206,339,205,339,205,339,203,340,203,342,203,342,199,342,194,342,194,342,194,343,194,343,194,343,194,343,194,343,194,344,194,344,194,344,193,344,193,344,193,345,193,347,193,348,193,349,193,349,193,349,192,351,192,354,192,359,192,360,193,362,195,362,196,361,197,360,197,360,198,360,198,360,199,360,199,360,199,360,199,360,199,360,199,360,200,359,200,359,201,358,201,358,202,358,202,358,203,357,203,357,203,356,203,356,203,356,203,356,203,355,204,355,204,354,204,354,204,354,204,354,204,354,204,353,204,353,204,352,204,352,205,351,205,351,206,348,206,347,206,346,205,346,205,346,205,345,205,345,205,344,205,344,205,344,205,344,204,344,204,343,204,342,204,342,204,342,205,342,205,342,206,342,206,343,206,344,206,344,207,344,207,344,208,345,208,345,208,345,208,345,208,345,209,345,209,345,209,344,209,344,209,344,210,344,211,344,212,343,212,342,212,342,212,342,213,342,213,342,213,342,213,342,213,342,213,342,213;126,212,125,212,125,212,124,212,124,211,124,211,124,211,123,211,122,211,120,211,120,211,120,211,120,210,119,210,117,210,116,210,115,210,115,210,115,210,114,210,114,210,112,210,112,209,112,209,112,209,112,208,113,208,113,208,113,208,113,208,112,208,112,207,112,207,112,206,112,205,112,205,111,205,111,204,111,204,111,203,111,202,110,202,109,201,109,201,110,200,111,199,112,199,112,200,112,200,113,200,114,200,116,200,116,200,117,201,117,201,117,202,120,202,121,202,122,202,122,202,122,202,123,202,124,202,125,202,126,202,126,203,126,203,127,203,129,203,131,203,132,203,132,203,132,203,133,204,134,204,135,204,135,204,136,204,136,205,137,205,137,206,137,206,135,208,135,208,134,208,134,208,134,209,134,209,133,210,133,210,132,210,132,211,132,211,132,212,131,212,128,212,127,212,126,212,126,212;296,212,296,212,295,212,295,212,294,211,294,211,294,211,293,211,292,211,291,211,290,211,290,211,290,210,289,210,288,210,287,210,286,210,286,210,286,210,285,210,284,210,283,210,283,209,283,209,283,209,283,208,283,208,284,208,284,208,283,208,283,208,283,207,283,207,283,206,283,205,282,205,282,205,282,204,282,204,282,203,281,202,281,202,280,201,280,201,281,200,281,199,283,199,283,200,283,200,284,200,285,200,286,200,287,200,287,201,288,201,288,202,290,202,292,202,293,202,293,202,293,202,294,202,295,202,296,202,297,202,297,203,297,203,298,203,300,203,302,203,303,203,303,203,303,203,304,204,304,204,306,204,306,204,307,204,307,205,308,205,308,206,308,206,306,208,305,208,305,208,304,208,304,209,304,209,304,210,304,210,303,210,303,211,303,211,303,212,302,212,299,212,297,212,296,212,296,212;467,212,466,212,466,212,465,212,465,211,465,211,465,211,464,211,463,211,462,211,461,211,461,211,461,210,460,210,459,210,457,210,456,210,456,210,456,210,456,210,455,210,454,210,454,209,454,209,454,209,454,208,454,208,454,208,454,208,454,208,454,208,454,207,454,207,454,206,453,205,453,205,452,205,452,204,452,204,452,203,452,202,452,202,451,201,451,201,451,200,452,199,454,199,454,200,454,200,454,200,455,200,457,200,457,200,458,201,458,201,459,202,461,202,462,202,464,202,464,202,464,202,464,202,466,202,467,202,468,202,468,203,468,203,469,203,471,203,472,203,474,203,474,203,474,203,474,204,475,204,476,204,477,204,477,204,478,205,478,205,478,206,478,206,477,208,476,208,476,208,475,208,475,209,475,209,475,210,474,210,474,210,474,211,474,211,474,212,473,212,470,212,468,212,467,212,467,212;72,211,71,211,70,211,69,211,68,210,68,209,68,209,68,208,68,208,67,207,67,207,67,206,67,204,67,204,68,204,68,204,68,204,68,204,68,204,69,204,71,204,72,204,73,203,73,203,73,203,73,203,74,203,74,203,75,203,75,203,75,202,75,202,76,202,76,202,76,202,76,202,76,202,77,202,77,202,78,202,78,201,78,201,78,201,79,201,79,201,80,201,80,201,80,201,80,200,81,200,82,200,83,200,84,200,84,200,84,200,84,200,85,200,86,200,87,199,87,199,87,199,87,199,88,199,88,199,88,199,88,199,88,199,89,200,90,200,92,200,93,200,93,200,94,201,94,202,94,202,94,202,94,203,95,203,95,203,95,204,95,206,95,208,95,208,94,208,94,208,94,208,94,209,94,209,92,209,91,209,89,209,88,209,88,209,88,209,87,210,85,210,83,210,82,210,82,210,82,210,81,210,80,210,79,210,78,210,78,211,78,211,77,211,76,211,75,211,74,211,74,211,74,211,74,212,73,212,72,212,72,211,72,211;142,211,141,211,141,211,139,211,139,211,139,210,139,210,139,210,139,210,138,210,138,208,138,207,138,205,138,204,139,204,139,204,139,204,139,204,139,203,139,203,140,203,140,203,140,203,140,203,140,202,141,202,143,202,144,202,146,202,146,202,146,202,148,202,153,202,158,202,160,202,160,202,160,202,161,202,162,202,163,202,164,202,164,203,164,203,164,203,165,203,166,203,166,203,166,205,166,206,165,207,165,207,165,207,165,207,165,208,165,208,165,209,165,209,164,209,164,209,164,209,164,210,163,211,162,211,161,211,161,211,161,211,161,211,159,212,157,212,154,212,153,211,153,211,153,211,152,211,150,211,148,211,147,211,147,211,147,211,146,212,145,212,143,212,142,211,142,211;242,211,242,211,241,211,240,211,239,210,239,209,239,209,239,208,238,208,238,207,238,207,238,206,238,204,238,204,238,204,239,204,239,204,239,204,239,204,240,204,241,204,243,204,244,203,244,203,244,203,244,203,245,203,245,203,246,203,246,203,246,202,246,202,246,202,247,202,247,202,247,202,247,202,247,202,248,202,248,202,249,201,249,201,249,201,249,201,250,201,250,201,251,201,251,201,251,200,252,200,253,200,253,200,254,200,254,200,254,200,255,200,256,200,257,200,258,199,258,199,258,199,258,199,258,199,259,199,259,199,259,199,259,199,260,200,261,200,263,200,263,200,264,200,264,201,265,202,265,202,265,202,265,203,265,203,265,203,266,204,266,206,266,208,265,208,265,208,264,208,264,208,264,209,264,209,263,209,262,209,260,209,259,209,259,209,259,209,258,210,256,210,254,210,253,210,253,210,253,210,252,210,251,210,250,210,249,210,249,211,249,211,248,211,247,211,246,211,245,211,245,211,245,211,244,212,244,212,243,212,242,211,242,211;313,211,312,211,311,211,310,211,310,211,310,210,310,210,309,210,309,210,309,210,309,208,309,207,309,205,309,204,309,204,309,204,310,204,310,204,310,203,310,203,310,203,311,203,311,203,311,203,311,202,312,202,314,202,315,202,316,202,316,202,316,202,319,202,324,202,328,202,331,202,331,202,331,202,332,202,333,202,333,202,334,202,334,203,334,203,335,203,335,203,336,203,336,203,336,205,336,206,336,207,336,207,336,207,336,207,336,208,336,208,335,209,335,209,335,209,335,209,335,209,335,210,334,211,333,211,332,211,332,211,332,211,332,211,330,212,328,212,325,212,324,211,324,211,324,211,322,211,321,211,319,211,318,211,318,211,318,211,317,212,315,212,314,212,313,211,313,211;413,211,412,211,412,211,410,211,410,210,410,209,410,209,409,208,409,208,408,207,408,207,408,206,408,204,408,204,409,204,409,204,410,204,410,204,410,204,411,204,412,204,413,204,414,203,414,203,414,203,415,203,415,203,416,203,416,203,416,203,416,202,416,202,417,202,417,202,418,202,418,202,418,202,418,202,419,202,419,202,420,201,420,201,420,201,420,201,421,201,421,201,422,201,422,201,422,200,422,200,423,200,424,200,425,200,425,200,425,200,426,200,427,200,427,200,428,199,428,199,428,199,428,199,429,199,429,199,430,199,430,199,430,199,430,200,432,200,434,200,434,200,435,200,435,201,436,202,436,202,436,202,436,203,436,203,436,203,436,204,436,206,436,208,436,208,436,208,435,208,435,208,435,209,435,209,434,209,432,209,431,209,430,209,430,209,430,209,428,210,427,210,425,210,424,210,424,210,424,210,423,210,422,210,420,210,420,210,420,211,420,211,419,211,418,211,416,211,416,211,416,211,416,211,415,212,414,212,413,212,413,211,413,211;484,211,483,211,482,211,480,211,480,211,480,210,480,210,480,210,480,210,480,210,480,208,480,207,480,205,480,204,480,204,480,204,480,204,480,204,480,203,480,203,481,203,481,203,482,203,482,203,482,202,483,202,484,202,486,202,487,202,487,202,487,202,490,202,494,202,499,202,502,202,502,202,502,202,502,202,503,202,504,202,505,202,505,203,505,203,505,203,506,203,507,203,507,203,507,205,507,206,507,207,507,207,506,207,506,207,506,208,506,208,506,209,506,209,506,209,506,209,506,209,506,210,505,211,503,211,503,211,502,211,502,211,502,211,501,212,498,212,496,212,494,211,494,211,494,211,493,211,491,211,489,211,488,211,488,211,488,211,487,212,486,212,485,212,484,211,484,211;98,208,98,208,98,207,98,207,97,206,97,206,96,205,96,205,96,204,96,203,96,203,96,203,95,203,95,200,96,199,97,199,103,199,103,199,103,199,104,200,105,200,107,200,108,200,108,201,108,201,108,202,109,202,109,202,109,202,109,202,109,203,109,203,109,203,109,203,110,203,110,204,110,204,110,205,110,205,110,205,110,205,110,206,110,206,110,206,111,206,111,206,111,207,110,208,110,208,110,208,109,208,109,208,109,208,109,209,109,209,107,209,104,209,99,209,98,209,98,208;268,208,268,208,268,207,268,207,268,206,268,206,267,205,267,205,267,204,267,203,267,203,267,203,266,203,266,200,267,199,267,199,274,199,274,199,274,199,274,200,276,200,278,200,279,200,279,201,279,201,279,202,279,202,279,202,280,202,280,202,280,203,280,203,280,203,280,203,280,203,280,204,280,204,280,205,281,205,281,205,281,205,281,206,281,206,281,206,281,206,282,206,282,207,281,208,281,208,280,208,280,208,280,208,280,208,280,209,280,209,278,209,274,209,270,209,269,209,269,208;439,208,439,208,439,207,439,207,439,206,438,206,438,205,438,205,438,204,438,203,437,203,437,203,437,203,437,200,437,199,438,199,444,199,444,199,444,199,445,200,446,200,449,200,450,200,450,201,450,201,450,202,450,202,450,202,450,202,450,202,450,203,450,203,451,203,451,203,451,203,451,204,451,204,451,205,451,205,451,205,452,205,452,206,452,206,452,206,452,206,452,206,452,207,452,208,451,208,451,208,451,208,450,208,450,208,450,209,450,209,448,209,445,209,441,209,440,209,439,208;36,203,35,203,33,203,30,203,29,203,29,203,29,202,27,202,24,202,19,202,19,201,19,200,19,200,20,199,20,199,20,198,20,198,20,198,20,197,21,197,21,197,22,196,22,196,22,196,22,195,22,195,23,195,23,194,23,194,23,194,23,193,24,193,24,193,24,192,24,192,24,192,24,191,25,191,25,191,26,190,26,190,26,190,26,190,26,190,26,190,26,189,26,189,26,189,27,188,27,188,28,187,28,186,28,186,28,186,29,185,29,185,30,184,32,184,33,185,33,185,34,186,35,186,35,186,36,186,36,186,36,187,37,188,37,188,38,188,44,194,44,194,44,194,44,195,45,196,46,197,47,198,47,198,47,199,47,199,47,199,48,199,48,199,47,199,47,199,47,200,47,200,47,201,46,202,44,202,44,202,43,202,43,202,43,202,42,202,42,202,41,202,40,202,40,203,40,203,40,203,40,203,39,203,39,203,39,203,39,203,38,204,38,204,37,204,36,203,36,203;207,203,205,203,203,203,201,203,200,203,200,203,200,202,198,202,195,202,190,202,190,201,190,200,190,200,190,199,191,199,191,198,191,198,191,198,191,197,192,197,192,197,192,196,192,196,192,196,192,195,193,195,193,195,194,194,194,194,194,194,194,193,194,193,195,193,195,192,195,192,195,192,195,191,196,191,196,191,196,190,196,190,196,190,196,190,197,190,197,190,197,189,197,189,197,189,197,188,198,188,198,187,199,186,199,186,199,186,199,185,200,185,201,184,203,184,204,185,204,185,205,186,205,186,206,186,206,186,206,186,206,187,208,188,208,188,209,188,214,194,214,194,214,194,215,195,216,196,217,197,218,198,218,198,218,199,218,199,218,199,218,199,218,199,218,199,218,199,218,200,218,200,218,201,217,202,215,202,214,202,214,202,214,202,214,202,213,202,212,202,211,202,211,202,211,203,211,203,211,203,210,203,210,203,210,203,210,203,210,203,209,204,208,204,207,204,207,203,207,203;378,203,376,203,374,203,372,203,370,203,370,203,370,202,368,202,365,202,360,202,360,201,360,200,360,200,361,199,361,199,362,198,362,198,362,198,362,197,362,197,363,197,363,196,363,196,363,196,363,195,364,195,364,195,364,194,364,194,364,194,364,193,365,193,365,193,366,192,366,192,366,192,366,191,366,191,367,191,367,190,367,190,367,190,367,190,367,190,367,190,368,189,368,189,368,189,368,188,369,188,369,187,370,186,370,186,370,186,370,185,370,185,371,184,374,184,375,185,375,185,375,186,376,186,377,186,377,186,377,186,377,187,378,188,379,188,379,188,385,194,385,194,385,194,386,195,387,196,387,197,388,198,388,198,388,199,388,199,389,199,389,199,389,199,389,199,388,199,388,200,388,200,388,201,387,202,386,202,385,202,384,202,384,202,384,202,384,202,383,202,382,202,382,202,382,203,382,203,381,203,381,203,380,203,380,203,380,203,380,203,380,204,379,204,378,204,378,203,378,203;69,201,69,200,69,200,69,200,70,200,70,199,70,199,70,198,70,198,70,198,70,198,70,198,70,197,70,197,71,197,71,197,71,196,71,196,71,194,71,194,72,194,73,194,73,193,73,193,73,192,73,192,73,192,73,192,74,192,74,191,74,191,74,190,74,190,75,190,75,189,75,189,75,189,75,188,76,188,76,188,76,187,76,187,76,186,78,184,78,184,78,184,79,184,80,183,81,182,81,182,83,182,84,182,84,182,85,182,85,183,85,183,86,183,86,183,87,183,87,184,87,184,88,184,89,184,89,184,90,184,90,185,90,185,91,186,91,186,92,186,92,186,92,186,92,186,93,186,94,186,95,186,96,187,96,188,96,188,96,189,97,189,97,189,97,189,97,190,97,190,97,190,97,190,96,190,96,191,96,192,96,193,96,193,95,194,95,194,94,195,94,195,94,195,93,195,93,196,93,196,92,196,92,196,91,196,90,196,90,197,89,197,89,198,88,198,87,198,87,198,87,198,87,198,86,198,85,198,84,198,84,198,84,199,84,199,83,199,82,199,80,199,80,199,80,199,80,199,79,200,79,200,78,200,78,200,78,200,78,200,78,200,77,200,76,200,76,200,75,201,75,201,74,202,73,202,73,202,72,202,72,202,72,202,70,202,69,202;239,201,239,200,240,200,240,200,240,200,240,199,240,199,240,198,241,198,241,198,241,198,241,198,241,197,241,197,241,197,241,197,242,196,242,196,242,194,242,194,243,194,243,194,244,193,244,193,244,192,244,192,244,192,244,192,244,192,244,191,244,191,244,190,245,190,245,190,246,189,246,189,246,189,246,188,246,188,247,188,247,187,247,187,247,186,248,184,249,184,249,184,250,184,251,183,252,182,252,182,253,182,254,182,255,182,255,182,255,183,256,183,257,183,257,183,258,183,258,184,258,184,259,184,259,184,260,184,260,184,261,185,261,185,261,186,262,186,262,186,263,186,263,186,263,186,264,186,264,186,266,186,267,187,267,188,267,188,267,189,267,189,267,189,268,189,268,190,268,190,267,190,267,190,267,190,267,191,267,192,267,193,267,193,266,194,266,194,265,195,265,195,265,195,264,195,264,196,264,196,263,196,262,196,261,196,261,196,261,197,260,197,260,198,259,198,258,198,258,198,258,198,258,198,257,198,256,198,255,198,254,198,254,199,254,199,253,199,252,199,251,199,250,199,250,199,250,199,250,200,250,200,249,200,249,200,249,200,249,200,248,200,248,200,247,200,246,200,246,201,245,201,245,202,244,202,243,202,243,202,243,202,243,202,240,202,240,202;410,201,410,200,411,200,411,200,411,200,411,199,411,199,411,198,411,198,411,198,412,198,412,198,412,197,412,197,412,197,412,197,412,196,412,196,412,194,413,194,414,194,414,194,414,193,414,193,414,192,414,192,415,192,415,192,415,192,415,191,415,191,415,190,416,190,416,190,416,189,416,189,416,189,416,188,417,188,417,188,418,187,418,187,418,186,419,184,420,184,420,184,420,184,421,183,422,182,423,182,424,182,425,182,425,182,426,182,426,183,427,183,427,183,428,183,428,183,429,184,429,184,429,184,430,184,430,184,431,184,431,185,431,185,432,186,433,186,433,186,434,186,434,186,434,186,434,186,435,186,437,186,438,187,438,188,438,188,438,189,438,189,438,189,438,189,438,190,438,190,438,190,438,190,438,190,438,191,438,192,438,193,437,193,437,194,436,194,436,195,435,195,435,195,435,195,435,196,434,196,434,196,433,196,432,196,431,196,431,197,431,197,430,198,429,198,429,198,428,198,428,198,428,198,427,198,427,198,426,198,425,198,425,199,425,199,424,199,423,199,422,199,421,199,421,199,421,199,421,200,420,200,420,200,420,200,420,200,420,200,419,200,418,200,417,200,417,200,417,201,416,201,416,202,415,202,414,202,414,202,414,202,414,202,411,202,411,202;164,201,163,201,162,201,160,201,160,201,160,201,160,200,158,200,155,200,151,200,151,200,151,200,150,199,150,199,149,199,147,199,147,199,146,198,145,197,145,196,145,196,145,196,146,196,146,195,146,194,146,193,146,193,146,193,146,193,145,192,145,192,144,191,144,191,144,191,144,190,144,190,143,190,143,189,143,189,143,188,143,188,142,188,142,188,142,188,142,188,143,188,143,187,143,186,143,186,143,186,143,186,143,186,144,185,144,184,144,182,143,182,143,182,143,182,143,181,143,181,143,180,143,180,144,180,144,180,145,180,145,181,145,181,145,181,145,181,146,180,147,180,151,180,154,180,156,180,156,180,156,180,157,180,160,180,163,180,165,180,165,180,165,180,165,180,165,180,166,180,166,180,166,181,167,181,167,181,166,182,166,182,165,183,165,183,165,183,164,183,164,184,163,185,163,186,164,187,164,187,164,188,164,189,164,189,164,190,165,190,165,190,165,190,165,190,165,191,165,191,165,191,165,191,166,191,166,192,166,192,166,193,166,193,166,193,166,193,166,194,166,194,166,194,167,194,167,194,167,195,167,196,167,198,167,198,166,199,166,199,166,199,166,200,166,200,165,201,165,201,164,202,164,202,164,201;167,200,168,198,169,198,169,198,170,199,170,199,170,201,169,202,168,202,167,202,167,201,167,201;334,201,333,201,332,201,331,201,330,201,330,201,330,200,329,200,326,200,322,200,322,200,321,200,321,199,320,199,319,199,318,199,318,199,317,198,316,197,316,196,316,196,316,196,316,196,316,195,316,194,316,193,317,193,317,193,317,193,316,192,315,192,315,191,315,191,315,191,315,190,314,190,314,190,314,189,314,189,314,188,313,188,313,188,313,188,313,188,313,188,313,188,314,187,314,186,314,186,314,186,314,186,314,186,314,185,314,184,314,182,314,182,314,182,314,182,314,181,314,181,314,180,314,180,314,180,315,180,316,180,316,181,316,181,316,181,316,181,316,180,318,180,321,180,324,180,326,180,326,180,326,180,328,180,331,180,334,180,336,180,336,180,336,180,336,180,336,180,336,180,337,180,337,181,337,181,337,181,337,182,336,182,336,183,336,183,335,183,335,183,334,184,333,185,333,186,334,187,335,187,335,188,335,189,335,189,335,190,335,190,335,190,336,190,336,190,336,191,336,191,336,191,336,191,336,191,336,192,336,192,336,193,337,193,337,193,337,193,337,194,337,194,337,194,337,194,337,194,338,195,338,196,338,198,337,198,337,199,336,199,336,199,336,200,336,200,336,201,336,201,335,202,334,202,334,201;338,200,339,198,340,198,340,198,340,199,340,199,340,201,340,202,338,202,338,202,338,201,338,201;505,201,504,201,503,201,502,201,501,201,501,201,501,200,499,200,497,200,493,200,492,200,492,200,491,199,491,199,490,199,489,199,488,199,487,198,487,197,486,196,486,196,487,196,487,196,487,195,487,194,487,193,487,193,488,193,487,193,487,192,486,192,486,191,486,191,486,191,485,190,485,190,484,190,484,189,484,189,484,188,484,188,484,188,483,188,483,188,484,188,484,188,484,187,484,186,484,186,484,186,485,186,485,186,485,185,485,184,485,182,485,182,485,182,484,182,484,181,484,181,484,180,484,180,485,180,486,180,486,180,486,181,486,181,487,181,487,181,487,180,488,180,492,180,495,180,497,180,497,180,497,180,499,180,502,180,504,180,506,180,506,180,506,180,506,180,507,180,507,180,507,180,508,181,508,181,508,181,507,182,507,182,506,183,506,183,506,183,505,183,505,184,504,185,504,186,505,187,505,187,506,188,506,189,506,189,506,190,506,190,506,190,506,190,506,190,506,191,506,191,507,191,507,191,507,191,507,192,507,192,507,193,507,193,507,193,508,193,508,194,508,194,508,194,508,194,508,194,508,195,508,196,508,198,508,198,508,199,507,199,507,199,507,200,507,200,507,201,506,201,506,202,505,202,505,201;508,200,510,198,510,198,511,198,511,199,511,199,511,201,510,202,509,202,508,202,508,201,508,201;63,200,62,200,61,200,60,200,60,200,60,200,60,200,58,200,57,200,55,200,54,200,54,200,54,200,50,200,49,200,49,199,49,198,49,192,49,188,49,186,49,186,49,186,50,185,50,185,50,183,50,183,52,183,54,183,54,183,55,184,55,184,55,184,55,184,56,184,56,185,57,186,58,186,59,187,59,187,59,187,60,187,61,188,61,189,62,190,63,190,63,190,64,190,64,190,64,191,65,191,65,191,65,191,66,191,66,192,66,192,67,192,67,192,67,192,68,193,68,194,68,194,68,194,69,194,69,194,69,194,69,195,69,195,69,196,69,196,68,196,68,196,68,196,68,197,68,198,68,198,67,198,67,199,67,199,67,200,65,201,64,201,63,201,63,201,63,201;127,200,126,200,124,200,122,200,122,200,122,200,122,199,121,199,121,199,121,199,121,197,121,195,121,192,121,192,122,191,122,190,123,190,128,190,134,190,135,191,136,192,136,193,136,193,136,193,136,194,137,194,137,194,138,195,138,195,138,196,138,196,138,197,139,197,139,197,139,198,139,198,139,198,140,199,140,199,140,199,140,200,140,201,134,201,129,201,127,201,127,201;234,200,233,200,232,200,231,200,230,200,230,200,230,200,229,200,228,200,226,200,225,200,225,200,225,200,221,200,220,200,220,199,220,198,220,192,220,188,220,186,220,186,220,186,220,185,220,185,220,183,221,183,223,183,224,183,225,183,225,184,225,184,226,184,226,184,226,184,227,185,228,186,229,186,229,187,230,187,230,187,230,187,231,188,232,189,233,190,233,190,234,190,234,190,235,190,235,191,235,191,236,191,236,191,236,191,237,192,237,192,237,192,237,192,238,192,239,193,239,194,239,194,239,194,239,194,239,194,240,194,240,195,240,195,239,196,239,196,239,196,239,196,239,196,239,197,239,198,238,198,238,198,238,199,238,199,238,200,236,201,235,201,234,201,234,201,234,201;298,200,296,200,295,200,292,200,292,200,292,200,292,199,292,199,292,199,292,199,292,197,292,195,292,192,292,192,292,191,293,190,293,190,299,190,305,190,306,191,306,192,307,193,307,193,307,193,307,194,308,194,308,194,308,195,308,195,308,196,308,196,309,197,309,197,310,197,310,198,310,198,310,198,310,199,311,199,311,199,311,200,311,201,304,201,300,201,298,201,298,201;404,200,403,200,403,200,402,200,401,200,401,200,401,200,400,200,398,200,397,200,396,200,396,200,396,200,391,200,391,200,390,199,390,198,390,192,390,188,390,186,391,186,391,186,391,185,391,185,391,183,392,183,394,183,395,183,395,183,396,184,396,184,397,184,397,184,397,184,398,185,399,186,399,186,400,187,400,187,400,187,401,187,402,188,403,189,403,190,404,190,404,190,405,190,405,190,405,191,406,191,406,191,406,191,407,191,407,192,407,192,408,192,408,192,409,192,410,193,410,194,410,194,410,194,410,194,410,194,410,194,410,195,410,195,410,196,410,196,410,196,410,196,410,196,410,197,409,198,409,198,408,198,408,199,408,199,408,200,407,201,405,201,405,201,404,201,404,201;468,200,467,200,466,200,463,200,463,200,463,200,463,199,463,199,463,199,462,199,462,197,462,195,462,192,462,192,463,191,464,190,464,190,469,190,475,190,476,191,477,192,478,193,478,193,478,193,478,194,478,194,479,194,479,195,479,195,479,196,479,196,480,197,480,197,480,197,480,198,480,198,480,198,481,199,481,199,482,199,482,200,482,201,475,201,471,201,468,201,468,201;112,198,111,198,110,198,108,198,107,198,107,198,107,198,106,198,105,198,103,198,102,197,102,197,102,197,101,197,100,197,99,197,98,197,98,196,97,195,97,194,97,194,97,194,98,193,98,192,98,191,98,190,98,190,98,190,98,190,98,190,98,189,98,189,98,189,97,189,97,188,98,187,99,187,100,186,100,186,100,186,101,186,101,186,101,186,102,186,104,186,106,186,107,185,107,185,107,185,107,185,108,185,108,185,109,185,109,184,109,184,116,191,116,192,116,192,117,192,118,193,119,194,119,195,119,196,119,196,119,197,119,197,120,197,120,198,119,198,118,199,112,199,112,199;283,198,282,198,280,198,279,198,278,198,278,198,278,198,277,198,275,198,274,198,273,197,273,197,273,197,272,197,271,197,269,197,269,197,268,196,267,195,267,194,268,194,268,194,268,193,268,192,268,191,268,190,269,190,269,190,269,190,269,190,269,189,269,189,269,189,268,189,268,188,269,187,269,187,270,186,271,186,271,186,272,186,272,186,272,186,273,186,275,186,276,186,278,185,278,185,278,185,278,185,278,185,279,185,280,185,280,184,280,184,287,191,287,192,287,192,287,192,288,193,289,194,290,195,290,196,290,196,290,197,290,197,290,197,290,198,290,198,289,199,283,199,283,199;454,198,452,198,451,198,449,198,448,198,448,198,448,198,447,198,446,198,445,198,444,197,444,197,444,197,443,197,442,197,440,197,440,197,439,196,438,195,438,194,439,194,439,194,439,193,439,192,439,191,439,190,439,190,439,190,440,190,440,190,440,189,439,189,439,189,439,189,439,188,440,187,440,187,441,186,441,186,442,186,442,186,442,186,442,186,443,186,445,186,447,186,448,185,448,185,448,185,449,185,449,185,450,185,450,185,450,184,450,184,458,191,458,192,458,192,458,192,459,193,460,194,460,195,460,196,460,196,460,197,461,197,461,197,461,198,460,198,460,199,454,199,454,199;46,195,46,195,46,195,46,194,45,194,45,194,44,194,41,190,41,190,41,190,42,190,42,189,42,189,42,188,42,188,43,187,43,187,45,187,47,187,48,187,48,192,48,194,47,195,47,196,46,196,46,196,46,196;216,195,216,195,216,195,216,194,216,194,216,194,215,194,211,190,212,190,212,190,212,190,212,189,212,189,213,188,213,188,214,187,214,187,216,187,218,187,218,187,218,192,218,194,218,195,218,196,217,196,217,196,217,196;387,195,387,195,387,195,387,194,387,194,386,194,386,194,382,190,382,190,383,190,383,190,383,189,383,189,383,188,384,188,384,187,385,187,386,187,389,187,389,187,389,192,389,194,389,195,388,196,388,196,388,196,387,196;168,193,168,193,168,193,167,193,167,193,167,192,167,191,167,190,166,190,166,190,166,189,166,188,166,187,165,187,165,187,164,186,164,184,165,184,165,184,166,183,167,183,169,180,170,180,170,184,170,185,170,186,170,186,170,186,170,192,170,193,169,194,168,194,168,193;339,193,339,193,338,193,338,193,338,193,338,192,338,191,337,190,337,190,336,190,336,189,336,188,336,187,336,187,336,187,335,186,335,184,335,184,336,184,337,183,338,183,340,180,340,180,340,184,340,185,340,186,341,186,341,186,341,192,340,193,340,194,339,194,339,193;510,193,509,193,509,193,508,193,508,193,508,192,508,191,508,190,508,190,507,190,507,189,507,188,507,187,507,187,506,187,505,186,505,184,506,184,506,184,507,183,508,183,511,180,511,180,511,184,511,185,511,186,511,186,512,186,512,192,511,193,510,194,510,194,510,193;119,192,119,192,118,192,118,192,118,192,118,192,118,191,117,191,117,191,117,191,117,191,117,190,117,190,117,190,119,190,120,190,120,191,120,193,120,193,120,193,119,193,119,193,119,193;290,192,289,192,289,192,288,192,288,192,288,192,288,191,288,191,288,191,288,191,288,191,288,190,288,190,288,190,289,190,291,190,291,191,291,193,291,193,290,193,290,193,290,193,290,193;460,192,460,192,460,192,459,192,459,192,459,192,459,191,459,191,459,191,458,191,458,191,458,190,458,190,458,190,460,190,462,190,462,191,462,193,461,193,461,193,460,193,460,193,460,193;138,191,138,191,138,191,138,190,138,190,139,190,139,190,139,190,140,190,140,190,140,191,140,191,140,191,139,192,139,192,139,192,138,192,138,192;308,191,308,191,308,191,308,190,309,190,310,190,310,190,310,190,310,190,311,190,311,191,311,191,311,191,310,192,309,192,309,192,309,192,309,192;479,191,479,191,479,191,479,190,480,190,480,190,480,190,481,190,481,190,481,190,482,191,482,191,482,191,481,192,480,192,480,192,479,192,479,192;2,187,2,186,2,186,3,185,3,185,3,184,3,183,3,183,4,183,4,183,4,183,4,183,4,182,4,182,5,182,5,182,6,182,6,182,6,182,6,182,7,182,8,182,8,181,8,181,8,181,9,181,9,181,10,181,10,181,10,181,10,180,11,180,12,180,12,180,13,180,13,180,13,180,14,180,16,180,18,180,19,180,19,180,19,180,19,180,20,180,21,180,22,180,22,181,22,181,22,181,22,181,23,181,24,181,24,182,25,182,25,183,25,184,25,185,25,186,25,186,24,186,24,187,24,188,24,190,24,190,22,190,21,190,21,190,21,191,21,191,19,191,16,191,12,191,10,191,10,191,10,191,9,192,6,192,2,192,2,189;172,187,172,186,173,186,173,185,174,185,174,184,174,183,174,183,174,183,175,183,175,183,175,183,175,182,175,182,176,182,176,182,176,182,176,182,176,182,177,182,178,182,178,182,179,181,179,181,179,181,179,181,180,181,180,181,181,181,181,181,181,180,181,180,182,180,183,180,184,180,184,180,184,180,185,180,187,180,188,180,190,180,190,180,190,180,190,180,191,180,192,180,192,180,192,181,192,181,193,181,193,181,193,181,194,181,195,182,195,182,196,183,196,184,196,185,195,186,195,186,195,186,195,187,195,188,195,190,194,190,193,190,192,190,192,190,192,191,192,191,190,191,186,191,183,191,181,191,181,191,181,191,179,192,177,192,172,192,172,189;343,187,343,186,344,186,344,185,344,185,344,184,344,183,344,183,345,183,345,183,346,183,346,183,346,182,346,182,346,182,347,182,347,182,347,182,347,182,347,182,348,182,349,182,350,181,350,181,350,181,350,181,351,181,351,181,352,181,352,181,352,180,352,180,353,180,354,180,354,180,354,180,354,180,355,180,357,180,359,180,360,180,360,180,360,180,361,180,362,180,362,180,363,180,363,181,363,181,363,181,364,181,364,181,365,181,365,182,366,182,366,183,366,184,366,185,366,186,366,186,366,186,366,187,366,188,366,190,365,190,363,190,363,190,362,190,362,191,362,191,360,191,357,191,354,191,352,191,352,191,352,191,350,192,347,192,343,192,343,189;120,188,119,188,117,188,114,188,114,188,114,188,114,187,114,187,115,187,115,187,115,187,115,186,115,186,115,186,115,186,116,186,117,185,118,184,119,182,120,182,120,182,120,182,121,181,122,180,123,179,126,179,128,179,129,179,129,179,129,179,130,180,132,180,134,180,135,180,135,180,135,180,136,180,138,180,141,180,142,180,142,181,142,181,142,182,142,182,142,182,142,182,142,183,142,184,142,185,142,185,142,185,142,185,142,186,142,187,141,187,141,187,141,187,140,187,140,188,139,188,139,188,137,188,136,188,136,188,136,189,136,189,133,189,128,189,123,189,120,189,120,189;291,188,290,188,288,188,285,188,285,188,285,188,285,187,285,187,285,187,285,187,286,187,286,186,286,186,286,186,286,186,286,186,287,185,289,184,290,182,291,182,291,182,291,182,292,181,293,180,294,179,297,179,298,179,300,179,300,179,300,179,301,180,303,180,304,180,306,180,306,180,306,180,307,180,309,180,312,180,312,180,312,181,312,181,312,182,313,182,313,182,313,182,313,183,313,184,313,185,313,185,312,185,312,185,312,186,312,187,312,187,312,187,311,187,311,187,311,188,310,188,310,188,308,188,307,188,306,188,306,189,306,189,303,189,299,189,294,189,291,189,291,189;462,188,460,188,459,188,456,188,456,188,456,188,456,187,456,187,456,187,456,187,456,187,456,186,456,186,456,186,457,186,457,186,458,185,459,184,460,182,461,182,462,182,462,182,462,181,463,180,464,179,467,179,469,179,470,179,470,179,470,179,471,180,473,180,475,180,476,180,476,180,476,180,478,180,480,180,483,180,483,180,483,181,483,181,483,182,483,182,483,182,484,182,484,183,484,184,483,185,483,185,483,185,483,185,483,186,483,187,483,187,482,187,482,187,481,187,481,188,481,188,480,188,479,188,478,188,477,188,477,189,477,189,474,189,469,189,464,189,462,189,462,189;26,186,26,185,26,185,27,185,27,184,27,184,26,184,26,183,27,182,28,181,28,181,28,181,28,181,29,182,29,182,30,182,30,182,28,184,27,185,27,185,27,186,27,187,27,187,26,187,26,187,26,187,26,186;196,186,197,185,197,185,197,185,198,184,197,184,197,184,197,183,198,182,198,181,199,181,199,181,199,181,199,182,200,182,201,182,200,182,199,184,198,185,198,185,198,186,198,187,197,187,197,187,196,187,196,187,196,186;367,186,367,185,368,185,368,185,368,184,368,184,367,184,367,183,368,182,369,181,369,181,369,181,369,181,370,182,370,182,371,182,371,182,370,184,369,185,368,185,368,186,368,187,368,187,368,187,367,187,367,187,367,186;0,183,0,183,1,183,1,183,2,183,2,184,2,185,1,186,0,186,0,186,0,185,0,185;61,186,61,186,60,186,60,186,59,185,59,185,59,184,58,184,58,184,58,184,58,184,58,184,58,183,57,183,57,183,57,183,57,182,57,182,57,182,58,182,58,181,58,181,58,180,58,180,59,180,59,179,59,179,59,178,59,178,59,177,60,177,63,177,63,177,63,177,64,178,65,178,66,178,67,178,67,178,67,178,67,178,68,178,68,178,69,178,69,179,69,179,70,179,72,179,73,179,74,179,74,179,74,179,75,180,75,180,76,180,76,180,76,180,76,180,77,180,77,180,77,180,78,180,78,181,79,181,79,183,78,183,78,183,77,183,77,184,75,185,75,186,74,186,73,186,73,186,73,186,73,186,71,186,67,186,63,186,61,186,61,186;171,183,171,183,172,183,172,183,172,183,172,184,172,185,172,186,171,186,171,186,171,185,171,185;232,186,231,186,231,186,231,186,230,185,230,185,230,184,229,184,229,184,228,184,228,184,228,184,228,183,228,183,228,183,227,183,227,182,228,182,228,182,228,182,228,181,228,181,228,180,229,180,229,180,230,179,230,179,230,178,230,178,230,177,231,177,234,177,234,177,234,177,234,178,236,178,237,178,238,178,238,178,238,178,238,178,239,178,239,178,240,178,240,179,240,179,241,179,242,179,244,179,245,179,245,179,245,179,245,180,246,180,246,180,247,180,247,180,247,180,247,180,248,180,248,180,249,180,249,181,250,181,250,183,249,183,249,183,248,183,247,184,246,185,246,186,245,186,244,186,244,186,244,186,244,186,241,186,238,186,234,186,232,186,232,186;342,183,342,183,342,183,343,183,343,183,343,184,343,185,342,186,342,186,342,186,342,185,342,185;402,186,402,186,402,186,401,186,401,185,401,185,400,184,400,184,399,184,399,184,399,184,399,184,399,183,399,183,398,183,398,183,398,182,398,182,399,182,399,182,399,181,399,181,399,180,400,180,400,180,400,179,400,179,400,178,400,178,401,177,401,177,404,177,404,177,404,177,405,178,406,178,407,178,408,178,408,178,408,178,409,178,409,178,410,178,410,178,410,179,410,179,411,179,413,179,414,179,416,179,416,179,416,179,416,180,417,180,417,180,418,180,418,180,418,180,418,180,418,180,419,180,419,180,420,181,420,181,420,183,420,183,419,183,419,183,418,184,417,185,416,186,415,186,415,186,414,186,414,186,414,186,412,186,408,186,404,186,402,186,402,186;38,185,37,185,37,185,36,185,36,185,36,185,36,184,35,184,35,184,35,184,34,184,34,184,34,183,33,183,33,183,32,183,32,182,32,182,32,181,33,180,34,180,35,180,36,180,36,180,36,180,36,180,37,180,38,180,38,180,38,181,38,181,39,181,39,181,39,180,39,180,40,180,41,180,41,180,43,179,45,177,46,176,46,178,46,178,46,178,47,178,47,178,47,179,47,179,47,180,47,180,47,180,47,180,48,180,48,181,48,181,48,182,48,182,49,182,48,183,47,184,46,186,42,186,39,186,38,185,38,185;111,184,110,184,110,184,110,184,110,183,110,183,110,183,109,183,109,183,108,183,108,183,108,183,108,183,108,184,108,184,107,184,107,184,107,184,107,184,106,184,105,184,104,184,104,184,104,185,104,185,102,185,102,184,101,184,101,183,101,183,101,182,101,182,101,182,100,182,100,182,100,181,100,180,102,179,103,179,103,179,104,179,104,179,104,178,105,178,109,178,114,178,114,178,115,179,115,180,116,180,116,182,116,183,115,184,115,184,115,184,115,184,115,184,115,186,113,186,112,185;208,185,208,185,207,185,207,185,206,185,206,185,206,184,206,184,206,184,205,184,205,184,205,184,204,183,204,183,204,183,203,183,202,182,202,182,202,181,204,180,205,180,206,180,206,180,206,180,206,180,207,180,207,180,208,180,209,180,209,181,209,181,209,181,209,181,209,180,210,180,211,180,212,180,212,180,214,179,215,177,217,176,217,178,217,178,217,178,217,178,217,178,218,179,218,179,218,180,218,180,218,180,218,180,218,180,218,181,218,181,218,182,219,182,219,182,219,183,218,184,217,186,212,186,210,186,208,185,208,185;282,184,281,184,281,184,280,184,280,183,280,183,280,183,280,183,280,183,279,183,279,183,279,183,279,183,279,184,278,184,278,184,278,184,278,184,278,184,277,184,276,184,275,184,274,184,274,185,274,185,273,185,272,184,272,184,272,183,272,183,272,182,271,182,271,182,271,182,271,180,272,180,272,179,273,179,273,179,274,179,274,179,274,179,274,178,276,178,279,178,284,178,285,178,285,179,286,180,286,180,286,182,286,183,286,184,286,184,286,184,286,184,286,184,286,186,283,186,282,185;379,185,378,185,378,185,377,185,377,185,377,185,377,184,377,184,376,184,376,184,375,184,375,184,375,183,374,183,374,183,374,183,373,182,373,182,373,181,374,180,376,180,376,180,377,180,377,180,377,180,377,180,378,180,379,180,380,180,380,181,380,181,380,181,380,181,380,180,381,180,381,180,382,180,383,180,384,179,386,177,388,176,388,178,388,178,388,178,388,178,388,178,388,179,388,179,388,180,388,180,389,180,389,180,389,180,389,181,389,181,389,182,389,182,390,182,389,183,388,184,387,186,383,186,380,186,379,185,379,185;452,184,452,184,451,184,451,184,451,183,451,183,451,183,451,183,450,183,450,183,450,183,450,183,450,183,449,184,449,184,448,184,448,184,448,184,448,184,447,184,447,184,446,184,445,184,445,185,445,185,444,185,443,184,443,184,442,183,442,183,442,182,442,182,442,182,441,182,442,180,442,180,443,179,444,179,444,179,444,179,445,179,445,179,445,178,447,178,450,178,455,178,455,178,456,179,457,180,457,180,457,182,457,183,457,184,457,184,456,184,456,184,456,184,456,186,454,186,453,185;98,184,96,184,94,184,92,184,90,183,90,183,90,183,90,183,89,183,89,183,88,183,88,182,88,182,87,182,86,182,86,182,86,181,86,181,86,181,85,180,85,180,85,180,85,180,85,180,85,180,86,179,86,179,86,178,86,178,88,178,89,178,90,177,90,177,90,177,90,177,91,177,92,177,92,177,92,177,92,177,93,178,94,178,96,178,97,178,98,179,99,180,99,180,99,181,99,182,99,183,99,183,99,183,100,183,100,184,100,184,99,184,99,184,98,184,98,184,98,184;268,184,267,184,265,184,262,184,261,183,261,183,261,183,260,183,260,183,259,183,259,183,259,182,258,182,258,182,257,182,256,182,256,181,256,181,256,181,256,180,256,180,255,180,255,180,256,180,256,180,256,179,256,179,256,178,257,178,259,178,259,178,260,177,260,177,260,177,261,177,262,177,262,177,263,177,263,177,263,177,264,178,265,178,267,178,267,178,268,179,269,180,270,180,270,181,270,182,270,183,270,183,270,183,270,183,270,184,270,184,270,184,269,184,269,184,268,184,268,184;439,184,437,184,435,184,433,184,432,183,432,183,432,183,431,183,431,183,430,183,429,183,429,182,429,182,428,182,428,182,427,182,427,181,427,181,427,181,427,180,426,180,426,180,426,180,426,180,427,180,427,179,427,179,427,178,428,178,429,178,430,178,431,177,431,177,431,177,431,177,432,177,433,177,434,177,434,177,434,177,434,178,436,178,438,178,438,178,439,179,440,180,440,180,440,181,440,182,440,183,441,183,441,183,441,183,441,184,441,184,441,184,440,184,439,184,439,184,439,184;2,178,3,178,4,178,4,178,4,178,4,179,4,180,5,180,5,180,5,180,5,180,4,180,4,181,4,181,4,181,4,182,3,182,2,182,2,180;48,180,48,179,48,179,48,178,48,177,48,177,47,177,47,176,47,176,47,176,47,175,46,175,46,175,46,174,46,174,46,172,46,172,52,172,57,172,58,172,58,173,59,173,59,173,59,173,58,174,58,174,58,175,58,176,58,177,58,177,58,177,58,177,58,178,58,179,57,179,57,180,56,180,56,181,56,181,56,181,56,182,55,182,55,182,54,181,54,181,54,181,54,181,54,181,54,181,53,181,52,181,50,181,50,181,49,181;117,180,119,178,119,178,119,179,119,179,120,179,121,179,121,179,121,180,121,180,121,180,120,180,120,180,119,180,119,181,119,181,118,182,118,182,117,182,117,181,117,181;172,178,174,178,175,178,175,178,175,178,175,179,175,180,175,180,176,180,176,180,175,180,175,180,175,181,175,181,175,181,175,182,174,182,172,182,172,180;219,180,219,179,219,179,219,178,219,177,218,177,218,177,218,176,218,176,218,176,217,175,217,175,216,175,216,174,216,174,216,172,217,172,223,172,228,172,229,172,229,173,230,173,230,173,229,173,229,174,229,174,229,175,229,176,229,177,229,177,228,177,228,177,228,178,228,179,228,179,228,180,227,180,227,181,227,181,227,181,227,182,226,182,225,182,225,181,225,181,225,181,224,181,224,181,224,181,223,181,222,181,221,181,220,181,220,181;288,180,289,178,289,178,289,179,290,179,291,179,291,179,292,179,292,180,292,180,291,180,291,180,291,180,290,180,290,181,290,181,289,182,288,182,288,182,288,181,288,181;343,178,344,178,345,178,346,178,346,178,346,179,346,180,346,180,346,180,346,180,346,180,346,180,346,181,346,181,346,181,345,182,344,182,343,182,343,180;390,180,390,179,390,179,390,178,389,177,389,177,388,177,388,176,388,176,388,176,388,175,388,175,387,175,387,174,387,174,387,172,387,172,394,172,398,172,399,172,400,173,400,173,400,173,400,173,400,174,400,174,400,175,400,176,399,177,399,177,399,177,399,177,399,178,399,179,399,179,398,180,398,180,398,181,398,181,398,181,397,182,397,182,396,182,395,181,395,181,395,181,395,181,395,181,395,181,394,181,393,181,391,181,391,181,390,181;458,180,460,178,460,178,460,179,461,179,461,179,462,179,462,179,462,180,462,180,462,180,462,180,461,180,461,180,461,181,460,181,460,182,459,182,458,182,458,181,458,181;6,179,6,178,6,178,6,177,4,176,3,176,2,176,2,176,2,176,2,176,1,176,1,176,0,176,0,175,0,174,0,173,0,173,1,173,1,173,2,173,2,173,2,172,4,172,7,172,13,172,14,172,14,174,14,174,14,174,15,174,15,174,15,174,15,175,15,175,15,176,16,176,16,176,16,177,16,177,16,177,16,178,15,178,14,178,14,178,13,178,13,179,12,179,11,179,10,179,10,179,10,179,10,179,9,180,9,180,8,180,8,180,8,180,8,180,7,180,6,179;29,180,29,180,28,180,28,180,27,179,27,178,27,177,27,177,28,177,28,177,28,177,28,177,28,177,29,178,29,178,30,178,31,178,31,179,31,180,31,180,30,180,29,180,29,180,29,180;169,179,168,179,168,179,168,179,168,179,168,178,168,178,168,178,168,178,169,178,169,177,169,177,169,177,169,177,170,177,171,177,171,177,171,179,171,180,171,180,170,180,170,180,169,180,169,180;177,179,176,178,176,178,176,177,175,176,173,176,173,176,172,176,172,176,172,176,172,176,172,176,171,176,171,175,171,174,171,173,171,173,172,173,172,173,172,173,172,173,172,172,174,172,178,172,184,172,185,172,185,174,185,174,185,174,185,174,185,174,186,174,186,175,186,175,186,176,186,176,187,176,187,177,187,177,187,177,187,178,186,178,185,178,184,178,184,178,183,179,183,179,182,179,181,179,180,179,180,179,180,179,180,180,180,180,179,180,179,180,179,180,179,180,178,180,177,179;200,180,199,180,199,180,198,180,198,179,198,178,198,177,198,177,198,177,199,177,199,177,199,177,199,177,199,178,200,178,200,178,201,178,201,178,201,178,202,179,202,179,202,180,201,180,201,180,200,180,200,180,200,180;340,179,339,179,339,179,338,179,338,179,338,178,338,178,338,178,339,178,339,178,340,177,340,177,340,177,340,177,341,177,341,177,342,177,342,179,342,180,341,180,341,180,341,180,340,180,340,180;347,179,347,178,347,178,347,177,345,176,344,176,343,176,343,176,343,176,343,176,343,176,342,176,342,176,342,175,342,174,342,173,342,173,342,173,343,173,343,173,343,173,343,172,345,172,349,172,355,172,356,172,356,174,356,174,356,174,356,174,356,174,356,174,356,175,356,175,356,176,357,176,357,176,358,177,358,177,358,177,357,178,356,178,355,178,355,178,355,178,354,179,354,179,352,179,352,179,351,179,351,179,351,179,351,180,350,180,350,180,350,180,350,180,350,180,348,180,348,179;370,180,370,180,370,180,369,180,368,179,368,178,368,177,368,177,369,177,369,177,370,177,370,177,370,177,370,178,370,178,371,178,371,178,372,178,372,178,372,179,372,179,372,180,372,180,371,180,371,180,370,180,370,180;510,179,510,179,509,179,509,179,509,179,509,178,509,178,509,178,510,178,510,178,510,177,510,177,510,177,511,177,511,177,512,177,512,177,512,179,512,180,512,180,512,180,511,180,511,180,511,180;22,179,21,179,20,179,19,179,19,179,19,178,19,176,19,176,19,176,20,176,20,176,21,176,21,175,21,175,23,175,25,175,26,175,26,177,26,178,25,179,25,179,24,180,22,180,22,179;39,179,38,179,37,179,36,179,36,179,36,179,36,178,35,178,34,178,33,178,33,178,33,178,33,178,33,178,32,178,32,178,31,177,31,177,31,176,30,176,30,176,28,176,27,175,27,174,27,174,27,174,28,174,30,174,30,173,31,173,31,172,31,172,33,172,33,172,34,172,34,172,34,172,36,172,38,172,40,172,42,172,42,172,42,172,42,172,42,172,43,172,43,172,43,173,43,173,43,174,44,174,45,175,44,176,43,177,42,178,41,179,41,179,40,179,40,179,40,179,40,179,40,180,40,180,39,180,39,179,39,179;145,179,144,179,143,179,140,179,140,178,140,177,140,177,141,177,141,177,138,174,137,174,137,174,137,173,137,173,137,172,137,172,151,172,165,172,166,173,167,174,167,176,166,177,166,177,166,178,166,178,166,179,165,179,156,179,150,179,146,179,146,179,146,179,146,180,146,180,145,180,145,179,145,179;192,179,192,179,191,179,190,179,190,179,190,178,190,176,190,176,190,176,190,176,191,176,191,176,192,175,192,175,193,175,196,175,196,175,196,177,196,178,196,179,196,179,195,180,192,180,192,179;210,179,209,179,208,179,207,179,206,179,206,179,206,178,206,178,205,178,204,178,204,178,204,178,204,178,203,178,203,178,203,178,202,177,202,177,202,176,201,176,200,176,199,176,198,175,198,174,198,174,198,174,199,174,200,174,201,173,201,173,202,172,202,172,203,172,204,172,205,172,205,172,205,172,206,172,209,172,211,172,212,172,212,172,212,172,212,172,213,172,213,172,214,172,214,173,214,173,214,174,214,174,215,175,215,176,213,177,213,178,212,179,211,179,211,179,211,179,211,179,211,179,211,180,210,180,210,180,210,179,210,179;316,179,315,179,313,179,311,179,311,178,311,177,311,177,311,177,312,177,309,174,308,174,308,174,308,173,308,173,308,172,308,172,322,172,336,172,337,173,338,174,338,176,337,177,336,177,336,178,336,178,336,179,336,179,327,179,320,179,317,179,317,179,317,179,317,180,316,180,316,180,316,179,316,179;363,179,362,179,362,179,360,179,360,179,360,178,360,176,360,176,361,176,361,176,362,176,362,176,362,175,363,175,364,175,366,175,367,175,367,177,367,178,367,179,366,179,366,180,363,180,363,179;380,179,379,179,379,179,378,179,377,179,377,179,377,178,376,178,376,178,375,178,374,178,374,178,374,178,374,178,374,178,373,178,373,177,373,177,372,176,372,176,371,176,370,176,368,175,368,174,368,174,369,174,370,174,371,174,371,173,372,173,372,172,373,172,374,172,375,172,376,172,376,172,376,172,377,172,379,172,381,172,383,172,383,172,383,172,383,172,384,172,384,172,384,172,384,173,384,173,384,174,385,174,386,175,386,176,384,177,383,178,382,179,382,179,382,179,382,179,382,179,382,179,381,180,381,180,380,180,380,179,380,179;486,179,485,179,484,179,482,179,482,178,482,177,482,177,482,177,482,177,479,174,479,174,478,174,478,173,478,173,478,172,478,172,492,172,507,172,507,173,508,174,509,176,508,177,507,177,507,178,507,178,507,179,506,179,497,179,491,179,488,179,488,179,488,179,487,180,487,180,486,180,486,179,486,179;78,177,78,177,78,176,78,175,77,175,77,175,77,175,77,174,77,174,77,172,77,172,78,172,78,172,79,172,79,172,79,172,81,172,84,172,90,172,90,172,90,173,88,175,87,175,87,175,87,175,87,176,86,176,86,176,85,176,85,176,85,176,85,177,85,177,85,177,84,177,84,177,84,177,84,177,84,177,83,178,83,178,82,178,81,178,81,178,81,179,79,179,78,178;248,177,248,177,248,176,248,175,248,175,248,175,248,175,248,174,248,174,248,172,248,172,249,172,249,172,250,172,250,172,250,172,252,172,255,172,260,172,260,172,260,173,259,175,258,175,258,175,257,175,257,176,257,176,256,176,256,176,256,176,256,176,256,177,256,177,255,177,255,177,254,177,254,177,254,177,254,177,254,178,253,178,253,178,252,178,252,178,251,179,250,179,249,178;419,177,419,177,419,176,419,175,419,175,419,175,418,175,418,174,418,174,418,172,418,172,419,172,420,172,420,172,420,172,420,172,422,172,426,172,431,172,431,172,431,173,430,175,429,175,429,175,428,175,428,176,428,176,427,176,427,176,426,176,426,176,426,177,426,177,426,177,426,177,425,177,425,177,425,177,425,177,424,178,424,178,423,178,423,178,423,178,422,179,421,179,420,178;122,178,122,178,121,178,120,178,120,177,119,177,119,176,118,176,118,176,118,176,118,176,118,176,118,175,117,175,117,175,117,175,117,175,117,174,117,174,117,174,118,174,118,174,119,173,119,173,120,172,120,172,125,172,128,172,130,172,130,173,130,173,130,173,132,173,133,173,134,173,134,173,134,173,134,174,134,174,135,174,136,174,136,174,136,175,137,175,137,175,138,175,139,176,139,176,139,177,138,178,136,178,135,178,134,177,134,177,134,177,133,177,132,177,131,177,130,177,130,177,130,177,129,178,127,178,125,178,124,178,124,178,124,178,124,178,123,178,123,178,122,178,122,178;293,178,292,178,292,178,291,178,290,177,290,177,290,176,289,176,289,176,288,176,288,176,288,176,288,175,288,175,288,175,288,175,288,175,288,174,288,174,288,174,288,174,289,174,290,173,290,173,290,172,291,172,295,172,298,172,300,172,300,173,300,173,301,173,302,173,303,173,304,173,304,173,304,173,305,174,305,174,306,174,306,174,307,174,307,175,307,175,308,175,309,175,310,176,310,176,310,177,309,178,307,178,306,178,305,177,305,177,305,177,304,177,303,177,302,177,301,177,301,177,301,177,300,178,298,178,296,178,295,178,295,178,295,178,294,178,294,178,293,178,293,178,293,178;464,178,463,178,462,178,461,178,461,177,461,177,460,176,460,176,459,176,459,176,459,176,459,176,459,175,459,175,459,175,458,175,458,175,458,174,458,174,458,174,459,174,460,174,460,173,461,173,461,172,461,172,466,172,469,172,471,172,471,173,471,173,472,173,473,173,474,173,475,173,475,173,475,173,475,174,476,174,476,174,477,174,477,174,477,175,478,175,478,175,479,175,480,176,480,176,480,177,479,178,477,178,476,178,476,177,476,177,476,177,475,177,474,177,472,177,472,177,472,177,472,177,470,178,469,178,467,178,466,178,466,178,466,178,465,178,465,178,464,178,464,178,464,178;16,175,16,175,16,174,16,174,16,174,17,174,17,174,18,174,18,174,19,175,19,176,18,176,18,176,18,176,18,176,18,176,17,176,17,176;67,176,66,176,65,176,64,176,64,175,64,175,64,175,63,175,63,175,63,175,62,175,62,174,61,174,62,173,64,173,65,173,66,173,66,172,67,172,67,172,67,172,66,172,66,171,66,171,66,171,68,171,71,171,75,171,75,172,75,174,74,175,73,175,72,175,72,175,72,175,72,175,71,176,71,176,70,176,70,176,70,176,70,176,69,176,69,176,68,176,67,176,67,176;88,175,88,175,89,175,89,175,90,174,91,174,91,173,92,172,92,172,93,172,93,172,93,172,93,171,93,171,93,172,93,172,94,172,94,172,95,172,96,173,96,174,96,175,95,175,95,176,94,176,92,176,91,176,91,175,91,175,91,176,91,176,90,176,89,176,88,176,88,176,88,176;97,175,97,173,98,172,98,172,106,172,114,172,115,172,116,173,116,174,115,174,115,174,115,174,115,175,115,176,114,176,106,176,99,176,98,176,97,176;187,175,187,175,187,174,187,174,187,174,188,174,188,174,189,174,189,174,190,175,190,176,189,176,188,176,188,176,188,176,188,176,188,176,187,176;238,176,237,176,236,176,235,176,234,175,234,175,234,175,234,175,234,175,233,175,233,175,233,174,232,174,233,173,235,173,236,173,237,173,237,172,238,172,238,172,237,172,237,172,237,171,237,171,237,171,239,171,241,171,246,171,246,172,246,174,245,175,243,175,243,175,242,175,242,175,242,175,242,176,242,176,241,176,241,176,241,176,241,176,240,176,239,176,238,176,238,176,238,176;259,175,259,175,259,175,260,175,260,174,261,174,262,173,263,172,263,172,263,172,264,172,264,172,264,171,264,171,264,172,264,172,264,172,265,172,266,172,266,173,266,174,266,175,266,175,266,176,265,176,262,176,262,176,262,175,262,175,262,176,262,176,261,176,260,176,259,176,259,176,259,176;267,175,267,173,268,172,269,172,277,172,285,172,285,172,286,173,286,174,286,174,286,174,286,174,286,175,286,176,285,176,276,176,270,176,268,176,268,176;358,175,358,175,358,174,358,174,358,174,358,174,359,174,359,174,360,174,360,175,360,176,360,176,359,176,359,176,359,176,359,176,358,176,358,176;408,176,407,176,407,176,406,176,405,175,405,175,405,175,405,175,404,175,404,175,404,175,403,174,402,174,403,173,406,173,407,173,407,173,408,172,408,172,408,172,408,172,408,172,408,171,408,171,408,171,409,171,412,171,416,171,416,172,416,174,416,175,414,175,413,175,413,175,413,175,413,175,413,176,412,176,412,176,412,176,412,176,412,176,411,176,410,176,409,176,408,176,408,176;430,175,430,175,430,175,430,175,431,174,432,174,433,173,433,172,434,172,434,172,434,172,434,172,434,171,435,171,435,172,435,172,435,172,435,172,436,172,437,173,437,174,437,175,437,175,436,176,436,176,433,176,433,176,433,175,432,175,432,176,432,176,432,176,431,176,430,176,430,176,430,176;438,175,438,173,439,172,440,172,448,172,455,172,456,172,457,173,457,174,457,174,456,174,456,174,456,175,456,176,456,176,447,176,441,176,439,176,439,176;169,174,169,174,169,174,169,174,170,174,170,175,170,175,169,175,169,175,169,175,169,175,169,175;340,174,340,174,340,174,340,174,340,174,340,175,340,175,340,175,340,175,340,175,340,175,340,175;510,174,510,174,511,174,511,174,511,174,511,175,511,175,511,175,511,175,510,175,510,175,510,175;21,173,20,173,18,173,15,173,15,172,15,171,23,171,27,171,30,171,30,171,30,172,29,172,28,172,27,172,26,172,26,173,25,173,25,174,23,174,22,174,21,173,21,173;192,173,190,173,189,173,186,173,186,172,186,171,193,171,197,171,201,171,201,171,201,172,200,172,198,172,197,172,197,172,197,173,196,173,196,174,194,174,192,174,192,173,192,173;362,173,361,173,359,173,356,173,356,172,356,171,364,171,368,171,372,171,372,171,372,172,370,172,369,172,368,172,368,172,367,173,367,173,366,174,364,174,363,174,362,173,362,173;44,171,44,171,45,171,45,171,46,171,46,171,46,171,45,172,45,172,44,172,44,171,44,171;215,171,215,171,216,171,216,171,216,171,216,171,216,171,216,172,216,172,215,172,215,171,215,171;386,171,386,171,386,171,387,171,387,171,387,171,387,171,387,172,386,172,386,172,386,171,386,171;1,169,1,168,1,163,1,158,1,158,3,158,4,158,4,158,5,158,5,159,5,159,6,159,7,159,8,159,8,159,8,159,8,160,9,160,9,160,10,159,10,159,10,159,10,159,11,159,11,159,12,159,12,159,12,158,12,158,13,158,13,158,14,158,14,159,14,159,14,159,14,159,15,159,15,159,15,159,15,160,15,160,16,161,16,161,16,161,16,162,16,162,16,162,17,162,17,162,17,163,17,165,17,166,17,168,17,168,18,168,18,169,17,170,17,170,15,170,9,170,2,170,2,170,2,169;19,169,19,169,19,169,19,168,19,168,19,168,18,168,18,167,18,166,18,165,18,164,19,164,19,164,19,163,19,162,19,160,19,160,19,160,19,160,20,159,20,158,20,156,20,156,20,156,21,156,22,156,22,155,23,155,23,154,24,154,24,154,24,154,24,154,24,154,24,154,25,154,25,154,26,153,26,153,26,153,27,153,28,153,29,153,30,153,30,153,30,152,31,152,33,152,34,152,35,152,35,153,35,153,35,153,36,153,36,153,37,153,37,153,37,153,37,154,38,154,39,154,39,154,40,155,41,156,42,158,41,158,41,158,41,158,41,159,41,160,41,161,41,161,40,161,40,162,40,164,40,166,40,167,41,167,41,167,41,168,40,169,39,169,39,170,38,170,37,170,36,170,36,170,36,170,33,170,28,170,21,170,20,170,19,170;42,168,42,168,42,168,43,168,43,169,42,170,42,170,42,170,42,169;44,169,44,169,44,169,44,169,44,168,43,167,42,166,42,166,42,164,42,162,42,162,42,162,43,162,43,161,43,161,43,161,44,161,45,161,45,161,46,161,46,161,46,160,47,160,48,160,49,160,50,160,50,160,50,160,50,160,50,160,51,160,51,159,51,159,51,159,52,159,55,159,57,159,58,159,58,159,58,158,58,158,59,158,59,158,60,158,60,158,60,158,60,158,61,158,61,158,62,157,62,157,62,157,62,157,62,157,63,157,63,157,63,157,63,156,63,156,64,156,64,156,65,156,65,156,65,155,67,156,67,156,68,157,68,158,68,158,68,158,68,159,69,159,69,159,69,160,69,162,69,163,69,164,69,164,69,164,70,164,70,165,70,165,70,166,70,166,70,166,70,167,69,167,69,168,68,168,67,168,67,168,66,168,66,169,66,169,66,169,66,169,65,169,65,169,65,169,65,169,64,170,64,170,63,170,63,170,63,170,63,170,60,170,54,170,47,170,45,170,45,170;86,170,83,170,78,170,70,170,70,169,70,169,70,168,70,168,70,168,71,168,71,168,71,168,71,168,74,168,80,168,85,168,88,167,88,167,88,167,89,167,89,167,90,167,90,167,90,167,90,166,91,166,92,166,92,166,93,166,93,166,93,166,94,166,95,166,97,166,97,166,97,166,97,167,97,167,97,167,96,167,96,167,96,168,96,169,95,170,93,170,92,170,91,170,91,170,91,170,90,170,88,170,87,170,86,170,86,170;101,170,100,170,100,170,99,170,99,169,99,169,99,168,99,168,100,168,100,168,101,168,101,167,102,167,102,167,102,167,102,167,103,168,103,168,103,168,104,168,104,168,104,168,104,168,105,168,106,168,106,168,106,169,106,169,106,170,106,170,105,170,105,170,105,170,105,170,104,170,103,170,102,170,101,170,101,170;107,168,107,168,107,167,107,167,106,167,105,167,104,167,104,167,103,166,103,166,102,166,102,166,101,166,101,164,102,164,103,163,103,163,103,162,103,161,103,161,103,161,103,161,104,160,104,159,104,157,104,156,105,156,105,156,106,156,106,156,106,155,107,155,114,155,123,155,123,156,124,156,124,157,124,158,124,159,124,160,125,160,125,160,125,160,125,161,125,161,125,162,125,162,125,162,126,162,126,164,126,165,126,166,126,166,126,166,126,166,126,167,126,168,126,169,125,169,125,170,117,170,109,170,108,169;128,169,128,168,128,167,128,166,127,166,127,166,127,166,127,165,127,164,127,162,127,162,127,162,127,162,128,161,128,161,128,161,127,161,127,161,126,161,126,161,126,160,126,158,126,158,128,158,129,158,129,158,129,159,129,159,129,160,128,160,128,160,128,160,128,160,128,160,129,160,129,160,129,159,130,159,131,159,131,159,132,159,132,159,132,158,132,158,133,158,134,158,135,158,135,158,135,158,136,158,139,158,141,158,142,157,142,157,142,157,143,157,145,157,147,157,147,157,147,158,147,158,147,159,146,159,146,160,146,160,146,162,146,164,143,166,142,167,141,168,141,168,141,168,140,168,140,169,140,169,139,170,139,170,138,170,138,170,138,170,138,170,136,170,134,170,129,170,129,170,128,169;147,170,146,170,145,170,143,170,142,169,142,169,142,169,143,167,145,166,147,164,147,162,147,160,147,160,148,159,148,159,148,158,148,158,148,158,149,157,149,157,150,156,150,157,151,157,151,158,152,158,152,158,152,158,153,158,153,159,153,159,154,159,154,159,155,159,155,160,155,160,156,160,157,160,157,160,158,160,158,161,158,161,159,162,159,162,160,162,160,162,161,162,161,163,161,163,162,163,162,163,163,163,163,164,163,164,164,164,164,164,164,164,165,164,165,165,165,165,166,166,166,166,167,166,168,167,168,168,168,170,161,170,157,170,154,170,154,170,154,170,153,170,151,170,148,170,147,170,147,170;170,169,170,169,170,169,171,168,171,168,171,169,171,170,171,170,170,170;172,169,172,168,172,163,172,158,172,158,174,158,174,158,175,158,175,158,176,159,176,159,177,159,178,159,178,159,178,159,178,159,179,160,179,160,180,160,180,159,180,159,180,159,181,159,181,159,182,159,182,159,182,159,182,158,183,158,183,158,184,158,184,158,184,159,184,159,184,159,185,159,185,159,186,159,186,159,186,160,186,160,186,161,187,161,187,161,187,162,187,162,187,162,187,162,187,162,188,163,188,165,188,166,188,168,188,168,188,168,188,169,188,170,187,170,186,170,180,170,173,170,173,170,172,169;190,169,190,169,190,169,190,168,189,168,189,168,189,168,189,167,189,166,189,165,189,164,189,164,189,164,190,163,190,162,190,160,190,160,190,160,190,160,190,159,190,158,190,156,190,156,191,156,192,156,192,156,193,155,193,155,194,154,194,154,195,154,195,154,195,154,195,154,195,154,196,154,196,154,196,153,196,153,196,153,197,153,199,153,200,153,201,153,201,153,201,152,202,152,203,152,205,152,206,152,206,153,206,153,206,153,207,153,207,153,208,153,208,153,208,153,208,154,209,154,210,154,210,154,211,155,212,156,213,158,212,158,212,158,212,158,212,159,212,160,211,161,211,161,211,161,211,162,211,164,211,166,211,167,211,167,212,167,212,168,211,169,210,169,210,170,208,170,208,170,207,170,207,170,207,170,204,170,199,170,192,170,190,170,190,170;212,168,212,168,213,168,214,168,214,169,213,170,212,170,212,170,212,169;215,169,215,169,215,169,215,169,214,168,214,167,212,166,212,166,212,164,212,162,212,162,213,162,213,162,214,161,214,161,214,161,214,161,215,161,216,161,217,161,217,161,217,160,218,160,219,160,219,160,220,160,220,160,220,160,220,160,221,160,221,160,222,159,222,159,222,159,223,159,225,159,227,159,229,159,229,159,229,158,229,158,230,158,230,158,230,158,230,158,230,158,231,158,231,158,232,158,232,157,232,157,232,157,232,157,233,157,233,157,234,157,234,157,234,156,234,156,235,156,235,156,236,156,236,156,236,156,236,156,236,156,237,156,239,157,239,158,239,158,239,159,239,159,239,159,240,160,240,162,240,163,240,164,240,164,240,164,240,164,240,165,240,165,240,166,241,166,241,166,241,167,240,167,239,168,239,168,238,168,237,168,237,168,237,169,237,169,237,169,236,169,236,169,236,169,236,169,236,169,235,170,235,170,234,170,234,170,234,170,234,170,230,170,225,170,217,170,216,170,215,170;256,170,253,170,248,170,240,170,240,169,240,169,240,168,240,168,241,168,241,168,242,168,242,168,242,168,245,168,250,168,256,168,259,167,259,167,259,167,259,167,260,167,260,167,261,167,261,167,261,166,261,166,262,166,263,166,264,166,264,166,264,166,264,166,266,166,267,166,268,166,268,166,268,167,267,167,267,167,267,167,267,167,267,168,267,169,266,170,264,170,262,170,262,170,262,170,262,170,260,170,259,170,257,170,256,170,256,170;272,170,271,170,271,170,270,170,270,169,270,169,270,168,270,168,270,168,271,168,272,168,272,167,272,167,273,167,273,167,273,167,273,168,274,168,274,168,274,168,274,168,274,168,275,168,276,168,277,168,277,168,277,169,277,169,277,170,276,170,276,170,276,170,276,170,276,170,275,170,274,170,272,170,272,170,272,170;278,168,278,168,278,167,278,167,277,167,276,167,275,167,274,167,274,166,274,166,273,166,273,166,272,166,272,164,273,164,273,163,274,163,274,162,274,161,274,161,274,161,274,161,274,160,274,159,274,157,275,156,276,156,276,156,276,156,277,156,277,155,277,155,285,155,293,155,294,156,295,156,295,157,295,158,295,159,295,160,295,160,295,160,296,160,296,161,296,161,296,162,296,162,296,162,296,162,296,164,296,165,296,166,297,166,297,166,297,166,297,167,297,168,297,169,296,169,295,170,287,170,280,170,279,169;298,169,298,168,298,167,298,166,298,166,298,166,298,166,298,165,298,164,298,162,298,162,298,162,298,162,298,161,298,161,298,161,298,161,298,161,297,161,297,161,297,160,297,158,297,158,298,158,299,158,300,158,300,159,300,159,299,160,299,160,299,160,299,160,299,160,299,160,299,160,300,160,300,159,301,159,301,159,302,159,302,159,302,159,302,158,303,158,304,158,305,158,306,158,306,158,306,158,307,158,309,158,311,158,313,157,313,157,313,157,314,157,315,157,317,157,318,157,318,158,318,158,317,159,317,159,316,160,316,160,316,162,316,164,314,166,313,167,312,168,311,168,311,168,311,168,311,169,310,169,310,170,309,170,309,170,309,170,309,170,309,170,307,170,304,170,300,170,300,170,299,169;318,170,317,170,315,170,313,170,313,169,313,169,313,169,314,167,315,166,318,164,318,162,318,160,318,160,318,159,319,159,319,158,319,158,319,158,319,157,320,157,321,156,321,157,321,157,322,158,322,158,322,158,323,158,323,158,323,159,324,159,325,159,325,159,326,159,326,160,326,160,327,160,327,160,328,160,328,160,329,161,329,161,329,162,330,162,330,162,331,162,331,162,331,163,332,163,333,163,333,163,334,163,334,164,334,164,335,164,335,164,335,164,336,164,336,165,336,165,337,166,337,166,338,166,339,167,339,168,339,170,332,170,327,170,325,170,325,170,325,170,323,170,321,170,319,170,318,170,318,170;340,169,340,169,341,169,341,168,342,168,342,169,342,170,341,170,341,170;342,169,342,168,342,163,342,158,342,158,344,158,345,158,346,158,346,158,346,159,347,159,348,159,348,159,349,159,349,159,349,159,349,160,350,160,350,160,351,159,351,159,351,159,351,159,352,159,352,159,353,159,353,159,353,158,353,158,354,158,354,158,355,158,355,159,355,159,355,159,356,159,356,159,356,159,356,159,356,160,356,160,357,161,357,161,358,161,358,162,358,162,358,162,358,162,358,162,358,163,358,165,358,166,358,168,359,168,359,168,359,169,358,170,358,170,357,170,351,170,344,170,344,170,343,169;360,169,360,169,360,169,360,168,360,168,360,168,360,168,360,167,360,166,360,165,360,164,360,164,360,164,360,163,360,162,360,160,360,160,361,160,361,160,361,159,361,158,361,156,361,156,362,156,362,156,363,156,364,155,364,155,365,154,365,154,365,154,366,154,366,154,366,154,366,154,366,154,367,154,367,153,367,153,367,153,368,153,369,153,371,153,372,153,372,153,372,152,373,152,374,152,375,152,376,152,376,153,376,153,377,153,377,153,378,153,378,153,378,153,378,153,379,154,379,154,380,154,381,154,382,155,383,156,383,158,383,158,382,158,382,158,382,159,382,160,382,161,382,161,382,161,382,162,382,164,382,166,382,167,382,167,382,167,382,168,381,169,381,169,380,170,379,170,378,170,378,170,378,170,378,170,375,170,369,170,363,170,361,170,361,170;383,168,383,168,384,168,384,168,384,169,384,170,383,170,383,170,383,169;386,169,386,169,386,169,386,169,385,168,384,167,383,166,383,166,383,164,383,162,383,162,384,162,384,162,384,161,384,161,384,161,385,161,386,161,387,161,388,161,388,161,388,160,388,160,389,160,390,160,391,160,391,160,391,160,391,160,392,160,392,160,392,159,392,159,392,159,394,159,396,159,398,159,400,159,400,159,400,158,400,158,400,158,401,158,401,158,401,158,401,158,401,158,402,158,402,158,403,157,403,157,403,157,403,157,404,157,404,157,404,157,404,157,404,156,405,156,405,156,406,156,406,156,406,156,406,156,407,156,407,156,408,156,410,157,410,158,410,158,410,159,410,159,410,159,410,160,410,162,410,163,410,164,411,164,411,164,411,164,411,165,411,165,411,166,411,166,412,166,412,167,411,167,410,168,409,168,409,168,408,168,408,168,408,169,408,169,407,169,407,169,406,169,406,169,406,169,406,169,406,170,405,170,405,170,404,170,404,170,404,170,401,170,395,170,388,170,386,170,386,170;427,170,424,170,419,170,411,170,411,169,411,169,411,168,411,168,412,168,412,168,412,168,412,168,412,168,415,168,421,168,426,168,430,167,430,167,430,167,430,167,431,167,431,167,432,167,432,167,432,166,432,166,433,166,434,166,434,166,434,166,434,166,435,166,436,166,438,166,438,166,438,166,438,167,438,167,438,167,438,167,438,167,438,168,438,169,437,170,434,170,433,170,432,170,432,170,432,170,431,170,430,170,428,170,427,170,427,170;442,170,442,170,441,170,440,170,440,169,440,169,440,168,440,168,441,168,442,168,442,168,443,167,443,167,443,167,443,167,443,167,444,168,444,168,445,168,445,168,445,168,445,168,445,168,446,168,447,168,448,168,448,169,448,169,447,170,447,170,446,170,446,170,446,170,446,170,445,170,444,170,443,170,442,170,442,170;449,168,448,168,448,167,448,167,448,167,447,167,445,167,445,167,445,166,444,166,444,166,443,166,443,166,443,164,444,164,444,163,444,163,444,162,444,161,444,161,445,161,445,161,445,160,445,159,445,157,445,156,446,156,446,156,447,156,447,156,448,155,448,155,456,155,464,155,465,156,465,156,466,157,466,158,466,159,466,160,466,160,466,160,466,160,466,161,466,161,466,162,467,162,467,162,467,162,467,164,467,165,467,166,467,166,467,166,468,166,468,167,468,168,467,169,467,169,466,170,458,170,450,170,449,169;469,169,469,168,469,167,469,166,469,166,469,166,468,166,468,165,468,164,468,162,468,162,469,162,469,162,469,161,469,161,469,161,469,161,468,161,468,161,468,161,468,160,468,158,468,158,469,158,470,158,470,158,470,159,470,159,470,160,470,160,470,160,469,160,470,160,470,160,470,160,470,160,471,159,471,159,472,159,472,159,473,159,473,159,473,158,474,158,475,158,475,158,476,158,476,158,476,158,478,158,480,158,482,158,484,157,484,157,484,157,485,157,486,157,488,157,488,157,488,158,488,158,488,159,488,159,487,160,487,160,487,162,487,164,485,166,483,167,482,168,482,168,482,168,481,168,481,169,481,169,480,170,480,170,480,170,480,170,480,170,480,170,478,170,475,170,471,170,470,170,470,169;488,170,487,170,486,170,484,170,484,169,484,169,484,169,485,167,486,166,488,164,488,162,488,160,488,160,489,159,489,159,490,158,490,158,490,158,490,157,490,157,491,156,492,157,492,157,493,158,493,158,493,158,494,158,494,158,494,159,495,159,495,159,496,159,496,159,497,160,497,160,497,160,498,160,498,160,499,160,499,161,499,161,500,162,501,162,501,162,502,162,502,162,502,163,503,163,503,163,504,163,504,163,505,164,505,164,505,164,506,164,506,164,506,164,507,165,507,165,507,166,507,166,508,166,510,167,510,168,510,170,503,170,498,170,496,170,496,170,496,170,494,170,492,170,490,170,488,170,488,170;511,169,511,169,511,169,512,168,512,168,512,169,512,170,512,170,511,170;76,166,75,166,74,166,73,166,72,166,72,166,72,166,72,166,72,166,71,166,71,165,71,165,71,164,71,164,71,164,70,164,70,163,70,162,70,159,71,158,72,158,73,158,74,158,74,158,74,158,75,158,77,158,78,158,80,157,80,157,80,157,80,157,80,157,81,157,81,157,81,157,81,156,81,156,82,156,82,156,83,156,83,156,83,155,83,155,83,156,84,156,88,156,88,156,88,156,88,156,90,156,91,156,92,155,92,155,92,155,93,155,95,155,98,155,99,155,99,155,99,156,99,156,100,157,100,157,100,157,100,159,100,162,100,163,99,163,99,163,98,163,98,164,97,164,97,164,95,164,94,164,93,164,93,165,93,165,92,165,92,165,91,165,90,165,90,165,90,165,90,166,89,166,88,166,88,166,88,166,88,166,87,166,86,166,84,166,84,166,84,167,84,167,82,167,80,167,77,167,76,167,76,167;246,166,245,166,245,166,244,166,243,166,243,166,243,166,243,166,242,166,242,166,242,165,242,165,242,164,241,164,241,164,241,164,241,163,241,162,241,159,241,158,243,158,244,158,244,158,244,158,244,158,245,158,247,158,249,158,250,157,250,157,250,157,250,157,251,157,251,157,252,157,252,157,252,156,252,156,252,156,253,156,254,156,254,156,254,155,254,155,254,156,254,156,258,156,258,156,258,156,259,156,260,156,261,156,262,155,262,155,262,155,264,155,266,155,269,155,270,155,270,155,270,156,270,156,270,157,271,157,271,157,271,159,271,162,270,163,269,163,269,163,269,163,269,164,268,164,268,164,266,164,264,164,264,164,264,165,264,165,263,165,262,165,261,165,261,165,261,165,261,165,260,166,260,166,259,166,258,166,258,166,258,166,257,166,256,166,255,166,254,166,254,167,254,167,253,167,250,167,248,167,246,167,246,167;417,166,416,166,415,166,414,166,414,166,414,166,414,166,413,166,413,166,412,166,412,165,412,165,412,164,412,164,412,164,412,164,412,163,412,162,412,159,412,158,414,158,414,158,415,158,415,158,415,158,416,158,418,158,420,158,421,157,421,157,421,157,421,157,422,157,422,157,422,157,422,157,422,156,423,156,423,156,424,156,424,156,424,156,424,155,425,155,425,156,425,156,429,156,429,156,429,156,430,156,431,156,432,156,433,155,433,155,433,155,434,155,437,155,440,155,440,155,440,155,440,156,440,156,441,157,441,157,442,157,442,159,442,162,441,163,440,163,440,163,439,163,439,164,439,164,438,164,436,164,435,164,434,164,434,165,434,165,434,165,433,165,432,165,432,165,432,165,432,165,431,166,430,166,429,166,429,166,429,166,429,166,428,166,427,166,426,166,425,166,425,167,425,167,423,167,421,167,418,167,417,167,417,167;170,161,170,160,171,160,171,160,171,162,171,163,171,166,171,166,170,166,170,166,170,166,170,164;340,161,341,160,341,160,341,160,342,162,342,163,342,166,341,166,341,166,340,166,340,166,340,164;511,161,511,160,512,160,512,160,512,162,512,163,512,166,512,166,512,166,511,166,511,166,511,164;167,164,167,164,166,164,166,164,165,164,165,164,165,163,164,163,164,163,164,163,163,163,163,162,163,162,162,162,162,162,162,162,161,161,161,161,161,160,160,160,160,160,159,160,159,160,159,160,158,159,158,159,157,159,157,159,157,159,157,158,157,158,157,158,158,158,159,158,160,157,160,157,160,157,160,157,160,157,161,157,161,157,161,157,161,156,161,156,162,156,163,156,164,156,164,156,164,155,168,155,169,156,170,157,170,158,169,158,169,158,169,159,169,160,169,161,169,162,169,162,168,162,168,162,168,163,168,163,168,164,168,164,167,165,167,165,167,165;338,164,337,164,337,164,337,164,336,164,336,164,336,163,335,163,335,163,335,163,334,163,334,162,334,162,333,162,333,162,333,162,332,161,332,161,332,160,331,160,331,160,330,160,329,160,329,160,329,159,328,159,328,159,328,159,328,159,328,158,328,158,328,158,329,158,330,158,330,157,330,157,330,157,330,157,331,157,331,157,332,157,332,157,332,156,332,156,333,156,334,156,334,156,334,156,334,155,339,155,340,156,340,157,340,158,340,158,340,158,340,159,340,160,340,161,339,162,339,162,339,162,339,162,339,163,339,163,339,164,338,164,338,165,338,165,338,165;508,164,508,164,508,164,507,164,507,164,507,164,506,163,506,163,506,163,505,163,505,163,505,162,504,162,504,162,504,162,503,162,503,161,503,161,502,160,502,160,501,160,501,160,500,160,500,160,500,159,499,159,499,159,498,159,498,159,498,158,498,158,498,158,500,158,500,158,501,157,501,157,501,157,501,157,502,157,502,157,502,157,502,157,502,156,503,156,504,156,504,156,505,156,505,156,505,155,510,155,510,156,511,157,511,158,511,158,510,158,510,159,510,160,510,161,510,162,510,162,510,162,510,162,510,163,510,163,509,164,509,164,508,165,508,165,508,165;42,159,42,158,43,158,43,158,43,157,43,156,43,154,43,154,44,154,44,154,44,154,44,155,44,155,45,155,45,155,46,155,47,155,47,156,47,156,48,156,48,156,49,156,50,157,50,158,50,159,49,159,48,159,47,159,46,159,46,159,46,159,46,160,45,160,44,160,44,160,44,160,44,160,43,160,43,160;213,159,213,158,213,158,213,158,214,157,214,156,214,154,214,154,214,154,215,154,215,154,215,155,215,155,215,155,216,155,217,155,217,155,218,156,218,156,219,156,219,156,219,156,220,157,220,158,220,159,220,159,219,159,218,159,217,159,217,159,217,159,216,160,216,160,215,160,214,160,214,160,214,160,214,160,213,160;383,159,383,158,384,158,384,158,384,157,384,156,384,154,384,154,385,154,385,154,386,154,386,155,386,155,386,155,387,155,388,155,388,155,389,156,389,156,389,156,389,156,390,156,391,157,391,158,391,159,391,159,389,159,388,159,388,159,388,159,388,159,387,160,386,160,385,160,385,160,385,160,385,160,384,160,384,160;8,158,7,158,7,158,6,158,6,157,6,156,6,155,5,155,5,155,5,155,5,154,5,153,6,153,7,153,7,153,7,153,7,154,8,154,8,154,8,154,8,154,8,154,9,155,9,155,9,156,10,156,10,156,11,156,11,156,11,157,11,157,11,158,10,158,9,158,9,158,9,158,9,158,9,158,8,158,8,158,8,158,8,158;178,158,178,158,177,158,176,158,176,157,176,156,176,155,176,155,176,155,175,155,175,154,176,153,177,153,178,153,178,153,178,153,178,154,178,154,179,154,179,154,179,154,179,155,180,156,181,156,181,156,182,156,182,157,182,157,181,158,181,158,180,158,180,158,180,158,180,158,179,158,179,158,178,158,178,158,178,158;349,158,348,158,348,158,347,158,347,157,347,156,347,155,347,155,347,155,346,155,346,154,347,153,347,153,348,153,348,153,348,153,348,154,349,154,349,154,350,154,350,154,350,155,351,156,352,156,352,156,352,156,352,157,352,157,352,158,351,158,351,158,350,158,350,158,350,158,350,158,350,158,349,158,349,158,349,158;125,155,125,154,125,154,126,154,126,152,125,151,124,151,124,150,124,150,124,150,124,150,124,150,123,150,123,149,124,148,124,148,126,148,129,148,132,148,134,147,134,147,134,147,135,147,135,147,136,147,136,147,136,147,136,146,138,146,142,146,145,146,148,146,148,146,148,146,148,146,150,146,151,146,152,145,152,145,152,145,152,145,152,145,153,145,154,145,154,144,154,144,154,144,154,145,155,145,155,145,152,148,150,150,150,151,150,151,150,152,149,152,149,153,148,153,148,153,148,154,148,155,147,156,145,156,144,156,144,156,144,156,144,156,142,156,140,156,137,156,136,156,136,157,136,157,134,157,131,157,127,157,126,157,126,156;152,156,152,156,152,156,151,156,151,156,150,155,149,155,149,154,150,154,150,154,150,153,150,153,150,152,150,152,151,152,151,152,151,152,151,151,151,150,154,147,155,147,155,147,156,147,156,146,156,146,157,146,159,146,160,146,162,146,162,146,162,146,162,146,164,146,165,146,166,146,166,147,166,147,166,147,167,147,168,147,168,147,168,148,168,148,168,148,169,148,169,148,169,149,169,150,169,151,169,152,169,152,169,152,170,152,170,153,170,153,169,154,169,154,168,154,168,154,168,154,168,154,167,154,166,154,164,154,163,154,163,155,163,155,162,155,162,155,161,155,160,155,160,156,159,156,159,156,158,156,157,156,157,156,157,157,157,157,156,157,155,157,153,157,152,157,152,157;295,155,295,154,296,154,296,154,296,152,296,151,295,151,295,150,295,150,295,150,295,150,295,150,294,150,294,149,295,148,295,148,296,148,300,148,303,148,305,147,305,147,305,147,305,147,306,147,306,147,307,147,307,147,307,146,309,146,313,146,316,146,318,146,318,146,318,146,319,146,320,146,321,146,322,145,322,145,322,145,323,145,323,145,324,145,324,145,324,144,324,144,325,144,325,145,326,145,325,145,323,148,321,150,320,151,320,151,320,152,320,152,320,153,319,153,319,153,319,154,319,155,318,156,316,156,315,156,314,156,314,156,314,156,313,156,310,156,308,156,306,156,306,157,306,157,304,157,302,157,297,157,297,157,296,156;323,156,323,156,322,156,322,156,321,156,321,155,320,155,320,154,321,154,321,154,321,153,321,153,321,152,321,152,321,152,321,152,322,152,322,151,322,150,325,147,326,147,326,147,326,147,327,146,327,146,327,146,330,146,331,146,332,146,332,146,332,146,333,146,334,146,335,146,336,146,336,147,336,147,337,147,338,147,339,147,339,147,339,148,339,148,339,148,339,148,339,148,340,149,340,150,340,151,340,152,340,152,340,152,340,152,340,153,340,153,340,154,340,154,339,154,339,154,339,154,339,154,338,154,336,154,335,154,334,154,334,155,334,155,333,155,332,155,331,155,331,155,331,156,330,156,330,156,329,156,328,156,328,156,328,157,328,157,327,157,325,157,324,157,323,157,323,157;466,155,466,154,467,154,467,154,467,152,466,151,466,151,466,150,466,150,466,150,465,150,465,150,465,150,465,149,465,148,466,148,467,148,471,148,474,148,476,147,476,147,476,147,476,147,477,147,477,147,478,147,478,147,478,146,480,146,483,146,487,146,489,146,489,146,489,146,490,146,491,146,492,146,493,145,493,145,493,145,493,145,494,145,494,145,495,145,495,144,495,144,495,144,496,145,496,145,496,145,494,148,492,150,491,151,491,151,491,152,491,152,490,153,490,153,490,153,490,154,490,155,489,156,487,156,486,156,485,156,485,156,485,156,483,156,481,156,478,156,477,156,477,157,477,157,475,157,472,157,468,157,468,157,467,156;494,156,493,156,493,156,493,156,492,156,492,155,491,155,491,154,491,154,491,154,492,153,492,153,492,152,492,152,492,152,492,152,492,152,492,151,492,150,495,147,496,147,496,147,497,147,497,146,498,146,498,146,500,146,502,146,503,146,503,146,503,146,504,146,505,146,506,146,507,146,507,147,507,147,507,147,508,147,509,147,510,147,510,148,510,148,510,148,510,148,510,148,510,149,510,150,510,151,510,152,511,152,511,152,511,152,511,153,511,153,511,154,510,154,510,154,510,154,510,154,510,154,508,154,507,154,505,154,504,154,504,155,504,155,504,155,503,155,502,155,502,155,501,156,501,156,500,156,499,156,499,156,498,156,498,157,498,157,497,157,496,157,495,157,494,157,494,157;0,147,0,147,1,147,1,147,2,147,2,147,2,147,2,148,3,148,4,148,4,151,4,152,4,154,4,154,4,154,4,154,4,155,4,156,4,156,3,156,2,156,1,156,1,156,1,155,1,155,1,156,0,157,0,156,0,152;13,156,13,156,12,156,11,156,10,152,12,151,12,151,12,150,12,150,12,150,15,147,16,147,16,147,16,147,16,147,16,146,16,146,17,146,17,146,18,146,18,146,18,146,18,146,18,146,19,146,19,145,19,145,19,145,19,145,20,145,20,145,21,145,21,145,21,144,21,144,22,144,22,144,23,144,23,144,23,144,23,144,24,144,24,144,24,143,24,143,24,143,25,143,26,143,27,143,28,143,28,143,28,142,28,142,28,142,29,142,29,142,29,143,29,143,29,143,29,143,30,143,31,144,31,145,31,145,31,146,32,146,32,146,32,147,32,147,32,148,32,148,33,148,33,148,33,150,32,150,32,151,31,151,31,151,31,151,30,151,30,151,30,151,29,152,28,152,27,152,26,152,26,152,26,152,25,152,25,152,25,152,24,152,24,153,24,153,23,154,23,154,22,154,21,154,21,154,21,155,20,155,20,155,20,155,19,155,19,156,19,156,18,156,16,156,14,156,13,156,13,156;55,156,54,156,54,156,53,156,53,155,53,155,53,155,52,155,52,155,51,155,51,154,49,153,47,151,47,151,46,151,44,151,43,150,44,150,44,150,44,149,44,148,44,148,44,148,45,148,45,148,45,147,45,145,45,144,45,143,45,143,44,143,44,142,44,142,44,140,44,140,43,140,42,140,42,139,42,139,42,139,42,138,42,138,43,137,44,138,44,139,44,140,44,140,45,140,45,140,46,141,47,142,48,143,48,143,50,143,51,143,51,143,52,144,52,144,53,144,53,144,54,144,54,144,54,145,54,145,55,145,56,145,57,145,58,145,58,145,58,145,58,146,58,146,59,146,59,146,59,146,59,146,59,146,60,146,60,146,61,146,61,147,61,147,61,147,61,147,62,147,63,148,63,148,63,148,63,149,64,149,65,150,64,152,63,152,63,152,62,152,62,153,62,153,61,154,60,154,59,154,59,154,58,155,57,156,56,156,56,156,55,156,55,156,55,156;72,155,71,155,71,155,70,155,70,155,70,155,70,154,70,154,70,154,69,154,69,154,68,153,68,153,68,152,68,150,68,147,70,145,71,143,72,143,72,142,72,140,73,139,74,139,74,139,75,139,75,139,75,138,75,138,76,138,76,138,76,138,76,139,76,139,77,139,78,139,78,139,79,139,79,139,79,139,79,140,80,140,80,140,80,140,80,140,80,140,80,140,81,140,81,140,82,140,82,141,82,141,82,142,82,142,83,142,83,143,83,143,83,143,83,144,84,144,84,144,84,145,84,145,84,146,84,146,85,146,85,146,85,146,85,147,85,147,85,148,85,148,85,148,86,148,86,149,86,150,86,150,86,150,86,150,86,150,86,151,86,151,86,152,87,152,87,152,87,152,87,153,87,153,87,154,86,154,86,154,86,154,86,154,86,154,85,154,84,154,83,154,83,154,83,155,83,155,83,155,82,155,82,155,82,155,82,155,82,155,81,156,81,156,80,156,80,156,80,156,80,156,78,156,76,156,73,156,72,156,72,156;171,147,171,147,172,147,172,147,172,147,172,147,172,147,173,148,173,148,174,148,174,151,174,152,174,154,175,154,175,154,175,154,175,155,175,156,175,156,174,156,173,156,172,156,172,156,172,155,172,155,172,156,171,157,171,156,171,152;184,156,183,156,183,156,181,156,181,152,182,151,183,151,183,150,183,150,183,150,186,147,186,147,187,147,187,147,187,147,187,146,187,146,188,146,188,146,188,146,188,146,188,146,188,146,189,146,189,146,190,145,190,145,190,145,190,145,191,145,191,145,192,145,192,145,192,144,192,144,193,144,193,144,194,144,194,144,194,144,194,144,194,144,195,144,195,143,195,143,195,143,196,143,197,143,197,143,198,143,198,143,198,142,198,142,199,142,199,142,200,142,200,143,200,143,200,143,200,143,201,143,202,144,202,145,202,145,202,146,202,146,203,146,203,147,203,147,203,148,203,148,203,148,204,148,204,150,203,150,203,151,202,151,202,151,201,151,201,151,201,151,201,151,200,152,199,152,197,152,196,152,196,152,196,152,196,152,196,152,195,152,195,152,195,153,194,153,194,154,193,154,193,154,192,154,192,154,192,155,191,155,191,155,191,155,190,155,190,156,189,156,189,156,186,156,185,156,184,156,184,156;226,156,225,156,225,156,224,156,224,155,224,155,224,155,223,155,223,155,222,155,221,154,220,153,218,151,218,151,216,151,215,151,214,150,214,150,215,150,215,149,215,148,215,148,215,148,215,148,215,148,216,147,216,145,216,144,215,143,215,143,215,143,215,142,215,142,215,140,215,140,214,140,213,140,212,139,212,139,212,139,212,138,213,138,214,137,215,138,215,139,215,140,215,140,215,140,216,140,216,141,217,142,218,143,219,143,220,143,222,143,222,143,223,144,223,144,223,144,224,144,224,144,225,144,225,145,225,145,226,145,227,145,227,145,228,145,228,145,228,145,228,146,229,146,229,146,230,146,230,146,230,146,230,146,231,146,231,146,232,146,232,147,232,147,232,147,232,147,233,147,234,148,234,148,234,148,234,149,234,149,235,150,235,152,233,152,233,152,233,152,233,153,232,153,232,154,231,154,230,154,229,154,229,155,228,156,227,156,226,156,226,156,226,156,226,156;242,155,242,155,241,155,241,155,241,155,241,155,241,154,241,154,240,154,240,154,239,154,239,153,238,153,238,152,238,150,238,147,240,145,242,143,242,143,242,142,242,140,243,139,245,139,245,139,246,139,246,139,246,138,246,138,246,138,247,138,247,138,247,139,247,139,247,139,248,139,249,139,250,139,250,139,250,139,250,140,250,140,251,140,251,140,251,140,251,140,251,140,252,140,252,140,252,140,252,141,252,141,252,142,253,142,253,142,254,143,254,143,254,143,254,144,254,144,255,144,255,145,255,145,255,146,255,146,255,146,255,146,256,146,256,147,256,147,256,148,256,148,256,148,256,148,256,149,256,150,256,150,257,150,257,150,257,150,257,151,257,151,257,152,257,152,257,152,258,152,258,153,258,153,257,154,257,154,256,154,256,154,256,154,256,154,256,154,255,154,254,154,254,154,254,155,254,155,253,155,253,155,252,155,252,155,252,155,252,155,252,156,251,156,251,156,250,156,250,156,250,156,249,156,247,156,243,156,243,156,243,156;342,147,342,147,342,147,343,147,343,147,343,147,343,147,343,148,344,148,345,148,345,151,345,152,345,154,345,154,345,154,346,154,346,155,346,156,345,156,344,156,343,156,343,156,343,156,343,155,342,155,342,156,342,157,342,156,342,152;354,156,354,156,354,156,352,156,352,152,353,151,353,151,354,150,354,150,354,150,356,147,357,147,357,147,358,147,358,147,358,146,358,146,358,146,359,146,359,146,359,146,359,146,359,146,360,146,360,146,360,145,360,145,360,145,361,145,361,145,362,145,362,145,362,145,362,144,363,144,363,144,364,144,364,144,364,144,364,144,364,144,365,144,365,144,366,143,366,143,366,143,366,143,367,143,368,143,369,143,369,143,369,142,369,142,370,142,370,142,370,142,370,143,370,143,370,143,371,143,371,143,372,144,372,145,372,145,372,146,373,146,373,146,374,147,374,147,374,148,374,148,374,148,374,148,374,150,374,150,373,151,373,151,372,151,372,151,372,151,372,151,372,151,371,152,369,152,368,152,367,152,367,152,367,152,367,152,366,152,366,152,365,152,365,153,365,153,364,154,364,154,363,154,363,154,363,154,362,155,362,155,362,155,361,155,361,155,361,156,360,156,360,156,357,156,355,156,354,156,354,156;396,156,396,156,395,156,395,156,394,155,394,155,394,155,394,155,393,155,393,155,392,154,391,153,389,151,388,151,387,151,386,151,384,150,385,150,385,150,386,149,386,148,386,148,386,148,386,148,386,148,386,147,386,145,386,144,386,143,386,143,386,143,386,142,386,142,386,140,385,140,385,140,384,140,383,139,383,139,383,139,383,138,383,138,384,137,386,138,386,139,386,140,386,140,386,140,386,140,387,141,388,142,389,143,389,143,391,143,392,143,393,143,393,144,393,144,394,144,395,144,395,144,396,144,396,145,396,145,396,145,397,145,398,145,399,145,399,145,399,145,399,146,400,146,400,146,400,146,400,146,400,146,401,146,401,146,402,146,402,146,402,147,402,147,402,147,403,147,403,147,404,148,404,148,404,148,404,149,405,149,406,150,405,152,404,152,404,152,403,152,403,153,403,153,402,154,402,154,401,154,400,154,399,155,398,156,398,156,397,156,397,156,396,156,396,156;413,155,412,155,412,155,412,155,412,155,412,155,412,154,411,154,411,154,411,154,410,154,410,153,409,153,409,152,409,150,409,147,411,145,413,143,413,143,413,142,413,140,414,139,415,139,416,139,416,139,416,139,416,138,416,138,417,138,417,138,418,138,418,139,418,139,418,139,419,139,420,139,420,139,420,139,420,139,420,140,421,140,421,140,422,140,422,140,422,140,422,140,422,140,423,140,423,140,423,141,423,141,423,142,424,142,424,142,424,143,424,143,424,143,424,144,425,144,425,144,426,145,426,145,426,146,426,146,426,146,426,146,426,146,426,147,426,147,426,148,427,148,427,148,427,148,427,149,427,150,427,150,427,150,427,150,428,150,428,151,428,151,428,152,428,152,428,152,428,152,428,153,428,153,428,154,428,154,427,154,427,154,427,154,427,154,426,154,426,154,425,154,424,154,424,155,424,155,424,155,424,155,423,155,423,155,423,155,423,155,422,156,422,156,421,156,421,156,421,156,421,156,419,156,417,156,414,156,414,156,413,156;91,154,91,154,90,154,90,154,89,153,89,153,89,152,88,152,88,151,88,151,88,151,88,151,88,151,88,149,88,147,88,145,88,144,88,144,88,144,88,143,88,143,88,141,89,141,91,141,92,141,92,141,93,142,94,143,99,143,102,143,104,143,104,143,104,143,104,144,105,144,105,144,106,144,106,144,106,144,106,144,106,144,106,144,107,144,107,145,107,145,108,146,108,146,109,146,110,146,110,147,110,147,110,148,110,148,111,148,111,149,111,149,111,149,112,150,113,151,114,152,115,153,115,153,115,153,113,154,111,154,108,154,106,153,106,153,106,153,106,153,106,153,105,153,105,153,105,153,105,153,104,154,103,154,102,154,101,154,101,154,101,154,101,154,100,154,100,154,100,154,100,154,100,154,98,154,96,154,93,154,92,154,92,154,92,154,91,154,91,154,91,154,91,154,91,154;262,154,261,154,261,154,260,154,259,152,259,151,259,151,259,151,259,151,258,151,258,149,258,147,258,145,258,144,259,144,259,144,259,143,259,143,259,141,260,141,261,141,262,141,263,141,264,142,264,143,269,143,272,143,274,143,274,143,274,143,275,144,275,144,276,144,276,144,276,144,276,144,276,144,277,144,277,144,278,144,278,145,278,145,279,146,279,146,279,146,280,146,280,147,280,147,280,148,281,148,281,148,282,149,282,149,282,149,282,150,284,151,285,152,286,153,286,153,286,153,284,154,281,154,279,154,277,153,277,153,277,153,277,153,276,153,276,153,276,153,276,153,276,153,275,154,274,154,272,154,272,154,272,154,272,154,271,154,271,154,270,154,270,154,270,154,270,154,269,154,266,154,264,154,262,154,262,154,262,154,262,154,262,154,262,154,262,154,262,154;432,154,432,154,432,154,431,154,430,152,430,151,430,151,429,151,429,151,429,151,429,149,429,147,429,145,429,144,429,144,429,144,430,143,430,143,430,141,430,141,432,141,433,141,433,141,434,142,435,143,440,143,443,143,445,143,445,143,445,143,445,144,446,144,446,144,447,144,447,144,447,144,447,144,447,144,448,144,448,144,449,145,449,145,449,146,449,146,450,146,451,146,451,147,451,147,451,148,452,148,452,148,452,149,452,149,452,149,453,150,454,151,455,152,456,153,456,153,456,153,454,154,452,154,449,154,448,153,448,153,448,153,447,153,447,153,446,153,446,153,446,153,446,153,445,154,444,154,443,154,442,154,442,154,442,154,442,154,442,154,441,154,441,154,441,154,441,154,439,154,437,154,434,154,433,154,433,154,433,154,433,154,433,154,432,154,432,154,432,154;116,153,116,153,116,153,115,153,114,152,114,151,114,151,114,151,113,150,113,150,112,149,112,148,112,148,112,147,112,147,111,146,111,145,112,144,113,143,113,143,116,143,119,143,120,143,120,144,120,145,120,145,121,145,121,145,121,145,121,146,121,146,121,146,121,146,121,146,122,147,122,147,122,148,122,148,122,149,123,149,123,149,123,150,123,150,123,151,124,151,124,152,124,152,124,153,123,154,116,154,116,153;287,153,287,153,286,153,286,153,285,152,285,151,285,151,284,151,284,150,283,150,283,149,283,148,283,148,283,147,282,147,281,146,281,145,283,144,284,143,284,143,287,143,290,143,291,143,291,144,291,145,291,145,291,145,291,145,292,145,292,146,292,146,292,146,292,146,292,146,292,147,292,147,292,148,292,148,293,149,293,149,294,149,294,150,294,150,294,151,294,151,295,152,295,152,294,153,294,154,287,154,287,153;458,153,457,153,457,153,456,153,456,152,456,151,456,151,455,151,455,150,454,150,454,149,454,148,454,148,453,147,453,147,452,146,452,145,453,144,454,143,454,143,458,143,461,143,462,143,462,144,462,145,462,145,462,145,462,145,462,145,462,146,462,146,462,146,463,146,463,146,463,147,463,147,463,148,463,148,464,149,464,149,464,149,464,150,464,150,464,151,465,151,466,152,466,152,465,153,464,154,458,154,458,153;5,150,5,149,5,149,5,148,5,147,4,147,4,147,4,147,5,147,5,146,6,146,7,146,7,146,8,146,8,146,8,146,8,146,9,146,9,146,10,145,10,145,10,144,11,144,11,144,11,144,12,143,13,142,14,141,15,140,16,140,16,140,17,141,17,142,17,142,17,142,17,142,18,142,18,144,17,145,17,145,16,146,16,146,15,146,14,147,13,148,11,150,10,151,9,151,9,151,9,151,9,151,9,151,8,151,8,151,7,151,6,151,6,151;176,150,176,149,176,149,176,148,175,147,175,147,175,147,175,147,175,147,176,146,176,146,177,146,178,146,179,146,179,146,179,146,179,146,179,146,180,146,180,145,181,145,181,144,181,144,181,144,182,144,183,143,184,142,185,141,186,140,186,140,187,140,188,141,188,142,188,142,188,142,188,142,188,142,188,144,188,145,187,145,187,146,187,146,186,146,185,147,183,148,182,150,180,151,180,151,180,151,180,151,180,151,180,151,179,151,178,151,177,151,177,151,176,151;346,150,346,149,346,149,346,148,346,147,346,147,345,147,345,147,346,147,346,146,347,146,348,146,349,146,350,146,350,146,350,146,350,146,350,146,350,146,351,145,351,145,351,144,352,144,352,144,352,144,353,143,355,142,356,141,357,140,357,140,357,140,358,141,358,142,358,142,358,142,359,142,359,142,359,144,358,145,358,145,358,146,357,146,357,146,355,147,354,148,352,150,351,151,351,151,350,151,350,151,350,151,350,151,350,151,349,151,348,151,347,151,347,151;39,150,38,150,37,150,36,150,36,150,35,149,34,148,34,148,34,147,34,147,33,147,33,147,33,147,33,147,33,146,33,146,33,146,33,146,32,146,32,145,32,145,32,144,32,144,32,144,31,144,31,142,32,141,33,140,33,140,37,140,39,140,41,140,41,141,41,141,41,141,41,141,42,141,43,142,43,142,43,143,43,143,43,143,43,143,44,144,44,145,44,147,43,148,43,148,43,148,43,148,43,148,43,149,42,150,41,150,41,150,41,150,41,150,40,151,39,151,39,151;210,150,209,150,208,150,207,150,206,150,205,149,205,148,204,148,204,147,204,147,204,147,204,147,204,147,204,147,204,146,204,146,203,146,203,146,203,146,203,145,203,145,203,144,203,144,203,144,202,144,202,142,203,141,204,140,204,140,208,140,210,140,212,140,212,141,212,141,212,141,212,141,213,141,214,142,214,142,214,143,214,143,214,143,214,143,214,144,214,145,214,147,214,148,214,148,214,148,214,148,214,148,214,149,213,150,212,150,212,150,211,150,211,150,211,151,210,151,210,151;380,150,379,150,379,150,377,150,377,150,376,149,375,148,375,148,375,147,375,147,375,147,375,147,374,147,374,147,374,146,374,146,374,146,374,146,374,146,374,145,374,145,374,144,373,144,373,144,372,144,373,142,374,141,374,140,375,140,378,140,381,140,382,140,382,141,382,141,382,141,383,141,383,141,384,142,384,142,384,143,384,143,385,143,385,143,385,144,385,145,385,147,385,148,385,148,384,148,384,148,384,148,384,149,383,150,383,150,383,150,382,150,382,150,381,151,380,151,380,151;64,146,64,146,63,146,62,146,60,145,61,144,61,144,62,144,62,143,62,142,62,142,62,142,63,142,63,142,63,142,63,142,64,142,65,142,67,142,68,141,68,141,68,141,68,141,68,141,70,141,71,143,69,145,68,146,68,146,66,146,65,146,64,146,64,146;124,146,123,146,123,146,122,146,122,145,122,144,122,144,121,143,121,143,120,143,120,142,120,142,120,142,119,140,118,140,118,140,118,140,118,139,118,139,117,138,117,138,117,138,117,138,117,138,117,137,117,137,117,137,117,137,118,137,118,136,118,136,118,135,118,135,119,135,119,134,119,134,119,134,119,134,122,134,124,134,125,134,125,134,125,134,126,134,128,134,129,134,130,134,130,135,130,135,131,135,131,135,132,135,132,139,132,144,132,144,130,144,130,144,129,144,129,145,129,145,128,146,127,146,126,146,126,146,126,146,126,146,125,146,125,146,124,146,124,146,124,146;170,146,170,146,170,146,169,146,169,145,169,145,168,144,168,144,167,144,166,144,166,144,166,144,166,144,165,144,164,144,163,144,163,143,163,143,163,143,161,143,159,143,155,143,155,143,155,141,155,141,155,140,155,140,154,140,154,140,154,140,154,139,154,139,154,139,154,139,154,138,154,138,154,137,153,137,153,137,153,137,153,136,153,136,153,136,154,136,154,136,154,135,155,134,156,134,156,134,156,133,156,133,156,133,157,133,158,133,159,133,160,133,160,133,160,132,161,132,162,132,163,132,164,132,164,132,164,132,164,132,164,132,165,132,165,131,165,131,165,131,166,131,167,131,168,131,169,131,169,131,169,130,169,130,170,130,170,130,171,130,171,131,171,131,171,131,172,131,172,131,172,131,172,131,172,131,173,132,174,132,175,132,176,132,176,132,176,132,176,132,178,132,179,132,180,132,180,133,180,133,180,133,181,133,181,133,182,133,182,133,182,132,184,132,185,133,185,133,186,133,186,134,186,134,186,135,186,135,187,135,187,136,187,136,187,136,187,137,186,137,186,137,186,138,186,138,186,139,182,143,181,143,181,143,181,143,181,144,180,144,180,144,179,144,179,144,179,144,179,145,179,145,178,145,177,145,176,145,175,145,175,145,175,145,174,146,173,146,172,146,171,146,171,146,171,146,171,146,171,146,170,146,170,146,170,146;235,146,234,146,234,146,232,146,231,145,232,144,232,144,232,144,232,143,232,142,232,142,233,142,233,142,234,142,234,142,234,142,235,142,236,142,237,142,238,141,238,141,238,141,239,141,239,141,241,141,241,143,240,145,239,146,238,146,237,146,236,146,235,146,235,146;294,146,294,146,294,146,293,146,292,145,292,144,292,144,292,143,292,143,291,143,291,142,291,142,291,142,289,140,289,140,288,140,288,140,288,139,288,139,288,138,288,138,288,138,288,138,288,138,288,137,288,137,288,137,288,137,288,137,288,136,288,136,288,135,289,135,289,135,290,134,290,134,290,134,290,134,293,134,294,134,296,134,296,134,296,134,297,134,298,134,300,134,301,134,301,135,301,135,301,135,302,135,303,135,303,139,303,144,303,144,301,144,301,144,300,144,300,145,299,145,299,146,298,146,297,146,296,146,296,146,296,146,296,146,295,146,295,146,294,146,294,146;341,146,341,146,340,146,340,146,339,145,339,145,339,144,338,144,337,144,337,144,336,144,336,144,336,144,336,144,335,144,334,144,334,143,334,143,334,143,332,143,330,143,326,143,326,143,326,141,326,141,325,140,325,140,325,140,325,140,325,140,325,139,325,139,325,139,324,139,324,138,324,138,324,137,324,137,324,137,323,137,323,136,324,136,324,136,324,136,324,136,324,135,326,134,326,134,327,134,327,133,327,133,327,133,328,133,329,133,330,133,331,133,331,133,331,132,332,132,333,132,333,132,334,132,334,132,334,132,334,132,335,132,335,132,336,131,336,131,336,131,336,131,338,131,339,131,340,131,340,131,340,130,340,130,341,130,341,130,342,130,342,131,342,131,342,131,342,131,343,131,343,131,343,131,343,131,344,132,345,132,345,132,346,132,346,132,346,132,347,132,348,132,349,132,350,132,350,133,350,133,351,133,351,133,352,133,352,133,352,133,352,132,355,132,356,133,356,133,356,133,356,134,356,134,356,135,357,135,357,135,358,136,358,136,358,136,357,137,357,137,356,137,356,138,356,138,356,139,353,143,352,143,352,143,351,143,351,144,351,144,350,144,350,144,350,144,350,144,350,145,350,145,349,145,348,145,346,145,346,145,346,145,346,145,345,146,344,146,342,146,342,146,342,146,342,146,341,146,341,146,341,146,341,146,341,146;406,146,405,146,404,146,403,146,402,145,402,144,403,144,403,144,403,143,403,142,403,142,404,142,404,142,404,142,404,142,404,142,405,142,407,142,408,142,409,141,409,141,409,141,409,141,410,141,412,141,412,143,410,145,409,146,409,146,407,146,406,146,406,146,406,146;465,146,465,146,464,146,464,146,463,145,463,144,463,144,463,143,462,143,462,143,462,142,462,142,462,142,460,140,459,140,459,140,459,140,459,139,459,139,459,138,459,138,458,138,458,138,458,138,458,137,458,137,459,137,459,137,459,137,459,136,459,136,459,135,460,135,460,135,460,134,460,134,460,134,461,134,463,134,465,134,466,134,466,134,466,134,467,134,469,134,470,134,472,134,472,135,472,135,472,135,473,135,474,135,474,139,474,144,473,144,472,144,471,144,471,144,471,145,470,145,470,146,468,146,468,146,467,146,467,146,467,146,466,146,466,146,465,146,465,146,465,146;512,146,511,146,511,146,511,146,510,145,510,145,509,144,509,144,508,144,507,144,507,144,507,144,507,144,506,144,506,144,505,144,504,143,504,143,504,143,503,143,501,143,497,143,496,143,496,141,496,141,496,140,496,140,496,140,496,140,496,140,496,139,495,139,495,139,495,139,495,138,495,138,495,137,495,137,494,137,494,137,494,136,494,136,495,136,495,136,495,136,495,135,496,134,497,134,497,134,498,133,498,133,498,133,498,133,500,133,501,133,502,133,502,133,502,132,502,132,503,132,504,132,505,132,505,132,505,132,505,132,506,132,506,132,506,131,506,131,506,131,507,131,508,131,509,131,510,131,510,131,510,130,511,130,511,130,512,130,512,130,512,131,512,131,512,131,513,131,513,131,514,131,514,131,514,131,514,132,515,132,516,132,517,132,517,132,517,132,518,132,519,132,520,132,521,132,521,133,521,133,521,133,522,133,522,133,523,133,523,133,523,132,526,132,526,133,527,133,527,133,527,134,527,134,527,135,528,135,528,135,528,136,528,136,528,136,528,137,528,137,527,137,527,138,527,138,527,139,524,143,523,143,523,143,522,143,522,144,522,144,521,144,521,144,520,144,520,144,520,145,520,145,519,145,518,145,517,145,516,145,516,145,516,145,515,146,514,146,513,146,512,146,512,146,512,146,512,146,512,146,512,146,512,146,512,146;132,145,132,145,133,145,133,145,134,145,134,145,134,145,133,146,133,146,132,146,132,145,132,145;303,145,303,145,304,145,304,145,304,145,304,145,304,145,304,146,304,146,303,146,303,145,303,145;474,145,474,145,474,145,475,145,475,145,475,145,475,145,475,146,474,146,474,146,474,145,474,145;135,144,135,144,134,144,134,144,134,144,134,140,134,137,133,135,133,135,133,135,133,134,133,133,134,133,137,133,137,133,137,133,139,134,142,134,147,134,147,134,148,134,148,135,149,135,149,135,149,135,151,136,151,137,151,138,151,138,152,139,152,139,152,139,152,140,152,141,152,142,153,142,153,142,153,142,153,142,152,142,152,142,152,143,152,144,151,144,149,144,148,144,148,144,148,145,148,145,145,145,141,145,137,145,135,145,135,145;306,144,305,144,305,144,304,144,304,144,304,140,304,137,304,135,304,135,303,135,303,134,304,133,305,133,308,133,308,133,308,133,309,134,313,134,318,134,318,134,319,134,319,135,319,135,319,135,320,135,322,136,322,137,322,138,322,138,322,139,323,139,323,139,323,140,323,141,323,142,323,142,324,142,324,142,323,142,323,142,323,142,323,143,323,144,322,144,320,144,319,144,318,144,318,145,318,145,316,145,312,145,308,145,306,145,306,145;476,144,476,144,476,144,475,144,475,144,475,140,475,137,475,135,475,135,474,135,474,134,475,133,475,133,478,133,478,133,478,133,480,134,483,134,488,134,489,134,489,134,489,135,490,135,490,135,491,135,492,136,492,137,492,138,492,138,493,139,493,139,494,139,494,140,494,141,494,142,494,142,494,142,494,142,494,142,494,142,494,142,494,143,494,144,493,144,491,144,490,144,489,144,489,145,489,145,487,145,483,145,479,145,476,145,476,145;57,144,56,144,56,144,55,144,55,143,55,143,55,142,57,142,61,142,61,142,60,143,59,144,59,144,58,144,57,144,57,144,57,144;228,144,227,144,227,144,226,144,226,143,226,143,226,142,228,142,231,142,232,142,231,143,230,144,229,144,229,144,228,144,228,144,228,144;398,144,398,144,397,144,396,144,396,143,396,143,396,142,399,142,402,142,403,142,401,143,401,144,400,144,399,144,399,144,398,144,398,144;19,143,19,142,19,142,19,142,19,141,18,141,18,141,18,140,18,139,18,138,18,137,18,137,18,137,18,137,18,136,18,136,18,136,19,136,19,136,19,135,19,135,19,134,22,131,23,131,24,131,24,131,25,130,25,130,25,130,26,130,26,130,26,130,27,130,27,131,27,131,28,131,28,131,28,131,29,132,29,132,29,132,29,132,31,132,31,133,31,137,31,140,31,141,29,141,29,141,28,141,28,141,28,141,27,142,26,142,25,142,24,142,24,142,24,142,24,142,24,142,23,142,23,142,23,143,23,143,22,143,22,143,21,143,20,143,20,143,20,144,20,144,19,143;190,143,190,142,190,142,190,142,189,141,189,141,188,141,188,140,188,139,188,138,188,137,189,137,189,137,189,137,189,136,189,136,189,136,189,136,189,136,190,135,190,135,190,134,193,131,194,131,194,131,195,131,195,130,195,130,196,130,196,130,196,130,197,130,197,130,197,131,198,131,198,131,198,131,199,131,199,132,199,132,200,132,200,132,201,132,202,133,202,137,202,140,201,141,200,141,199,141,199,141,199,141,199,141,198,142,197,142,196,142,195,142,195,142,195,142,195,142,194,142,194,142,194,142,194,143,194,143,193,143,192,143,191,143,191,143,191,143,191,144,190,144,190,143;360,143,360,142,360,142,360,142,360,141,360,141,359,141,359,140,359,139,359,138,359,137,359,137,359,137,360,137,360,136,360,136,360,136,360,136,360,136,360,135,360,135,360,134,364,131,365,131,365,131,366,131,366,130,366,130,367,130,367,130,367,130,368,130,368,130,368,131,369,131,369,131,369,131,370,131,370,132,370,132,371,132,371,132,372,132,372,133,372,137,372,140,372,141,370,141,370,141,370,141,370,141,370,141,369,142,368,142,366,142,366,142,366,142,366,142,365,142,365,142,364,142,364,142,364,143,364,143,364,143,363,143,362,143,362,143,362,143,362,144,361,144,361,143;100,142,99,142,97,142,94,142,94,141,93,141,93,140,92,140,92,139,92,139,92,139,92,139,91,139,91,139,91,138,90,138,90,137,91,137,91,137,91,136,91,136,91,135,91,135,92,135,92,135,92,135,92,135,92,134,93,134,93,134,94,134,94,134,94,134,94,134,95,134,96,134,97,134,98,133,98,133,98,133,99,133,99,133,100,133,100,133,100,133,100,132,100,132,101,132,101,132,102,132,102,132,102,132,102,132,102,132,102,132,103,131,104,131,104,130,105,130,106,130,107,130,108,129,108,129,108,129,109,129,110,129,113,129,114,129,114,130,114,131,114,131,114,131,114,131,114,131,114,132,114,132,114,132,115,132,115,132,115,133,115,134,115,135,115,136,115,136,115,136,116,136,116,137,116,138,116,138,116,138,116,138,116,139,116,139,115,139,115,140,116,140,117,140,115,142,114,142,114,142,114,142,114,142,114,142,111,142,107,142,103,142,100,142,100,142;271,142,270,142,268,142,265,142,264,141,264,141,263,140,263,140,263,139,263,139,263,139,262,139,262,139,262,139,261,138,261,138,261,137,261,137,261,137,262,136,262,136,262,135,262,135,262,135,263,135,263,135,263,135,263,134,263,134,264,134,264,134,265,134,265,134,265,134,266,134,267,134,268,134,269,133,269,133,269,133,269,133,270,133,270,133,271,133,271,133,271,132,271,132,272,132,272,132,272,132,272,132,272,132,272,132,273,132,273,132,274,131,274,131,275,130,275,130,277,130,278,130,279,129,279,129,279,129,280,129,281,129,283,129,284,129,284,130,284,131,284,131,285,131,285,131,285,131,285,132,285,132,285,132,285,132,285,132,286,133,286,134,286,135,286,136,286,136,286,136,286,136,286,137,286,138,286,138,287,138,287,138,287,139,287,139,286,139,286,140,287,140,287,140,286,142,285,142,285,142,284,142,284,142,284,142,282,142,278,142,273,142,271,142,271,142;442,142,440,142,438,142,435,142,435,141,434,141,434,140,434,140,434,139,434,139,433,139,433,139,433,139,432,139,432,138,431,138,431,137,432,137,432,137,432,136,432,136,432,135,432,135,433,135,433,135,434,135,434,135,434,134,434,134,435,134,435,134,436,134,436,134,436,134,436,134,438,134,439,134,440,133,440,133,440,133,440,133,441,133,441,133,442,133,442,133,442,132,442,132,442,132,443,132,443,132,443,132,443,132,443,132,443,132,444,132,444,131,445,131,446,130,446,130,448,130,449,130,450,129,450,129,450,129,450,129,452,129,454,129,455,129,455,130,455,131,455,131,455,131,455,131,456,131,456,132,456,132,456,132,456,132,456,132,456,133,456,134,456,135,456,136,457,136,457,136,457,136,457,137,457,138,457,138,457,138,458,138,458,139,457,139,457,139,457,140,457,140,458,140,457,142,456,142,455,142,455,142,455,142,455,142,452,142,448,142,444,142,442,142,442,142;46,140,46,139,46,139,46,139,45,138,45,138,44,138,44,137,44,137,44,136,44,136,44,136,44,136,44,136,44,136,44,135,44,135,44,135,44,135,44,134,44,134,44,132,45,131,47,131,47,131,48,131,48,131,48,130,48,130,49,130,50,130,51,130,51,130,51,130,52,130,53,130,54,130,55,129,55,129,55,129,56,129,58,129,59,129,60,129,60,129,60,128,66,128,67,129,68,129,68,135,67,135,67,135,67,135,67,136,68,137,68,138,68,139,67,139,67,140,66,140,65,140,65,140,65,140,65,140,63,140,60,140,55,140,55,140,55,141,54,141,54,141,51,141,48,141,48,141,47,140;217,140,216,139,216,139,216,139,216,138,216,138,215,138,215,137,215,137,215,136,215,136,215,136,214,136,214,136,214,136,214,135,214,135,215,135,215,135,215,134,215,134,215,132,216,131,217,131,218,131,218,131,218,131,218,130,219,130,220,130,221,130,222,130,222,130,222,130,222,130,224,130,225,130,226,129,226,129,226,129,227,129,228,129,230,129,231,129,231,129,231,128,237,128,238,129,238,129,238,135,238,135,237,135,238,135,238,136,239,137,239,138,238,139,238,139,237,140,237,140,236,140,236,140,236,140,236,140,234,140,231,140,226,140,226,140,225,141,225,141,224,141,222,141,218,141,218,141,217,140;387,140,387,139,387,139,387,139,387,138,386,138,386,138,386,137,386,137,386,136,385,136,385,136,385,136,385,136,385,136,385,135,385,135,385,135,385,135,386,134,386,134,386,132,387,131,388,131,388,131,389,131,389,131,389,130,390,130,391,130,391,130,392,130,392,130,392,130,393,130,394,130,395,130,396,129,396,129,396,129,397,129,399,129,400,129,402,129,402,129,402,128,408,128,408,129,409,129,409,135,408,135,408,135,408,135,409,136,410,137,410,138,409,139,409,139,408,140,407,140,407,140,406,140,406,140,406,140,404,140,401,140,397,140,396,140,396,141,395,141,395,141,392,141,389,141,389,141,388,140;82,139,82,139,82,139,81,139,81,139,81,139,81,138,81,138,80,138,80,138,80,138,80,138,80,138,79,138,78,138,77,138,77,137,77,137,77,137,77,137,76,137,76,137,76,137,75,136,75,136,75,136,75,135,75,135,75,135,75,135,74,135,74,135,74,134,74,134,74,134,75,134,75,134,75,133,75,133,75,132,75,132,76,132,76,132,76,132,76,132,76,131,77,130,78,130,79,130,80,130,80,130,80,130,80,130,82,130,83,130,84,130,84,130,84,130,84,130,85,130,85,130,86,130,86,131,86,131,86,131,87,131,89,131,90,132,90,135,90,137,89,138,88,138,88,138,88,138,88,138,88,138,87,138,87,138,86,138,86,138,86,139,86,139,86,139,85,139,84,139,84,139,84,139,84,139,83,140,83,140,82,140,82,139,82,139;253,139,253,139,252,139,252,139,252,139,252,139,252,138,251,138,251,138,250,138,250,138,250,138,250,138,250,138,249,138,248,138,248,137,248,137,248,137,247,137,247,137,246,137,246,136,246,135,246,135,245,135,245,135,245,135,245,135,245,134,245,134,245,134,245,134,245,134,246,133,246,133,246,132,246,132,246,132,247,132,247,132,247,132,247,131,248,130,249,130,250,130,250,130,250,130,250,130,251,130,252,130,253,130,254,130,254,130,254,130,255,130,255,130,256,130,256,130,256,131,256,131,257,131,257,131,259,131,260,132,260,135,260,137,260,138,259,138,258,138,258,138,258,138,258,138,258,138,258,138,257,138,257,138,257,139,257,139,256,139,256,139,255,139,254,139,254,139,254,139,254,140,254,140,253,140,253,139,253,139;424,139,423,139,423,139,422,139,422,139,422,139,422,138,422,138,422,138,421,138,421,138,421,138,421,138,420,138,420,138,419,138,418,137,418,137,418,137,418,137,418,137,417,137,416,136,416,135,416,135,416,135,416,135,416,135,416,135,416,134,416,134,416,134,416,134,416,134,416,133,416,133,416,132,416,132,417,132,417,132,418,132,418,132,418,131,418,130,420,130,420,130,421,130,421,130,421,130,422,130,423,130,424,130,425,130,425,130,425,130,425,130,426,130,426,130,427,130,427,131,427,131,427,131,428,131,430,131,431,132,431,135,431,137,430,138,429,138,429,138,429,138,429,138,429,138,429,138,428,138,428,138,428,138,428,139,428,139,427,139,426,139,425,139,425,139,425,139,425,139,425,140,424,140,424,140,424,139,424,139;34,138,34,138,34,138,33,138,32,137,32,135,32,133,33,132,34,132,35,132,36,132,36,132,36,131,42,131,42,132,43,133,43,135,43,135,42,135,42,135,42,136,42,137,42,138,41,138,41,138,40,138,40,138,39,139,39,139,37,139,35,139,34,139,34,139;205,138,205,138,204,138,203,138,203,137,203,135,203,133,203,132,205,132,206,132,206,132,206,132,206,131,212,131,213,132,214,133,214,135,213,135,213,135,213,135,213,136,213,137,213,138,212,138,211,138,211,138,211,138,210,139,210,139,207,139,206,139,205,139,205,139;376,138,375,138,375,138,374,138,374,137,374,135,374,133,374,132,376,132,376,132,377,132,377,132,377,131,383,131,384,132,384,133,384,135,384,135,384,135,384,135,384,136,384,137,383,138,383,138,382,138,381,138,381,138,381,139,380,139,378,139,377,139,376,139,376,139;150,134,149,134,149,134,148,134,148,133,148,133,148,132,148,132,149,132,149,132,150,132,150,133,150,133,150,133,151,133,152,133,153,133,153,133,153,134,153,134,153,135,152,136,151,136,150,135;320,134,320,134,319,134,319,134,319,133,319,133,319,132,319,132,320,132,320,132,320,132,320,133,320,133,321,133,322,133,323,133,323,133,324,133,324,134,324,134,323,135,322,136,322,136,321,135;491,134,490,134,490,134,490,134,490,133,490,133,490,132,490,132,490,132,491,132,491,132,491,133,491,133,492,133,492,133,493,133,494,133,494,133,495,134,495,134,494,135,493,136,493,136,492,135;68,130,68,130,69,130,69,130,70,130,70,130,70,130,71,130,72,130,74,130,74,131,74,132,74,132,74,132,73,132,73,132,73,133,72,133,72,134,72,134,71,134,71,134,71,134,70,135,70,135,69,135,68,135,68,132;239,130,239,130,240,130,240,130,240,130,240,130,240,130,241,130,243,130,245,130,245,131,245,132,245,132,244,132,244,132,243,132,243,133,243,133,242,134,242,134,242,134,241,134,241,134,241,135,240,135,240,135,239,135,239,132;410,130,410,130,410,130,411,130,411,130,411,130,411,130,412,130,413,130,416,130,416,131,416,132,415,132,415,132,415,132,414,132,414,133,414,133,413,134,413,134,413,134,412,134,412,134,412,135,411,135,410,135,410,135,410,132;16,133,16,132,17,132,17,132,18,132,18,132,19,132,19,132,19,133,19,133,19,134,18,134,18,134,18,134,18,134,18,134,17,134,17,134,16,134,16,134,16,133;187,132,188,132,189,132,189,132,190,132,190,133,190,133,189,134,189,134,188,134,188,134,188,134,188,134,188,134,188,134,187,134,187,134,187,133;358,132,358,132,359,132,360,132,360,132,360,133,360,133,360,134,360,134,359,134,359,134,359,134,359,134,359,134,358,134,358,134,358,134,358,133;90,133,90,132,90,132,91,132,91,132,91,131,91,130,91,130,96,130,100,130,100,130,100,130,100,131,99,132,98,132,98,132,98,132,98,132,98,132,97,132,96,132,95,132,94,132,94,133,94,133,94,133,93,133,93,133,92,133,92,133,92,134,91,134,91,133;261,133,261,132,261,132,261,132,262,132,262,131,262,130,262,130,267,130,270,130,271,130,271,130,271,131,270,132,269,132,269,132,268,132,268,132,268,132,267,132,267,132,266,132,265,132,265,133,265,133,264,133,264,133,263,133,263,133,263,133,263,134,262,134,261,133;431,133,431,132,432,132,432,132,432,132,432,131,432,130,433,130,437,130,441,130,442,130,442,130,442,131,441,132,440,132,439,132,439,132,439,132,439,132,438,132,437,132,436,132,436,132,436,133,436,133,435,133,435,133,434,133,434,133,434,133,434,134,432,134,432,133;116,131,116,131,116,131,116,130,115,130,115,130,115,130,115,129,116,129,116,128,116,128,116,127,116,127,116,127,117,127,117,127,118,127,118,126,118,126,118,126,118,127,119,127,119,128,119,129,119,130,119,131,118,131,117,132,117,132,116,132;130,131,130,131,127,131,125,131,124,131,123,130,122,129,122,128,122,127,122,126,122,126,122,126,122,126,122,125,122,125,122,125,121,124,121,124,120,123,120,123,120,121,120,118,121,117,122,117,122,117,122,117,122,117,122,116,124,116,126,116,129,116,129,116,130,117,130,117,131,118,132,118,132,118,133,118,133,118,133,118,133,118,134,118,134,118,135,118,135,119,135,119,136,119,137,119,137,119,138,119,138,119,138,119,139,120,139,120,140,120,140,120,140,120,140,120,141,120,142,120,143,120,144,121,144,122,144,122,144,123,145,123,145,123,145,124,145,125,145,126,145,127,145,127,144,127,144,127,144,128,144,128,144,128,144,128,143,128,143,128,143,129,143,129,142,129,142,129,141,129,140,129,140,130,139,130,139,130,137,130,136,130,136,130,136,131,136,131,135,131,134,131,133,131,133,131,133,132,133,132,133,132,132,132,131,132,131,132,131,132;141,131,141,131,141,131,142,131,142,131,143,130,143,129,144,129,145,130,145,131,145,131,145,132,145,132,144,132,143,132,141,132,141,132,141,132;155,132,154,132,152,132,151,132,150,131,150,131,150,131,149,131,148,131,147,131,147,131,147,130,147,130,147,129,146,129,145,128,145,127,147,126,148,125,148,125,149,125,150,125,151,125,151,125,151,125,151,126,152,126,153,126,154,126,154,126,154,126,154,126,154,126,155,126,155,126,155,127,155,127,155,127,156,127,156,127,157,127,157,127,157,127,159,128,161,128,164,128,166,128,166,128,166,128,166,128,168,128,169,128,170,128,170,129,170,129,169,130,167,130,166,130,165,130,165,130,165,130,165,130,164,130,164,130,164,130,164,131,164,131,163,131,162,131,161,131,160,131,160,131,160,131,159,132,158,132,157,132,156,132,156,132,156,132,156,132,156,132,155,132,155,132,155,132;286,131,286,131,286,131,286,130,286,130,286,130,285,130,285,129,286,129,287,128,287,128,287,127,287,127,287,127,287,127,288,127,288,127,288,126,288,126,289,126,289,127,289,127,290,128,290,129,290,130,289,131,289,131,288,132,287,132,287,132;301,131,300,131,298,131,295,131,295,131,294,130,293,129,293,128,293,127,293,126,293,126,293,126,292,126,292,125,292,125,292,125,292,124,292,124,291,123,291,123,291,121,291,118,291,117,292,117,293,117,293,117,293,117,293,116,294,116,296,116,300,116,300,116,301,117,301,117,301,118,302,118,303,118,304,118,304,118,304,118,304,118,305,118,305,118,306,118,306,119,306,119,306,119,307,119,308,119,309,119,309,119,309,119,309,120,310,120,310,120,311,120,311,120,311,120,312,120,312,120,314,120,315,121,315,122,315,122,315,123,315,123,315,123,316,124,316,125,316,126,315,127,315,127,315,127,315,127,315,128,315,128,315,128,314,128,314,128,314,128,314,129,314,129,313,129,312,129,311,129,311,129,311,130,310,130,310,130,308,130,307,130,306,130,306,131,306,131,306,131,305,131,304,131,304,131,304,132,304,132,303,132,303,132,302,132,301,132,301,132;312,131,312,131,312,131,312,131,313,131,313,130,314,129,314,129,315,130,316,131,316,131,316,132,315,132,315,132,313,132,312,132,312,132,312,132;326,132,324,132,323,132,321,132,320,131,320,131,320,131,320,131,319,131,318,131,318,131,318,130,318,130,317,129,317,129,316,128,316,127,317,126,318,125,319,125,320,125,321,125,322,125,322,125,322,125,322,126,323,126,324,126,324,126,324,126,324,126,324,126,325,126,325,126,326,126,326,127,326,127,326,127,327,127,327,127,328,127,328,127,328,127,329,128,332,128,335,128,336,128,336,128,336,128,337,128,338,128,340,128,340,128,340,129,340,129,340,130,338,130,337,130,336,130,336,130,336,130,335,130,335,130,334,130,334,130,334,131,334,131,333,131,333,131,332,131,331,131,331,131,331,131,330,132,329,132,328,132,327,132,327,132,327,132,327,132,326,132,326,132,326,132,326,132;457,131,457,131,457,131,457,130,457,130,457,130,456,130,456,129,457,129,457,128,458,128,458,127,458,127,458,127,458,127,458,127,459,127,459,126,459,126,459,126,460,127,460,127,460,128,460,129,460,130,460,131,459,131,458,132,458,132,457,132;471,131,471,131,469,131,466,131,466,131,465,130,464,129,464,128,464,127,464,126,463,126,463,126,463,126,463,125,463,125,463,125,463,124,462,124,462,123,462,123,462,121,462,118,462,117,463,117,463,117,464,117,464,117,464,116,465,116,467,116,470,116,471,116,471,117,472,117,472,118,473,118,474,118,474,118,474,118,474,118,475,118,475,118,476,118,476,118,476,119,476,119,477,119,478,119,479,119,480,119,480,119,480,119,480,120,481,120,481,120,482,120,482,120,482,120,482,120,483,120,485,120,486,121,486,122,486,122,486,123,486,123,486,123,486,124,486,125,486,126,486,127,486,127,486,127,486,127,486,128,486,128,485,128,485,128,484,128,484,128,484,129,484,129,484,129,483,129,482,129,482,129,481,130,481,130,480,130,479,130,478,130,477,130,477,131,477,131,476,131,476,131,474,131,474,131,474,132,474,132,474,132,473,132,473,132,472,132,472,132;482,131,482,131,483,131,483,131,484,131,484,130,484,129,485,129,486,130,487,131,487,131,486,132,486,132,485,132,484,132,482,132,482,132,482,132;496,132,495,132,494,132,492,132,491,131,491,131,491,131,490,131,490,131,488,131,488,131,488,130,488,130,488,129,488,129,487,128,487,127,488,126,489,125,489,125,491,125,491,125,492,125,492,125,492,125,493,126,494,126,494,126,495,126,495,126,495,126,495,126,496,126,496,126,496,126,496,127,496,127,497,127,497,127,498,127,498,127,498,127,498,127,500,128,503,128,505,128,507,128,507,128,507,128,508,128,509,128,511,128,511,128,511,129,511,129,511,130,509,130,507,130,506,130,506,130,506,130,506,130,506,130,505,130,505,130,505,131,505,131,504,131,503,131,502,131,502,131,502,131,502,131,501,132,500,132,498,132,498,132,498,132,498,132,497,132,497,132,496,132,496,132,496,132;9,131,8,131,7,131,6,131,5,131,5,131,5,130,4,130,4,130,2,130,1,129,2,128,3,128,3,127,3,127,3,127,3,126,4,126,4,126,4,125,4,125,4,125,4,124,5,124,5,124,6,123,6,123,6,122,8,120,8,120,9,120,9,120,9,120,9,120,9,120,10,120,10,120,10,119,10,119,10,119,11,119,11,119,13,119,14,118,14,118,14,117,14,116,15,116,15,116,16,116,16,117,16,117,17,118,17,118,17,118,18,118,18,118,18,119,19,119,20,119,21,119,22,119,22,119,22,119,22,120,23,120,23,120,24,120,24,120,25,121,25,121,25,124,25,126,25,128,25,128,24,128,24,128,24,128,24,129,24,129,24,129,23,129,23,129,23,129,23,129,22,130,22,130,21,130,21,130,21,130,21,130,20,130,19,130,18,130,17,130,17,131,17,131,16,131,14,131,13,131,12,131,12,131,12,131,11,132,10,132,9,132,9,131,9,131;180,131,179,131,178,131,176,131,176,131,176,131,176,130,175,130,174,130,172,130,172,129,173,128,173,128,174,127,174,127,174,127,174,126,174,126,175,126,175,125,175,125,175,125,175,124,176,124,176,124,176,123,176,123,176,122,178,120,179,120,179,120,180,120,180,120,180,120,180,120,180,120,181,120,181,119,181,119,181,119,181,119,182,119,183,119,184,118,184,118,184,117,185,116,186,116,186,116,186,116,187,117,187,117,187,118,188,118,188,118,188,118,189,118,189,119,189,119,191,119,192,119,193,119,193,119,193,119,193,120,193,120,194,120,194,120,195,120,195,121,196,121,196,124,196,126,195,128,195,128,195,128,195,128,195,128,195,129,195,129,194,129,194,129,194,129,194,129,194,129,193,130,193,130,192,130,192,130,192,130,192,130,191,130,190,130,188,130,188,130,188,131,188,131,186,131,185,131,183,131,182,131,182,131,182,131,182,132,181,132,180,132,180,131,180,131;350,131,349,131,348,131,347,131,346,131,346,131,346,130,346,130,345,130,343,130,342,129,344,128,344,128,344,127,344,127,344,127,344,126,345,126,345,126,346,125,346,125,346,125,346,124,346,124,347,124,347,123,347,123,347,122,349,120,350,120,350,120,350,120,350,120,350,120,350,120,351,120,351,120,352,119,352,119,352,119,352,119,353,119,354,119,355,118,355,118,355,117,356,116,356,116,356,116,357,116,357,117,357,117,358,118,358,118,358,118,359,118,359,118,360,119,360,119,362,119,363,119,364,119,364,119,364,119,364,120,364,120,364,120,365,120,365,120,366,121,366,121,366,124,366,126,366,128,366,128,366,128,366,128,366,128,366,129,365,129,365,129,364,129,364,129,364,129,364,129,364,130,363,130,363,130,362,130,362,130,362,130,361,130,360,130,359,130,358,130,358,131,358,131,357,131,356,131,354,131,353,131,353,131,353,131,352,132,352,132,351,132,350,131,350,131;30,130,30,130,29,130,29,130,28,130,28,130,28,130,28,130,28,130,27,130,27,129,27,129,27,128,27,128,27,128,26,128,26,127,26,127,26,126,26,125,27,125,27,125,27,124,27,123,27,122,28,120,29,120,30,120,30,120,31,120,31,119,31,119,33,119,35,119,36,119,36,119,36,118,36,118,36,118,37,118,37,118,37,118,37,118,38,118,41,118,45,118,45,118,45,119,45,120,46,120,47,121,47,121,47,122,47,123,47,124,48,125,49,125,50,126,50,126,50,127,50,127,50,127,50,127,50,127,50,128,50,129,50,129,49,129,48,129,47,129,47,129,47,129,46,130,46,130,45,130,45,130,45,130,45,130,43,130,40,130,37,130,35,130,35,131,35,131,34,131,33,131,31,131,30,131,30,131;201,130,200,130,200,130,199,130,199,130,199,130,199,130,199,130,198,130,198,130,198,129,198,129,198,128,197,128,197,128,197,128,197,127,197,127,197,126,197,125,197,125,197,125,198,124,198,123,198,122,199,120,200,120,200,120,201,120,201,120,202,119,202,119,204,119,205,119,206,119,206,119,206,118,206,118,207,118,207,118,208,118,208,118,208,118,209,118,212,118,216,118,216,118,216,119,216,120,217,120,217,121,218,121,218,122,218,123,218,124,219,125,220,125,220,126,220,126,220,127,220,127,221,127,221,127,221,127,221,128,221,129,221,129,219,129,218,129,218,129,218,129,218,129,217,130,217,130,216,130,216,130,216,130,216,130,214,130,211,130,207,130,206,130,206,131,206,131,205,131,203,131,202,131,201,131,201,131;372,130,371,130,371,130,370,130,370,130,370,130,370,130,369,130,369,130,368,130,368,129,368,129,368,128,368,128,368,128,368,128,368,127,368,127,368,126,368,125,368,125,368,125,368,124,368,123,368,122,369,120,371,120,371,120,372,120,372,120,372,119,373,119,375,119,376,119,377,119,377,119,377,118,377,118,378,118,378,118,378,118,378,118,378,118,380,118,382,118,386,118,386,118,386,119,387,120,387,120,388,121,388,121,388,122,388,123,388,124,390,125,390,125,391,126,391,126,391,127,391,127,391,127,391,127,392,127,392,128,392,129,391,129,390,129,389,129,388,129,388,129,388,129,388,130,387,130,387,130,386,130,386,130,386,130,384,130,381,130,378,130,376,130,376,131,376,131,375,131,374,131,373,131,372,131,372,131;68,126,67,126,66,126,65,126,65,126,64,125,64,125,65,125,65,124,66,124,66,123,66,123,66,123,66,123,67,122,67,122,67,121,67,121,67,121,67,121,68,121,68,120,69,120,70,119,70,119,71,119,72,119,72,119,72,119,72,118,73,118,73,118,74,118,74,118,74,118,74,117,77,117,78,118,78,118,78,119,78,119,78,119,78,119,78,120,78,121,77,122,77,122,77,122,77,123,77,124,77,125,77,126,77,126,78,126,78,128,77,128,77,129,76,129,72,129,68,129,68,128;84,128,83,128,82,128,80,128,79,128,79,126,79,126,79,126,79,126,78,126,78,125,78,124,78,122,78,122,79,122,79,122,79,121,79,120,79,118,79,118,80,118,80,118,81,118,81,118,81,118,82,118,84,118,86,118,87,118,87,119,87,119,89,119,93,119,100,119,100,119,101,120,101,120,102,121,102,124,102,127,101,128,101,128,101,129,100,129,100,129,100,128,92,128,92,129,92,129,91,129,88,129,85,129,84,129,84,129;103,128,103,119,103,119,103,119,104,118,104,117,104,115,104,114,104,114,105,113,107,113,107,114,107,114,107,114,108,114,108,114,108,114,108,115,108,115,109,115,110,115,111,115,112,115,112,115,112,115,113,116,114,116,117,116,118,116,118,117,118,117,118,118,118,118,119,118,119,119,119,121,119,124,119,124,118,125,118,125,117,126,116,126,116,126,115,126,115,127,114,127,114,128,111,128,109,128,108,128,108,128,108,128,107,128,106,128,105,128,104,128,104,129,104,129,104,129,103,128;239,126,237,126,236,126,236,126,235,126,235,125,235,125,235,125,236,124,236,124,236,123,236,123,236,123,237,123,237,122,238,122,238,121,238,121,238,121,238,121,238,121,239,120,240,120,240,119,241,119,242,119,242,119,243,119,243,119,243,118,243,118,244,118,244,118,245,118,245,118,245,117,248,117,248,118,249,118,249,119,249,119,248,119,248,119,248,120,248,121,248,122,248,122,248,122,248,123,248,124,248,125,248,126,248,126,248,126,248,128,248,128,247,129,246,129,243,129,239,129,239,128;254,128,253,128,252,128,250,128,250,128,250,126,250,126,249,126,249,126,249,126,249,125,249,124,249,122,249,122,249,122,249,122,250,121,250,120,250,118,250,118,251,118,251,118,252,118,252,118,252,118,253,118,255,118,256,118,258,118,258,119,258,119,260,119,264,119,270,119,271,119,271,120,272,120,272,121,272,124,272,127,272,128,272,128,271,129,271,129,271,129,271,128,263,128,263,129,263,129,261,129,259,129,256,129,254,129,254,129;273,128,273,119,274,119,274,119,274,118,274,117,274,115,274,114,275,114,275,113,278,113,278,114,278,114,278,114,278,114,279,114,279,114,279,115,279,115,280,115,281,115,282,115,283,115,283,115,283,115,284,116,285,116,287,116,288,116,288,117,288,117,288,118,289,118,289,118,290,119,290,121,290,124,289,124,289,125,288,125,288,126,287,126,287,126,286,126,286,127,285,127,284,128,282,128,280,128,279,128,279,128,279,128,278,128,277,128,276,128,275,128,275,129,275,129,274,129,274,128;410,126,408,126,407,126,406,126,406,126,405,125,405,125,406,125,407,124,407,124,407,123,407,123,407,123,408,123,408,122,408,122,408,121,408,121,408,121,409,121,409,121,410,120,410,120,411,119,411,119,412,119,413,119,414,119,414,119,414,118,414,118,415,118,415,118,416,118,416,118,416,117,418,117,419,118,420,118,420,119,419,119,419,119,419,119,419,120,419,121,419,122,419,122,418,122,418,123,418,124,418,125,418,126,419,126,419,126,419,128,418,128,418,129,417,129,414,129,410,129,410,128;425,128,424,128,423,128,421,128,420,128,420,126,420,126,420,126,420,126,420,126,420,125,420,124,420,122,420,122,420,122,420,122,420,121,420,120,420,118,420,118,421,118,422,118,422,118,422,118,422,118,423,118,425,118,427,118,428,118,428,119,428,119,431,119,435,119,441,119,441,119,442,120,443,120,443,121,443,124,443,127,443,128,442,128,442,129,442,129,442,129,441,128,434,128,434,129,434,129,432,129,429,129,427,129,425,129,425,129;444,128,444,119,445,119,445,119,445,118,445,117,445,115,445,114,445,114,446,113,448,113,448,114,448,114,448,114,449,114,449,114,450,114,450,115,450,115,450,115,452,115,453,115,454,115,454,115,454,115,454,116,456,116,458,116,459,116,459,117,459,117,459,118,460,118,460,118,460,119,460,121,460,124,460,124,459,125,459,125,458,126,458,126,457,126,457,126,456,127,455,127,455,128,452,128,451,128,450,128,450,128,450,128,449,128,448,128,446,128,446,128,446,129,446,129,445,129,445,128;52,127,52,127,52,127,52,126,52,126,52,126,52,126,52,126,52,125,52,124,52,123,53,123,53,123,54,123,54,122,54,122,55,122,55,122,55,122,56,121,56,121,56,120,57,120,57,120,57,120,58,120,58,120,58,120,58,120,59,120,59,120,60,120,60,120,60,120,60,120,61,120,62,120,63,120,63,120,63,119,65,120,65,120,66,121,65,122,65,123,64,123,64,124,64,124,64,124,64,124,64,124,64,125,64,125,64,126,63,127,62,127,61,127,61,127,61,127,61,127,60,128,58,128,57,128,56,128,56,128,56,128,53,128,53,128;223,127,223,127,223,127,223,126,223,126,223,126,222,126,222,126,222,125,222,124,223,123,224,123,224,123,224,123,225,122,225,122,225,122,226,122,226,122,226,121,227,121,227,120,227,120,228,120,228,120,228,120,228,120,228,120,229,120,229,120,230,120,230,120,230,120,230,120,231,120,232,120,233,120,234,120,234,120,234,119,235,120,236,120,237,121,236,122,235,123,235,123,235,124,235,124,235,124,235,124,234,124,234,125,234,125,234,126,233,127,232,127,232,127,232,127,232,127,232,127,230,128,229,128,227,128,226,128,226,128,226,128,224,128,223,128;394,127,394,127,394,127,394,126,393,126,393,126,393,126,393,126,393,125,393,124,393,123,394,123,394,123,395,123,395,122,395,122,396,122,396,122,396,122,397,121,397,121,397,120,398,120,398,120,399,120,399,120,399,120,399,120,399,120,400,120,400,120,401,120,401,120,401,120,402,120,403,120,403,120,404,120,404,120,404,119,406,120,407,120,408,121,407,122,406,123,406,123,406,124,406,124,405,124,405,124,405,124,405,125,405,125,405,126,404,127,403,127,403,127,402,127,402,127,402,127,401,128,400,128,398,128,397,128,397,128,397,128,394,128,394,128;162,126,161,126,160,126,158,126,158,126,158,126,158,126,157,126,156,126,155,126,155,125,155,125,155,125,155,125,154,125,154,125,154,125,154,125,154,124,153,124,153,124,152,124,152,124,152,124,152,124,150,124,149,124,146,124,146,122,146,120,145,120,144,120,144,120,144,119,144,119,144,118,144,118,144,118,145,118,145,117,145,117,145,117,146,117,147,117,149,117,150,117,150,117,150,116,151,116,153,116,154,116,156,116,156,116,156,115,156,115,157,116,158,116,158,117,157,117,157,117,157,117,157,118,157,119,157,119,159,119,160,119,161,119,161,120,161,120,162,120,163,120,163,120,164,120,164,121,164,121,164,121,165,121,166,121,166,121,166,121,166,121,167,122,167,122,169,122,170,122,170,123,170,123,170,124,170,124,171,124,171,124,171,125,171,127,166,127,163,127,162,127,162,127;332,126,331,126,330,126,329,126,328,126,328,126,328,126,328,126,327,126,326,126,326,125,326,125,326,125,325,125,325,125,324,125,324,125,324,125,324,124,324,124,323,124,323,124,322,124,322,124,322,124,321,124,319,124,316,124,316,122,316,120,316,120,315,120,314,120,314,119,314,119,314,118,314,118,315,118,315,118,316,117,316,117,316,117,317,117,318,117,319,117,320,117,320,117,320,116,321,116,323,116,325,116,326,116,326,116,326,115,327,115,328,116,328,116,328,117,328,117,328,117,328,117,328,118,328,119,328,119,329,119,331,119,331,119,332,120,332,120,333,120,333,120,334,120,334,120,334,121,334,121,335,121,336,121,336,121,337,121,337,121,337,121,337,122,338,122,339,122,340,122,340,123,340,123,340,124,341,124,341,124,342,124,342,125,342,127,337,127,334,127,332,127,332,127;503,126,502,126,501,126,500,126,499,126,499,126,499,126,498,126,498,126,497,126,496,125,496,125,496,125,496,125,496,125,495,125,495,125,495,125,495,124,494,124,494,124,493,124,493,124,493,124,493,124,492,124,490,124,487,124,487,122,487,120,486,120,485,120,485,120,485,119,485,119,485,118,485,118,486,118,486,118,486,117,486,117,486,117,487,117,489,117,490,117,491,117,491,117,491,116,492,116,494,116,496,116,497,116,497,116,497,115,498,115,498,116,499,116,499,117,499,117,498,117,498,117,498,118,498,119,498,119,500,119,502,119,502,119,503,120,503,120,503,120,504,120,504,120,505,120,505,121,505,121,505,121,506,121,507,121,508,121,508,121,508,121,508,122,509,122,510,122,511,122,511,123,511,123,511,124,512,124,512,124,512,124,512,125,512,127,508,127,505,127,503,127,503,127;48,120,48,120,47,120,47,120,47,120,47,120,47,119,47,119,46,119,46,119,46,118,47,118,47,118,48,118,51,118,53,118,54,118,54,118,54,118,54,118,55,118,55,118,56,118,56,119,56,120,55,120,55,120,54,120,54,120,54,121,54,121,54,121,54,121,53,121,53,121,53,121,53,121,52,122,51,122,49,122,49,121,49,121;219,120,218,120,218,120,218,120,218,120,218,120,218,119,217,119,217,119,217,119,217,118,217,118,218,118,218,118,221,118,223,118,225,118,225,118,225,118,225,118,226,118,226,118,226,118,226,119,226,120,226,120,226,120,225,120,225,120,225,121,225,121,225,121,224,121,224,121,224,121,224,121,224,121,223,122,222,122,220,122,220,121,219,121;390,120,389,120,389,120,388,120,388,120,388,120,388,119,388,119,388,119,387,119,387,118,388,118,388,118,389,118,392,118,394,118,396,118,396,118,396,118,396,118,396,118,397,118,397,118,397,119,397,120,397,120,396,120,396,120,396,120,396,121,396,121,395,121,395,121,394,121,394,121,394,121,394,121,393,122,392,122,391,122,390,121,390,121;170,119,169,119,167,119,166,119,165,119,165,119,165,118,164,118,163,118,161,118,160,118,160,118,160,118,160,118,160,118,159,118,159,117,159,115,159,113,159,112,159,112,159,112,160,112,160,112,160,111,160,111,160,111,160,111,160,110,160,110,160,109,160,109,161,109,161,108,162,108,162,107,162,107,162,106,162,106,163,106,163,105,163,105,163,104,163,104,165,104,167,104,168,104,168,105,168,105,168,105,169,105,169,105,170,105,170,105,170,105,170,106,170,106,171,106,171,106,171,106,171,107,171,107,172,107,172,107,173,107,173,108,173,108,174,108,174,108,175,108,175,108,175,109,175,109,175,109,176,109,176,109,176,109,176,109,176,109,177,110,177,110,179,110,180,111,180,112,180,112,180,112,181,113,181,113,182,113,182,114,182,114,182,114,182,115,183,115,183,115,183,116,183,117,183,118,182,118,181,118,181,118,181,118,181,118,180,118,180,118,179,118,179,118,179,119,179,119,177,119,175,119,172,119,171,119,171,119,171,119,171,120,170,120,170,120,170,119,170,119;340,119,339,119,338,119,337,119,336,119,336,119,336,118,335,118,333,118,332,118,331,118,331,118,331,118,331,118,330,118,330,118,330,117,330,115,330,113,330,112,330,112,330,112,330,112,330,112,330,111,330,111,331,111,331,111,331,110,331,110,331,109,331,109,332,109,332,108,332,108,332,107,332,107,332,106,333,106,333,106,334,105,334,105,334,104,334,104,336,104,337,104,338,104,338,105,338,105,339,105,339,105,340,105,340,105,340,105,340,105,340,106,341,106,341,106,342,106,342,106,342,107,342,107,342,107,343,107,344,107,344,108,344,108,345,108,345,108,345,108,346,108,346,109,346,109,346,109,346,109,347,109,347,109,347,109,347,109,347,110,348,110,349,110,351,111,351,112,351,112,351,112,352,113,352,113,352,113,352,114,352,114,352,114,353,115,353,115,354,115,354,116,354,117,353,118,353,118,352,118,352,118,352,118,352,118,351,118,351,118,350,118,350,118,350,119,350,119,348,119,346,119,343,119,342,119,342,119,342,119,341,120,341,120,340,120,340,119,340,119;511,119,510,119,509,119,507,119,506,119,506,119,506,118,505,118,504,118,503,118,502,118,502,118,502,118,501,118,501,118,500,118,500,117,500,115,500,113,500,112,501,112,501,112,501,112,501,112,501,111,501,111,501,111,501,111,502,110,502,110,502,109,502,109,502,109,503,108,503,108,503,107,503,107,503,106,504,106,504,106,504,105,504,105,504,104,504,104,507,104,508,104,509,104,509,105,509,105,509,105,510,105,510,105,511,105,511,105,511,105,511,106,512,106,512,106,512,106,512,106,512,107,512,107,513,107,514,107,514,107,515,108,515,108,515,108,516,108,516,108,516,108,516,109,516,109,516,109,517,109,517,109,518,109,518,109,518,109,518,110,519,110,520,110,522,111,522,112,522,112,522,112,522,113,523,113,523,113,523,114,523,114,523,114,524,115,524,115,524,115,524,116,524,117,524,118,523,118,523,118,522,118,522,118,522,118,522,118,521,118,521,118,520,118,520,119,520,119,519,119,516,119,514,119,512,119,512,119,512,119,512,120,512,120,511,120,511,119,511,119;60,116,60,116,60,116,60,116,60,115,60,115,60,114,59,114,59,114,59,114,59,113,59,112,59,111,59,110,59,110,58,110,58,110,58,109,58,108,61,108,62,108,64,107,64,107,64,107,64,107,64,107,64,107,65,107,65,106,65,106,66,106,66,106,67,106,67,105,67,105,67,105,67,105,68,105,68,105,69,104,72,101,76,98,76,98,77,98,79,98,79,101,79,103,79,104,79,104,79,104,80,106,80,110,80,115,78,115,76,115,76,115,75,116,75,116,74,116,74,116,74,116,74,116,74,117,74,117,73,117,73,117,72,117,72,117,72,117,72,117,71,118,71,118,70,118,69,118,69,118,69,119,68,119,66,119,64,119,63,119,63,118,63,118,62,118,62,118,62,119,62,119,61,119,60,119,60,119,60,117;231,116,231,116,231,116,230,116,230,115,230,115,230,114,230,114,230,114,230,114,230,113,230,112,230,111,229,110,229,110,229,110,229,110,229,109,229,108,232,108,233,108,234,107,234,107,234,107,234,107,235,107,235,107,236,107,236,106,236,106,237,106,237,106,237,106,238,105,238,105,238,105,238,105,238,105,239,105,240,104,243,101,246,98,247,98,248,98,250,98,250,101,250,103,250,104,250,104,250,104,250,106,250,110,250,115,248,115,247,115,246,115,246,116,246,116,245,116,245,116,244,116,244,116,244,117,244,117,244,117,243,117,243,117,242,117,242,117,242,117,242,118,241,118,241,118,240,118,240,118,239,119,239,119,236,119,234,119,233,119,233,118,233,118,233,118,233,118,233,119,232,119,232,119,231,119,231,119,231,117;402,116,401,116,401,116,401,116,401,115,401,115,401,114,401,114,401,114,400,114,400,113,400,112,400,111,400,110,400,110,400,110,400,110,400,109,400,108,402,108,404,108,405,107,405,107,405,107,405,107,405,107,406,107,406,107,407,106,407,106,407,106,408,106,408,106,408,105,408,105,408,105,409,105,409,105,410,105,411,104,414,101,417,98,417,98,419,98,420,98,420,101,420,103,420,104,421,104,421,104,421,106,421,110,421,115,419,115,417,115,417,115,417,116,416,116,416,116,415,116,415,116,415,116,415,117,415,117,414,117,414,117,413,117,413,117,413,117,413,117,412,118,412,118,411,118,411,118,411,118,410,119,410,119,407,119,405,119,404,119,404,118,404,118,404,118,404,118,404,119,403,119,402,119,402,119,402,119,402,117;22,118,21,118,20,118,19,118,19,117,19,117,19,117,19,117,18,117,18,117,18,117,18,117,18,116,17,116,17,116,16,116,16,116,16,115,16,115,16,114,17,114,17,114,18,113,18,112,18,112,18,112,18,112,18,112,18,111,18,111,18,110,18,110,19,110,19,110,19,110,19,109,19,108,19,108,19,108,20,108,20,108,21,108,21,107,21,107,22,107,22,107,22,107,23,106,23,106,23,106,24,106,24,106,24,105,25,105,25,104,25,104,26,104,26,104,27,104,27,104,27,104,27,104,28,104,28,104,28,103,28,103,28,102,29,102,30,102,31,102,32,101,32,101,32,101,32,101,33,101,34,101,34,101,34,101,34,101,34,102,35,102,35,102,36,102,36,102,36,103,37,103,37,104,37,104,37,104,37,104,37,104,38,104,38,105,38,105,38,106,38,106,39,106,39,107,39,108,39,108,39,109,39,109,38,109,38,109,38,110,38,110,38,110,38,110,38,110,38,111,38,112,38,112,37,113,37,113,37,113,37,114,37,114,37,116,37,116,36,117,35,117,35,118,33,118,31,118,30,118,30,118,30,118,29,118,26,118,23,118,22,118,22,118;192,118,192,118,191,118,190,118,190,117,190,117,190,117,189,117,189,117,188,117,188,117,188,117,188,116,188,116,188,116,187,116,187,116,187,115,187,115,187,114,188,114,188,114,188,113,188,112,188,112,188,112,189,112,189,112,189,111,189,111,189,110,189,110,189,110,189,110,190,110,190,109,190,108,190,108,190,108,190,108,191,108,191,108,191,107,192,107,192,107,192,107,193,107,193,106,193,106,194,106,194,106,194,106,195,105,195,105,195,104,196,104,197,104,197,104,198,104,198,104,198,104,198,104,198,104,199,104,199,103,199,103,199,102,200,102,201,102,202,102,202,101,202,101,202,101,203,101,204,101,204,101,205,101,205,101,205,101,205,102,205,102,206,102,208,103,208,104,208,104,208,104,208,104,208,104,208,104,208,105,208,105,208,106,209,106,209,106,210,107,210,108,210,108,209,109,209,109,209,109,209,109,209,110,209,110,209,110,209,110,208,110,208,111,208,112,208,112,208,113,208,113,208,113,208,114,208,114,208,116,207,116,207,117,206,117,206,118,203,118,202,118,201,118,201,118,201,118,199,118,197,118,194,118,192,118,192,118;363,118,362,118,362,118,361,118,360,117,360,117,360,117,360,117,360,117,359,117,359,117,359,117,359,116,359,116,358,116,358,116,358,116,358,115,358,115,358,114,358,114,359,114,359,113,359,112,359,112,359,112,359,112,359,112,360,111,360,111,360,110,360,110,360,110,360,110,360,110,360,109,360,108,360,108,361,108,361,108,362,108,362,108,362,107,363,107,363,107,363,107,364,107,364,106,364,106,365,106,365,106,365,106,366,105,366,105,366,104,367,104,367,104,368,104,368,104,368,104,368,104,368,104,369,104,369,104,370,103,370,103,370,102,370,102,372,102,372,102,373,101,373,101,373,101,373,101,374,101,375,101,376,101,376,101,376,101,376,102,376,102,377,102,378,103,378,104,378,104,378,104,379,104,379,104,379,104,379,105,379,105,379,106,380,106,380,106,380,107,380,108,380,108,380,109,380,109,380,109,380,109,380,110,380,110,379,110,379,110,379,110,379,111,379,112,379,112,379,113,379,113,378,113,378,114,378,114,378,116,378,116,377,117,377,117,376,118,374,118,373,118,372,118,372,118,372,118,370,118,367,118,365,118,363,118,363,118;56,117,55,117,54,117,53,117,52,117,52,117,52,116,50,116,48,116,45,116,45,116,45,116,44,115,44,115,43,115,42,115,42,115,42,115,42,114,41,114,41,114,40,114,40,114,39,114,39,113,39,111,39,111,39,111,40,110,40,110,40,109,40,109,40,109,40,109,40,109,40,108,40,108,40,107,41,107,41,107,41,107,40,106,39,106,39,105,39,105,39,105,39,104,38,104,38,104,38,103,38,102,38,102,40,102,42,102,43,101,43,101,43,100,44,100,45,100,45,100,46,100,46,100,46,100,47,100,48,100,49,100,50,100,50,100,50,100,50,100,51,100,51,100,52,101,53,102,55,104,55,104,55,105,55,106,55,107,56,107,56,107,56,108,56,109,56,109,56,110,57,110,57,110,57,110,57,110,57,111,57,111,57,111,57,111,58,111,58,112,58,113,58,114,58,114,58,114,58,114,58,115,58,115,58,116,59,116,59,116,59,116,58,117,58,118,56,118,56,117;227,117,226,117,225,117,223,117,222,117,222,117,222,116,221,116,219,116,216,116,216,116,215,116,215,115,214,115,213,115,213,115,212,115,212,115,212,114,212,114,211,114,211,114,210,114,210,114,209,113,209,111,210,111,210,111,210,110,210,110,210,109,210,109,211,109,211,109,211,109,211,108,211,108,211,107,211,107,212,107,211,107,211,106,210,106,210,105,210,105,210,105,209,104,209,104,208,104,208,103,208,102,208,102,211,102,213,102,213,101,214,101,214,100,215,100,215,100,216,100,216,100,216,100,216,100,217,100,219,100,220,100,221,100,221,100,221,100,221,100,221,100,222,100,223,101,224,102,225,104,226,104,226,105,226,106,226,107,226,107,227,107,227,108,227,109,227,109,227,110,227,110,227,110,228,110,228,110,228,111,228,111,228,111,228,111,228,111,228,112,228,113,228,114,229,114,229,114,229,114,229,115,229,115,229,116,229,116,230,116,230,116,229,117,228,118,227,118,227,117;398,117,397,117,395,117,394,117,393,117,393,117,393,116,392,116,390,116,387,116,386,116,386,116,385,115,385,115,384,115,383,115,383,115,383,115,383,114,382,114,382,114,382,114,381,114,381,114,380,113,380,111,381,111,381,111,381,110,381,110,381,109,381,109,381,109,381,109,382,109,382,108,382,108,382,107,382,107,382,107,382,107,381,106,381,106,380,105,380,105,380,105,380,104,380,104,379,104,379,103,379,102,379,102,381,102,384,102,384,101,385,101,385,100,385,100,386,100,386,100,387,100,387,100,387,100,388,100,389,100,391,100,392,100,392,100,392,100,392,100,392,100,392,100,393,101,394,102,396,104,396,104,396,105,396,106,396,107,397,107,397,107,398,108,398,109,398,109,398,110,398,110,398,110,398,110,398,110,398,111,398,111,399,111,399,111,399,111,399,112,399,113,399,114,399,114,399,114,400,114,400,115,400,115,400,116,400,116,400,116,400,116,400,117,399,118,398,118,398,117;82,114,82,114,82,110,82,107,82,106,83,106,83,105,84,105,84,105,85,105,85,105,85,105,85,104,87,104,91,104,95,104,97,104,97,105,97,105,97,105,98,105,98,105,99,105,99,105,99,105,100,106,101,106,102,106,103,106,103,106,104,106,104,107,103,107,103,107,103,108,103,109,103,109,103,110,103,110,102,110,102,111,102,112,102,114,102,115,102,115,101,115,100,115,92,115,84,115,83,115;253,114,253,114,253,110,253,107,253,106,254,106,254,105,255,105,255,105,255,105,256,105,256,105,256,104,258,104,262,104,265,104,268,104,268,105,268,105,268,105,269,105,269,105,270,105,270,105,270,105,270,106,271,106,273,106,273,106,274,106,274,106,274,107,274,107,274,107,274,108,274,109,274,109,273,110,273,110,273,110,273,111,273,112,273,114,273,115,272,115,272,115,270,115,263,115,254,115,254,115;424,114,424,114,424,110,424,107,424,106,424,106,425,105,425,105,426,105,426,105,426,105,426,105,426,104,428,104,432,104,436,104,438,104,438,105,438,105,439,105,439,105,440,105,440,105,440,105,440,105,441,106,442,106,443,106,444,106,444,106,445,106,445,107,445,107,444,107,444,108,444,109,444,109,444,110,444,110,444,110,444,111,444,112,444,114,443,115,443,115,443,115,441,115,434,115,425,115,424,115;12,113,12,113,13,112,14,111,15,112,15,114,15,115,14,115,13,114;121,114,119,114,116,114,113,114,112,114,112,114,112,114,111,114,110,114,109,114,109,113,109,113,108,112,108,112,107,112,107,112,106,112,105,111,104,110,104,110,104,108,104,107,104,106,105,106,105,106,105,105,105,103,105,100,105,100,106,99,106,98,107,98,109,98,111,98,112,98,112,99,112,99,113,99,114,99,115,99,116,99,116,99,116,99,116,100,116,100,117,100,117,100,117,100,117,100,117,100,118,100,118,100,119,100,119,101,119,101,119,101,120,101,120,101,121,101,121,101,121,101,122,102,123,102,123,102,124,102,124,102,124,102,125,102,125,102,126,102,126,102,126,103,126,103,127,103,127,103,128,103,128,103,129,104,129,104,129,104,130,104,130,104,130,104,130,105,130,106,130,106,131,106,131,106,131,108,131,111,131,115,126,115,123,115,121,115,121,115;143,114,142,114,140,114,138,114,136,114,136,114,136,114,135,114,134,114,132,114,132,110,132,108,132,106,132,106,132,106,132,106,132,106,132,105,132,105,132,105,133,105,133,105,133,105,133,104,133,104,134,104,134,104,135,104,136,103,136,103,137,102,137,102,137,102,138,103,139,104,139,104,140,105,140,105,141,105,141,105,141,105,141,105,141,106,142,106,143,106,144,106,144,106,144,106,144,106,145,106,145,106,146,106,146,107,146,107,147,107,148,107,149,107,150,107,150,107,150,106,151,106,153,106,154,106,156,106,156,106,156,106,157,106,158,106,160,106,160,106,160,106,160,107,160,108,160,108,159,108,159,109,159,109,159,110,159,110,159,110,158,110,158,111,158,111,158,112,158,112,158,112,158,112,158,112,158,113,158,113,157,114,157,114,156,114,156,114,156,114,156,114,156,114,155,114,155,114,154,114,154,115,154,115,152,115,149,115,145,115,143,115,143,115;183,113,183,113,183,112,184,111,186,112,186,114,186,115,185,115,184,114;292,114,290,114,287,114,284,114,282,114,282,114,282,114,282,114,281,114,280,114,280,113,279,113,279,112,278,112,278,112,277,112,277,112,276,111,275,110,275,110,275,108,275,107,275,106,275,106,275,106,276,105,276,103,276,100,276,100,276,99,277,98,277,98,280,98,282,98,283,98,283,99,283,99,284,99,285,99,285,99,286,99,286,99,286,99,286,100,287,100,287,100,288,100,288,100,288,100,288,100,289,100,289,100,290,100,290,101,290,101,290,101,291,101,291,101,292,101,292,101,292,101,292,102,293,102,294,102,295,102,295,102,295,102,295,102,296,102,296,102,297,102,297,103,297,103,297,103,298,103,298,103,299,103,299,104,299,104,300,104,300,104,301,104,301,104,301,105,301,106,301,106,301,106,301,106,302,108,302,111,302,115,297,115,293,115,292,115,292,115;314,114,312,114,310,114,308,114,307,114,307,114,307,114,306,114,305,114,303,114,303,110,303,108,303,106,303,106,302,106,302,106,302,106,302,105,302,105,303,105,303,105,304,105,304,105,304,104,304,104,304,104,305,104,306,104,306,103,307,103,307,102,307,102,308,102,308,103,309,104,310,104,311,105,311,105,311,105,312,105,312,105,312,105,312,106,313,106,314,106,314,106,314,106,314,106,315,106,315,106,316,106,316,106,316,107,316,107,317,107,319,107,320,107,321,107,321,107,321,106,322,106,324,106,325,106,326,106,326,106,326,106,327,106,329,106,331,106,331,106,331,106,331,107,331,108,330,108,330,108,330,109,330,109,330,110,329,110,329,110,329,110,329,111,329,111,329,112,329,112,329,112,328,112,328,112,328,113,328,113,328,114,328,114,327,114,327,114,327,114,327,114,326,114,326,114,325,114,325,114,325,115,325,115,323,115,319,115,316,115,314,115,314,115;353,113,353,113,354,112,355,111,356,112,356,114,356,115,355,115,354,114;462,114,460,114,458,114,455,114,453,114,453,114,453,114,452,114,452,114,451,114,450,113,450,113,450,112,449,112,449,112,448,112,447,112,447,111,446,110,446,110,446,108,446,107,446,106,446,106,446,106,446,105,446,103,446,100,446,100,447,99,448,98,448,98,451,98,452,98,454,98,454,99,454,99,454,99,455,99,456,99,457,99,457,99,457,99,457,100,458,100,458,100,458,100,458,100,458,100,459,100,459,100,460,100,460,100,460,101,460,101,461,101,461,101,462,101,462,101,462,101,462,101,463,102,464,102,465,102,466,102,466,102,466,102,466,102,467,102,467,102,468,102,468,103,468,103,468,103,468,103,469,103,470,103,470,104,470,104,471,104,471,104,471,104,472,104,472,105,472,106,472,106,472,106,472,106,472,108,472,111,472,115,467,115,464,115,462,115,462,115;484,114,483,114,481,114,479,114,478,114,478,114,478,114,477,114,476,114,474,114,474,110,474,108,473,106,473,106,473,106,473,106,473,106,473,105,473,105,474,105,474,105,474,105,474,105,474,104,475,104,475,104,476,104,476,104,477,103,477,103,478,102,478,102,478,102,479,103,480,104,481,104,481,105,482,105,482,105,482,105,482,105,482,105,483,106,484,106,484,106,485,106,485,106,485,106,485,106,486,106,486,106,487,106,487,107,487,107,488,107,489,107,491,107,492,107,492,107,492,106,493,106,494,106,496,106,497,106,497,106,497,106,498,106,499,106,501,106,502,106,502,106,502,107,501,108,501,108,500,108,500,109,500,109,500,110,500,110,500,110,500,110,500,111,500,111,500,112,499,112,499,112,499,112,499,112,499,113,499,113,499,114,498,114,498,114,498,114,498,114,498,114,497,114,497,114,496,114,496,114,496,115,496,115,493,115,490,115,486,115,484,115,484,115;11,110,11,110,10,110,10,110,8,108,8,107,8,107,8,107,8,107,7,106,7,106,7,105,7,104,7,104,8,104,8,104,8,104,8,104,8,104,9,104,11,104,12,104,13,103,13,103,13,103,14,103,15,103,17,103,17,104,17,105,17,106,17,106,16,106,16,106,16,106,16,106,15,107,15,108,14,109,13,110,13,110,12,110,12,110,12,110,12,110,12,110,12,110,11,110,11,110,11,110;182,110,181,110,181,110,180,110,179,108,179,107,179,107,179,107,178,107,178,106,178,106,178,105,178,104,178,104,178,104,179,104,179,104,179,104,179,104,180,104,181,104,183,104,184,103,184,103,184,103,184,103,186,103,188,103,188,104,188,105,187,106,187,106,187,106,187,106,187,106,187,107,184,110,183,110,183,110,183,110,183,110,183,110,183,110,182,110,182,110,182,110,182,110;352,110,352,110,352,110,351,110,350,108,350,107,350,107,349,107,349,107,348,106,348,106,348,105,348,104,348,104,349,104,349,104,350,104,350,104,350,104,351,104,352,104,353,104,354,103,354,103,354,103,355,103,356,103,358,103,358,104,358,105,358,106,358,106,358,106,358,106,358,106,358,107,355,110,354,110,354,110,354,110,354,110,354,110,353,110,353,110,352,110,352,110,352,110;16,108,16,107,17,107,17,107,18,106,18,106,18,106,18,105,18,105,19,105,19,104,19,104,19,103,19,103,19,103,19,103,20,103,20,103,20,103,20,104,21,104,21,104,22,104,22,104,23,104,23,105,22,105,22,105,22,106,21,106,21,106,21,106,21,106,20,107,20,107,20,107,19,107,19,107,19,108,18,108,16,108,16,108;187,108,187,107,188,107,188,107,188,106,188,106,188,106,188,105,189,105,189,105,190,104,190,104,190,103,190,103,190,103,190,103,190,103,190,103,190,103,191,104,191,104,192,104,193,104,193,104,193,104,193,105,193,105,193,105,192,106,192,106,192,106,191,106,191,106,191,107,190,107,190,107,190,107,189,107,189,108,189,108,187,108,187,108;358,108,358,107,358,107,359,107,359,106,359,106,359,106,359,105,360,105,360,105,360,104,360,104,360,103,360,103,361,103,361,103,361,103,361,103,361,103,361,104,362,104,363,104,363,104,364,104,364,104,364,105,364,105,363,105,363,106,363,106,363,106,362,106,362,106,362,107,361,107,361,107,361,107,360,107,360,108,359,108,358,108,358,108;5,107,4,107,4,107,3,107,2,105,2,105,2,104,2,104,2,104,3,104,3,104,3,105,3,105,3,105,4,105,4,105,4,105,4,105,4,105,4,106,5,106,5,106,6,106,6,107,6,107,5,108,5,108,5,108,5,107,5,107;176,107,175,107,175,107,174,107,172,105,172,105,172,104,172,104,173,104,173,104,174,104,174,105,174,105,174,105,174,105,175,105,175,105,175,105,175,105,175,106,176,106,176,106,176,106,176,107,176,107,176,108,176,108,176,108,176,107,176,107;346,107,346,107,345,107,344,107,343,105,343,105,343,104,343,104,344,104,344,104,344,104,344,105,344,105,344,105,345,105,345,105,346,105,346,105,346,105,346,106,346,106,347,106,347,106,347,107,347,107,347,108,347,108,346,108,346,107,346,107;146,105,145,105,145,105,144,105,144,105,144,105,144,104,143,104,142,104,141,104,141,104,141,104,140,103,140,103,139,103,139,103,139,103,139,102,139,101,139,101,138,101,138,100,138,100,138,99,138,99,137,98,137,98,137,98,137,98,137,98,137,98,138,97,138,96,138,95,138,94,138,94,139,94,139,93,139,93,139,92,139,92,139,92,140,92,140,92,141,92,141,91,141,91,142,91,142,91,142,91,142,91,142,90,142,90,143,90,143,90,144,89,146,88,147,87,148,86,148,86,149,86,149,85,149,85,149,85,149,85,150,85,151,85,152,85,154,87,155,89,156,90,156,90,156,90,156,91,157,91,157,91,158,92,158,92,158,93,158,93,158,93,158,93,158,93,158,94,158,94,158,94,159,94,159,94,159,94,159,95,159,95,159,96,160,96,160,96,160,97,160,97,160,97,160,98,161,98,161,98,161,98,161,98,161,99,161,99,161,99,161,99,162,99,162,100,162,100,162,101,162,101,163,102,163,102,162,103,161,104,161,104,159,104,158,104,157,104,157,105,157,105,156,105,154,105,152,105,151,105,151,105,151,105,150,106,148,106,147,106,146,105,146,105;316,105,316,105,315,105,315,105,314,105,314,105,314,104,314,104,313,104,312,104,312,104,311,104,311,103,310,103,310,103,310,103,310,103,310,102,310,101,309,101,309,101,308,100,308,100,308,99,308,99,308,98,308,98,307,98,307,98,308,98,308,98,308,97,308,96,308,95,308,94,309,94,309,94,310,93,310,93,310,92,310,92,310,92,310,92,311,92,311,92,311,91,312,91,312,91,313,91,313,91,313,91,313,90,313,90,313,90,314,90,315,89,316,88,317,87,319,86,319,86,319,86,320,85,320,85,320,85,320,85,321,85,322,85,322,85,324,87,326,89,327,90,327,90,327,90,327,91,328,91,328,91,328,92,328,92,328,93,328,93,329,93,329,93,329,93,329,94,329,94,329,94,329,94,329,94,330,94,330,95,330,95,330,96,330,96,331,96,331,97,331,97,331,97,331,98,331,98,331,98,332,98,332,98,332,99,332,99,332,99,332,99,332,99,332,100,332,100,332,101,333,101,334,102,334,102,333,103,332,104,332,104,330,104,328,104,328,104,328,105,328,105,326,105,325,105,323,105,322,105,322,105,322,105,320,106,319,106,317,106,316,105,316,105;487,105,486,105,486,105,485,105,485,105,485,105,485,104,484,104,484,104,483,104,482,104,482,104,482,103,481,103,481,103,480,103,480,103,480,102,480,101,480,101,480,101,479,100,479,100,479,99,479,99,479,98,478,98,478,98,478,98,478,98,479,98,479,97,479,96,479,95,479,94,480,94,480,94,480,93,480,93,480,92,480,92,481,92,481,92,482,92,482,92,482,91,483,91,483,91,483,91,484,91,484,91,484,90,484,90,484,90,484,90,486,89,487,88,488,87,489,86,490,86,490,86,490,85,490,85,490,85,491,85,491,85,492,85,493,85,495,87,496,89,498,90,498,90,498,90,498,91,498,91,499,91,499,92,499,92,499,93,499,93,499,93,499,93,500,93,500,94,500,94,500,94,500,94,500,94,500,94,500,95,500,95,500,96,501,96,501,96,502,97,502,97,502,97,502,98,502,98,502,98,502,98,502,98,502,99,502,99,503,99,503,99,503,99,503,100,503,100,503,101,504,101,504,102,504,102,503,103,503,104,502,104,500,104,499,104,498,104,498,105,498,105,497,105,495,105,493,105,492,105,492,105,492,105,491,106,490,106,488,106,487,105,487,105;58,103,58,103,57,103,56,103,55,101,55,101,55,100,55,100,55,100,54,100,54,100,54,100,54,99,54,99,56,99,57,99,58,99,58,99,58,98,58,98,59,98,60,98,60,98,60,99,60,99,61,99,63,99,64,99,65,99,65,99,65,99,66,100,67,100,68,100,69,100,69,100,69,100,69,100,70,100,71,100,71,100,71,101,71,101,69,103,69,103,68,103,68,103,68,103,68,103,68,104,68,104,67,104,67,104,67,104,67,104,65,104,63,104,59,104,59,104,59,104;82,103,82,102,82,101,82,99,82,98,83,97,84,96,84,96,86,96,87,96,88,96,88,96,88,96,88,96,89,96,91,96,91,96,92,96,92,97,93,97,95,97,96,97,98,97,98,97,98,97,98,98,99,98,101,98,101,98,102,99,103,100,104,100,104,101,104,102,103,103,103,103,103,103,103,103,103,104,103,104,103,104,101,104,100,104,100,104,100,104,100,104,99,104,98,104,97,104,97,103,97,103,97,103,95,103,92,103,88,103,86,103,86,103,86,103,85,104,85,104,84,104,83,104,83,104,83,104,82,104,82,104;128,102,128,102,127,102,127,102,126,101,126,101,126,101,126,101,125,101,125,101,124,101,124,101,124,100,123,100,123,100,121,100,121,100,121,99,121,99,121,98,121,98,121,98,122,98,122,97,122,96,122,96,122,96,122,96,122,95,122,95,122,94,122,94,123,94,123,94,123,94,123,93,123,92,124,92,125,92,126,92,126,91,126,91,126,91,127,91,128,91,129,91,130,91,130,91,130,90,130,90,131,90,132,90,132,90,132,91,132,91,132,91,133,91,133,91,134,91,134,91,134,91,134,92,135,92,135,92,136,92,136,92,136,92,136,92,136,92,137,92,137,92,137,93,137,94,137,94,137,94,136,94,136,95,136,97,136,98,136,99,136,99,136,99,136,99,136,100,136,101,135,102,135,102,135,102,135,102,135,102,135,103,135,103,134,103,133,103,133,103,133,103,133,103,133,104,132,104,132,104,132,104,132,104,132,105,130,104,129,103;229,103,228,103,228,103,227,103,226,101,226,101,226,100,225,100,225,100,225,100,225,100,225,100,225,99,225,99,227,99,227,99,228,99,228,99,228,98,229,98,230,98,230,98,231,98,231,99,231,99,232,99,233,99,235,99,236,99,236,99,236,99,236,100,238,100,239,100,240,100,240,100,240,100,240,100,241,100,241,100,242,100,242,101,242,101,240,103,239,103,239,103,239,103,239,103,239,103,239,104,238,104,238,104,238,104,238,104,238,104,236,104,234,104,230,104,230,104,229,104;252,103,252,102,252,101,252,99,252,98,253,97,254,96,255,96,256,96,257,96,258,96,258,96,258,96,259,96,260,96,262,96,262,96,263,96,263,97,263,97,266,97,267,97,268,97,268,97,268,97,269,98,270,98,272,98,272,98,273,99,274,100,274,100,274,101,274,102,274,103,274,103,274,103,274,103,274,104,274,104,273,104,272,104,271,104,270,104,270,104,270,104,270,104,269,104,268,104,268,103,268,103,268,103,266,103,262,103,259,103,257,103,257,103,257,103,256,104,255,104,254,104,254,104,254,104,254,104,253,104,253,104;299,102,298,102,298,102,297,102,297,101,297,101,297,101,296,101,296,101,295,101,295,101,295,101,295,100,294,100,293,100,292,100,292,100,292,99,292,99,292,98,292,98,292,98,292,98,292,97,292,96,292,96,293,96,293,96,293,95,293,95,293,94,293,94,293,94,293,94,294,94,294,93,294,92,294,92,296,92,296,92,297,91,297,91,297,91,298,91,299,91,299,91,300,91,300,91,300,90,301,90,302,90,302,90,303,90,303,91,303,91,303,91,304,91,304,91,304,91,304,91,304,91,305,92,305,92,306,92,306,92,306,92,306,92,306,92,307,92,307,92,308,92,308,93,308,94,307,94,307,94,307,94,307,95,307,97,307,98,307,99,307,99,306,99,306,99,306,100,306,101,306,102,306,102,306,102,306,102,306,102,306,103,305,103,305,103,304,103,304,103,304,103,304,103,303,104,303,104,302,104,302,104,302,104,302,105,301,104,300,103;400,103,399,103,399,103,398,103,396,101,396,101,396,100,396,100,396,100,396,100,396,100,396,100,396,99,396,99,397,99,398,99,399,99,399,99,399,98,399,98,400,98,401,98,402,98,402,99,402,99,403,99,404,99,405,99,406,99,406,99,406,99,407,100,408,100,409,100,410,100,410,100,410,100,411,100,411,100,412,100,412,100,412,101,412,101,411,103,410,103,410,103,410,103,410,103,410,103,409,104,409,104,408,104,408,104,408,104,408,104,407,104,404,104,401,104,400,104,400,104;423,103,423,102,423,101,423,99,423,98,424,97,425,96,425,96,427,96,428,96,429,96,429,96,429,96,430,96,431,96,432,96,433,96,433,96,434,97,434,97,436,97,438,97,439,97,439,97,439,97,440,98,441,98,442,98,443,98,444,99,445,100,445,100,445,101,445,102,445,103,445,103,444,103,444,103,444,104,444,104,444,104,443,104,442,104,441,104,441,104,441,104,440,104,440,104,439,104,438,103,438,103,438,103,436,103,433,103,430,103,428,103,428,103,428,103,427,104,426,104,425,104,424,104,424,104,424,104,424,104,423,104;470,102,469,102,468,102,468,102,468,101,468,101,468,101,467,101,467,101,466,101,466,101,466,101,466,100,465,100,464,100,462,100,462,100,462,99,462,99,462,98,463,98,463,98,463,98,463,97,463,96,463,96,463,96,463,96,464,95,464,95,464,94,464,94,464,94,464,94,464,94,464,93,464,92,465,92,466,92,467,92,468,91,468,91,468,91,468,91,469,91,470,91,471,91,471,91,471,90,471,90,472,90,473,90,474,90,474,91,474,91,474,91,474,91,475,91,475,91,475,91,475,91,475,92,476,92,476,92,477,92,477,92,477,92,477,92,478,92,478,92,478,92,478,93,478,94,478,94,478,94,478,94,478,95,478,97,478,98,477,99,477,99,477,99,477,99,477,100,477,101,477,102,477,102,476,102,476,102,476,102,476,103,476,103,475,103,475,103,474,103,474,103,474,103,474,104,474,104,473,104,473,104,473,104,473,105,472,104,471,103;173,103,172,103,171,103,170,103,169,103,169,103,169,102,168,102,167,102,165,102,165,102,164,101,163,100,163,100,163,99,163,99,163,98,162,98,162,98,162,97,162,97,162,97,161,96,161,96,160,95,160,95,160,93,160,91,161,91,162,91,163,91,163,92,164,92,164,92,166,92,167,92,168,92,168,93,168,93,169,93,170,93,170,93,171,93,171,93,171,93,172,94,172,94,174,94,175,94,175,95,175,96,175,96,175,96,175,96,176,96,176,97,176,97,176,98,176,98,176,98,176,98,176,99,176,100,176,100,177,100,177,100,177,100,177,101,177,101,177,102,177,102,177,102,178,102,178,102,178,103,177,103,177,103,176,103,176,103,176,103,176,103,175,104,175,104,174,104,173,103,173,103;344,103,343,103,342,103,340,103,340,103,340,103,340,102,339,102,338,102,336,102,336,102,335,101,334,100,334,100,334,99,334,99,333,98,333,98,332,98,332,97,332,97,332,97,332,96,332,96,331,95,331,95,331,93,331,91,332,91,333,91,333,91,334,92,334,92,335,92,337,92,338,92,339,92,339,93,339,93,339,93,340,93,341,93,342,93,342,93,342,93,342,94,343,94,345,94,346,94,346,95,346,96,346,96,346,96,346,96,346,96,346,97,346,97,346,98,347,98,347,98,347,98,347,99,347,100,347,100,347,100,347,100,348,100,348,101,348,101,348,102,348,102,348,102,348,102,348,102,348,103,348,103,348,103,347,103,347,103,347,103,347,103,346,104,345,104,344,104,344,103,344,103;514,103,513,103,512,103,511,103,510,103,510,103,510,102,509,102,508,102,507,102,506,102,505,101,505,100,504,100,504,99,504,99,504,98,504,98,503,98,503,97,503,97,503,97,503,96,502,96,502,95,502,95,502,93,502,91,503,91,504,91,504,91,505,92,505,92,505,92,507,92,509,92,510,92,510,93,510,93,510,93,511,93,512,93,512,93,512,93,512,93,513,94,514,94,515,94,516,94,516,95,516,96,516,96,517,96,517,96,517,96,517,97,517,97,517,98,517,98,517,98,518,98,518,99,518,100,518,100,518,100,518,100,518,100,518,101,518,101,518,102,519,102,519,102,519,102,519,102,519,103,519,103,518,103,518,103,518,103,518,103,518,103,517,104,516,104,515,104,514,103,514,103;7,100,7,100,7,99,7,98,7,98,7,98,6,98,6,97,6,97,6,96,6,96,6,96,6,96,6,95,6,94,6,93,5,92,5,92,5,92,5,91,5,91,5,90,5,90,5,90,5,90,6,89,6,89,6,88,6,88,6,88,7,88,8,89,8,90,8,90,9,91,10,91,11,91,12,91,12,91,12,91,12,92,13,92,13,92,14,92,14,92,14,92,15,92,17,92,18,92,20,92,20,93,20,93,20,93,21,93,22,93,23,93,23,93,23,93,24,94,26,94,28,94,28,96,28,97,28,98,28,98,28,98,28,99,28,99,28,100,27,100,27,100,27,100,27,100,27,101,27,102,26,102,22,102,20,102,18,102,18,102,18,102,17,102,16,102,15,102,14,102,14,102,14,102,13,102,12,102,9,102,9,102,8,101;178,100,178,100,178,99,178,98,177,98,177,98,177,98,177,97,177,97,177,96,177,96,177,96,176,96,176,95,176,94,176,93,176,92,176,92,176,92,176,91,176,91,176,90,176,90,176,90,176,90,176,89,176,89,176,88,176,88,177,88,178,88,179,89,179,90,179,90,180,91,181,91,182,91,182,91,182,91,182,91,183,92,183,92,184,92,184,92,184,92,184,92,185,92,187,92,189,92,190,92,190,93,190,93,191,93,192,93,193,93,194,93,194,93,194,93,195,94,196,94,199,94,199,96,199,97,199,98,199,98,198,98,198,99,198,99,198,100,198,100,198,100,198,100,198,100,198,101,198,102,197,102,193,102,190,102,189,102,189,102,189,102,188,102,187,102,186,102,185,102,185,102,185,102,184,102,182,102,180,102,180,102,179,101;348,100,348,100,348,99,348,98,348,98,348,98,348,98,348,97,348,97,348,96,347,96,347,96,347,96,347,95,347,94,347,93,347,92,347,92,346,92,346,91,346,91,346,90,346,90,347,90,347,90,347,89,347,89,347,88,347,88,348,88,349,88,350,89,350,90,350,90,350,91,352,91,352,91,353,91,353,91,353,91,353,92,354,92,354,92,355,92,355,92,355,92,356,92,358,92,360,92,361,92,361,93,361,93,362,93,363,93,363,93,364,93,364,93,364,93,365,94,367,94,370,94,370,96,370,97,369,98,369,98,369,98,369,99,369,99,369,100,369,100,369,100,368,100,368,100,368,101,368,102,367,102,363,102,361,102,360,102,360,102,360,102,359,102,358,102,356,102,356,102,356,102,356,102,354,102,353,102,350,102,350,102,349,101;32,99,32,99,32,99,31,99,31,99,31,98,31,97,31,96,31,96,30,96,30,93,31,93,31,92,32,92,32,92,32,92,33,92,33,92,33,92,34,92,35,92,35,92,36,91,36,91,36,91,38,91,42,91,45,91,48,91,48,91,48,90,49,90,52,90,54,90,56,90,56,90,56,89,57,89,58,90,58,90,58,91,58,93,58,96,57,96,57,96,56,96,56,97,56,97,55,97,53,97,51,97,50,97,50,97,50,97,48,98,47,98,45,98,44,98,44,98,44,98,43,98,42,98,41,98,40,98,40,99,40,99,38,99,37,99,35,99,34,99,34,99,34,99,34,100,33,100,33,100,32,99,32,99;203,99,203,99,202,99,202,99,202,99,202,98,202,97,201,96,201,96,201,96,201,93,201,93,202,92,202,92,203,92,203,92,204,92,204,92,204,92,204,92,205,92,206,92,207,91,207,91,207,91,209,91,213,91,216,91,218,91,218,91,218,90,220,90,222,90,225,90,226,90,226,90,226,89,228,89,228,90,229,90,229,91,229,93,229,96,228,96,227,96,227,96,227,97,227,97,226,97,224,97,222,97,220,97,220,97,220,97,219,98,218,98,216,98,215,98,215,98,215,98,214,98,213,98,211,98,210,98,210,99,210,99,209,99,208,99,206,99,205,99,205,99,205,99,204,100,204,100,203,100,203,99,203,99;374,99,373,99,373,99,372,99,372,99,372,98,372,97,372,96,372,96,371,96,371,93,372,93,372,92,373,92,373,92,374,92,374,92,374,92,374,92,375,92,376,92,377,92,378,91,378,91,378,91,380,91,383,91,387,91,389,91,389,91,389,90,390,90,393,90,395,90,397,90,397,90,397,89,398,89,399,90,399,90,400,91,400,93,400,96,399,96,398,96,398,96,398,97,398,97,396,97,394,97,392,97,391,97,391,97,391,97,390,98,388,98,387,98,386,98,386,98,386,98,385,98,383,98,382,98,381,98,381,99,381,99,380,99,378,99,377,99,376,99,376,99,376,99,375,100,375,100,374,100,374,99,374,99;118,98,118,98,117,98,117,98,116,97,116,97,116,97,116,97,115,97,115,97,114,97,114,97,114,96,113,96,112,96,110,96,109,96,109,96,109,96,107,96,103,96,100,96,98,96,98,96,98,96,97,96,97,96,96,96,96,96,96,96,96,96,95,96,95,96,94,96,94,95,94,95,94,94,94,94,96,94,96,94,97,93,97,93,97,93,97,93,98,93,98,93,98,93,98,93,98,92,99,92,100,92,100,92,101,92,101,92,101,92,101,92,102,92,102,92,102,91,102,91,102,91,103,91,104,91,104,91,105,91,105,91,105,90,105,90,106,90,106,90,106,90,106,90,106,90,107,90,108,90,108,90,109,89,109,89,109,89,109,89,110,89,110,89,110,89,110,89,110,88,111,88,112,88,113,88,114,88,114,88,114,88,114,88,114,88,115,88,115,88,115,88,115,88,115,88,116,88,116,88,117,88,117,89,117,89,118,90,118,90,119,90,122,92,122,93,122,93,121,94,121,94,121,94,121,94,121,94,121,95,121,95,121,95,120,95,120,95,120,96,120,97,120,98,120,98,119,98,119,98,119,98,119,98,119,98,119,98,118,98,118,98,118,98;289,98,288,98,288,98,287,98,287,97,287,97,287,97,286,97,286,97,285,97,285,97,285,97,285,96,284,96,282,96,281,96,280,96,280,96,280,96,277,96,274,96,270,96,268,96,268,96,268,96,268,96,267,96,267,96,266,96,266,96,266,96,266,96,266,96,265,96,265,95,265,95,265,94,265,94,266,94,267,94,268,93,268,93,268,93,268,93,268,93,269,93,269,93,269,93,269,92,269,92,270,92,271,92,272,92,272,92,272,92,272,92,272,92,273,92,273,91,273,91,273,91,273,91,274,91,275,91,276,91,276,91,276,90,276,90,276,90,277,90,277,90,277,90,277,90,277,90,278,90,279,90,280,89,280,89,280,89,280,89,280,89,281,89,281,89,281,89,281,88,282,88,283,88,283,88,284,88,284,88,284,88,284,88,285,88,285,88,286,88,286,88,286,88,286,88,286,88,287,88,288,88,288,89,288,89,289,90,289,90,290,90,292,92,292,93,292,93,292,94,292,94,292,94,292,94,292,94,292,95,291,95,291,95,291,95,291,95,291,96,291,97,291,98,290,98,290,98,290,98,290,98,290,98,289,98,289,98,289,98,289,98,289,98;460,98,459,98,459,98,458,98,458,97,458,97,458,97,457,97,457,97,456,97,456,97,456,97,456,96,454,96,453,96,451,96,450,96,450,96,450,96,448,96,445,96,441,96,439,96,439,96,439,96,438,96,438,96,437,96,437,96,437,96,437,96,437,96,436,96,436,96,436,95,436,95,436,94,436,94,437,94,438,94,438,93,438,93,438,93,438,93,439,93,439,93,440,93,440,93,440,92,440,92,441,92,442,92,442,92,442,92,442,92,442,92,443,92,443,92,444,91,444,91,444,91,444,91,445,91,446,91,446,91,446,91,446,90,446,90,447,90,447,90,448,90,448,90,448,90,448,90,449,90,450,90,450,89,450,89,450,89,450,89,451,89,451,89,452,89,452,89,452,88,452,88,453,88,454,88,455,88,455,88,455,88,455,88,456,88,456,88,456,88,456,88,456,88,457,88,457,88,458,88,458,88,459,89,459,89,459,90,460,90,461,90,463,92,463,93,463,93,463,94,463,94,462,94,462,94,462,94,462,95,462,95,462,95,462,95,462,95,462,96,462,97,461,98,461,98,460,98,460,98,460,98,460,98,460,98,460,98,460,98,460,98,460,98;73,96,72,96,70,96,68,96,66,95,66,95,66,95,65,95,64,95,61,95,60,94,60,92,60,90,61,90,64,90,66,90,68,89,68,89,68,89,69,89,70,89,72,89,73,89,73,89,73,89,73,90,74,90,76,90,76,90,76,93,76,94,76,95,76,96,75,96,73,96,73,96;244,96,242,96,240,96,238,96,237,95,237,95,237,95,236,95,235,95,232,95,231,94,231,92,231,90,231,90,235,90,237,90,238,89,238,89,238,89,239,89,241,89,242,89,244,89,244,89,244,89,244,90,245,90,246,90,247,90,247,93,247,94,247,95,246,96,246,96,244,96,244,96;414,96,413,96,411,96,409,96,408,95,408,95,408,95,407,95,405,95,403,95,402,94,402,92,402,90,402,90,406,90,408,90,409,89,409,89,409,89,410,89,412,89,413,89,414,89,414,89,414,89,415,90,415,90,417,90,418,90,418,93,418,94,417,95,417,96,416,96,414,96,414,96;77,92,78,90,80,90,80,90,81,89,81,89,81,89,81,89,82,89,82,89,83,89,83,89,83,88,84,88,85,88,85,88,86,88,86,88,86,88,86,88,87,88,87,88,88,88,88,88,88,88,88,88,88,88,89,88,90,89,90,89,91,90,91,90,91,92,91,94,91,94,84,94,80,94,78,94,78,94;247,92,249,90,251,90,251,90,252,89,252,89,252,89,252,89,253,89,253,89,254,89,254,89,254,88,254,88,255,88,256,88,257,88,257,88,257,88,257,88,258,88,258,88,258,88,258,88,258,88,259,88,259,88,259,88,260,89,261,89,261,90,262,90,262,92,262,94,261,94,255,94,250,94,249,94,249,94;418,92,419,90,421,90,422,90,422,89,422,89,422,89,423,89,423,89,424,89,424,89,424,89,424,88,425,88,426,88,427,88,428,88,428,88,428,88,428,88,428,88,429,88,429,88,429,88,429,88,429,88,430,88,430,88,431,89,431,89,432,90,432,90,432,92,432,94,432,94,425,94,421,94,420,94,419,94;92,90,92,90,93,90,93,90,94,90,94,91,94,91,94,91,95,91,95,91,96,91,96,92,96,92,95,92,95,92,94,92,94,92,94,93,94,93,94,93,93,93,92,93,92,93,92,92;263,90,263,90,264,90,264,90,264,90,264,91,264,91,265,91,265,91,266,91,266,91,266,92,266,92,266,92,266,92,265,92,265,92,265,93,265,93,264,93,264,93,263,93,263,93,263,92;434,90,434,90,434,90,435,90,435,90,435,91,435,91,435,91,436,91,437,91,437,91,437,92,437,92,437,92,436,92,436,92,436,92,436,93,436,93,435,93,435,93,434,93,434,93,434,92;1,91,1,90,1,89,2,89,2,89,3,90,3,90,4,91,4,91,4,92,3,92,3,92,2,92,1,92,1,92;171,91,171,90,172,89,172,89,173,89,173,90,174,90,174,91,174,91,174,92,174,92,173,92,173,92,172,92,172,92;342,91,342,90,343,89,343,89,343,89,344,90,344,90,345,91,345,91,345,92,345,92,344,92,343,92,343,92,343,92;168,91,167,91,166,91,165,91,164,91,164,91,164,90,164,90,164,90,163,90,163,90,163,90,163,90,162,90,162,90,160,90,160,88,160,86,160,86,161,85,162,84,162,84,165,84,167,84,169,84,169,84,169,84,170,84,171,84,171,84,172,84,172,84,172,84,173,84,175,84,177,84,178,85,178,86,178,87,178,87,178,87,177,87,177,87,177,87,177,87,176,88,174,88,171,88,171,90,171,92,170,92,169,92,168,91,168,91;339,91,338,91,337,91,336,91,335,91,335,91,335,90,335,90,334,90,334,90,334,90,334,90,334,90,333,90,332,90,331,90,331,88,331,86,331,86,332,85,332,84,333,84,336,84,338,84,340,84,340,84,340,84,340,84,341,84,342,84,343,84,343,84,343,84,344,84,345,84,348,84,349,85,349,86,349,87,349,87,348,87,348,87,348,87,348,87,348,87,346,88,345,88,342,88,342,90,342,92,340,92,339,92,339,91,339,91;510,91,509,91,508,91,506,91,506,91,506,91,506,90,505,90,505,90,504,90,504,90,504,90,504,90,504,90,503,90,502,90,502,88,502,86,502,86,502,85,503,84,503,84,507,84,509,84,510,84,510,84,510,84,511,84,512,84,513,84,514,84,514,84,514,84,515,84,516,84,519,84,520,85,520,86,520,87,519,87,519,87,518,87,518,87,518,87,518,87,517,88,515,88,512,88,512,90,512,92,511,92,510,92,510,91,510,91;14,90,13,90,13,90,12,90,12,90,12,90,12,90,12,90,11,90,10,90,10,88,10,85,10,84,13,84,13,84,14,84,14,84,14,84,17,84,23,84,28,84,31,83,31,83,31,83,32,83,34,83,36,83,37,83,37,83,37,83,37,84,37,84,38,84,38,84,38,84,39,84,39,85,37,86,36,88,35,89,35,89,35,89,35,90,34,90,34,90,34,90,34,90,34,90,31,90,27,90,22,90,20,90,20,91,20,91,18,91,17,91,15,91,14,91,14,91;98,90,98,90,98,90,99,90,99,89,99,89,99,88,100,88,101,88,102,88,102,88,102,88,102,88,103,88,103,88,104,88,104,88,104,89,104,89,104,90,103,90,102,90,102,90,101,90,101,91,100,91,99,91,98,91,98,91,98,91;136,90,136,90,135,90,135,90,134,90,134,90,134,90,134,90,134,90,132,90,132,86,133,85,133,85,134,84,135,84,135,84,136,84,136,84,136,84,137,84,139,84,140,84,142,83,142,83,142,83,142,83,142,83,143,83,143,83,143,83,143,83,143,84,144,84,144,84,145,84,145,84,145,84,145,84,146,84,147,84,147,85,145,87,145,87,144,88,143,88,143,88,143,88,143,89,143,89,143,89,142,89,142,89,142,89,142,89,142,90,140,90,140,89,140,89,140,89,140,89,140,89,139,90,139,90,138,90,138,90,138,90,138,90,138,90,138,90,137,90,137,90,137,91,137,91,137,91,137,91,136,91,136,91,136,91;184,90,184,90,184,90,183,90,183,90,183,90,183,90,182,90,182,90,180,90,180,88,180,85,181,84,183,84,184,84,185,84,185,84,185,84,188,84,193,84,199,84,202,83,202,83,202,83,203,83,205,83,206,83,208,83,208,83,208,83,208,84,208,84,208,84,209,84,209,84,209,84,209,85,208,86,206,88,206,89,206,89,206,89,205,90,205,90,204,90,204,90,204,90,204,90,202,90,197,90,193,90,190,90,190,91,190,91,189,91,187,91,185,91,184,91,184,91;268,90,268,90,269,90,269,90,270,89,270,89,270,88,270,88,272,88,272,88,273,88,273,88,273,88,273,88,274,88,275,88,275,88,275,89,275,89,275,90,274,90,273,90,272,90,272,90,271,91,271,91,270,91,269,91,268,91,268,91;307,90,306,90,306,90,305,90,305,90,305,90,305,90,305,90,304,90,303,90,302,86,304,85,304,85,305,84,305,84,306,84,306,84,306,84,306,84,307,84,309,84,311,84,312,83,312,83,312,83,312,83,313,83,313,83,314,83,314,83,314,83,314,84,315,84,315,84,316,84,316,84,316,84,316,84,317,84,317,84,318,84,318,85,318,85,315,88,314,88,314,88,314,88,314,89,314,89,313,89,313,89,312,89,312,89,312,89,312,90,311,90,311,89,311,89,310,89,310,89,310,89,310,90,309,90,309,90,309,90,309,90,309,90,309,90,308,90,308,90,308,90,308,91,308,91,307,91,307,91,307,91,307,91,307,91;355,90,355,90,354,90,354,90,354,90,354,90,354,90,353,90,352,90,351,90,351,88,351,85,352,84,354,84,355,84,356,84,356,84,356,84,359,84,364,84,369,84,372,83,372,83,372,83,373,83,375,83,377,83,378,83,378,83,378,83,378,84,379,84,379,84,379,84,380,84,380,84,380,85,378,86,377,88,376,89,376,89,376,89,376,90,376,90,375,90,375,90,375,90,375,90,372,90,368,90,363,90,361,90,361,91,361,91,360,91,358,91,356,91,355,91,355,91;439,90,439,90,440,90,440,90,440,89,440,89,440,88,441,88,442,88,443,88,444,88,444,88,444,88,444,88,445,88,445,88,446,88,446,89,446,89,445,90,444,90,443,90,443,90,443,90,442,91,442,91,440,91,440,91,439,91,439,91;478,90,477,90,477,90,476,90,476,90,476,90,476,90,475,90,475,90,473,90,473,86,474,85,475,85,476,84,476,84,476,84,477,84,477,84,477,84,478,84,480,84,482,84,483,83,483,83,483,83,483,83,484,83,484,83,484,83,484,83,484,83,485,84,485,84,486,84,486,84,486,84,486,84,487,84,487,84,488,84,488,84,488,85,488,85,485,88,485,88,484,88,484,88,484,89,484,89,484,89,484,89,483,89,483,89,483,89,483,90,482,90,481,89,481,89,481,89,481,89,481,89,480,90,480,90,480,90,480,90,480,90,480,90,479,90,479,90,478,90,478,90,478,91,478,91,478,91,478,91,478,91,478,91,478,91;94,89,93,88,92,88,92,88,91,88,91,88,91,87,90,87,90,87,89,87,89,87,89,86,88,86,88,86,87,86,87,86,87,85,87,85,87,85,86,84,86,83,85,82,84,82,84,82,84,81,83,80,83,80,82,80,82,79,82,79,82,78,81,78,81,78,81,78,81,78,81,78,81,77,81,77,83,77,83,77,84,77,84,77,84,77,85,78,86,78,86,78,87,78,87,78,87,78,87,78,88,78,88,78,88,78,88,79,88,79,91,79,97,79,105,79,105,79,106,80,106,80,107,80,108,80,108,80,109,80,109,81,109,81,110,82,111,82,111,82,112,82,112,83,112,83,111,84,110,84,109,84,108,83,108,83,108,83,107,83,105,83,101,83,100,84,99,85,99,85,99,86,99,86,99,86,98,87,98,87,98,87,98,88,98,88,97,89,97,89,97,89,97,89,97,90,97,91,95,90,94,89;264,89,264,88,263,88,263,88,262,88,262,88,262,87,261,87,261,87,260,87,259,87,259,86,259,86,258,86,258,86,258,86,258,85,258,85,258,85,257,84,256,83,255,82,255,82,255,82,255,81,254,80,254,80,253,80,252,79,252,79,252,78,252,78,252,78,252,78,252,78,252,78,252,77,252,77,253,77,254,77,255,77,255,77,255,77,255,78,256,78,257,78,258,78,258,78,258,78,258,78,258,78,259,78,259,78,259,79,259,79,262,79,267,79,276,79,276,79,277,80,277,80,277,80,278,80,279,80,280,80,280,81,280,81,281,82,281,82,282,82,282,82,282,83,282,83,282,84,281,84,280,84,279,83,279,83,279,83,277,83,275,83,272,83,271,84,270,85,270,85,270,86,270,86,269,86,269,87,268,87,268,87,268,88,268,88,268,89,268,89,268,89,268,89,268,90,268,91,266,90,265,89;435,89,434,88,434,88,433,88,433,88,433,88,432,87,432,87,431,87,431,87,430,87,430,86,430,86,429,86,429,86,428,86,428,85,428,85,428,85,428,84,427,83,426,82,426,82,426,82,426,81,425,80,424,80,424,80,423,79,423,79,423,78,423,78,423,78,422,78,422,78,422,78,422,77,422,77,424,77,425,77,426,77,426,77,426,77,426,78,427,78,428,78,428,78,428,78,428,78,428,78,429,78,429,78,430,78,430,79,430,79,433,79,438,79,446,79,447,79,447,80,447,80,448,80,449,80,450,80,450,80,451,81,451,81,451,82,452,82,453,82,453,82,453,83,453,83,453,84,451,84,450,84,450,83,450,83,450,83,448,83,446,83,442,83,441,84,441,85,440,85,440,86,440,86,440,86,440,87,439,87,439,87,439,88,439,88,439,89,439,89,438,89,438,89,438,90,438,91,437,90,436,89;53,89,51,89,49,89,47,89,46,89,46,89,46,88,44,88,42,88,39,88,38,88,38,88,38,87,38,87,38,86,39,86,39,86,41,86,42,86,42,85,43,85,43,84,43,84,45,84,45,84,46,84,46,84,46,84,48,84,50,84,52,84,53,84,53,84,53,84,53,84,54,84,55,84,56,84,56,85,56,85,56,85,56,85,57,85,57,85,57,85,57,85,57,86,58,86,58,86,58,86,58,86,58,87,58,87,58,87,57,87,57,87,57,88,56,88,56,88,56,88,55,88,55,88,55,89,54,90,53,90,53,89;224,89,222,89,220,89,218,89,216,89,216,89,216,88,215,88,213,88,210,88,209,88,209,88,208,87,208,87,209,86,210,86,210,86,211,86,212,86,213,85,213,85,214,84,214,84,215,84,216,84,217,84,217,84,217,84,218,84,220,84,222,84,224,84,224,84,224,84,224,84,225,84,226,84,226,84,226,85,226,85,226,85,227,85,227,85,228,85,228,85,228,85,228,86,228,86,229,86,229,86,229,86,229,87,229,87,228,87,228,87,227,87,227,88,227,88,226,88,226,88,226,88,225,88,225,89,225,90,224,90,224,89;394,89,393,89,391,89,388,89,387,89,387,89,387,88,385,88,383,88,381,88,380,88,379,88,379,87,379,87,380,86,380,86,381,86,382,86,383,86,383,85,384,85,384,84,385,84,386,84,387,84,388,84,388,84,388,84,389,84,391,84,393,84,394,84,394,84,394,84,395,84,396,84,396,84,397,84,397,85,397,85,397,85,398,85,398,85,398,85,398,85,398,85,398,86,399,86,399,86,400,86,400,86,400,87,399,87,399,87,399,87,398,87,398,88,398,88,397,88,397,88,397,88,396,88,396,89,395,90,394,90,394,89;60,87,60,84,61,83,61,83,63,83,69,83,77,83,78,83,78,83,78,84,78,84,78,85,79,85,79,85,79,86,79,88,74,88,71,88,69,88,69,88,69,88,61,88,61,88;231,87,231,84,231,83,232,83,233,83,240,83,248,83,248,83,248,83,248,84,248,84,249,85,249,85,250,85,250,86,250,88,245,88,241,88,240,88,240,88,240,88,232,88,231,88;401,87,401,84,402,83,402,83,404,83,411,83,418,83,419,83,419,83,419,84,419,84,420,85,420,85,420,85,420,86,420,88,415,88,412,88,410,88,410,88,410,88,402,88,402,88;81,86,80,86,80,85,80,85,80,85,80,85,79,84,79,84,79,82,79,81,79,81,78,81,78,81,77,80,77,80,76,79,76,79,76,77,76,75,76,75,77,75,78,75,79,76,79,78,79,79,80,80,81,80,81,80,82,81,83,82,85,84,86,85,86,86,86,87,85,87,84,87,83,87,83,87,83,87,83,88,82,87,81,87;106,87,105,87,104,87,103,87,102,87,102,87,102,86,102,86,102,86,101,86,101,86,101,86,100,85,100,85,101,85,101,84,102,84,106,84,110,84,111,84,111,85,112,86,112,86,112,86,111,87,111,87,109,87,108,87,108,87,108,87,108,87,107,88,107,88,106,88,106,87,106,87;251,86,251,86,251,85,251,85,251,85,250,85,250,84,250,84,250,82,250,81,249,81,249,81,249,81,248,80,248,80,247,79,247,79,247,77,247,75,247,75,247,75,248,75,250,76,250,78,250,79,251,80,251,80,252,80,253,81,254,82,256,84,256,85,256,86,256,87,256,87,255,87,254,87,254,87,254,87,254,88,252,87,252,87;277,87,276,87,275,87,274,87,273,87,273,87,273,86,273,86,272,86,272,86,272,86,271,86,271,85,271,85,271,85,272,84,273,84,276,84,281,84,281,84,282,85,283,86,283,86,282,86,282,87,281,87,280,87,279,87,278,87,278,87,278,87,278,88,278,88,277,88,277,87,277,87;422,86,422,86,422,85,422,85,421,85,421,85,420,84,420,84,420,82,420,81,420,81,420,81,419,81,419,80,418,80,418,79,418,79,418,77,418,75,418,75,418,75,419,75,420,76,420,78,420,79,421,80,422,80,422,80,423,81,425,82,427,84,427,85,427,86,427,87,427,87,426,87,425,87,424,87,424,87,424,88,423,87,422,87;448,87,447,87,446,87,444,87,444,87,444,87,444,86,443,86,443,86,443,86,442,86,442,86,442,85,442,85,442,85,442,84,443,84,447,84,452,84,452,84,453,85,453,86,453,86,453,86,453,87,452,87,451,87,450,87,449,87,449,87,449,87,449,88,448,88,448,88,448,87,448,87;114,85,114,85,114,85,114,85,114,85,114,85,114,85,114,86,114,86,114,86,114,85,114,85;284,85,284,85,285,85,285,85,285,85,285,85,285,85,285,86,285,86,284,86,284,85,284,85;455,85,455,85,455,85,455,85,456,85,456,85,456,85,455,86,455,86,455,86,455,85,455,85;151,84,150,84,150,84,149,84,149,83,149,83,149,83,148,83,147,83,146,83,145,83,145,83,145,82,143,82,141,82,138,82,136,82,136,82,136,82,136,82,136,82,135,82,135,81,135,81,134,80,134,78,135,78,135,78,135,78,135,77,135,77,135,76,135,76,135,76,136,75,136,75,136,74,135,73,135,73,135,73,135,71,135,69,135,66,135,66,136,66,136,66,136,65,136,65,136,65,136,65,137,65,137,65,138,65,138,65,138,64,138,64,139,64,140,64,140,64,140,64,140,64,142,64,144,64,146,64,147,64,147,64,147,64,148,64,149,64,150,64,151,64,151,65,151,65,151,65,152,65,152,65,152,65,152,65,152,65,152,66,153,66,153,66,154,66,154,66,154,67,155,67,155,67,155,67,156,67,156,68,157,68,157,69,157,72,157,74,157,75,157,75,158,75,158,75,157,75,157,75,157,77,157,79,157,82,157,82,156,83,156,83,155,84,155,84,154,84,154,84,154,84,154,84,153,84,153,84,152,84,151,84,151,84;322,84,321,84,321,84,320,84,320,83,320,83,320,83,319,83,318,83,316,83,316,83,316,83,316,82,314,82,311,82,309,82,307,82,307,82,307,82,307,82,306,82,306,82,306,81,305,81,305,80,305,78,305,78,305,78,306,78,306,77,306,77,306,76,306,76,306,76,306,75,306,75,306,74,306,73,306,73,306,73,306,71,306,69,306,66,306,66,306,66,307,66,307,65,307,65,307,65,307,65,308,65,308,65,308,65,308,65,308,64,309,64,310,64,310,64,311,64,311,64,311,64,312,64,314,64,316,64,318,64,318,64,318,64,318,64,320,64,321,64,322,64,322,65,322,65,322,65,322,65,323,65,323,65,323,65,323,65,323,66,323,66,324,66,324,66,325,66,325,67,325,67,325,67,326,67,326,67,327,68,327,68,328,69,328,72,328,74,328,75,328,75,328,75,328,75,328,75,328,75,328,77,328,79,328,82,327,82,327,83,326,83,326,84,325,84,325,84,325,84,325,84,325,84,324,84,323,84,322,84,322,84,322,84;492,84,492,84,491,84,491,84,490,83,490,83,490,83,489,83,488,83,487,83,486,83,486,83,486,82,485,82,482,82,479,82,478,82,478,82,478,82,477,82,477,82,477,82,476,81,476,81,475,80,475,78,476,78,476,78,476,78,476,77,476,77,476,76,477,76,477,76,477,75,477,75,477,74,477,73,477,73,476,73,476,71,476,69,476,66,476,66,477,66,477,66,478,65,478,65,478,65,478,65,478,65,479,65,479,65,479,65,479,64,479,64,480,64,481,64,482,64,482,64,482,64,483,64,485,64,487,64,488,64,488,64,488,64,489,64,490,64,491,64,492,64,492,65,492,65,492,65,493,65,493,65,494,65,494,65,494,65,494,66,494,66,494,66,495,66,495,66,495,67,496,67,496,67,496,67,497,67,497,68,498,68,498,69,498,72,498,74,498,75,499,75,499,75,499,75,499,75,498,75,498,77,498,79,498,82,498,82,497,83,497,83,496,84,496,84,496,84,496,84,496,84,496,84,495,84,494,84,493,84,492,84,492,84;40,82,39,82,39,82,38,82,37,81,37,81,37,80,36,80,36,80,35,80,35,80,35,80,35,79,35,79,35,79,34,79,34,78,34,76,34,75,34,74,34,74,34,74,34,73,34,73,34,72,34,72,34,72,34,72,34,72,34,72,34,71,34,71,35,71,35,71,35,71,35,70,35,69,36,69,40,69,43,69,44,69,44,69,44,69,44,70,45,70,45,70,47,71,47,72,47,72,47,72,48,73,48,73,48,73,48,74,48,74,48,74,49,74,49,74,49,75,49,75,49,76,49,76,49,76,48,76,48,77,48,77,48,78,48,78,48,78,47,78,47,79,48,79,48,79,48,79,48,79,48,80,48,80,49,81,50,81,50,81,49,82,49,82,48,82,48,82,47,82,47,82,47,83,47,83,46,83,44,83,41,83,40,83,40,82;174,82,172,82,170,82,168,82,166,82,166,82,166,82,165,82,163,82,160,82,159,81,159,81,158,80,158,76,159,76,159,76,159,75,159,75,159,74,159,73,160,73,160,73,160,72,160,72,160,72,160,71,161,71,161,71,162,70,162,70,162,70,162,70,162,70,163,70,163,70,163,70,163,70,163,70,164,70,164,70,164,70,164,71,164,71,164,71,165,71,165,71,166,71,166,71,166,71,166,72,167,72,168,72,169,71,169,71,169,71,169,71,170,71,170,71,170,71,170,70,169,69,168,69,168,70,168,70,167,70,167,70,166,70,166,70,166,70,166,70,165,70,165,70,164,70,164,69,164,69,164,69,164,68,165,68,165,68,166,67,166,67,166,66,166,66,167,66,168,66,168,65,169,65,169,64,170,64,170,64,171,64,171,63,171,61,171,58,173,58,174,58,175,58,176,58,176,59,176,60,176,60,176,60,176,62,176,64,176,66,176,67,176,67,176,67,176,68,176,71,176,73,176,75,177,75,177,75,177,75,177,76,177,77,177,78,177,78,176,78,176,78,176,79,176,80,176,81,177,81,177,81,177,82,176,82,176,83,174,83,174,83;210,82,210,82,209,82,209,82,208,81,208,81,208,80,207,80,206,80,206,80,206,80,206,80,206,79,205,79,205,79,205,79,205,78,205,76,205,75,205,74,205,74,204,74,204,73,204,73,204,72,204,72,205,72,205,72,205,72,205,72,205,71,205,71,205,71,205,71,206,71,206,70,206,69,206,69,211,69,213,69,215,69,215,69,215,69,215,70,215,70,216,70,218,71,218,72,218,72,218,72,218,73,219,73,219,73,219,74,219,74,219,74,219,74,219,74,220,75,220,75,220,76,219,76,219,76,219,76,219,77,219,77,219,78,219,78,218,78,218,78,218,79,218,79,219,79,219,79,219,79,219,80,219,80,220,81,220,81,220,81,220,82,219,82,219,82,218,82,218,82,218,82,218,83,218,83,216,83,214,83,211,83,211,83,211,82;344,82,343,82,341,82,338,82,337,82,337,82,337,82,335,82,333,82,331,82,330,81,329,81,329,80,329,76,329,76,329,76,330,75,330,75,330,74,330,73,330,73,331,73,331,72,331,72,331,72,331,71,332,71,332,71,332,70,332,70,332,70,332,70,333,70,333,70,334,70,334,70,334,70,334,70,334,70,335,70,335,70,335,71,335,71,335,71,336,71,336,71,336,71,336,71,336,71,337,72,338,72,339,72,340,71,340,71,340,71,340,71,340,71,341,71,341,71,340,70,340,69,338,69,338,70,338,70,338,70,337,70,337,70,336,70,336,70,336,70,336,70,336,70,335,70,335,69,335,69,335,69,335,68,336,68,336,68,336,67,336,67,336,66,337,66,338,66,338,66,339,65,340,65,340,64,341,64,341,64,341,64,342,63,342,61,342,58,344,58,345,58,346,58,346,58,347,59,347,60,347,60,346,60,346,62,346,64,346,66,346,67,347,67,347,67,347,68,347,71,347,73,347,75,347,75,347,75,348,75,348,76,348,77,347,78,347,78,347,78,347,78,347,79,347,80,347,81,347,81,348,81,348,82,347,82,346,83,344,83,344,83;381,82,380,82,380,82,379,82,379,81,379,81,378,80,378,80,377,80,376,80,376,80,376,80,376,79,376,79,376,79,376,79,376,78,376,76,376,75,375,74,375,74,375,74,375,73,375,73,375,72,375,72,375,72,375,72,376,72,376,72,376,71,376,71,376,71,376,71,376,71,376,70,376,69,377,69,381,69,384,69,386,69,386,69,386,69,386,70,386,70,387,70,388,71,388,72,388,72,388,72,389,73,389,73,390,73,390,74,390,74,390,74,390,74,390,74,390,75,390,75,390,76,390,76,390,76,390,76,390,77,390,77,390,78,389,78,389,78,389,78,389,79,389,79,389,79,390,79,390,79,390,80,390,80,390,81,391,81,391,81,390,82,390,82,389,82,389,82,389,82,388,82,388,83,388,83,387,83,385,83,382,83,382,83,381,82;515,82,513,82,511,82,509,82,508,82,508,82,508,82,506,82,504,82,501,82,500,81,500,81,499,80,499,76,500,76,500,76,500,75,500,75,500,74,500,73,501,73,501,73,502,72,502,72,502,72,502,71,502,71,503,71,503,70,503,70,503,70,503,70,504,70,504,70,504,70,504,70,504,70,504,70,505,70,505,70,506,70,506,71,506,71,506,71,506,71,507,71,507,71,507,71,507,71,508,72,509,72,509,72,510,71,510,71,510,71,510,71,511,71,512,71,512,71,511,70,510,69,509,69,509,70,509,70,508,70,508,70,507,70,507,70,507,70,507,70,507,70,506,70,506,70,506,69,506,69,506,69,506,68,506,68,507,68,507,67,507,67,507,66,508,66,509,66,509,66,510,65,510,65,511,64,511,64,512,64,512,64,512,63,512,61,512,58,514,58,516,58,517,58,517,58,518,59,518,60,517,60,517,60,517,62,517,64,517,66,517,67,517,67,517,67,518,68,518,71,518,73,518,75,518,75,518,75,518,75,518,76,518,77,518,78,518,78,518,78,518,78,518,79,518,80,518,81,518,81,518,81,518,82,518,82,517,83,515,83,515,83;50,80,50,79,50,79,50,79,49,78,49,78,49,78,49,78,49,78,49,78,50,77,50,75,50,74,50,73,50,73,50,73,50,73,50,72,50,72,50,72,51,72,51,72,51,71,51,71,51,70,51,70,51,70,51,70,52,69,52,68,52,67,52,67,52,67,52,67,52,67,52,66,52,66,52,66,55,66,56,66,58,66,58,66,58,66,60,66,64,66,67,66,70,66,70,67,70,67,70,67,70,67,71,67,72,68,72,68,72,68,72,69,73,69,73,69,74,70,74,70,74,70,74,71,74,71,75,72,75,72,75,76,75,79,75,79,76,80,76,80,76,81,76,81,76,81,75,81,64,81,51,81,50,81;114,81,114,81,113,81,113,81,112,81,112,81,112,80,112,80,111,80,111,80,110,80,110,80,110,80,110,80,110,80,109,80,109,79,109,79,109,79,108,79,108,79,107,79,107,79,107,78,107,78,107,78,107,78,106,78,106,77,106,77,106,76,106,76,107,76,107,76,107,75,107,74,107,73,107,72,107,72,107,72,108,72,108,71,108,70,108,70,108,70,108,70,108,69,108,69,108,68,109,68,111,68,111,68,112,68,112,68,112,68,113,68,113,68,114,68,115,68,115,69,116,69,116,70,117,70,118,70,118,70,118,70,118,70,119,70,119,70,120,70,120,70,120,71,120,71,121,71,122,71,122,71,123,71,123,71,123,70,124,70,125,70,126,70,127,70,127,71,127,71,128,71,129,71,130,71,131,71,131,71,131,71,131,72,132,72,133,72,134,72,134,73,134,73,134,74,134,74,134,74,134,74,134,75,134,75,134,76,134,76,134,76,134,76,134,77,134,78,133,78,133,79,132,79,132,79,132,80,132,80,132,80,132,80,131,80,131,80,131,81,131,81,129,81,126,81,123,81,121,81,121,81,121,81,120,82,118,82,116,82,114,81,114,81;221,80,220,79,220,79,220,79,220,78,220,78,219,78,219,78,220,78,220,78,220,77,220,75,220,74,220,73,221,73,221,73,221,73,221,72,221,72,221,72,221,72,221,72,222,71,222,71,222,70,222,70,222,70,222,70,222,69,222,68,222,67,222,67,223,67,223,67,223,67,223,66,223,66,223,66,226,66,227,66,228,66,228,66,228,66,230,66,234,66,238,66,240,66,240,67,240,67,241,67,241,67,242,67,243,68,243,68,243,68,243,69,244,69,244,69,244,70,244,70,244,70,244,71,245,71,245,72,246,72,246,76,246,79,246,79,246,80,247,80,247,81,247,81,247,81,246,81,234,81,222,81,221,81;285,81,284,81,284,81,283,81,283,81,283,81,283,80,282,80,282,80,281,80,281,80,281,80,281,80,281,80,280,80,280,80,280,79,280,79,280,79,279,79,279,79,278,79,278,79,278,78,278,78,277,78,277,78,277,78,277,77,277,77,277,76,277,76,277,76,277,76,278,75,278,74,278,73,278,72,278,72,278,72,278,72,278,71,278,70,278,70,279,70,279,70,279,69,279,69,279,68,280,68,281,68,282,68,283,68,283,68,283,68,283,68,284,68,285,68,285,68,286,69,286,69,287,70,288,70,288,70,289,70,289,70,289,70,289,70,290,70,290,70,291,70,291,71,291,71,291,71,292,71,293,71,294,71,294,71,294,70,294,70,296,70,297,70,298,70,298,71,298,71,298,71,300,71,301,71,302,71,302,71,302,71,302,72,302,72,303,72,304,72,304,73,304,73,304,74,305,74,305,74,305,74,305,75,305,75,305,76,305,76,304,76,304,76,304,77,304,78,304,78,304,79,303,79,303,79,303,80,303,80,303,80,302,80,302,80,302,80,302,81,302,81,300,81,297,81,293,81,292,81,292,81,292,81,290,82,288,82,286,82,285,81,285,81;391,80,391,79,391,79,391,79,391,78,390,78,390,78,390,78,390,78,391,78,391,77,391,75,391,74,391,73,391,73,391,73,392,73,392,72,392,72,392,72,392,72,392,72,392,71,392,71,392,70,392,70,393,70,393,70,393,69,393,68,393,67,393,67,393,67,393,67,394,67,394,66,394,66,394,66,396,66,398,66,399,66,399,66,399,66,401,66,405,66,409,66,411,66,411,67,411,67,411,67,412,67,413,67,414,68,414,68,414,68,414,69,414,69,415,69,415,70,415,70,415,70,415,71,416,71,416,72,416,72,416,76,416,79,416,79,417,80,417,80,418,81,418,81,418,81,417,81,405,81,392,81,392,81;456,81,455,81,455,81,454,81,454,81,454,81,454,80,453,80,453,80,452,80,452,80,452,80,452,80,451,80,451,80,450,80,450,79,450,79,450,79,450,79,449,79,448,79,448,79,448,78,448,78,448,78,448,78,448,78,448,77,448,77,448,76,448,76,448,76,448,76,448,75,448,74,448,73,448,72,449,72,449,72,449,72,449,71,449,70,449,70,449,70,449,70,450,69,450,69,450,68,450,68,452,68,453,68,454,68,454,68,454,68,454,68,455,68,456,68,456,68,457,69,457,69,457,70,458,70,459,70,460,70,460,70,460,70,460,70,461,70,461,70,462,70,462,71,462,71,462,71,463,71,464,71,464,71,464,71,464,70,465,70,466,70,467,70,468,70,468,71,468,71,469,71,470,71,471,71,472,71,472,71,472,71,473,72,473,72,474,72,475,72,475,73,475,73,475,74,475,74,475,74,476,74,476,75,476,75,475,76,475,76,475,76,475,76,475,77,475,78,475,78,474,79,474,79,474,79,474,80,474,80,473,80,473,80,472,80,472,80,472,81,472,81,470,81,467,81,464,81,462,81,462,81,462,81,461,82,459,82,457,82,456,81,456,81;10,80,10,80,10,80,9,80,8,79,8,78,8,78,8,78,9,78,9,78,10,77,10,77,10,76,11,76,11,76,11,76,12,76,12,76,12,75,13,75,13,75,13,75,14,75,14,74,14,74,15,74,15,74,15,74,16,73,16,73,16,72,17,72,17,72,17,72,18,72,18,72,18,71,19,71,19,71,19,71,20,71,20,70,20,70,21,70,21,70,21,70,22,69,22,69,22,68,23,68,23,68,24,68,24,68,25,68,25,67,25,67,25,67,26,67,27,68,27,68,27,69,27,69,27,69,27,69,28,69,28,70,28,70,28,70,28,70,28,70,28,71,28,71,28,72,28,72,29,73,29,73,30,73,30,74,30,74,30,75,30,75,30,75,30,75,30,76,30,76,30,76,31,76,31,76,31,77,31,77,31,78,31,78,32,79,32,79,32,80,32,80,31,81,29,81,21,81,14,81,10,81,10,81;181,80,181,80,180,80,180,80,179,79,179,78,179,78,179,78,179,78,180,78,180,77,181,77,181,76,181,76,182,76,182,76,182,76,183,76,183,75,183,75,184,75,184,75,184,75,185,74,185,74,185,74,186,74,186,74,186,73,187,73,187,72,187,72,188,72,188,72,188,72,189,72,189,71,189,71,190,71,190,71,190,71,191,70,191,70,191,70,192,70,192,70,192,69,193,69,193,68,193,68,194,68,194,68,195,68,195,68,195,67,196,67,196,67,197,67,198,68,198,68,198,69,198,69,198,69,198,69,198,69,198,70,198,70,198,70,199,70,199,70,199,71,199,71,199,72,199,72,200,73,200,73,200,73,200,74,200,74,200,75,201,75,201,75,201,75,201,76,201,76,201,76,201,76,201,76,202,77,202,77,202,78,202,78,202,79,203,79,203,80,202,80,202,81,200,81,191,81,185,81,181,81,181,81;352,80,351,80,351,80,350,80,350,79,350,78,350,78,350,78,350,78,350,78,351,77,351,77,351,76,352,76,352,76,352,76,353,76,353,76,353,75,354,75,354,75,354,75,355,75,355,74,355,74,356,74,356,74,356,74,357,73,357,73,357,72,358,72,358,72,358,72,359,72,359,72,359,71,360,71,360,71,360,71,361,71,361,70,361,70,362,70,362,70,362,70,363,69,363,69,363,68,364,68,365,68,365,68,366,68,366,68,366,67,367,67,367,67,367,67,368,68,368,68,368,69,368,69,369,69,369,69,369,69,369,70,369,70,369,70,369,70,369,70,370,71,370,71,370,72,370,72,370,73,371,73,371,73,371,74,371,74,371,75,371,75,371,75,372,75,372,76,372,76,372,76,372,76,372,76,372,77,372,77,372,78,372,78,373,79,374,79,374,80,373,80,373,81,371,81,362,81,355,81,352,81,352,81;90,76,90,76,91,76,92,76,93,76,93,76,93,76,94,76,95,76,96,76,97,75,97,75,97,75,98,75,100,75,102,75,103,75,103,74,103,74,103,74,104,75,105,76,105,76,104,77,104,77,102,78,97,78,90,78,90,77,90,77;260,76,260,76,262,76,263,76,264,76,264,76,264,76,264,76,266,76,267,76,268,75,268,75,268,75,269,75,270,75,273,75,273,75,274,74,274,74,274,74,275,75,276,76,276,76,275,77,275,77,273,78,267,78,260,78,260,77,260,77;431,76,431,76,433,76,433,76,434,76,434,76,434,76,435,76,436,76,437,76,438,75,438,75,438,75,439,75,441,75,443,75,444,75,444,74,444,74,445,74,445,75,446,76,446,76,446,77,445,77,444,78,438,78,431,78,431,77,431,77;7,68,7,68,9,68,10,68,10,67,10,67,10,67,12,67,14,67,17,67,17,67,18,68,18,68,19,68,19,68,19,68,20,68,20,69,20,69,19,70,19,70,19,70,18,70,18,70,18,71,17,71,17,71,17,71,16,71,16,72,16,72,15,72,15,72,15,72,14,72,14,73,14,73,13,74,13,74,13,74,12,74,12,74,12,75,11,75,11,75,11,75,10,75,10,76,9,76,9,76,8,76,7,76,7,72;178,68,178,68,180,68,180,68,181,67,181,67,181,67,182,67,184,67,188,67,188,67,189,68,189,68,189,68,190,68,190,68,190,68,190,69,190,69,190,70,190,70,189,70,189,70,189,70,188,71,188,71,188,71,187,71,187,71,187,72,186,72,186,72,186,72,185,72,185,72,185,73,184,73,184,74,184,74,183,74,183,74,183,74,182,75,182,75,182,75,181,75,181,75,181,76,180,76,180,76,179,76,178,76,178,72;348,68,348,68,350,68,351,68,352,67,352,67,352,67,353,67,355,67,358,67,359,67,359,68,359,68,360,68,360,68,361,68,361,68,361,69,361,69,361,70,360,70,360,70,359,70,359,70,359,71,358,71,358,71,358,71,357,71,357,72,357,72,356,72,356,72,356,72,355,72,355,73,355,73,354,74,354,74,354,74,353,74,353,74,353,75,352,75,352,75,352,75,351,75,351,76,351,76,350,76,349,76,348,76,348,72;30,72,30,71,30,70,30,70,29,70,29,70,29,70,29,69,29,69,29,68,29,68,30,68,30,68,31,68,31,69,31,69,31,69,32,69,33,69,34,70,34,70,34,70,31,73,31,73,31,73,31,72,30,72;201,72,200,71,200,70,200,70,200,70,200,70,200,70,200,69,200,69,200,68,200,68,201,68,201,68,202,68,202,69,202,69,202,69,202,69,203,69,204,70,204,70,204,70,202,73,202,73,202,73,201,72,201,72;371,72,371,71,371,70,371,70,371,70,371,70,370,70,370,69,370,69,370,68,370,68,371,68,372,68,372,68,372,69,372,69,373,69,373,69,374,69,375,70,375,70,375,70,373,73,372,73,372,73,372,72,372,72;131,70,130,70,130,70,128,70,128,69,128,69,128,67,130,66,132,66,133,66,134,66,134,68,134,69,133,69,133,70,132,70,131,70,131,70;302,70,301,70,300,70,299,70,299,69,299,69,299,67,301,66,302,66,304,66,304,66,304,68,304,69,304,69,304,70,303,70,302,70,302,70;472,70,472,70,471,70,470,70,470,69,470,69,470,67,472,66,473,66,474,66,475,66,475,68,475,69,475,69,474,70,474,70,472,70,472,70;160,68,159,68,159,68,159,68,158,68,158,68,158,67,157,67,157,67,157,67,156,66,156,66,155,65,154,65,154,65,154,65,154,65,154,65,154,64,153,64,153,64,152,64,152,64,152,64,152,64,152,64,151,64,151,64,150,63,150,63,150,63,150,63,150,63,149,63,149,62,148,62,147,61,146,60,147,60,147,60,148,59,148,59,148,58,148,58,148,58,148,58,148,58,148,57,148,56,148,56,149,56,149,56,150,56,150,56,150,55,151,55,152,55,154,55,154,55,155,56,155,56,155,56,156,56,157,56,158,56,158,57,158,57,159,58,159,58,159,58,160,58,161,59,161,60,162,60,162,60,162,60,163,61,163,61,164,62,164,62,164,65,164,67,164,68,162,68,162,68,162,68,162,69,162,69,161,69,161,69,160,69,160,69,160,69;330,68,330,68,330,68,329,68,329,68,329,68,328,67,328,67,328,67,327,67,327,66,326,66,326,65,325,65,325,65,324,65,324,65,324,65,324,64,324,64,324,64,323,64,323,64,323,64,323,64,322,64,322,64,321,64,321,63,321,63,321,63,321,63,320,63,320,63,318,61,318,60,318,60,318,60,318,60,318,60,318,59,318,59,318,58,318,58,319,58,319,58,319,58,319,57,319,56,319,56,319,56,320,56,320,56,321,56,321,55,321,55,323,55,324,55,325,55,325,56,325,56,326,56,327,56,328,56,328,56,329,57,329,57,329,58,329,58,330,58,330,58,331,59,332,60,333,60,333,60,333,60,334,61,334,61,335,62,335,62,335,65,335,67,334,68,333,68,333,68,332,68,332,69,332,69,332,69,331,69,331,69,330,69,330,69;501,68,501,68,500,68,500,68,499,68,499,68,499,67,498,67,498,67,498,67,497,66,497,66,496,65,496,65,495,65,495,65,495,65,495,65,495,64,495,64,494,64,494,64,494,64,494,64,494,64,493,64,493,64,492,64,492,63,492,63,492,63,491,63,491,63,490,63,488,61,488,60,488,60,488,60,489,60,489,60,489,59,489,59,489,58,489,58,489,58,489,58,490,58,490,57,490,56,490,56,490,56,490,56,491,56,491,56,492,55,492,55,494,55,495,55,495,55,496,56,496,56,497,56,498,56,498,56,499,56,499,57,499,57,500,58,500,58,500,58,501,58,502,59,503,60,503,60,503,60,504,60,504,61,505,61,505,62,506,62,506,65,506,67,505,68,504,68,503,68,503,68,503,69,503,69,502,69,502,69,501,69,501,69,501,69;46,68,43,68,38,68,33,68,30,67,30,67,30,67,29,67,29,67,27,67,27,63,27,61,27,60,27,60,27,60,28,59,28,59,28,58,29,57,30,57,30,57,31,57,31,57,31,57,31,58,32,58,33,58,34,58,34,58,34,58,34,58,34,58,34,58,35,58,36,58,38,58,38,57,39,57,39,56,39,56,40,56,40,56,41,56,41,56,42,55,44,55,44,55,44,56,45,57,46,57,46,57,46,57,46,57,46,57,47,58,48,58,49,58,50,58,50,58,50,58,50,59,50,59,50,59,50,59,50,59,50,59,50,60,50,61,50,62,50,63,50,63,51,63,51,64,51,64,51,65,51,65,51,65,52,65,52,65,51,65,51,65,51,66,51,66,51,66,50,67,50,67,49,68,49,68,47,68,46,68,46,68,46,68;99,68,98,68,98,68,97,68,96,67,96,67,96,67,95,67,95,67,94,67,93,67,93,67,93,66,93,66,92,66,92,66,92,66,92,66,92,66,91,66,91,66,90,66,90,65,90,65,90,64,89,64,89,64,89,64,89,64,89,64,89,63,89,63,89,63,89,63,90,62,90,62,90,61,90,60,90,60,91,60,91,59,91,59,91,59,91,58,92,58,92,58,92,57,92,57,92,57,92,56,93,56,93,56,94,55,94,55,94,55,94,54,94,54,95,54,95,53,95,53,95,52,98,50,98,50,99,50,99,49,99,49,99,48,100,49,101,50,101,50,102,51,102,51,103,51,104,52,104,53,104,54,104,54,105,55,105,55,106,55,106,56,106,56,106,57,106,57,107,57,107,58,107,58,107,58,107,59,108,59,108,60,108,60,108,62,108,64,108,64,108,64,107,64,107,64,107,65,106,65,106,66,105,66,104,66,103,66,103,66,103,67,102,67,102,67,102,67,101,67,101,68,101,68,99,68,99,68;216,68,213,68,209,68,204,68,201,67,201,67,201,67,200,67,199,67,198,67,198,63,198,61,198,60,198,60,198,60,198,59,198,59,198,58,200,57,201,57,201,57,202,57,202,57,202,57,202,58,203,58,204,58,204,58,204,58,204,58,205,58,205,58,205,58,206,58,207,58,208,58,209,57,209,57,209,56,210,56,211,56,211,56,212,56,212,56,212,55,215,55,215,55,215,56,216,57,216,57,217,57,217,57,217,57,217,57,218,58,219,58,220,58,220,58,220,58,220,58,220,59,221,59,221,59,221,59,221,59,220,59,220,60,220,61,220,62,220,63,221,63,221,63,222,64,222,64,222,65,222,65,222,65,222,65,222,65,222,65,222,65,222,66,222,66,222,66,221,67,221,67,220,68,220,68,218,68,217,68,216,68,216,68;270,68,269,68,268,68,267,68,267,67,267,67,267,67,266,67,265,67,264,67,264,67,264,67,264,66,263,66,263,66,262,66,262,66,262,66,262,66,262,66,261,66,260,66,260,65,260,65,260,64,260,64,260,64,260,64,260,64,260,64,260,63,260,63,260,63,260,63,260,62,260,62,260,61,260,60,261,60,261,60,262,59,262,59,262,59,262,58,262,58,263,58,263,57,263,57,263,57,263,56,264,56,264,56,264,55,264,55,264,55,264,54,265,54,265,54,266,53,266,53,266,52,268,50,269,50,269,50,270,49,270,49,270,48,271,49,272,50,272,50,273,51,273,51,273,51,275,52,275,53,275,54,275,54,276,55,276,55,276,55,276,56,276,56,276,57,277,57,277,57,278,58,278,58,278,58,278,59,278,59,279,60,279,60,279,62,279,64,279,64,278,64,278,64,277,64,277,65,277,65,276,66,276,66,275,66,274,66,274,66,274,67,273,67,273,67,273,67,272,67,272,68,271,68,270,68,270,68;387,68,384,68,379,68,374,68,372,67,372,67,372,67,371,67,370,67,368,67,368,63,368,61,368,60,369,60,369,60,369,59,369,59,369,58,370,57,371,57,372,57,372,57,372,57,372,57,373,58,373,58,374,58,375,58,375,58,375,58,375,58,375,58,375,58,376,58,377,58,379,58,379,57,380,57,380,56,381,56,381,56,382,56,382,56,383,56,383,55,386,55,386,55,386,56,386,57,387,57,387,57,388,57,388,57,388,57,388,58,389,58,391,58,391,58,391,58,391,58,391,59,391,59,392,59,392,59,391,59,391,59,391,60,391,61,391,62,391,63,392,63,392,63,392,64,392,64,392,65,392,65,393,65,393,65,393,65,393,65,392,65,392,66,392,66,392,66,392,67,391,67,391,68,390,68,389,68,388,68,387,68,387,68;440,68,440,68,439,68,438,68,438,67,438,67,438,67,437,67,436,67,435,67,434,67,434,67,434,66,434,66,434,66,433,66,433,66,433,66,433,66,432,66,432,66,431,66,431,65,431,65,431,64,431,64,431,64,430,64,430,64,430,64,430,63,430,63,431,63,431,63,431,62,431,62,431,61,431,60,432,60,432,60,432,59,432,59,432,59,432,58,433,58,433,58,434,57,434,57,434,57,434,56,434,56,435,56,435,55,435,55,435,55,435,54,436,54,436,54,436,53,436,53,436,52,439,50,440,50,440,50,440,49,440,49,440,48,441,49,442,50,443,50,443,51,443,51,444,51,446,52,446,53,446,54,446,54,446,55,447,55,447,55,447,56,447,56,447,57,448,57,448,57,448,58,448,58,448,58,448,59,449,59,449,60,450,60,450,62,450,64,449,64,449,64,449,64,448,64,448,65,448,65,447,66,446,66,445,66,445,66,445,66,444,67,444,67,444,67,443,67,443,67,443,68,442,68,440,68,440,68;18,65,18,65,18,61,18,56,19,56,21,56,21,56,22,57,22,57,23,58,23,58,23,58,23,59,24,59,24,59,24,60,24,61,24,61,24,62,25,62,25,62,25,62,25,62,25,63,25,63,25,63,24,63,24,63,24,64,24,64,24,64,25,64,25,64,25,64,25,65,25,65,25,66,25,66,24,66,24,66,24,66,24,67,24,67,22,67,19,67,19,67,18,66;188,65,188,65,188,61,188,56,190,56,192,56,192,56,193,57,193,57,194,58,194,58,194,58,194,59,194,59,195,59,195,60,195,61,195,61,195,62,195,62,195,62,196,62,196,62,196,63,195,63,195,63,195,63,195,63,195,64,195,64,195,64,195,64,195,64,196,64,196,65,196,65,195,66,195,66,195,66,195,66,195,66,195,67,195,67,192,67,190,67,190,67,189,66;359,65,359,65,359,61,359,56,361,56,362,56,363,56,363,57,364,57,364,58,364,58,364,58,364,59,365,59,365,59,366,60,366,61,366,61,366,62,366,62,366,62,366,62,366,62,366,63,366,63,366,63,366,63,366,63,366,64,366,64,366,64,366,64,366,64,366,64,366,65,366,65,366,66,366,66,366,66,366,66,366,66,366,67,365,67,363,67,361,67,360,67,360,66;6,65,6,64,6,63,6,62,6,61,7,61,7,61,7,60,7,60,7,59,7,59,9,59,9,59,10,59,10,59,10,58,10,58,11,58,11,58,12,58,12,58,12,58,13,58,14,58,16,58,16,61,16,65,16,66,13,66,12,66,12,66,12,66,12,66,11,66,10,66,8,66,8,66,7,65;117,66,117,66,116,66,116,66,115,65,115,65,115,64,114,64,114,64,114,64,113,64,113,63,111,62,113,59,115,59,116,59,116,59,116,59,116,58,116,58,117,58,117,58,118,58,118,58,118,58,118,58,118,58,118,58,119,57,119,57,119,56,120,56,120,56,121,56,121,56,121,56,121,56,121,56,122,56,122,56,122,55,122,55,122,55,123,55,124,55,125,55,126,55,126,54,126,54,126,54,126,54,126,55,127,55,127,55,129,55,131,57,131,58,131,59,131,60,131,60,132,60,132,61,131,61,130,62,130,62,129,62,129,62,129,62,129,63,129,63,129,63,128,63,128,63,127,63,127,64,126,65,125,66,125,66,124,66,124,66,124,66,124,66,123,66,121,66,118,66,117,66,117,66;177,65,177,64,177,63,177,62,177,61,177,61,177,61,178,60,178,60,178,59,178,59,179,59,180,59,181,59,181,59,181,58,181,58,182,58,182,58,182,58,182,58,182,58,183,58,185,58,187,58,187,61,187,65,187,66,184,66,183,66,182,66,182,66,182,66,181,66,180,66,179,66,178,66,178,65;288,66,287,66,287,66,287,66,286,65,286,65,286,64,285,64,285,64,285,64,284,64,284,63,282,62,283,59,286,59,286,59,287,59,287,59,287,58,287,58,288,58,288,58,288,58,288,58,288,58,288,58,289,58,289,58,290,57,290,57,290,56,291,56,291,56,291,56,292,56,292,56,292,56,292,56,292,56,293,56,293,55,293,55,293,55,294,55,294,55,295,55,296,55,296,54,296,54,297,54,297,54,297,55,297,55,298,55,300,55,302,57,302,58,302,59,302,60,302,60,302,60,302,61,301,61,301,62,300,62,300,62,300,62,300,62,300,63,300,63,299,63,299,63,299,63,298,63,297,64,296,65,296,66,295,66,295,66,295,66,295,66,295,66,293,66,291,66,289,66,288,66,288,66;348,65,348,64,348,63,348,62,348,61,348,61,348,61,348,60,348,60,348,59,348,59,350,59,351,59,352,59,352,59,352,58,352,58,352,58,353,58,353,58,353,58,353,58,354,58,355,58,358,58,358,61,358,65,357,66,355,66,354,66,353,66,353,66,353,66,352,66,351,66,349,66,349,66,348,65;458,66,458,66,458,66,457,66,457,65,457,65,456,64,456,64,456,64,455,64,455,64,454,63,453,62,454,59,456,59,457,59,458,59,458,59,458,58,458,58,458,58,459,58,459,58,459,58,459,58,459,58,459,58,460,58,460,57,461,57,461,56,461,56,462,56,462,56,462,56,462,56,462,56,462,56,463,56,463,56,464,55,464,55,464,55,464,55,465,55,466,55,467,55,467,54,467,54,467,54,467,54,467,55,468,55,469,55,470,55,472,57,472,58,472,59,472,60,473,60,473,60,473,61,472,61,472,62,471,62,471,62,470,62,470,62,470,63,470,63,470,63,470,63,469,63,469,63,468,64,467,65,466,66,466,66,466,66,466,66,466,66,466,66,464,66,462,66,460,66,458,66,458,66;74,64,72,64,68,64,64,64,62,64,62,64,61,63,61,62,62,62,62,62,62,62,62,62,62,61,63,60,64,60,64,59,65,58,66,58,66,58,66,58,66,58,66,58,67,58,67,58,68,58,68,57,69,57,69,56,69,56,70,56,70,56,71,56,71,56,72,55,72,55,74,55,75,55,76,55,76,55,76,54,77,54,78,54,79,54,80,54,80,54,80,54,81,54,82,54,82,54,83,53,83,53,83,53,83,53,84,53,84,53,84,53,84,53,84,52,87,52,88,53,88,53,88,54,88,54,88,54,88,55,89,55,89,55,89,55,89,56,89,57,89,58,89,58,90,58,90,59,89,60,88,60,88,61,88,61,88,62,88,62,88,62,88,62,88,62,88,63,88,63,87,64,87,64,86,65,86,65,80,65,76,65,74,65,74,65;245,64,243,64,239,64,234,64,233,64,233,64,232,63,232,62,233,62,233,62,233,62,233,62,233,61,236,58,236,58,237,58,237,58,237,58,237,58,237,58,238,58,238,58,239,57,239,57,239,56,240,56,241,56,241,56,242,56,242,56,242,55,243,55,244,55,245,55,246,55,246,55,246,54,247,54,249,54,250,54,251,54,251,54,251,54,251,54,252,54,253,54,254,53,254,53,254,53,254,53,254,53,255,53,255,53,255,53,255,52,258,52,258,53,259,53,259,54,259,54,259,54,259,55,259,55,259,55,260,55,260,56,260,57,260,58,260,58,260,58,260,59,260,60,259,60,259,61,259,61,259,62,259,62,259,62,258,62,258,62,258,63,258,63,258,64,257,64,257,65,256,65,251,65,247,65,245,65,245,65;416,64,413,64,410,64,405,64,404,64,403,64,403,63,403,62,403,62,403,62,404,62,404,62,404,61,406,58,407,58,407,58,408,58,408,58,408,58,408,58,408,58,409,58,410,57,410,57,410,56,411,56,411,56,412,56,412,56,413,56,413,55,413,55,415,55,416,55,417,55,417,55,417,54,418,54,419,54,421,54,422,54,422,54,422,54,422,54,423,54,424,54,424,53,424,53,424,53,424,53,425,53,425,53,426,53,426,53,426,52,428,52,429,53,429,53,430,54,430,54,430,54,430,55,430,55,430,55,430,55,430,56,430,57,430,58,431,58,431,58,431,59,430,60,430,60,430,61,430,61,430,62,429,62,429,62,429,62,429,62,429,63,429,63,428,64,428,64,427,65,427,65,421,65,418,65,416,65,416,65;51,62,51,59,52,58,52,58,53,58,53,58,53,58,54,57,55,56,57,54,59,54,61,54,62,54,62,54,62,54,62,54,62,54,63,54,63,54,63,55,63,55,64,55,65,55,67,55,68,55,68,56,68,56,67,56,67,56,67,56,65,57,64,59,62,60,61,62,61,62,61,62,60,62,60,62,60,63,59,63,59,63,58,63,58,63,58,63,58,63,57,63,55,63,53,63,52,63,52,63;221,62,221,59,222,58,223,58,223,58,224,58,224,58,225,57,226,56,228,54,230,54,231,54,232,54,232,54,232,54,232,54,233,54,233,54,234,54,234,55,234,55,235,55,236,55,238,55,238,55,238,56,238,56,238,56,238,56,237,56,236,57,235,59,233,60,232,62,231,62,231,62,231,62,231,62,230,63,230,63,229,63,229,63,229,63,229,63,229,63,228,63,226,63,223,63,223,63,222,63;392,62,392,59,393,58,393,58,394,58,394,58,394,58,395,57,397,56,398,54,401,54,402,54,403,54,403,54,403,54,403,54,404,54,404,54,404,54,404,55,404,55,405,55,407,55,409,55,409,55,409,56,409,56,409,56,408,56,408,56,407,57,405,59,404,60,402,62,402,62,402,62,401,62,401,62,401,63,400,63,400,63,400,63,400,63,400,63,400,63,398,63,397,63,394,63,394,63,393,63;146,62,146,62,145,62,144,62,144,62,143,62,143,61,143,61,143,61,144,60,146,60,146,61,146,61,146,62,146,62,147,62,147,63,147,63,146,63,146,63,146,63;167,62,166,62,166,62,166,62,165,61,165,60,164,59,163,59,163,59,163,59,162,58,161,58,160,57,160,56,159,56,159,56,159,56,159,54,159,53,159,52,160,52,161,52,163,54,163,54,163,55,163,55,163,55,163,55,164,55,164,56,164,56,164,56,166,56,167,56,168,56,168,57,168,57,168,57,168,57,169,57,170,58,170,60,170,60,170,61,170,61,170,61,170,61,170,62,170,63,169,63,169,63,168,63,167,63,167,62;317,62,316,62,316,62,315,62,314,62,314,62,314,61,314,61,314,61,315,60,316,60,316,61,316,61,316,62,317,62,318,62,318,63,317,63,317,63,317,63,317,63;338,62,337,62,337,62,337,62,336,61,335,60,334,59,334,59,334,59,333,59,333,58,332,58,331,57,330,56,330,56,330,56,330,56,330,54,330,53,330,52,331,52,331,52,334,54,334,54,334,55,334,55,334,55,334,55,334,55,334,56,334,56,334,56,336,56,337,56,338,56,338,57,338,57,338,57,339,57,340,57,341,58,341,60,341,60,341,61,341,61,340,61,340,61,340,62,340,63,340,63,339,63,339,63,338,63,338,62;488,62,487,62,486,62,486,62,485,62,485,62,484,61,484,61,485,61,485,60,487,60,487,61,487,61,487,62,488,62,488,62,488,63,488,63,488,63,488,63,488,63;508,62,508,62,508,62,507,62,507,61,506,60,505,59,504,59,504,59,504,59,503,58,503,58,502,57,501,56,501,56,500,56,500,56,500,54,500,53,501,52,501,52,502,52,504,54,504,54,504,55,504,55,505,55,505,55,505,55,505,56,505,56,505,56,507,56,508,56,509,56,509,57,509,57,509,57,509,57,510,57,512,58,512,60,512,60,511,61,511,61,511,61,511,61,511,62,511,63,511,63,510,63,509,63,509,63,509,62;136,62,135,62,135,62,134,62,134,61,133,61,133,61,133,60,133,60,133,59,133,59,133,59,132,59,132,58,132,58,132,57,132,57,132,57,131,57,131,56,132,56,132,56,132,56,132,56,132,55,135,52,136,52,136,52,137,52,137,52,137,52,137,52,138,52,139,52,140,51,140,51,140,51,140,51,141,51,143,51,143,51,143,52,143,52,143,52,143,52,143,52,144,54,144,56,144,58,143,59,143,59,143,59,143,59,143,59,143,60,141,62,140,62,140,62,140,62,140,62,140,62,139,62,138,62,136,62,136,62,136,62;306,62,306,62,305,62,304,62,304,61,304,60,304,59,303,59,303,59,303,59,303,58,303,58,303,57,303,57,302,57,302,57,302,56,302,56,303,56,303,56,303,56,303,55,306,52,307,52,307,52,308,52,308,52,308,52,308,52,309,52,310,52,310,51,310,51,310,51,311,51,312,51,313,51,314,51,314,52,314,52,314,52,314,52,314,52,314,54,314,56,314,58,314,59,314,59,314,59,314,59,314,59,314,60,312,62,311,62,311,62,310,62,310,62,310,62,309,62,308,62,307,62,306,62,306,62;477,62,476,62,476,62,475,62,474,61,474,60,474,59,474,59,474,59,474,59,474,58,474,58,474,57,473,57,473,57,473,57,473,56,473,56,473,56,474,56,474,56,474,55,476,52,477,52,478,52,478,52,478,52,478,52,479,52,480,52,480,52,481,51,481,51,481,51,482,51,483,51,484,51,484,51,484,52,484,52,484,52,485,52,485,52,485,54,485,56,485,58,485,59,485,59,484,59,484,59,484,59,484,60,483,62,482,62,481,62,481,62,481,62,481,62,480,62,479,62,478,62,477,62,477,62;51,57,51,57,50,57,50,57,50,57,50,57,50,56,49,56,48,56,47,56,47,56,47,56,46,55,46,55,46,55,45,55,44,54,44,53,44,53,44,53,44,53,44,53,44,52,44,51,44,49,44,48,44,48,44,48,44,48,44,48,44,47,45,47,45,46,46,46,46,46,50,46,53,46,54,46,54,46,54,46,54,46,55,46,55,46,56,46,56,47,56,47,56,47,57,47,57,47,58,47,58,47,58,48,58,48,58,49,59,49,59,49,59,49,59,50,58,51,58,51,57,51,55,53,55,54,55,55,55,55,54,55,54,55,53,55,53,56,51,58,51,58,51,57;107,57,107,56,107,55,107,55,107,54,106,54,105,53,105,53,106,53,107,52,110,52,110,53,110,53,110,53,112,53,113,53,114,53,114,53,114,53,114,54,114,54,115,54,115,55,114,56,114,56,113,56,113,56,113,56,112,56,112,57,112,57,112,57,112,57,111,57,111,57,111,57,111,58,108,58,107,57;116,57,116,57,116,57,116,57,116,57,116,57,116,57,116,58,116,58,116,58,116,57,116,57;145,56,145,55,145,54,146,54,146,54,147,54,149,54,149,54,148,56,147,56,147,57,147,57,147,58,146,58,145,57;222,57,221,57,221,57,220,57,220,57,220,57,220,56,220,56,219,56,218,56,218,56,217,56,217,55,216,55,216,55,216,55,215,54,215,53,215,53,215,53,215,53,214,53,214,52,214,51,214,49,214,48,215,48,215,48,215,48,215,48,215,47,215,47,216,46,216,46,217,46,221,46,223,46,225,46,225,46,225,46,225,46,226,46,226,46,226,46,226,47,226,47,227,47,227,47,228,47,228,47,228,47,228,48,228,48,229,49,229,49,230,49,230,49,230,50,229,51,228,51,227,51,226,53,226,54,226,55,225,55,225,55,225,55,224,55,223,56,222,58,222,58,222,57;278,57,278,56,278,55,278,55,277,54,277,54,276,53,276,53,277,53,277,52,280,52,280,53,280,53,281,53,282,53,283,53,284,53,284,53,284,53,284,54,285,54,285,54,286,54,286,54,286,55,285,56,284,56,283,56,283,56,283,57,283,57,283,57,282,57,282,57,282,57,282,57,282,58,278,58,278,57;286,57,286,57,287,57,287,57,287,57,287,57,287,57,287,58,287,58,286,58,286,57,286,57;315,56,315,55,316,54,316,54,317,54,318,54,320,54,320,54,319,56,318,56,318,57,318,57,318,58,316,58,316,57;392,57,392,57,392,57,391,57,391,57,391,57,391,56,390,56,390,56,389,56,388,56,388,56,388,55,387,55,387,55,386,55,386,54,386,53,386,53,385,53,385,53,385,53,385,52,385,51,385,49,385,48,385,48,385,48,386,48,386,48,386,47,386,47,386,46,387,46,387,46,391,46,394,46,396,46,396,46,396,46,396,46,396,46,397,46,397,46,397,47,397,47,397,47,398,47,399,47,399,47,399,47,399,48,399,48,400,49,400,49,400,49,400,49,400,50,399,51,399,51,398,51,396,53,396,54,396,55,396,55,396,55,395,55,395,55,394,56,393,58,392,58,392,57;448,57,448,56,448,55,448,55,448,54,447,54,447,53,447,53,447,53,448,52,451,52,451,53,451,53,452,53,453,53,454,53,455,53,455,53,455,53,455,54,456,54,456,54,456,54,456,54,456,55,455,56,454,56,454,56,454,56,454,57,454,57,453,57,453,57,452,57,452,57,452,57,452,58,449,58,449,57;457,57,457,57,457,57,457,57,458,57,458,57,458,57,457,58,457,58,457,58,457,57,457,57;486,56,486,55,487,54,487,54,488,54,489,54,490,54,491,54,489,56,489,56,488,57,488,57,488,58,487,58,487,57;-1,56,-1,56,-2,56,-3,56,-3,55,-3,55,-3,55,-4,55,-5,55,-6,55,-7,55,-7,54,-7,54,-7,53,-7,53,-8,53,-8,52,-8,52,-8,52,-9,51,-10,50,-11,49,-11,48,-11,47,-11,46,-11,46,-11,46,-11,46,-11,45,-11,45,-11,44,-10,44,-10,44,-9,44,-9,44,-9,44,-9,44,-7,44,-4,44,0,44,2,43,2,43,2,43,2,43,2,43,3,43,4,43,4,42,4,42,5,42,6,42,7,42,8,42,8,42,8,42,8,42,9,42,10,42,10,42,10,43,10,43,11,43,12,43,13,43,13,43,14,44,14,44,15,44,16,44,16,44,17,44,17,45,17,45,17,45,18,45,18,45,18,45,18,45,18,45,19,46,19,46,19,46,20,46,21,46,21,47,22,47,22,50,22,52,21,53,20,53,19,53,19,53,19,53,19,53,18,54,16,54,13,54,12,54,12,54,11,55,11,55,10,55,9,55,8,55,8,55,8,55,8,56,8,56,7,56,7,56,7,56,7,56,5,56,3,56,1,56,-1,56,-1,56;31,56,30,56,29,56,28,56,27,55,27,55,27,55,26,55,26,55,25,55,24,55,24,54,24,54,24,53,24,53,24,52,23,52,23,52,23,52,23,51,23,50,23,49,23,49,24,48,25,47,25,47,26,47,26,47,27,47,27,46,28,46,28,46,30,46,32,46,33,45,33,45,33,45,34,45,35,45,35,45,36,45,36,45,36,44,37,44,38,44,38,44,39,44,39,45,39,45,40,45,40,45,43,45,43,45,43,48,43,50,43,51,43,51,42,51,42,51,42,52,42,53,40,55,39,55,39,55,39,55,39,56,38,56,38,56,34,56,32,56,31,56,31,56;116,55,116,54,117,53,117,53,120,53,120,53,121,54,121,54,120,55,118,56,117,56,117,56;170,56,170,56,169,56,168,56,168,55,168,55,168,55,167,55,166,55,164,55,164,55,164,54,164,54,164,53,164,53,163,53,163,52,163,52,163,52,162,51,161,50,160,49,160,48,160,47,160,46,160,46,160,46,160,46,160,45,160,45,160,44,160,44,161,44,162,44,162,44,162,44,162,44,164,44,167,44,170,44,172,43,172,43,172,43,173,43,173,43,174,43,174,43,175,42,175,42,175,42,177,42,177,42,178,42,178,42,178,42,179,42,180,42,180,42,181,42,181,43,181,43,182,43,182,43,184,43,184,43,185,44,185,44,185,44,186,44,187,44,188,44,188,45,188,45,188,45,188,45,189,45,189,45,189,45,189,45,189,46,190,46,190,46,191,46,191,46,192,47,192,47,192,50,192,52,192,53,190,53,190,53,190,53,190,53,190,53,188,54,186,54,183,54,183,54,183,54,182,55,182,55,180,55,180,55,179,55,179,55,179,55,179,56,178,56,178,56,178,56,178,56,178,56,176,56,174,56,172,56,170,56,170,56;202,56,201,56,200,56,198,56,198,55,198,55,198,55,197,55,196,55,195,55,194,54,194,53,194,52,194,52,194,52,194,52,194,51,194,50,194,49,194,49,195,48,195,47,196,47,197,47,197,47,198,47,198,46,198,46,199,46,201,46,202,46,204,45,204,45,204,45,204,45,205,45,206,45,207,45,207,45,207,44,207,44,208,44,209,44,210,44,210,45,210,45,210,45,211,45,213,45,214,45,214,48,214,50,213,51,213,51,213,51,213,51,213,52,213,53,211,55,210,55,210,55,209,55,209,56,209,56,208,56,205,56,203,56,202,56,202,56;287,55,287,54,287,53,288,53,290,53,291,53,291,54,291,54,290,55,289,56,288,56,287,56;341,56,340,56,340,56,339,56,338,55,338,55,338,55,337,55,337,55,335,55,335,55,335,54,335,54,335,53,334,53,334,53,334,52,334,52,334,52,333,51,332,50,330,49,330,48,330,47,330,46,330,46,331,46,331,46,331,45,331,45,331,44,331,44,332,44,332,44,333,44,333,44,333,44,335,44,338,44,341,44,343,43,343,43,343,43,343,43,344,43,344,43,345,43,345,42,346,42,346,42,347,42,348,42,349,42,349,42,349,42,349,42,350,42,351,42,352,42,352,43,352,43,352,43,353,43,354,43,355,43,355,44,356,44,356,44,357,44,358,44,358,44,358,45,358,45,358,45,359,45,359,45,360,45,360,45,360,45,360,46,360,46,361,46,362,46,362,46,363,47,363,47,363,50,363,52,362,53,361,53,361,53,360,53,360,53,360,53,359,54,357,54,354,54,354,54,353,54,353,55,352,55,351,55,350,55,350,55,350,55,350,55,349,56,349,56,348,56,348,56,348,56,348,56,347,56,345,56,342,56,341,56,341,56;372,56,371,56,370,56,369,56,368,55,368,55,368,55,368,55,367,55,365,55,365,54,365,53,365,52,365,52,365,52,364,52,364,51,364,50,364,49,364,49,365,48,366,47,367,47,367,47,368,47,368,47,369,46,369,46,369,46,372,46,373,46,374,45,374,45,374,45,375,45,376,45,377,45,378,45,378,45,378,44,378,44,379,44,380,44,380,44,380,45,380,45,381,45,382,45,384,45,384,45,384,48,384,50,384,51,384,51,384,51,384,51,384,52,384,53,382,55,381,55,381,55,380,55,380,56,379,56,379,56,376,56,374,56,372,56,372,56;457,55,457,54,458,53,459,53,461,53,462,53,462,54,462,54,461,55,460,56,459,56,458,56;129,54,129,54,129,54,129,54,130,53,130,53,130,53,130,52,131,51,132,50,132,50,132,49,132,48,133,48,134,49,135,50,135,51,133,53,131,55,130,55,129,54;154,54,154,54,153,54,152,54,152,53,152,53,152,53,151,53,151,53,150,53,150,53,150,53,150,52,149,52,148,52,147,52,146,52,146,52,146,52,146,52,145,52,144,52,144,49,144,47,144,47,145,47,145,46,146,46,146,46,146,45,146,45,146,45,147,44,147,44,147,43,147,42,148,42,150,42,152,42,153,42,153,42,153,43,154,43,154,43,154,43,155,43,155,44,155,44,156,44,156,44,157,44,157,44,157,45,157,45,157,46,157,46,157,46,158,46,158,46,158,47,158,47,158,47,158,47,158,48,158,50,158,51,158,52,158,52,158,52,158,53,158,54,158,55,157,55,156,55,155,55,155,55,155,54;299,54,299,54,300,54,300,54,300,53,300,53,300,53,301,52,302,51,302,50,303,50,303,49,303,48,304,48,305,49,306,50,306,51,304,53,302,55,301,55,300,54;325,54,324,54,323,54,323,54,322,53,322,53,322,53,322,53,321,53,321,53,320,53,320,53,320,52,319,52,319,52,318,52,317,52,317,52,317,52,316,52,316,52,315,52,315,49,315,47,315,47,316,47,316,46,316,46,316,46,316,45,316,45,317,45,317,44,318,44,318,43,318,42,318,42,321,42,323,42,323,42,324,42,324,43,325,43,325,43,325,43,326,43,326,44,326,44,327,44,327,44,327,44,328,44,328,45,328,45,328,46,328,46,328,46,328,46,328,46,328,47,328,47,329,47,329,47,329,48,329,50,329,51,329,52,329,52,328,52,328,53,328,54,328,55,328,55,327,55,326,55,326,55,325,54;470,54,470,54,470,54,471,54,471,53,471,53,471,53,471,52,472,51,473,50,474,50,474,49,474,48,474,48,475,49,477,50,476,51,474,53,472,55,471,55,471,54;495,54,495,54,494,54,493,54,493,53,493,53,493,53,492,53,492,53,491,53,491,53,491,53,491,52,490,52,489,52,488,52,488,52,488,52,488,52,487,52,487,52,486,52,486,49,486,47,486,47,486,47,487,46,487,46,487,46,487,45,487,45,488,45,488,44,488,44,488,43,488,42,489,42,492,42,494,42,494,42,495,42,495,43,495,43,496,43,496,43,496,43,497,44,497,44,497,44,498,44,498,44,498,44,498,45,498,45,498,46,499,46,499,46,499,46,499,46,499,47,499,47,499,47,499,47,500,48,500,50,500,51,499,52,499,52,499,52,499,53,499,54,499,55,499,55,498,55,497,55,496,55,496,54;63,53,63,53,62,53,62,53,62,53,62,53,62,52,61,52,60,52,59,52,59,52,59,52,59,51,59,51,60,51,60,50,60,50,60,49,60,49,60,49,61,49,61,49,61,49,61,48,61,48,61,48,61,48,61,48,62,47,62,46,62,44,62,44,62,43,63,43,63,42,63,42,63,42,64,41,64,41,64,41,65,42,66,42,67,42,68,42,68,42,68,42,69,42,69,42,70,42,70,42,70,43,70,43,71,43,71,43,72,43,73,43,73,44,73,44,74,44,75,44,75,44,76,44,76,45,76,45,76,45,77,45,78,45,79,45,79,45,79,45,80,46,82,46,86,46,86,47,86,49,85,49,84,50,84,51,83,52,83,52,82,52,82,52,82,52,82,52,80,52,77,52,74,52,72,52,72,53,72,53,72,53,72,53,71,53,71,53,71,53,71,53,69,54,67,54,64,54,63,53,63,53;124,53,124,53,124,53,123,53,123,53,123,53,123,52,122,52,122,52,121,52,121,52,121,52,121,52,120,52,119,52,117,52,116,52,116,52,116,52,115,52,115,52,114,52,113,52,113,52,113,52,112,52,111,52,110,52,110,51,110,51,110,51,109,51,108,51,107,51,107,51,107,50,107,50,107,49,106,49,106,49,106,49,106,49,107,49,107,49,107,48,107,48,107,47,108,47,108,47,108,46,108,46,108,46,108,46,109,46,109,46,109,44,109,43,109,41,109,40,109,39,110,39,111,39,111,40,112,40,112,40,113,40,114,40,115,40,115,41,115,41,116,41,117,41,119,41,120,41,120,41,120,41,120,42,122,42,123,42,124,42,124,42,124,42,124,42,125,42,125,42,126,42,126,43,126,43,127,43,128,43,131,43,131,44,131,44,131,45,131,45,131,45,132,45,132,46,132,47,131,48,131,48,131,48,131,48,131,49,131,49,131,50,131,50,130,50,130,50,130,50,130,50,129,51,129,52,127,53,127,54,126,54,125,54,124,53,124,53;234,53,233,53,233,53,232,53,232,53,232,53,232,52,232,52,231,52,230,52,230,52,230,52,230,51,230,51,230,51,231,50,231,50,231,49,231,49,231,49,231,49,231,49,232,49,232,48,232,48,232,48,232,48,232,48,232,47,232,46,232,44,232,44,233,43,233,43,234,42,234,42,234,42,235,41,235,41,235,41,236,42,237,42,238,42,239,42,239,42,239,42,239,42,240,42,240,42,241,42,241,43,241,43,241,43,242,43,243,43,243,43,244,44,244,44,245,44,245,44,246,44,246,44,246,45,246,45,247,45,248,45,249,45,250,45,250,45,250,45,251,46,253,46,256,46,256,47,256,49,256,49,255,50,254,51,254,52,253,52,253,52,253,52,253,52,253,52,251,52,248,52,245,52,243,52,243,53,243,53,243,53,242,53,242,53,242,53,242,53,242,53,240,54,238,54,235,54,234,53,234,53;295,53,295,53,294,53,294,53,294,53,294,53,294,52,293,52,293,52,292,52,292,52,292,52,292,52,291,52,289,52,288,52,287,52,287,52,287,52,286,52,285,52,284,52,284,52,284,52,284,52,283,52,282,52,281,52,280,51,280,51,280,51,280,51,279,51,278,51,278,51,278,50,278,50,277,49,277,49,277,49,277,49,277,49,277,49,278,49,278,48,278,48,278,47,278,47,279,47,279,46,279,46,279,46,279,46,279,46,279,46,280,44,280,43,280,41,280,40,280,39,281,39,281,39,282,40,282,40,283,40,284,40,285,40,286,40,286,41,286,41,287,41,288,41,289,41,290,41,290,41,290,41,291,42,292,42,293,42,294,42,294,42,294,42,295,42,295,42,296,42,296,42,296,43,296,43,297,43,299,43,302,43,302,44,302,44,302,45,302,45,302,45,302,45,302,46,302,47,302,48,302,48,302,48,302,48,302,49,302,49,301,50,301,50,301,50,301,50,301,50,301,50,300,51,299,52,298,53,298,54,296,54,296,54,295,53,295,53;404,53,404,53,404,53,403,53,403,53,403,53,403,52,402,52,402,52,400,52,400,52,400,52,400,51,400,51,401,51,401,50,402,50,402,49,402,49,402,49,402,49,402,49,402,49,402,48,402,48,402,48,403,48,403,48,403,47,403,46,403,44,403,44,404,43,404,43,404,42,404,42,404,42,405,41,405,41,406,41,406,42,408,42,409,42,410,42,410,42,410,42,410,42,411,42,411,42,412,42,412,43,412,43,412,43,413,43,414,43,414,43,415,44,415,44,415,44,416,44,416,44,417,44,417,45,417,45,418,45,419,45,419,45,420,45,420,45,420,45,422,46,424,46,427,46,427,47,427,49,427,49,426,50,425,51,424,52,424,52,424,52,424,52,424,52,424,52,422,52,419,52,415,52,414,52,414,53,414,53,413,53,413,53,412,53,412,53,412,53,412,53,411,54,408,54,406,54,404,53,404,53;466,53,465,53,465,53,464,53,464,53,464,53,464,52,464,52,463,52,463,52,462,52,462,52,462,52,461,52,460,52,459,52,458,52,458,52,458,52,457,52,456,52,455,52,454,52,454,52,454,52,453,52,453,52,452,52,451,51,451,51,451,51,450,51,450,51,448,51,448,51,448,50,448,50,448,49,448,49,447,49,447,49,448,49,448,49,448,49,448,48,448,48,448,47,449,47,449,47,450,46,450,46,450,46,450,46,450,46,450,46,450,44,450,43,450,41,450,40,451,39,451,39,452,39,453,40,453,40,453,40,455,40,455,40,456,40,456,41,456,41,457,41,459,41,460,41,461,41,461,41,461,41,462,42,463,42,464,42,465,42,465,42,465,42,465,42,466,42,466,42,467,42,467,43,467,43,468,43,470,43,472,43,472,44,472,44,472,45,473,45,473,45,473,45,473,46,473,47,473,48,473,48,472,48,472,48,472,49,472,49,472,50,472,50,472,50,472,50,472,50,472,50,471,51,470,52,469,53,468,54,467,54,466,54,466,53,466,53;94,50,93,50,92,50,90,50,90,50,90,50,90,50,89,50,89,50,87,50,87,49,87,47,87,47,87,46,87,46,86,46,86,46,86,46,86,45,86,45,87,45,87,45,87,44,87,44,87,43,87,43,88,43,88,43,88,43,88,43,88,42,90,42,93,42,96,42,98,42,98,43,98,43,99,43,99,43,100,43,102,44,102,45,102,45,99,48,98,48,98,48,97,48,97,49,97,49,96,50,96,50,96,50,95,50,95,50,95,51,94,51,94,51;264,50,263,50,262,50,261,50,260,50,260,50,260,50,260,50,259,50,258,50,258,49,258,47,258,47,257,46,257,46,257,46,257,46,257,46,257,45,257,45,257,45,257,45,258,44,258,44,258,43,258,43,258,43,259,43,259,43,259,43,259,42,261,42,264,42,267,42,269,42,269,43,269,43,269,43,270,43,271,43,272,44,272,45,272,45,269,48,269,48,269,48,268,48,268,49,268,49,267,50,267,50,267,50,266,50,266,50,265,51,264,51,264,51;435,50,434,50,433,50,432,50,431,50,431,50,431,50,430,50,430,50,429,50,428,49,428,47,428,47,428,46,428,46,428,46,428,46,428,46,428,45,428,45,428,45,428,45,428,44,428,44,428,43,428,43,429,43,429,43,430,43,430,43,430,42,431,42,435,42,438,42,440,42,440,43,440,43,440,43,440,43,441,43,443,44,443,45,443,45,440,48,439,48,439,48,439,48,439,49,438,49,438,50,438,50,437,50,437,50,437,50,436,51,435,51,435,51;134,47,133,46,133,45,133,45,133,45,133,45,132,45,132,44,132,43,132,42,132,42,133,41,133,41,134,40,134,40,134,39,134,39,136,39,136,39,137,39,138,40,139,41,139,42,140,42,141,42,142,42,142,43,142,43,142,44,142,44,142,44,142,44,142,45,142,45,142,46,143,46,143,46,143,48,142,48,142,49,142,49,141,49,141,49,141,49,141,49,141,49,140,49,139,49,136,49,135,48;304,47,304,46,304,45,304,45,303,45,303,45,303,45,303,44,303,43,303,42,303,42,304,41,304,41,304,40,304,40,304,39,305,39,306,39,307,39,308,39,309,40,310,41,310,42,311,42,312,42,312,42,312,43,312,43,312,44,313,44,313,44,313,44,313,45,313,45,313,46,313,46,314,46,314,48,313,48,313,49,312,49,312,49,312,49,312,49,312,49,312,49,311,49,309,49,307,49,305,48;475,47,474,46,474,45,474,45,474,45,474,45,474,45,474,44,474,43,474,42,474,42,474,41,475,41,475,40,475,40,475,39,476,39,477,39,478,39,478,39,479,40,480,41,481,42,482,42,483,42,483,42,483,43,483,43,483,44,483,44,483,44,484,44,484,45,484,45,484,46,484,46,484,46,484,48,484,48,483,49,483,49,483,49,482,49,482,49,482,49,482,49,481,49,480,49,478,49,476,48;105,45,104,44,104,44,104,43,105,42,105,42,105,43,106,43,106,43,106,43,107,43,107,43,108,44,108,45,107,45,107,45,107,45,107,46,107,46,106,46,105,45;275,45,275,44,275,44,275,43,276,42,276,42,276,43,276,43,277,43,277,43,277,43,278,43,278,44,278,45,278,45,278,45,278,45,278,46,278,46,277,46,276,45;446,45,446,44,446,44,446,43,447,42,447,42,447,43,447,43,447,43,448,43,448,43,448,43,449,44,449,45,449,45,448,45,448,45,448,46,448,46,447,46,446,45;156,43,156,43,157,43,157,42,158,42,158,42,159,42,160,42,160,43,160,44,159,44,159,44,158,44,158,44,158,45,158,45,158,45,157,44;327,43,327,43,327,43,328,42,328,42,329,42,330,42,330,42,330,43,330,44,330,44,330,44,329,44,329,44,329,45,329,45,328,45,328,44;498,43,498,43,498,43,498,42,499,42,500,42,501,42,501,42,501,43,501,44,501,44,500,44,500,44,500,44,500,45,500,45,499,45,498,44;17,43,17,43,16,43,15,43,15,43,15,43,15,42,15,42,14,42,14,42,14,42,14,42,14,42,13,42,12,42,11,42,10,41,10,41,10,41,10,41,10,41,9,41,7,39,8,39,8,39,8,38,8,38,8,37,9,36,10,36,10,36,11,36,11,36,11,35,12,35,13,35,13,35,14,35,14,34,14,34,15,34,16,34,17,34,18,33,18,33,18,33,20,33,24,33,28,33,30,33,30,33,30,33,32,34,34,34,36,34,37,34,37,34,37,34,37,34,37,34,38,34,39,35,39,37,39,37,39,38,39,38,40,38,40,39,39,39,39,39,39,39,39,39,39,40,39,40,38,41,38,41,38,41,38,41,38,42,37,43,36,43,36,43,36,43,36,43,36,43,35,44,34,44,33,44,32,44,32,44,32,44,31,44,29,44,27,44,26,44,26,44,26,44,25,44,25,44,24,44,24,44,24,44,24,44,23,44,21,44,19,44,18,44,18,44;44,44,43,44,43,44,42,44,41,43,41,43,40,42,40,40,41,39,41,39,41,39,41,39,40,39,40,38,40,36,40,34,41,33,42,33,42,33,43,33,43,33,43,32,44,32,45,32,46,32,47,32,47,32,47,32,47,32,48,32,48,32,49,31,49,31,49,31,50,31,51,31,53,31,54,31,54,31,54,30,55,30,57,30,58,30,60,30,60,31,60,31,60,31,60,31,60,31,61,31,61,32,61,32,62,32,62,32,63,32,63,32,63,33,63,34,63,34,63,34,63,34,64,35,64,36,64,36,63,37,63,37,63,37,63,37,63,38,63,39,62,40,61,40,61,40,60,40,60,41,59,41,59,42,58,42,57,42,57,42,57,42,57,42,57,42,56,42,56,42,56,42,56,43,56,43,55,43,54,43,53,43,53,43,53,43,53,43,52,44,51,44,49,44,48,44,48,44,48,44,47,44,46,44,45,44,44,44,44,44;79,44,78,44,78,44,77,44,76,43,76,43,76,43,76,43,76,43,75,43,75,43,75,42,75,42,75,42,77,42,77,42,78,41,78,41,78,41,79,41,80,41,81,41,82,41,82,41,82,40,83,40,83,40,84,40,84,40,84,41,84,41,84,42,85,42,85,42,86,43,86,43,86,44,82,44,80,44,79,44,79,44;188,43,188,43,187,43,186,43,186,43,186,43,186,42,185,42,185,42,184,42,184,42,184,42,184,42,183,42,183,42,182,42,181,41,181,41,181,41,181,41,180,41,180,41,178,39,178,39,179,39,179,38,179,38,179,37,180,36,181,36,181,36,182,36,182,36,182,35,183,35,183,35,184,35,184,35,185,34,185,34,185,34,187,34,188,34,189,33,189,33,189,33,191,33,195,33,199,33,201,33,201,33,201,33,202,34,204,34,206,34,208,34,208,34,208,34,208,34,208,34,209,34,210,35,210,37,210,37,210,38,210,38,210,38,210,39,210,39,210,39,210,39,210,39,210,40,209,40,209,41,208,41,208,41,208,41,208,42,207,43,207,43,206,43,206,43,206,43,206,43,205,44,205,44,204,44,203,44,203,44,203,44,202,44,200,44,198,44,196,44,196,44,196,44,196,44,196,44,195,44,195,44,195,44,195,44,194,44,192,44,189,44,189,44,189,44;215,44,214,44,213,44,212,44,212,43,211,43,211,42,211,40,211,39,212,39,212,39,211,39,211,39,211,38,211,36,211,34,211,33,213,33,213,33,214,33,214,33,214,32,214,32,216,32,217,32,218,32,218,32,218,32,218,32,219,32,219,32,220,31,220,31,220,31,221,31,222,31,223,31,224,31,224,31,224,30,225,30,227,30,229,30,230,30,230,31,230,31,230,31,231,31,231,31,232,31,232,32,232,32,233,32,233,32,233,32,234,32,234,33,234,34,234,34,234,34,234,34,234,35,234,36,234,36,234,37,234,37,234,37,234,37,234,38,234,39,232,40,231,40,231,40,231,40,231,41,230,41,230,42,229,42,228,42,228,42,228,42,228,42,227,42,227,42,226,42,226,42,226,43,226,43,226,43,225,43,224,43,224,43,224,43,224,43,223,44,221,44,220,44,219,44,219,44,219,44,218,44,217,44,216,44,215,44,215,44;250,44,249,44,248,44,247,44,247,43,247,43,247,43,247,43,246,43,246,43,246,43,246,42,246,42,246,42,247,42,248,42,249,41,249,41,249,41,250,41,251,41,252,41,253,41,253,41,253,40,253,40,254,40,255,40,255,40,255,41,255,41,255,42,256,42,256,42,256,43,256,43,256,44,253,44,251,44,250,44,250,44;359,43,358,43,357,43,357,43,356,43,356,43,356,42,356,42,356,42,355,42,355,42,355,42,355,42,354,42,353,42,352,42,352,41,352,41,352,41,351,41,351,41,350,41,349,39,349,39,349,39,350,38,350,38,350,37,350,36,351,36,352,36,352,36,353,36,353,35,353,35,354,35,354,35,355,35,355,34,356,34,356,34,358,34,359,34,360,33,360,33,360,33,362,33,366,33,369,33,372,33,372,33,372,33,373,34,375,34,377,34,378,34,378,34,378,34,378,34,379,34,380,34,380,35,380,37,380,37,380,38,381,38,381,38,381,39,381,39,380,39,380,39,380,39,380,40,380,40,380,41,379,41,379,41,379,41,379,42,378,43,377,43,377,43,377,43,377,43,377,43,376,44,375,44,374,44,374,44,374,44,374,44,372,44,370,44,368,44,367,44,367,44,367,44,367,44,366,44,366,44,366,44,366,44,366,44,364,44,363,44,360,44,360,44,359,44;386,44,385,44,384,44,383,44,382,43,382,43,381,42,381,40,382,39,382,39,382,39,382,39,382,39,382,38,382,36,382,34,382,33,383,33,384,33,384,33,384,33,384,32,385,32,386,32,387,32,388,32,388,32,388,32,389,32,389,32,390,32,390,31,390,31,390,31,391,31,393,31,394,31,395,31,395,31,395,30,396,30,398,30,400,30,401,30,401,31,401,31,401,31,401,31,402,31,402,31,403,32,403,32,403,32,404,32,404,32,404,32,404,33,404,34,404,34,405,34,405,34,405,35,405,36,405,36,405,37,405,37,404,37,404,37,404,38,404,39,403,40,402,40,402,40,401,40,401,41,401,41,400,42,399,42,399,42,398,42,398,42,398,42,398,42,398,42,397,42,397,42,397,43,397,43,396,43,396,43,395,43,394,43,394,43,394,43,393,44,392,44,391,44,390,44,390,44,390,44,389,44,388,44,386,44,386,44,386,44;420,44,420,44,419,44,418,44,418,43,418,43,418,43,417,43,417,43,416,43,416,43,416,42,416,42,416,42,418,42,419,42,420,41,420,41,420,41,420,41,422,41,423,41,424,41,424,41,424,40,424,40,425,40,425,40,426,40,426,41,426,41,426,42,426,42,427,42,427,43,427,43,427,44,424,44,422,44,420,44,420,44;0,42,0,42,0,42,-1,42,-1,41,-2,40,-3,39,-3,39,-3,37,-3,36,-3,36,-3,36,-3,36,-3,35,-3,34,-3,32,-1,32,0,32,0,28,0,24,0,24,1,24,1,24,2,23,2,23,2,23,2,23,2,23,3,23,3,23,3,23,3,22,4,22,5,22,7,22,8,22,8,22,8,22,9,22,13,22,18,22,19,23,20,24,21,26,20,27,19,27,19,27,19,28,19,28,19,28,19,28,18,28,18,28,18,29,18,29,18,30,17,30,17,31,16,31,16,32,16,32,16,32,15,32,15,32,14,32,14,33,14,33,14,33,14,33,13,33,13,33,13,33,13,33,12,34,12,34,11,34,11,34,11,34,10,35,10,35,7,35,5,35,4,35,4,35,4,34,4,34,4,34,3,34,3,34,3,34,3,34,2,34,2,34,0,34,0,34,0,34,0,35,0,35,1,35,2,35,3,36,3,36,3,37,3,37,3,37,3,37,4,37,4,38,4,38,3,38,3,38,3,38,3,39,3,39,3,41,2,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,0,42,0,42,0,42;171,42,171,42,170,42,170,42,169,41,169,40,168,39,168,39,168,37,168,36,168,36,168,36,168,36,168,35,168,34,168,32,170,32,171,32,171,28,171,24,171,24,172,24,172,24,172,23,172,23,172,23,172,23,173,23,173,23,174,23,174,23,174,22,175,22,176,22,177,22,178,22,178,22,178,22,180,22,183,22,189,22,190,23,191,24,191,26,190,27,190,27,190,27,190,28,190,28,189,28,189,28,189,28,189,28,189,29,189,29,188,30,188,30,187,31,187,31,187,32,187,32,187,32,186,32,185,32,185,32,185,33,185,33,185,33,184,33,184,33,184,33,184,33,184,33,183,34,183,34,182,34,181,34,181,34,181,35,180,35,178,35,176,35,175,35,175,35,175,34,175,34,174,34,174,34,174,34,174,34,174,34,173,34,172,34,171,34,171,34,171,34,171,35,171,35,172,35,173,35,174,36,174,36,174,37,174,37,174,37,174,37,174,37,174,38,174,38,174,38,174,38,174,38,174,39,174,39,174,41,173,42,172,42,172,42,172,42,172,42,172,42,171,42,171,42,171,42,171,42,171,42;342,42,341,42,341,42,341,42,340,41,339,40,338,39,338,39,338,37,338,36,338,36,339,36,339,36,339,35,339,34,339,32,340,32,342,32,342,28,342,24,342,24,342,24,343,24,343,23,343,23,343,23,343,23,344,23,344,23,344,23,344,23,344,22,345,22,347,22,348,22,349,22,349,22,349,22,351,22,354,22,359,22,360,23,362,24,362,26,361,27,360,27,360,27,360,28,360,28,360,28,360,28,360,28,360,28,360,29,360,29,359,30,359,30,358,31,358,31,358,32,358,32,357,32,357,32,356,32,356,32,356,33,356,33,355,33,355,33,354,33,354,33,354,33,354,33,354,34,353,34,353,34,352,34,352,34,351,35,351,35,348,35,347,35,346,35,346,35,346,34,345,34,345,34,344,34,344,34,344,34,344,34,344,34,343,34,342,34,342,34,342,34,342,35,342,35,342,35,343,35,344,36,344,36,344,37,344,37,345,37,345,37,345,37,345,38,345,38,345,38,345,38,344,38,344,39,344,39,344,41,344,42,343,42,342,42,342,42,342,42,342,42,342,42,342,42,342,42,342,42,342,42;126,41,125,41,125,41,124,41,124,41,124,41,124,40,123,40,122,40,120,40,120,40,120,40,120,40,119,40,117,40,116,40,115,39,115,39,115,39,114,39,114,39,112,39,112,39,112,38,112,38,112,37,113,37,113,37,113,37,113,37,112,37,112,36,112,36,112,35,112,35,112,35,111,34,111,34,111,33,111,32,111,31,110,31,109,31,109,30,110,29,111,29,112,29,112,29,112,29,113,30,114,30,116,30,116,30,117,30,117,31,117,31,120,31,121,31,122,31,122,31,122,31,123,32,124,32,125,32,126,32,126,32,126,32,127,32,129,32,131,32,132,32,132,33,132,33,133,33,134,33,135,33,135,33,136,34,136,34,137,35,137,35,137,35,135,37,135,37,134,37,134,38,134,38,134,38,133,39,133,39,132,39,132,40,132,40,132,41,131,42,128,42,127,42,126,41,126,41;296,41,296,41,295,41,295,41,294,41,294,41,294,40,293,40,292,40,291,40,290,40,290,40,290,40,289,40,288,40,287,40,286,39,286,39,286,39,285,39,284,39,283,39,283,39,283,38,283,38,283,37,283,37,284,37,284,37,283,37,283,37,283,36,283,36,283,35,283,35,282,35,282,34,282,34,282,33,282,32,281,31,281,31,280,31,280,30,281,29,281,29,283,29,283,29,283,29,284,30,285,30,286,30,287,30,287,30,288,31,288,31,290,31,292,31,293,31,293,31,293,31,294,32,295,32,296,32,297,32,297,32,297,32,298,32,300,32,302,32,303,32,303,33,303,33,304,33,304,33,306,33,306,33,307,34,307,34,308,35,308,35,308,35,306,37,305,37,305,37,304,38,304,38,304,38,304,39,304,39,303,39,303,40,303,40,303,41,302,42,299,42,297,42,296,41,296,41;467,41,466,41,466,41,465,41,465,41,465,41,465,40,464,40,463,40,462,40,461,40,461,40,461,40,460,40,459,40,457,40,456,39,456,39,456,39,456,39,455,39,454,39,454,39,454,38,454,38,454,37,454,37,454,37,454,37,454,37,454,37,454,36,454,36,454,35,453,35,453,35,452,34,452,34,452,33,452,32,452,31,452,31,451,31,451,30,451,29,452,29,454,29,454,29,454,29,454,30,455,30,457,30,457,30,458,30,458,31,459,31,461,31,462,31,464,31,464,31,464,31,464,32,466,32,467,32,468,32,468,32,468,32,469,32,471,32,472,32,474,32,474,33,474,33,474,33,475,33,476,33,477,33,477,34,478,34,478,35,478,35,478,35,477,37,476,37,476,37,475,38,475,38,475,38,475,39,474,39,474,39,474,40,474,40,474,41,473,42,470,42,468,42,467,41,467,41;72,40,71,40,70,40,69,40,68,40,68,38,68,38,68,37,68,37,67,37,67,36,67,35,67,34,67,34,68,34,68,34,68,33,68,33,68,33,69,33,71,33,72,33,73,33,73,33,73,32,73,32,74,32,74,32,75,32,75,32,75,32,75,32,76,32,76,32,76,31,76,31,76,31,77,31,77,31,78,31,78,31,78,31,78,30,79,30,79,30,80,30,80,30,80,30,80,30,81,30,82,30,83,30,84,29,84,29,84,29,84,29,85,29,86,29,87,29,87,29,87,28,87,28,88,28,88,28,88,28,88,29,88,29,89,29,90,29,92,29,93,29,93,30,94,30,94,31,94,31,94,32,94,32,95,32,95,32,95,33,95,35,95,37,95,38,94,38,94,38,94,38,94,38,94,38,92,38,91,38,89,38,88,38,88,39,88,39,87,39,85,39,83,39,82,39,82,39,82,39,81,40,80,40,79,40,78,40,78,40,78,40,77,40,76,40,75,40,74,40,74,41,74,41,74,41,73,41,72,41,72,41,72,41;142,40,141,40,141,40,139,40,139,40,139,40,139,39,139,39,139,39,138,39,138,38,138,36,138,35,138,34,139,34,139,34,139,33,139,33,139,32,139,32,140,32,140,32,140,32,140,32,140,32,141,32,143,32,144,32,146,31,146,31,146,31,148,31,153,31,158,31,160,31,160,31,160,31,161,32,162,32,163,32,164,32,164,32,164,32,164,32,165,32,166,32,166,32,166,34,166,35,165,36,165,36,165,36,165,37,165,37,165,38,165,38,165,38,164,38,164,38,164,39,164,40,163,40,162,40,161,40,161,40,161,41,161,41,159,41,157,41,154,41,153,41,153,41,153,40,152,40,150,40,148,40,147,40,147,41,147,41,146,41,145,41,143,41,142,41,142,41;242,40,242,40,241,40,240,40,239,40,239,38,239,38,239,37,238,37,238,37,238,36,238,35,238,34,238,34,238,34,239,34,239,33,239,33,239,33,240,33,241,33,243,33,244,33,244,33,244,32,244,32,245,32,245,32,246,32,246,32,246,32,246,32,246,32,247,32,247,31,247,31,247,31,247,31,248,31,248,31,249,31,249,31,249,30,249,30,250,30,250,30,251,30,251,30,251,30,252,30,253,30,253,30,254,29,254,29,254,29,255,29,256,29,257,29,258,29,258,29,258,28,258,28,258,28,259,28,259,28,259,29,259,29,260,29,261,29,263,29,263,29,264,30,264,30,265,31,265,31,265,32,265,32,265,32,265,32,266,33,266,35,266,37,265,38,265,38,264,38,264,38,264,38,264,38,263,38,262,38,260,38,259,38,259,39,259,39,258,39,256,39,254,39,253,39,253,39,253,39,252,40,251,40,250,40,249,40,249,40,249,40,248,40,247,40,246,40,245,40,245,41,245,41,244,41,244,41,243,41,242,41,242,41;313,40,312,40,311,40,310,40,310,40,310,40,310,39,309,39,309,39,309,39,309,38,309,36,309,35,309,34,309,34,309,34,310,33,310,33,310,32,310,32,310,32,311,32,311,32,311,32,311,32,312,32,314,32,315,32,316,31,316,31,316,31,319,31,324,31,328,31,331,31,331,31,331,31,332,32,333,32,333,32,334,32,334,32,334,32,335,32,335,32,336,32,336,32,336,34,336,35,336,36,336,36,336,36,336,37,336,37,336,38,335,38,335,38,335,38,335,38,335,39,335,40,334,40,333,40,332,40,332,40,332,41,332,41,330,41,328,41,325,41,324,41,324,41,324,40,322,40,321,40,319,40,318,40,318,41,318,41,317,41,315,41,314,41,313,41,313,41;413,40,412,40,412,40,410,40,410,40,410,38,410,38,409,37,409,37,408,37,408,36,408,35,408,34,408,34,409,34,409,34,410,33,410,33,410,33,411,33,412,33,413,33,414,33,414,33,414,32,415,32,415,32,416,32,416,32,416,32,416,32,416,32,417,32,417,32,418,31,418,31,418,31,418,31,419,31,419,31,420,31,420,31,420,30,420,30,421,30,421,30,422,30,422,30,422,30,422,30,423,30,424,30,425,29,425,29,425,29,426,29,427,29,427,29,428,29,428,29,428,28,428,28,429,28,429,28,430,28,430,29,430,29,430,29,432,29,434,29,434,29,435,30,435,30,436,31,436,31,436,32,436,32,436,32,436,32,436,33,436,35,436,37,436,38,436,38,435,38,435,38,435,38,435,38,434,38,432,38,431,38,430,38,430,39,430,39,428,39,427,39,425,39,424,39,424,39,424,39,423,40,422,40,420,40,420,40,420,40,420,40,419,40,418,40,416,40,416,40,416,41,416,41,415,41,414,41,413,41,413,41,413,41;484,40,483,40,482,40,480,40,480,40,480,40,480,39,480,39,480,39,480,39,480,38,480,36,480,35,480,34,480,34,480,34,480,33,480,33,480,32,480,32,481,32,481,32,482,32,482,32,482,32,483,32,484,32,486,32,487,31,487,31,487,31,490,31,494,31,499,31,502,31,502,31,502,31,502,32,503,32,504,32,505,32,505,32,505,32,505,32,506,32,507,32,507,32,507,34,507,35,507,36,507,36,506,36,506,37,506,37,506,38,506,38,506,38,506,38,506,38,506,39,506,40,505,40,503,40,503,40,502,40,502,41,502,41,501,41,498,41,496,41,494,41,494,41,494,40,493,40,491,40,489,40,488,40,488,41,488,41,487,41,486,41,485,41,484,41,484,41;98,37,98,37,98,36,98,36,97,35,97,35,96,35,96,34,96,33,96,33,96,32,96,32,95,32,95,29,96,29,97,28,103,28,103,29,103,29,104,29,105,29,107,29,108,29,108,30,108,31,108,31,109,31,109,31,109,31,109,32,109,32,109,32,109,32,109,32,110,33,110,33,110,34,110,34,110,34,110,34,110,34,110,35,110,35,110,36,111,36,111,36,111,36,110,37,110,37,110,38,109,38,109,38,109,38,109,38,109,38,107,38,104,38,99,38,98,38,98,38;268,37,268,37,268,36,268,36,268,35,268,35,267,35,267,34,267,33,267,33,267,32,267,32,266,32,266,29,267,29,267,28,274,28,274,29,274,29,274,29,276,29,278,29,279,29,279,30,279,31,279,31,279,31,279,31,280,31,280,32,280,32,280,32,280,32,280,32,280,33,280,33,280,34,280,34,281,34,281,34,281,34,281,35,281,35,281,36,281,36,282,36,282,36,281,37,281,37,280,38,280,38,280,38,280,38,280,38,280,38,278,38,274,38,270,38,269,38,269,38;439,37,439,37,439,36,439,36,439,35,438,35,438,35,438,34,438,33,438,33,437,32,437,32,437,32,437,29,437,29,438,28,444,28,444,29,444,29,445,29,446,29,449,29,450,29,450,30,450,31,450,31,450,31,450,31,450,31,450,32,450,32,450,32,451,32,451,32,451,33,451,33,451,34,451,34,451,34,451,34,452,34,452,35,452,35,452,36,452,36,452,36,452,36,452,37,451,37,451,38,451,38,450,38,450,38,450,38,450,38,448,38,445,38,441,38,440,38,439,38;36,32,35,32,33,32,30,32,29,32,29,32,29,32,27,32,24,32,19,32,19,30,19,29,19,29,20,29,20,28,20,28,20,28,20,27,20,27,21,27,21,26,22,26,22,26,22,25,22,25,22,25,23,24,23,24,23,24,23,23,23,23,24,23,24,22,24,22,24,22,24,21,24,21,25,21,25,20,26,20,26,19,26,19,26,19,26,19,26,19,26,19,26,18,26,18,27,17,27,17,28,16,28,16,28,16,28,15,29,15,29,14,30,13,32,13,33,14,33,15,34,15,35,15,35,15,36,15,36,15,36,16,37,18,37,18,38,18,44,23,44,24,44,24,44,25,45,26,46,26,47,27,47,28,47,28,47,28,47,28,48,28,48,29,47,29,47,29,47,29,47,29,47,30,46,31,44,31,44,31,43,31,43,31,43,31,42,32,42,32,41,32,40,32,40,32,40,32,40,32,40,32,39,32,39,32,39,33,39,33,38,33,38,33,37,33,36,33,36,33;207,32,205,32,203,32,201,32,200,32,200,32,200,32,198,32,195,32,190,32,190,30,190,29,190,29,190,29,191,28,191,28,191,28,191,27,191,27,192,27,192,26,192,26,192,26,192,25,192,25,193,25,193,24,194,24,194,24,194,23,194,23,194,23,195,22,195,22,195,22,195,21,195,21,196,21,196,20,196,20,196,19,196,19,196,19,197,19,197,19,197,19,197,18,197,18,197,17,198,17,198,16,199,16,199,16,199,15,199,15,200,14,201,13,203,13,204,14,204,15,205,15,205,15,206,15,206,15,206,15,206,16,208,18,208,18,209,18,214,23,214,24,214,24,215,25,216,26,217,26,218,27,218,28,218,28,218,28,218,28,218,28,218,29,218,29,218,29,218,29,218,29,218,30,217,31,215,31,214,31,214,31,214,31,214,31,213,32,212,32,211,32,211,32,211,32,211,32,211,32,210,32,210,32,210,32,210,33,210,33,209,33,208,33,207,33,207,33,207,33;378,32,376,32,374,32,372,32,370,32,370,32,370,32,368,32,365,32,360,32,360,30,360,29,360,29,361,29,361,28,362,28,362,28,362,27,362,27,362,27,363,26,363,26,363,26,363,25,363,25,364,25,364,24,364,24,364,24,364,23,364,23,365,23,365,22,366,22,366,22,366,21,366,21,366,21,367,20,367,20,367,19,367,19,367,19,367,19,367,19,368,19,368,18,368,18,368,17,369,17,369,16,370,16,370,16,370,15,370,15,370,14,371,13,374,13,375,14,375,15,375,15,376,15,377,15,377,15,377,15,377,16,378,18,379,18,379,18,385,23,385,24,385,24,386,25,387,26,387,26,388,27,388,28,388,28,388,28,389,28,389,28,389,29,389,29,388,29,388,29,388,29,388,30,387,31,386,31,385,31,384,31,384,31,384,31,384,32,383,32,382,32,382,32,382,32,382,32,381,32,381,32,380,32,380,32,380,33,380,33,380,33,379,33,378,33,378,33,378,33;69,30,69,30,69,30,69,30,70,29,70,29,70,28,70,28,70,28,70,28,70,27,70,27,70,26,70,26,71,26,71,26,71,26,71,25,71,24,71,23,72,23,73,23,73,23,73,22,73,22,73,22,73,22,73,22,74,21,74,21,74,20,74,19,74,19,75,19,75,18,75,18,75,18,75,17,76,17,76,17,76,16,76,16,76,15,78,14,78,14,78,14,79,13,80,12,81,11,81,11,83,11,84,11,84,11,85,12,85,12,85,12,86,12,86,12,87,12,87,13,87,13,88,14,89,14,89,14,90,14,90,14,90,15,91,15,91,15,92,15,92,15,92,15,92,15,93,16,94,16,95,16,96,16,96,17,96,18,96,18,97,18,97,18,97,18,97,19,97,19,97,20,97,20,96,20,96,20,96,21,96,22,96,23,95,23,95,24,94,24,94,24,94,24,93,24,93,25,93,25,92,26,92,26,91,26,90,26,90,26,89,27,89,27,88,27,87,27,87,27,87,27,87,27,86,28,85,28,84,28,84,28,84,28,84,28,83,28,82,28,80,28,80,28,80,29,80,29,79,29,79,29,78,29,78,29,78,29,78,29,78,30,77,30,76,30,76,30,75,30,75,31,74,31,73,31,73,31,72,31,72,31,72,32,70,32,69,31;239,30,239,30,240,30,240,30,240,29,240,29,240,28,240,28,241,28,241,28,241,27,241,27,241,26,241,26,241,26,241,26,242,26,242,25,242,24,242,23,243,23,243,23,244,23,244,22,244,22,244,22,244,22,244,22,244,21,244,21,244,20,244,19,245,19,245,19,246,18,246,18,246,18,246,17,246,17,247,17,247,16,247,16,247,15,248,14,249,14,249,14,250,13,251,12,252,11,252,11,253,11,254,11,255,11,255,12,255,12,256,12,257,12,257,12,258,12,258,13,258,13,259,14,259,14,260,14,260,14,261,14,261,15,261,15,262,15,262,15,263,15,263,15,263,15,264,16,264,16,266,16,267,16,267,17,267,18,267,18,267,18,267,18,268,18,268,19,268,19,267,20,267,20,267,20,267,20,267,21,267,22,267,23,266,23,266,24,265,24,265,24,265,24,264,24,264,25,264,25,263,26,262,26,261,26,261,26,261,26,260,27,260,27,259,27,258,27,258,27,258,27,258,27,257,28,256,28,255,28,254,28,254,28,254,28,253,28,252,28,251,28,250,28,250,29,250,29,250,29,250,29,249,29,249,29,249,29,249,29,248,30,248,30,247,30,246,30,246,30,245,31,245,31,244,31,243,31,243,31,243,31,243,32,240,32,240,31;410,30,410,30,411,30,411,30,411,29,411,29,411,28,411,28,411,28,411,28,412,27,412,27,412,26,412,26,412,26,412,26,412,26,412,25,412,24,413,23,414,23,414,23,414,23,414,22,414,22,414,22,415,22,415,22,415,21,415,21,415,20,415,19,416,19,416,19,416,18,416,18,416,18,416,17,417,17,417,17,418,16,418,16,418,15,419,14,420,14,420,14,420,13,421,12,422,11,423,11,424,11,425,11,425,11,426,12,426,12,427,12,427,12,428,12,428,12,429,13,429,13,429,14,430,14,430,14,431,14,431,14,431,15,432,15,433,15,433,15,434,15,434,15,434,15,434,16,435,16,437,16,438,16,438,17,438,18,438,18,438,18,438,18,438,18,438,19,438,19,438,20,438,20,438,20,438,20,438,21,438,22,437,23,437,23,436,24,436,24,435,24,435,24,435,24,435,25,434,25,434,26,433,26,432,26,431,26,431,26,431,27,430,27,429,27,429,27,428,27,428,27,428,27,427,28,427,28,426,28,425,28,425,28,425,28,424,28,423,28,422,28,421,28,421,29,421,29,421,29,420,29,420,29,420,29,420,29,420,29,419,30,418,30,417,30,417,30,417,30,416,31,416,31,415,31,414,31,414,31,414,31,414,32,411,32,411,31;164,30,163,30,162,30,160,30,160,30,160,30,160,30,158,30,155,30,151,30,151,29,151,29,150,28,150,28,149,28,147,28,147,28,146,27,145,26,145,26,145,26,145,26,146,25,146,24,146,23,146,23,146,23,146,23,146,22,145,22,145,21,144,20,144,20,144,20,144,19,144,19,143,19,143,18,143,18,143,18,143,17,142,17,142,17,142,17,142,17,143,17,143,16,143,16,143,15,143,15,143,15,143,15,144,14,144,13,144,12,143,11,143,11,143,11,143,11,143,10,143,10,143,10,144,10,144,10,145,10,145,10,145,10,145,10,145,10,146,10,147,10,151,10,154,10,156,9,156,9,156,9,157,9,160,9,163,9,165,9,165,9,165,9,165,10,165,10,166,10,166,10,166,10,167,10,167,11,166,11,166,12,165,12,165,12,165,12,164,13,164,13,163,14,163,16,164,17,164,17,164,17,164,18,164,18,164,19,165,19,165,19,165,19,165,20,165,20,165,20,165,20,165,20,166,21,166,21,166,22,166,22,166,22,166,22,166,22,166,23,166,23,166,24,167,24,167,24,167,24,167,25,167,27,167,27,166,28,166,28,166,29,166,29,166,30,165,30,165,30,164,31,164,31,164,31;167,29,168,28,169,28,169,28,170,28,170,29,170,30,169,31,168,31,167,31,167,31,167,30;334,30,333,30,332,30,331,30,330,30,330,30,330,30,329,30,326,30,322,30,322,29,321,29,321,28,320,28,319,28,318,28,318,28,317,27,316,26,316,26,316,26,316,26,316,25,316,24,316,23,316,23,317,23,317,23,317,22,316,22,315,21,315,20,315,20,315,20,315,19,314,19,314,19,314,18,314,18,314,18,313,17,313,17,313,17,313,17,313,17,313,17,314,16,314,16,314,15,314,15,314,15,314,15,314,14,314,13,314,12,314,11,314,11,314,11,314,11,314,10,314,10,314,10,314,10,315,10,316,10,316,10,316,10,316,10,316,10,316,10,318,10,321,10,324,10,326,9,326,9,326,9,328,9,331,9,334,9,336,9,336,9,336,9,336,10,336,10,336,10,337,10,337,10,337,10,337,11,337,11,336,12,336,12,336,12,335,12,335,13,334,13,333,14,333,16,334,17,335,17,335,17,335,18,335,18,335,19,335,19,335,19,336,19,336,20,336,20,336,20,336,20,336,20,336,21,336,21,336,22,336,22,337,22,337,22,337,22,337,23,337,23,337,24,337,24,337,24,338,24,338,25,338,27,337,27,337,28,336,28,336,29,336,29,336,30,336,30,336,30,335,31,334,31,334,31;338,29,339,28,340,28,340,28,340,28,340,29,340,30,340,31,338,31,338,31,338,31,338,30;505,30,504,30,503,30,502,30,501,30,501,30,501,30,499,30,497,30,493,30,492,29,492,29,491,28,491,28,490,28,489,28,488,28,487,27,487,26,486,26,486,26,487,26,487,25,487,24,487,23,487,23,487,23,488,23,487,22,487,22,486,21,486,20,486,20,486,20,485,19,485,19,484,19,484,18,484,18,484,18,484,17,484,17,483,17,483,17,484,17,484,17,484,16,484,16,484,15,484,15,485,15,485,15,485,14,485,13,485,12,485,11,485,11,484,11,484,11,484,10,484,10,484,10,485,10,486,10,486,10,486,10,486,10,487,10,487,10,487,10,488,10,492,10,495,10,497,9,497,9,497,9,499,9,502,9,504,9,506,9,506,9,506,9,506,10,507,10,507,10,507,10,508,10,508,10,508,11,507,11,507,12,506,12,506,12,506,12,505,13,505,13,504,14,504,16,505,17,505,17,506,17,506,18,506,18,506,19,506,19,506,19,506,19,506,20,506,20,506,20,507,20,507,20,507,21,507,21,507,22,507,22,507,22,507,22,508,22,508,23,508,23,508,24,508,24,508,24,508,24,508,25,508,27,508,27,508,28,507,28,507,29,507,29,507,30,507,30,506,30,506,31,505,31,505,31;508,29,510,28,510,28,511,28,511,28,511,29,511,30,510,31,509,31,508,31,508,31,508,30;63,30,62,30,61,30,60,30,60,29,60,29,60,29,58,29,57,29,55,29,54,29,54,29,54,30,50,30,49,29,49,29,49,27,49,22,49,17,49,15,49,15,49,15,50,14,50,14,50,13,50,12,52,12,54,12,54,12,55,13,55,13,55,14,55,14,56,14,56,14,57,15,58,16,59,16,59,16,59,16,60,17,61,18,61,18,62,19,63,19,63,19,64,19,64,20,64,20,65,20,65,20,65,20,66,20,66,21,66,21,67,22,67,22,67,22,68,22,68,23,68,23,68,24,69,24,69,24,69,24,69,24,69,25,69,25,69,25,68,25,68,25,68,26,68,26,68,27,68,27,67,27,67,28,67,28,67,29,65,30,64,30,63,30,63,30,63,30;127,30,126,30,124,30,122,30,122,29,122,29,122,28,121,28,121,28,121,28,121,27,121,25,121,21,121,21,122,20,122,20,123,20,128,20,134,20,135,21,136,21,136,22,136,22,136,22,136,23,137,23,137,23,138,24,138,25,138,25,138,26,138,26,139,26,139,27,139,27,139,27,139,28,140,28,140,28,140,29,140,29,140,30,134,30,129,30,127,30,127,30;234,30,233,30,232,30,231,30,230,29,230,29,230,29,229,29,228,29,226,29,225,29,225,29,225,30,221,30,220,29,220,29,220,27,220,22,220,17,220,15,220,15,220,15,220,14,220,14,220,13,221,12,223,12,224,12,225,12,225,13,225,13,226,14,226,14,226,14,227,14,228,15,229,16,229,16,230,16,230,16,230,17,231,18,232,18,233,19,233,19,234,19,234,19,235,20,235,20,235,20,236,20,236,20,236,20,237,21,237,21,237,22,237,22,238,22,239,22,239,23,239,23,239,24,239,24,239,24,240,24,240,24,240,25,239,25,239,25,239,25,239,25,239,26,239,26,239,27,238,27,238,27,238,28,238,28,238,29,236,30,235,30,234,30,234,30,234,30;298,30,296,30,295,30,292,30,292,29,292,29,292,28,292,28,292,28,292,28,292,27,292,25,292,21,292,21,292,20,293,20,293,20,299,20,305,20,306,21,306,21,307,22,307,22,307,22,307,23,308,23,308,23,308,24,308,25,308,25,308,26,309,26,309,26,310,27,310,27,310,27,310,28,310,28,311,28,311,29,311,29,311,30,304,30,300,30,298,30,298,30;404,30,403,30,403,30,402,30,401,29,401,29,401,29,400,29,398,29,397,29,396,29,396,29,396,30,391,30,391,29,390,29,390,27,390,22,390,17,390,15,391,15,391,15,391,14,391,14,391,13,392,12,394,12,395,12,395,12,396,13,396,13,397,14,397,14,397,14,398,14,399,15,399,16,400,16,400,16,400,16,401,17,402,18,403,18,403,19,404,19,404,19,405,19,405,20,405,20,406,20,406,20,406,20,407,20,407,21,407,21,408,22,408,22,409,22,410,22,410,23,410,23,410,24,410,24,410,24,410,24,410,24,410,25,410,25,410,25,410,25,410,25,410,26,410,26,409,27,409,27,408,27,408,28,408,28,408,29,407,30,405,30,405,30,404,30,404,30;468,30,467,30,466,30,463,30,463,29,463,29,463,28,463,28,463,28,462,28,462,27,462,25,462,21,462,21,463,20,464,20,464,20,469,20,475,20,476,21,477,21,478,22,478,22,478,22,478,23,478,23,479,23,479,24,479,25,479,25,479,26,480,26,480,26,480,27,480,27,480,27,480,28,481,28,481,28,482,29,482,29,482,30,475,30,471,30,468,30,468,30;112,28,111,28,110,28,108,28,107,27,107,27,107,27,106,27,105,27,103,27,102,27,102,27,102,26,101,26,100,26,99,26,98,26,98,25,97,25,97,24,97,24,97,24,98,23,98,22,98,20,98,20,98,20,98,20,98,19,98,19,98,18,98,18,98,18,97,18,97,17,98,16,99,16,100,16,100,16,100,16,101,15,101,15,101,15,102,15,104,15,106,15,107,15,107,15,107,14,107,14,108,14,108,14,109,14,109,14,109,13,116,20,116,21,116,21,117,22,118,23,119,24,119,24,119,25,119,26,119,26,119,26,120,26,120,27,119,28,118,28,112,28,112,28;283,28,282,28,280,28,279,28,278,27,278,27,278,27,277,27,275,27,274,27,273,27,273,27,273,26,272,26,271,26,269,26,269,26,268,25,267,25,267,24,268,24,268,24,268,23,268,22,268,20,268,20,269,20,269,20,269,19,269,19,269,18,269,18,269,18,268,18,268,17,269,16,269,16,270,16,271,16,271,16,272,15,272,15,272,15,273,15,275,15,276,15,278,15,278,15,278,14,278,14,278,14,279,14,280,14,280,14,280,13,287,20,287,21,287,21,287,22,288,23,289,24,290,24,290,25,290,26,290,26,290,26,290,26,290,27,290,28,289,28,283,28,283,28;454,28,452,28,451,28,449,28,448,27,448,27,448,27,447,27,446,27,445,27,444,27,444,27,444,26,443,26,442,26,440,26,440,26,439,25,438,25,438,24,439,24,439,24,439,23,439,22,439,20,439,20,439,20,439,20,440,19,440,19,440,18,439,18,439,18,439,18,439,17,440,16,440,16,441,16,441,16,442,16,442,15,442,15,442,15,443,15,445,15,447,15,448,15,448,15,448,14,449,14,449,14,450,14,450,14,450,14,450,13,458,20,458,21,458,21,458,22,459,23,460,24,460,24,460,25,460,26,460,26,461,26,461,26,461,27,460,28,460,28,454,28,454,28;46,25,46,24,46,24,46,24,45,24,45,24,44,24,41,20,41,20,41,20,42,19,42,19,42,18,42,17,42,17,43,16,43,16,45,16,47,16,48,16,48,21,48,24,47,25,47,25,46,26,46,26,46,25;216,25,216,24,216,24,216,24,216,24,216,24,215,24,211,20,212,20,212,20,212,19,212,19,212,18,213,17,213,17,214,16,214,16,216,16,218,16,218,16,218,21,218,24,218,25,218,25,217,26,217,26,217,25;387,25,387,24,387,24,387,24,387,24,386,24,386,24,382,20,382,20,383,20,383,19,383,19,383,18,383,17,384,17,384,16,385,16,386,16,389,16,389,16,389,21,389,24,389,25,388,25,388,26,388,26,387,25;168,22,168,22,168,22,167,22,167,22,167,21,167,20,167,20,166,19,166,19,166,18,166,18,166,17,165,16,165,16,164,15,164,14,165,14,165,14,166,13,167,12,169,9,170,10,170,13,170,14,170,16,170,16,170,16,170,22,170,22,169,23,168,23,168,23;339,22,339,22,338,22,338,22,338,22,338,21,338,20,337,20,337,19,336,19,336,18,336,18,336,17,336,16,336,16,335,15,335,14,335,14,336,14,337,13,338,12,340,9,340,10,340,13,340,14,340,16,341,16,341,16,341,22,340,22,340,23,339,23,339,23;510,22,509,22,509,22,508,22,508,22,508,21,508,20,508,20,508,19,507,19,507,18,507,18,507,17,507,16,506,16,505,15,505,14,506,14,506,14,507,13,508,12,511,9,511,10,511,13,511,14,511,16,511,16,512,16,512,22,511,22,510,23,510,23,510,23;119,22,119,22,118,22,118,22,118,21,118,21,118,20,117,20,117,20,117,20,117,20,117,20,117,19,117,19,119,19,120,19,120,21,120,22,120,22,120,22,119,22,119,22,119,22;290,22,289,22,289,22,288,22,288,21,288,21,288,20,288,20,288,20,288,20,288,20,288,20,288,19,288,19,289,19,291,19,291,21,291,22,291,22,290,22,290,22,290,22,290,22;460,22,460,22,460,22,459,22,459,21,459,21,459,20,459,20,459,20,458,20,458,20,458,20,458,19,458,19,460,19,462,19,462,21,462,22,461,22,461,22,460,22,460,22,460,22;138,21,138,20,138,20,138,20,138,19,139,19,139,19,139,19,140,19,140,20,140,20,140,20,140,21,139,22,139,21,139,21,138,21,138,21;308,21,308,20,308,20,308,20,309,19,310,19,310,19,310,19,310,19,311,20,311,20,311,20,311,21,310,22,309,21,309,21,309,21,309,21;479,21,479,20,479,20,479,20,480,19,480,19,480,19,481,19,481,19,481,20,482,20,482,20,482,21,481,22,480,21,480,21,479,21,479,21;2,16,2,16,2,15,3,15,3,14,3,13,3,12,3,12,4,12,4,12,4,12,4,12,4,12,4,12,5,12,5,12,6,11,6,11,6,11,6,11,7,11,8,11,8,11,8,11,8,10,9,10,9,10,10,10,10,10,10,10,10,10,11,10,12,10,12,10,13,9,13,9,13,9,14,9,16,9,18,9,19,9,19,9,19,9,19,10,20,10,21,10,22,10,22,10,22,10,22,10,22,10,23,10,24,11,24,11,25,12,25,12,25,14,25,15,25,16,25,16,24,16,24,16,24,17,24,19,24,20,22,20,21,20,21,20,21,20,21,20,19,20,16,20,12,20,10,20,10,21,10,21,9,21,6,21,2,21,2,18;172,16,172,16,173,15,173,15,174,14,174,13,174,12,174,12,174,12,175,12,175,12,175,12,175,12,175,12,176,12,176,12,176,11,176,11,176,11,177,11,178,11,178,11,179,11,179,11,179,10,179,10,180,10,180,10,181,10,181,10,181,10,181,10,182,10,183,10,184,9,184,9,184,9,185,9,187,9,188,9,190,9,190,9,190,9,190,10,191,10,192,10,192,10,192,10,192,10,193,10,193,10,193,10,194,11,195,11,195,12,196,12,196,14,196,15,195,16,195,16,195,16,195,16,195,17,195,19,194,20,193,20,192,20,192,20,192,20,192,20,190,20,186,20,183,20,181,20,181,21,181,21,179,21,177,21,172,21,172,18;343,16,343,16,344,15,344,15,344,14,344,13,344,12,344,12,345,12,345,12,346,12,346,12,346,12,346,12,346,12,347,12,347,11,347,11,347,11,347,11,348,11,349,11,350,11,350,11,350,10,350,10,351,10,351,10,352,10,352,10,352,10,352,10,353,10,354,10,354,9,354,9,354,9,355,9,357,9,359,9,360,9,360,9,360,9,361,10,362,10,362,10,363,10,363,10,363,10,363,10,364,10,364,10,365,11,365,11,366,12,366,12,366,14,366,15,366,16,366,16,366,16,366,16,366,17,366,19,365,20,363,20,363,20,362,20,362,20,362,20,360,20,357,20,354,20,352,20,352,21,352,21,350,21,347,21,343,21,343,18;120,18,119,18,117,18,114,18,114,17,114,17,114,16,114,16,115,16,115,16,115,16,115,16,115,15,115,15,115,15,116,15,117,14,118,13,119,12,120,11,120,11,120,11,121,10,122,10,123,8,126,8,128,8,129,8,129,9,129,9,130,9,132,9,134,9,135,9,135,9,135,9,136,10,138,10,141,10,142,10,142,10,142,11,142,11,142,11,142,11,142,12,142,13,142,13,142,14,142,14,142,14,142,15,142,15,142,16,141,16,141,16,141,16,140,16,140,17,139,17,139,18,137,18,136,18,136,18,136,18,136,18,133,18,128,18,123,18,120,18,120,18;291,18,290,18,288,18,285,18,285,17,285,17,285,16,285,16,285,16,285,16,286,16,286,16,286,15,286,15,286,15,286,15,287,14,289,13,290,12,291,11,291,11,291,11,292,10,293,10,294,8,297,8,298,8,300,8,300,9,300,9,301,9,303,9,304,9,306,9,306,9,306,9,307,10,309,10,312,10,312,10,312,10,312,11,312,11,313,11,313,11,313,12,313,13,313,13,313,14,313,14,312,14,312,15,312,15,312,16,312,16,312,16,311,16,311,16,311,17,310,17,310,18,308,18,307,18,306,18,306,18,306,18,303,18,299,18,294,18,291,18,291,18;462,18,460,18,459,18,456,18,456,17,456,17,456,16,456,16,456,16,456,16,456,16,456,16,456,15,456,15,457,15,457,15,458,14,459,13,460,12,461,11,462,11,462,11,462,10,463,10,464,8,467,8,469,8,470,8,470,9,470,9,471,9,473,9,475,9,476,9,476,9,476,9,478,10,480,10,483,10,483,10,483,10,483,11,483,11,483,11,483,11,484,12,484,13,484,13,483,14,483,14,483,14,483,15,483,15,483,16,483,16,482,16,482,16,481,16,481,17,481,17,480,18,479,18,478,18,477,18,477,18,477,18,474,18,469,18,464,18,462,18,462,18;26,15,26,15,26,14,27,14,27,14,27,14,26,13,26,12,27,11,28,10,28,10,28,10,28,11,29,11,29,11,30,11,30,12,28,13,27,14,27,15,27,15,27,16,27,16,26,16,26,16,26,16,26,16;196,15,197,15,197,14,197,14,198,14,197,14,197,13,197,12,198,11,198,10,199,10,199,10,199,11,199,11,200,11,201,11,200,12,199,13,198,14,198,15,198,15,198,16,197,16,197,16,196,16,196,16,196,16;367,15,367,15,368,14,368,14,368,14,368,14,367,13,367,12,368,11,369,10,369,10,369,10,369,11,370,11,370,11,371,11,371,12,370,13,369,14,368,15,368,15,368,16,368,16,368,16,367,16,367,16,367,16;0,12,0,12,1,12,1,12,2,12,2,13,2,14,1,16,0,16,0,16,0,15,0,14;61,15,61,15,60,15,60,15,59,15,59,14,59,14,58,14,58,14,58,14,58,13,58,13,58,13,57,12,57,12,57,12,57,12,57,12,57,12,58,11,58,11,58,10,58,9,58,9,59,9,59,8,59,8,59,7,59,7,59,7,60,6,63,6,63,7,63,7,64,7,65,7,66,7,67,7,67,7,67,7,67,8,68,8,68,8,69,8,69,8,69,8,70,8,72,8,73,8,74,8,74,9,74,9,75,9,75,9,76,9,76,9,76,9,76,9,77,10,77,10,77,10,78,10,78,10,79,11,79,12,78,12,78,12,77,13,77,14,75,15,75,15,74,15,73,15,73,15,73,15,73,15,71,16,67,16,63,16,61,15,61,15;171,12,171,12,172,12,172,12,172,12,172,13,172,14,172,16,171,16,171,16,171,15,171,14;232,15,231,15,231,15,231,15,230,15,230,14,230,14,229,14,229,14,228,14,228,13,228,13,228,13,228,12,228,12,227,12,227,12,228,12,228,12,228,11,228,11,228,10,228,9,229,9,229,9,230,8,230,8,230,7,230,7,230,7,231,6,234,6,234,7,234,7,234,7,236,7,237,7,238,7,238,7,238,7,238,8,239,8,239,8,240,8,240,8,240,8,241,8,242,8,244,8,245,8,245,9,245,9,245,9,246,9,246,9,247,9,247,9,247,9,247,10,248,10,248,10,249,10,249,10,250,11,250,12,249,12,249,12,248,13,247,14,246,15,246,15,245,15,244,15,244,15,244,15,244,15,241,16,238,16,234,16,232,15,232,15;342,12,342,12,342,12,343,12,343,12,343,13,343,14,342,16,342,16,342,16,342,15,342,14;402,15,402,15,402,15,401,15,401,15,401,14,400,14,400,14,399,14,399,14,399,13,399,13,399,13,399,12,398,12,398,12,398,12,398,12,399,12,399,11,399,11,399,10,399,9,400,9,400,9,400,8,400,8,400,7,400,7,401,7,401,6,404,6,404,7,404,7,405,7,406,7,407,7,408,7,408,7,408,7,409,8,409,8,410,8,410,8,410,8,410,8,411,8,413,8,414,8,416,8,416,9,416,9,416,9,417,9,417,9,418,9,418,9,418,9,418,10,418,10,419,10,419,10,420,10,420,11,420,12,420,12,419,12,419,13,418,14,417,15,416,15,415,15,415,15,414,15,414,15,414,15,412,16,408,16,404,16,402,15,402,15;38,14,37,14,37,14,36,14,36,14,36,14,36,14,35,14,35,14,35,14,34,13,34,13,34,12,33,12,33,12,32,12,32,11,32,11,32,10,33,9,34,9,35,9,36,9,36,9,36,9,36,10,37,10,38,10,38,10,38,10,38,10,39,10,39,10,39,10,39,10,40,10,41,10,41,9,43,8,45,6,46,6,46,7,46,7,46,8,47,8,47,8,47,8,47,9,47,9,47,10,47,10,47,10,48,10,48,10,48,11,48,11,48,11,49,11,48,13,47,14,46,15,42,15,39,15,38,15,38,15;111,13,110,13,110,13,110,13,110,13,110,13,110,12,109,12,109,12,108,12,108,12,108,13,108,13,108,13,108,13,107,13,107,13,107,13,107,13,106,14,105,14,104,14,104,14,104,14,104,14,102,14,102,13,101,13,101,12,101,12,101,12,101,12,101,12,100,12,100,11,100,11,100,10,102,8,103,8,103,8,104,8,104,8,104,8,105,8,109,8,114,8,114,8,115,8,115,9,116,9,116,11,116,12,115,13,115,13,115,13,115,13,115,13,115,15,113,15,112,14;208,14,208,14,207,14,207,14,206,14,206,14,206,14,206,14,206,14,205,14,205,13,205,13,204,12,204,12,204,12,203,12,202,11,202,11,202,10,204,9,205,9,206,9,206,9,206,9,206,9,207,10,207,10,208,10,209,10,209,10,209,10,209,10,209,10,209,10,210,10,211,10,212,10,212,9,214,8,215,6,217,6,217,7,217,7,217,8,217,8,217,8,218,8,218,9,218,9,218,10,218,10,218,10,218,10,218,10,218,11,218,11,219,11,219,11,219,13,218,14,217,15,212,15,210,15,208,15,208,15;282,13,281,13,281,13,280,13,280,13,280,13,280,12,280,12,280,12,279,12,279,12,279,13,279,13,279,13,278,13,278,13,278,13,278,13,278,13,277,14,276,14,275,14,274,14,274,14,274,14,273,14,272,13,272,13,272,12,272,12,272,12,271,12,271,12,271,12,271,10,272,9,272,9,273,8,273,8,274,8,274,8,274,8,274,8,276,8,279,8,284,8,285,8,285,8,286,9,286,9,286,11,286,12,286,13,286,13,286,13,286,13,286,13,286,15,283,15,282,14;379,14,378,14,378,14,377,14,377,14,377,14,377,14,377,14,376,14,376,14,375,13,375,13,375,12,374,12,374,12,374,12,373,11,373,11,373,10,374,9,376,9,376,9,377,9,377,9,377,9,377,10,378,10,379,10,380,10,380,10,380,10,380,10,380,10,380,10,381,10,381,10,382,10,383,9,384,8,386,6,388,6,388,7,388,7,388,8,388,8,388,8,388,8,388,9,388,9,388,10,389,10,389,10,389,10,389,10,389,11,389,11,389,11,390,11,389,13,388,14,387,15,383,15,380,15,379,15,379,15;452,13,452,13,451,13,451,13,451,13,451,13,451,12,451,12,450,12,450,12,450,12,450,13,450,13,449,13,449,13,448,13,448,13,448,13,448,13,447,14,447,14,446,14,445,14,445,14,445,14,444,14,443,13,443,13,442,12,442,12,442,12,442,12,442,12,441,12,442,10,442,9,443,9,444,8,444,8,444,8,445,8,445,8,445,8,447,8,450,8,455,8,455,8,456,8,457,9,457,9,457,11,457,12,457,13,457,13,456,13,456,13,456,13,456,15,454,15,453,14;98,13,96,13,94,13,92,13,90,13,90,13,90,12,90,12,89,12,89,12,88,12,88,12,88,11,87,11,86,11,86,11,86,11,86,10,86,10,85,9,85,9,85,9,85,9,85,9,85,9,86,9,86,8,86,7,86,7,88,7,89,7,90,7,90,7,90,6,90,6,91,6,92,6,92,6,92,7,92,7,93,7,94,7,96,7,97,7,98,8,99,9,99,9,99,11,99,11,99,12,99,12,99,12,100,12,100,13,100,13,99,14,99,14,98,14,98,13,98,13;268,13,267,13,265,13,262,13,261,13,261,13,261,12,260,12,260,12,259,12,259,12,259,12,258,11,258,11,257,11,256,11,256,11,256,10,256,10,256,9,256,9,255,9,255,9,256,9,256,9,256,9,256,8,256,7,257,7,259,7,259,7,260,7,260,7,260,6,261,6,262,6,262,6,263,6,263,7,263,7,264,7,265,7,267,7,267,7,268,8,269,9,270,9,270,11,270,11,270,12,270,12,270,12,270,12,270,13,270,13,270,14,269,14,269,14,268,13,268,13;439,13,437,13,435,13,433,13,432,13,432,13,432,12,431,12,431,12,430,12,429,12,429,12,429,11,428,11,428,11,427,11,427,11,427,10,427,10,427,9,426,9,426,9,426,9,426,9,427,9,427,9,427,8,427,7,428,7,429,7,430,7,431,7,431,7,431,6,431,6,432,6,433,6,434,6,434,7,434,7,434,7,436,7,438,7,438,7,439,8,440,9,440,9,440,11,440,11,440,12,441,12,441,12,441,12,441,13,441,13,441,14,440,14,439,14,439,13,439,13;2,7,3,7,4,7,4,7,4,8,4,8,4,9,5,9,5,9,5,9,5,9,4,9,4,10,4,10,4,11,4,11,3,11,2,11,2,9;48,9,48,9,48,8,48,7,48,7,48,7,47,6,47,6,47,6,47,5,47,5,46,5,46,4,46,4,46,3,46,2,46,2,52,2,57,2,58,2,58,2,59,2,59,3,59,3,58,3,58,4,58,5,58,5,58,6,58,6,58,6,58,7,58,7,58,8,57,9,57,9,56,9,56,10,56,10,56,11,56,11,55,11,55,11,54,11,54,10,54,10,54,10,54,10,54,11,53,11,52,11,50,11,50,11,49,10;117,9,119,7,119,8,119,8,119,8,120,8,121,8,121,8,121,9,121,9,121,10,120,10,120,10,119,10,119,10,119,11,118,11,118,11,117,11,117,11,117,10;172,7,174,7,175,7,175,7,175,8,175,8,175,9,175,9,176,9,176,9,175,9,175,9,175,10,175,10,175,11,175,11,174,11,172,11,172,9;219,9,219,9,219,8,219,7,219,7,218,7,218,6,218,6,218,6,218,5,217,5,217,5,216,4,216,4,216,3,216,2,217,2,223,2,228,2,229,2,229,2,230,2,230,3,229,3,229,3,229,4,229,5,229,5,229,6,229,6,228,6,228,7,228,7,228,8,228,9,228,9,227,9,227,10,227,10,227,11,227,11,226,11,225,11,225,11,225,10,225,10,224,10,224,10,224,11,223,11,222,11,221,11,220,11,220,10;288,9,289,7,289,8,289,8,290,8,291,8,291,8,292,8,292,9,292,9,291,10,291,10,291,10,290,10,290,10,290,11,289,11,288,11,288,11,288,11,288,10;343,7,344,7,345,7,346,7,346,8,346,8,346,9,346,9,346,9,346,9,346,9,346,9,346,10,346,10,346,11,345,11,344,11,343,11,343,9;390,9,390,9,390,8,390,7,389,7,389,7,388,6,388,6,388,6,388,5,388,5,388,5,387,4,387,4,387,3,387,2,387,2,394,2,398,2,399,2,400,2,400,2,400,3,400,3,400,3,400,4,400,5,400,5,399,6,399,6,399,6,399,7,399,7,399,8,399,9,398,9,398,9,398,10,398,10,398,11,397,11,397,11,396,11,395,11,395,10,395,10,395,10,395,10,395,11,394,11,393,11,391,11,391,11,390,10;458,9,460,7,460,8,460,8,461,8,461,8,462,8,462,8,462,9,462,9,462,10,462,10,461,10,461,10,461,10,460,11,460,11,459,11,458,11,458,11,458,10;6,8,6,8,6,7,6,7,4,6,3,6,2,6,2,5,2,5,2,5,1,5,1,5,0,5,0,5,0,4,0,2,0,2,1,2,1,2,2,2,2,2,2,2,4,2,7,2,13,2,14,2,14,3,14,3,14,4,15,4,15,4,15,4,15,4,15,4,15,5,16,5,16,5,16,6,16,6,16,7,16,7,15,7,14,7,14,7,13,8,13,8,12,8,11,8,10,8,10,8,10,9,10,9,9,9,9,9,8,9,8,9,8,9,8,10,7,9,6,9;29,9,29,9,28,9,28,9,27,8,27,7,27,6,27,6,28,6,28,6,28,6,28,7,28,7,29,7,29,7,29,7,30,7,30,7,31,8,31,8,31,9,31,9,31,10,30,10,29,10,29,9,29,9;169,8,168,8,168,8,168,8,168,8,168,8,168,7,168,7,168,7,169,7,169,7,169,7,169,6,169,6,170,6,171,6,171,6,171,8,171,9,171,10,170,10,170,10,169,9,169,9;177,8,176,8,176,7,176,7,175,6,173,6,173,6,172,5,172,5,172,5,172,5,172,5,171,5,171,5,171,4,171,2,171,2,172,2,172,2,172,2,172,2,172,2,174,2,178,2,184,2,185,2,185,3,185,3,185,4,185,4,185,4,186,4,186,4,186,4,186,5,186,5,187,5,187,6,187,6,187,7,187,7,186,7,185,7,184,7,184,8,183,8,183,8,182,8,181,8,180,8,180,9,180,9,180,9,180,9,179,9,179,9,179,9,179,10,178,9,177,9;200,9,199,9,199,9,198,9,198,8,198,7,198,6,198,6,198,6,199,6,199,6,199,7,199,7,199,7,200,7,201,7,202,8,202,9,202,9,201,10,201,10,200,10,200,9,200,9;340,8,339,8,339,8,338,8,338,8,338,8,338,7,338,7,339,7,339,7,340,7,340,7,340,6,340,6,341,6,341,6,342,6,342,8,342,9,341,10,341,10,341,10,340,9,340,9;347,8,347,8,347,7,347,7,345,6,344,6,343,6,343,5,343,5,343,5,343,5,342,5,342,5,342,5,342,4,342,2,342,2,342,2,343,2,343,2,343,2,343,2,345,2,349,2,355,2,356,2,356,3,356,3,356,4,356,4,356,4,356,4,356,4,356,4,356,5,357,5,357,5,358,6,358,6,358,7,357,7,356,7,355,7,355,7,355,8,354,8,354,8,352,8,352,8,351,8,351,9,351,9,351,9,350,9,350,9,350,9,350,9,350,10,348,9,348,9;370,9,370,9,370,9,369,9,368,8,368,7,368,6,368,6,369,6,369,6,370,6,370,7,370,7,370,7,370,7,371,7,372,8,372,9,372,9,372,10,371,10,371,10,370,9,370,9;510,8,510,8,509,8,509,8,509,8,509,8,509,7,509,7,510,7,510,7,510,7,510,7,510,6,511,6,511,6,512,6,512,6,512,8,512,9,512,10,512,10,511,10,511,9,511,9;22,8,21,8,20,8,19,8,19,8,19,7,19,6,19,6,19,6,20,6,20,5,21,5,21,4,21,4,23,4,25,4,26,5,26,7,26,7,25,8,25,8,24,9,22,9,22,9;39,8,38,8,37,8,36,8,36,8,36,8,36,8,35,8,34,8,33,8,33,7,33,7,33,7,33,7,32,7,32,7,31,7,31,6,31,6,30,6,30,6,28,6,27,4,27,3,27,3,27,3,28,3,30,3,30,3,31,2,31,2,31,2,33,2,33,2,34,1,34,1,34,1,36,1,38,1,40,1,42,1,42,1,42,1,42,2,42,2,43,2,43,2,43,2,43,2,43,3,44,3,45,4,44,5,43,7,42,7,41,8,41,8,40,8,40,8,40,9,40,9,40,9,40,9,39,9,39,9,39,9;145,8,144,8,143,8,140,8,140,7,140,7,140,6,141,6,141,6,138,3,137,3,137,3,137,3,137,2,137,2,137,2,151,2,165,2,166,2,167,3,167,6,166,7,166,7,166,7,166,8,166,8,165,8,156,8,150,8,146,8,146,9,146,9,146,9,146,9,145,9,145,9,145,9;192,8,192,8,191,8,190,8,190,8,190,7,190,6,190,6,190,6,190,6,191,5,191,5,192,4,192,4,193,4,196,4,196,5,196,7,196,7,196,8,196,8,195,9,192,9,192,9;210,8,209,8,208,8,207,8,206,8,206,8,206,8,206,8,205,8,204,8,204,7,204,7,204,7,203,7,203,7,203,7,202,7,202,6,202,6,201,6,200,6,199,6,198,4,198,3,198,3,198,3,199,3,200,3,201,3,201,2,202,2,202,2,203,2,204,2,205,1,205,1,205,1,206,1,209,1,211,1,212,1,212,1,212,1,212,2,213,2,213,2,214,2,214,2,214,2,214,3,214,3,215,4,215,5,213,7,213,7,212,8,211,8,211,8,211,8,211,9,211,9,211,9,210,9,210,9,210,9,210,9;316,8,315,8,313,8,311,8,311,7,311,7,311,6,311,6,312,6,309,3,308,3,308,3,308,3,308,2,308,2,308,2,322,2,336,2,337,2,338,3,338,6,337,7,336,7,336,7,336,8,336,8,336,8,327,8,320,8,317,8,317,9,317,9,317,9,316,9,316,9,316,9,316,9;363,8,362,8,362,8,360,8,360,8,360,7,360,6,360,6,361,6,361,6,362,5,362,5,362,4,363,4,364,4,366,4,367,5,367,7,367,7,367,8,366,8,366,9,363,9,363,9;380,8,379,8,379,8,378,8,377,8,377,8,377,8,376,8,376,8,375,8,374,7,374,7,374,7,374,7,374,7,373,7,373,7,373,6,372,6,372,6,371,6,370,6,368,4,368,3,368,3,369,3,370,3,371,3,371,3,372,2,372,2,373,2,374,2,375,2,376,1,376,1,376,1,377,1,379,1,381,1,383,1,383,1,383,1,383,2,384,2,384,2,384,2,384,2,384,2,384,3,385,3,386,4,386,5,384,7,383,7,382,8,382,8,382,8,382,8,382,9,382,9,381,9,381,9,380,9,380,9,380,9;486,8,485,8,484,8,482,8,482,7,482,7,482,6,482,6,482,6,479,3,479,3,478,3,478,3,478,2,478,2,478,2,492,2,507,2,507,2,508,3,509,6,508,7,507,7,507,7,507,8,507,8,506,8,497,8,491,8,488,8,488,9,488,9,487,9,487,9,486,9,486,9,486,9;78,7,78,6,78,5,78,5,77,4,77,4,77,4,77,4,77,3,77,2,77,2,78,2,78,2,79,1,79,1,79,1,81,1,84,1,90,1,90,2,90,3,88,4,87,4,87,4,87,4,87,5,86,5,86,6,85,6,85,6,85,6,85,6,85,6,85,6,84,6,84,6,84,6,84,7,84,7,83,7,83,7,82,7,81,7,81,8,81,8,79,8,78,7;248,7,248,6,248,5,248,5,248,4,248,4,248,4,248,4,248,3,248,2,248,2,249,2,249,2,250,1,250,1,250,1,252,1,255,1,260,1,260,2,260,3,259,4,258,4,258,4,257,4,257,5,257,5,256,6,256,6,256,6,256,6,256,6,256,6,255,6,255,6,254,6,254,6,254,7,254,7,254,7,253,7,253,7,252,7,252,8,251,8,250,8,249,7;419,7,419,6,419,5,419,5,419,4,419,4,418,4,418,4,418,3,418,2,418,2,419,2,420,2,420,1,420,1,420,1,422,1,426,1,431,1,431,2,431,3,430,4,429,4,429,4,428,4,428,5,428,5,427,6,427,6,426,6,426,6,426,6,426,6,426,6,426,6,425,6,425,6,425,7,425,7,424,7,424,7,423,7,423,7,423,8,422,8,421,8,420,7;122,7,122,7,121,7,120,7,120,7,119,6,119,6,118,6,118,6,118,6,118,5,118,5,118,4,117,4,117,4,117,4,117,4,117,4,117,3,117,3,118,3,118,3,119,3,119,2,120,2,120,2,125,2,128,2,130,2,130,2,130,2,130,2,132,2,133,2,134,2,134,3,134,3,134,3,134,3,135,3,136,3,136,4,136,4,137,4,137,4,138,4,139,5,139,6,139,6,138,7,136,7,135,7,134,7,134,7,134,6,133,6,132,6,131,6,130,6,130,7,130,7,129,7,127,7,125,7,124,7,124,7,124,7,124,8,123,8,123,8,122,7,122,7;293,7,292,7,292,7,291,7,290,7,290,6,290,6,289,6,289,6,288,6,288,5,288,5,288,4,288,4,288,4,288,4,288,4,288,4,288,3,288,3,288,3,289,3,290,3,290,2,290,2,291,2,295,2,298,2,300,2,300,2,300,2,301,2,302,2,303,2,304,2,304,3,304,3,305,3,305,3,306,3,306,3,307,4,307,4,307,4,308,4,309,4,310,5,310,6,310,6,309,7,307,7,306,7,305,7,305,7,305,6,304,6,303,6,302,6,301,6,301,7,301,7,300,7,298,7,296,7,295,7,295,7,295,7,294,8,294,8,293,8,293,7,293,7;464,7,463,7,462,7,461,7,461,7,461,6,460,6,460,6,459,6,459,6,459,5,459,5,459,4,459,4,459,4,458,4,458,4,458,4,458,3,458,3,459,3,460,3,460,3,461,2,461,2,461,2,466,2,469,2,471,2,471,2,471,2,472,2,473,2,474,2,475,2,475,3,475,3,475,3,476,3,476,3,477,3,477,4,477,4,478,4,478,4,479,4,480,5,480,6,480,6,479,7,477,7,476,7,476,7,476,7,476,6,475,6,474,6,472,6,472,6,472,7,472,7,470,7,469,7,467,7,466,7,466,7,466,7,465,8,465,8,464,8,464,7,464,7;16,5,16,4,16,4,16,3,16,3,17,3,17,3,18,3,18,3,19,4,19,5,18,5,18,5,18,5,18,5,18,6,17,6,17,5;67,5,66,5,65,5,64,5,64,5,64,5,64,4,63,4,63,4,63,4,62,4,62,4,61,3,62,2,64,2,65,2,66,2,66,2,67,1,67,1,67,1,66,1,66,1,66,0,66,0,68,0,71,0,75,0,75,2,75,4,74,4,73,4,72,4,72,4,72,5,72,5,71,5,71,5,70,5,70,5,70,5,70,5,69,6,69,6,68,6,67,5,67,5;88,4,88,4,89,4,89,4,90,4,91,3,91,2,92,2,92,2,93,2,93,1,93,1,93,1,93,1,93,1,93,1,94,2,94,2,95,2,96,2,96,4,96,4,95,5,95,5,94,6,92,6,91,5,91,5,91,5,91,5,91,5,90,6,89,6,88,6,88,5,88,5;97,4,97,3,98,2,98,1,106,1,114,1,115,2,116,2,116,4,115,4,115,4,115,4,115,4,115,5,114,6,106,5,99,5,98,5,97,5;187,5,187,4,187,4,187,3,187,3,188,3,188,3,189,3,189,3,190,4,190,5,189,5,188,5,188,5,188,5,188,6,188,6,187,5;238,5,237,5,236,5,235,5,234,5,234,5,234,4,234,4,234,4,233,4,233,4,233,4,232,3,233,2,235,2,236,2,237,2,237,2,238,1,238,1,237,1,237,1,237,1,237,0,237,0,239,0,241,0,246,0,246,2,246,4,245,4,243,4,243,4,242,4,242,5,242,5,242,5,242,5,241,5,241,5,241,5,241,5,240,6,239,6,238,6,238,5,238,5;259,4,259,4,259,4,260,4,260,4,261,3,262,2,263,2,263,2,263,2,264,1,264,1,264,1,264,1,264,1,264,1,264,2,265,2,266,2,266,2,266,4,266,4,266,5,266,5,265,6,262,6,262,5,262,5,262,5,262,5,262,5,261,6,260,6,259,6,259,5,259,5;267,4,267,3,268,2,269,1,277,1,285,1,285,2,286,2,286,4,286,4,286,4,286,4,286,4,286,5,285,6,276,5,270,5,268,5,268,5;358,5,358,4,358,4,358,3,358,3,358,3,359,3,359,3,360,3,360,4,360,5,360,5,359,5,359,5,359,5,359,6,358,6,358,5;408,5,407,5,407,5,406,5,405,5,405,5,405,4,405,4,404,4,404,4,404,4,403,4,402,3,403,2,406,2,407,2,407,2,408,2,408,1,408,1,408,1,408,1,408,1,408,0,408,0,409,0,412,0,416,0,416,2,416,4,416,4,414,4,413,4,413,4,413,5,413,5,413,5,412,5,412,5,412,5,412,5,412,5,411,6,410,6,409,6,408,5,408,5;430,4,430,4,430,4,430,4,431,4,432,3,433,2,433,2,434,2,434,2,434,1,434,1,434,1,435,1,435,1,435,1,435,2,435,2,436,2,437,2,437,4,437,4,437,5,436,5,436,6,433,6,433,5,433,5,432,5,432,5,432,5,432,6,431,6,430,6,430,5,430,5;438,4,438,3,439,2,440,1,448,1,455,1,456,2,457,2,457,4,457,4,456,4,456,4,456,4,456,5,456,6,447,5,441,5,439,5,439,5;169,4,169,4,169,4,169,4,170,4,170,4,170,4,169,4,169,4,169,4,169,4,169,4;340,4,340,4,340,4,340,4,340,4,340,4,340,4,340,4,340,4,340,4,340,4,340,4;510,4,510,4,511,4,511,4,511,4,511,4,511,4,511,4,511,4,510,4,510,4,510,4;21,2,20,2,18,2,15,2,15,1,15,0,23,0,27,0,30,0,30,0,30,1,29,2,28,2,27,2,26,2,26,2,25,3,25,3,23,3,22,3,21,3,21,3;192,2,190,2,189,2,186,2,186,1,186,0,193,0,197,0,201,0,201,0,201,1,200,2,198,2,197,2,197,2,197,2,196,3,196,3,194,3,192,3,192,3,192,3;362,2,361,2,359,2,356,2,356,1,356,0,364,0,368,0,372,0,372,0,372,1,370,2,369,2,368,2,368,2,367,2,367,3,366,3,364,3,363,3,362,3,362,3;44,0,44,0,45,0,45,0,46,0,46,1,46,1,45,1,45,1,44,1,44,1,44,1;215,0,215,0,216,0,216,0,216,0,216,1,216,1,216,1,216,1,215,1,215,1,215,1;386,0,386,0,386,0,387,0,387,0,387,1,387,1,387,1,386,1,386,1,386,1,386,1 diff --git a/planet/Tests.ocf/Materials.ocs/Scenario.txt b/planet/Tests.ocf/Materials.ocs/Scenario.txt deleted file mode 100644 index 0420b998c..000000000 --- a/planet/Tests.ocf/Materials.ocs/Scenario.txt +++ /dev/null @@ -1,6 +0,0 @@ - -[Definitions] -Definition1=Objects.ocd/Clonk.ocd - -[Landscape] -MapZoom=10 diff --git a/planet/Tests.ocf/Moss_Test.ocs/Map.bmp b/planet/Tests.ocf/Moss_Test.ocs/Map.bmp deleted file mode 100644 index 289ff0c66..000000000 Binary files a/planet/Tests.ocf/Moss_Test.ocs/Map.bmp and /dev/null differ diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png b/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png deleted file mode 100644 index 031bc29b9..000000000 Binary files a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Lichenpart.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt b/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt deleted file mode 100644 index 66e08b86f..000000000 --- a/planet/Tests.ocf/Moss_Test.ocs/Moss.ocd/Lichen.ocd/Lichenpart.ocd/Particle.txt +++ /dev/null @@ -1,15 +0,0 @@ -[Particle] -Name=Lichen -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -DrawFn=Std -Face=0,0,64,64,-32,-32 -Delay=0 -Repeats=1 -GravityAcc=33 -VertexCount=1 -VertexY=0 -AlphaFade=15 -RByV=3 -Attach=0 \ No newline at end of file diff --git a/planet/Tests.ocf/Moss_Test.ocs/Scenario.txt b/planet/Tests.ocf/Moss_Test.ocs/Scenario.txt deleted file mode 100644 index ae3cd08e7..000000000 Binary files a/planet/Tests.ocf/Moss_Test.ocs/Scenario.txt and /dev/null differ diff --git a/planet/Tests.ocf/Moss_Test.ocs/Script.c b/planet/Tests.ocf/Moss_Test.ocs/Script.c deleted file mode 100644 index f7e8fabcd..000000000 --- a/planet/Tests.ocf/Moss_Test.ocs/Script.c +++ /dev/null @@ -1,44 +0,0 @@ -/* MOOSSSSSS */ - -func Initialize() -{ - - - CreateObject(Moss_Lichen,280,380); - CreateObject(Moss_Lichen,166,166); - CreateObject(Moss,470,220); - - Log("Try /fast 10 for faster growing!"); - -} - - func InitializePlayer(int iPlr, int iX, int iY, object pBase, int iTeam) -{ - SetFoW(0,iPlr); - JoinPlayer(iPlr); - return; -} - - func RelaunchPlayer(int iPlr) -{ - var clonk = CreateObject(Clonk, 0, 0, iPlr); - clonk->MakeCrewMember(iPlr); - SetCursor(iPlr,clonk); - JoinPlayer(iPlr); - return; -} - - func JoinPlayer(int iPlr) -{ - var clonk = GetCrew(iPlr); - clonk->DoEnergy(100000); - clonk->SetPosition(150, 100); -// clonk->CreateContents(Javelin); -// clonk->CreateContents(DynamiteBox); - clonk->CreateContents(Sword); - clonk->CreateContents(Firestone); - clonk->CreateContents(Shovel); - clonk->CreateContents(GrappleBow); - return; - -} \ No newline at end of file diff --git a/planet/Tests.ocf/Moss_Test.ocs/Title.txt b/planet/Tests.ocf/Moss_Test.ocs/Title.txt deleted file mode 100644 index 4a84c18f4..000000000 --- a/planet/Tests.ocf/Moss_Test.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Moos Test -US:Moss Test \ No newline at end of file diff --git a/planet/Tests.ocf/OneMillionParticles.ocs/Scenario.txt b/planet/Tests.ocf/OneMillionParticles.ocs/Scenario.txt new file mode 100644 index 000000000..facf2eb51 --- /dev/null +++ b/planet/Tests.ocf/OneMillionParticles.ocs/Scenario.txt @@ -0,0 +1,2 @@ +[Head] +Title=One Million Particles \ No newline at end of file diff --git a/planet/Tests.ocf/OneMillionParticles.ocs/Script.c b/planet/Tests.ocf/OneMillionParticles.ocs/Script.c new file mode 100644 index 000000000..cbfac59dc --- /dev/null +++ b/planet/Tests.ocf/OneMillionParticles.ocs/Script.c @@ -0,0 +1,119 @@ +static const LOG_LINE_LEN = 50; +static PARTICLES; +static const PARTICLE_COUNT = 1000000; // in words ONE MILLION +static const TEST_RUN_COUNT = 2; +static PARTICLES_PER_RUN; + +static MEASUREMENTS; + +func Initialize() +{ + PARTICLES = + { + Prototype = Particles_Glimmer(), + R = PV_Random(0, 255), + G = PV_Random(0, 255), + B = PV_Random(0, 255), + Size = PV_Linear(1, 0), + OnCollision = PC_Bounce(), + ForceX = PV_Random(-5, 5, 10), + ForceY = PV_Random(-5, 5, 10) + }; + PARTICLES_PER_RUN = PARTICLE_COUNT / TEST_RUN_COUNT; + MEASUREMENTS = []; + + Schedule(nil, "Test1()", 1); + // PauseGame(); // used for testing purposes +} + +global func Test1() +{ + var t = GetTime(); + CreateParticle("FireDense", PV_Random(0, LandscapeWidth()), PV_Random(0, LandscapeHeight()/2), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(100, 300), PARTICLES, PARTICLES_PER_RUN); + t = GetTime() - t; + FixLenLog("Test1 - batch creation", t, LOG_LINE_LEN, "ms"); + MEASUREMENTS[0] = t; + Schedule(nil, "Test2()", 36); + // PauseGame(); // used for testing purposes +} + +global func Test2() +{ + var t = GetTime(); + for (var i = 0; i < PARTICLES_PER_RUN; ++i) + CreateParticle("FireDense", PV_Random(0, LandscapeWidth()), PV_Random(0, LandscapeHeight()/2), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(100, 300), PARTICLES); + t = GetTime() - t; + FixLenLog("Test2 - seperate creation", t, LOG_LINE_LEN, "ms"); + MEASUREMENTS[1] = t; + Schedule(nil, "Test3()", 300); + // PauseGame(); // used for testing purposes +} + +global func Test3() +{ + // SPAWN FIRE + for (var fire_count = 20; fire_count > 0; --fire_count) + { + var x = RandomX(100, LandscapeWidth() - 100); + var y = LandscapeHeight() / 2 - 20; + AddEffect("ScorchEverything", nil, 1, 1, nil, nil, x, y); + } +} + +global func FxScorchEverythingStart(target, effect, temp, x, y) +{ + if (temp) return; + effect.x = x; + effect.y = y; + effect.offset = Random(180); + effect.glimmer = + { + Prototype = Particles_Glimmer(), + ForceY = PV_Random(-10, 5), + ForceX = PV_Random(-10, 10, 10) + }; + effect.fire = + { + Prototype = Particles_Fire(), + R = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0), + G = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0), + B = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0), + Alpha = PV_KeyFrames(0, 0, 255, 900, 255, 1000, 0), + Size = PV_KeyFrames(0, 0, 0, 100, PV_Random(10, 20), 1000, PV_Random(20, 30)) + }; + + effect.fire_na = + { + Prototype = effect.fire, + BlitMode = 0 + }; +} + +global func FxScorchEverythingTimer(target, effect, time) +{ + var strength = Abs(Sin(effect.offset + time / 2, 100)); + var glimmer_count = strength / 2; + var fire_density = (strength - 30) / 10; + var glimmer_speed = strength / 4; + CreateParticle("Fire", effect.x, effect.y, PV_Random(-glimmer_speed, glimmer_speed), PV_Random(-glimmer_speed, 5), PV_Random(Max(30, strength), Max(60, strength * 2)), effect.glimmer, glimmer_count); + if (fire_density > 0) + { + var speed = 2 * fire_density; + var size = 2 * fire_density; + effect.fire.Size = PV_KeyFrames(0, 0, 0, 100, PV_Random(size, 2 * size), 900, PV_Random(2 * size, 3 * size), 1000, 0); + CreateParticle("FireDense", effect.x, effect.y, PV_Random(-speed, speed), PV_Random(-speed, speed), PV_Random(30, Min(60, fire_density * 20)), effect.fire_na, fire_density); + CreateParticle("Fire", effect.x, effect.y, PV_Random(-speed, speed), PV_Random(-speed, speed), PV_Random(30, Min(60, fire_density * 20)), effect.fire, fire_density); + } +} + + +global func FixLenLog(string msg, int value, int len, string unit) +{ + len = len ?? 30; + unit = unit ?? ""; + var num_len = 4; + + while (GetLength(msg) < len - num_len) + msg = Format("%s_", msg); + Log("%s%4d%s", msg, value, unit); +} \ No newline at end of file diff --git a/planet/Tests.ocf/PoT.ocs/Map.bmp b/planet/Tests.ocf/PoT.ocs/Map.bmp deleted file mode 100644 index 42f72fc0e..000000000 Binary files a/planet/Tests.ocf/PoT.ocs/Map.bmp and /dev/null differ diff --git a/planet/Tests.ocf/PoT.ocs/Scenario.txt b/planet/Tests.ocf/PoT.ocs/Scenario.txt deleted file mode 100644 index 03a49a457..000000000 --- a/planet/Tests.ocf/PoT.ocs/Scenario.txt +++ /dev/null @@ -1,41 +0,0 @@ -[Head] -Icon=34 -Title=Cavern -Version=5,1,90 - -[Game] -Goals=MELE=0 - -[Player1] -Crew=Clonk=1 - -[Player2] -Crew=Clonk=1 - -[Player3] -Crew=Clonk=1 - -[Player4] -Crew=Clonk=1 - -[Landscape] -InEarth=Rock=1;Firestone=3;Loam=3 -InEarthLevel=80,0,0,100 -Sky=Clouds1 -TopOpen=false -MapWidth=100,0,64,10000 -MapHeight=250,0,40,10000 -SkyScrollMode=2 -NewStyleLandscape=2 - -[Animals] -Nest=Loam=50;Firestone=20 - -[Weather] -Climate=100,0,0,100 -StartSeason=0,0,0,100 -YearSpeed=0,0,0,100 -Wind=1,100,-100,100 - -[Environment] -Objects=Earthquake=10 diff --git a/planet/Tests.ocf/PoT.ocs/Title.txt b/planet/Tests.ocf/PoT.ocs/Title.txt deleted file mode 100644 index d43b35c2a..000000000 --- a/planet/Tests.ocf/PoT.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Power of Two -US:Power of Two \ No newline at end of file diff --git a/planet/Tests.ocf/Pumps.ocs/Map.bmp b/planet/Tests.ocf/Pumps.ocs/Map.bmp new file mode 100644 index 000000000..78dfe62e6 Binary files /dev/null and b/planet/Tests.ocf/Pumps.ocs/Map.bmp differ diff --git a/planet/Tests.ocf/Pumps.ocs/Scenario.txt b/planet/Tests.ocf/Pumps.ocs/Scenario.txt new file mode 100644 index 000000000..5fec6fcf7 --- /dev/null +++ b/planet/Tests.ocf/Pumps.ocs/Scenario.txt @@ -0,0 +1,8 @@ +[Head] +Title=Pumps + +[Landscape] +MapWidth=20 + +[Weather] +Climate=0,0,0,0 diff --git a/planet/Tests.ocf/Pumps.ocs/Script.c b/planet/Tests.ocf/Pumps.ocs/Script.c new file mode 100644 index 000000000..e6fa666a2 --- /dev/null +++ b/planet/Tests.ocf/Pumps.ocs/Script.c @@ -0,0 +1,13 @@ + +func InitializePlayer(int plr) +{ + CreateObject(Flagpole, 100,200, plr); + CreateObject(SteamEngine, 50,200, plr); + CreateObject(Pump, 130,200, plr); + GetCrew(plr)->CreateContents(Pipe); + GetCrew(plr)->CreateContents(Pipe); + GetCrew(plr)->CreateContents(Shovel); + GetCrew(plr)->CreateContents(Coal, 10); + GetCrew(plr)->SetPosition(130,190); + return true; +} diff --git a/planet/Tests.ocf/Pyramid.ocs/DescDE.rtf b/planet/Tests.ocf/Pyramid.ocs/DescDE.rtf deleted file mode 100644 index a622c4a3e..000000000 Binary files a/planet/Tests.ocf/Pyramid.ocs/DescDE.rtf and /dev/null differ diff --git a/planet/Tests.ocf/Pyramid.ocs/DescUS.rtf b/planet/Tests.ocf/Pyramid.ocs/DescUS.rtf deleted file mode 100644 index c68169bda..000000000 Binary files a/planet/Tests.ocf/Pyramid.ocs/DescUS.rtf and /dev/null differ diff --git a/planet/Tests.ocf/Pyramid.ocs/Icon.png b/planet/Tests.ocf/Pyramid.ocs/Icon.png deleted file mode 100644 index 7164713e5..000000000 Binary files a/planet/Tests.ocf/Pyramid.ocs/Icon.png and /dev/null differ diff --git a/planet/Tests.ocf/Pyramid.ocs/Map.bmp b/planet/Tests.ocf/Pyramid.ocs/Map.bmp deleted file mode 100644 index 803cbdc99..000000000 Binary files a/planet/Tests.ocf/Pyramid.ocs/Map.bmp and /dev/null differ diff --git a/planet/Tests.ocf/Pyramid.ocs/Scenario.txt b/planet/Tests.ocf/Pyramid.ocs/Scenario.txt deleted file mode 100644 index 24167814f..000000000 --- a/planet/Tests.ocf/Pyramid.ocs/Scenario.txt +++ /dev/null @@ -1,34 +0,0 @@ -[Head] -Icon=19 -Title=Pyramid -Version=5,2,0,1 -MinPlayer=2 -MaxPlayer=8 - -[Definitions] -Definition1=Objects.ocd - -[Player1] -Crew=Clonk=1 - -[Player2] -Crew=Clonk=1 - -[Player3] -Crew=Clonk=1 - -[Player4] -Crew=Clonk=1 - -[Landscape] -InEarth=Rock=1;Gold=1;Flint=1;Loam=1; -InEarthLevel=65 -Sky=Clouds1;Default -MapWidth=120 -MapHeight=80 -MapZoom=10 - -[Weather] -Climate=40 -YearSpeed=20,10 -Wind=0,100 \ No newline at end of file diff --git a/planet/Tests.ocf/Pyramid.ocs/Script.c b/planet/Tests.ocf/Pyramid.ocs/Script.c deleted file mode 100644 index 6e8944f69..000000000 --- a/planet/Tests.ocf/Pyramid.ocs/Script.c +++ /dev/null @@ -1,105 +0,0 @@ -/*-- - Pyramid - Author: Maikel - - A king of the hill scenario on a pyramid. ---*/ - -protected func Initialize() -{ - // Goal settings. - var goal = CreateObject(Goal_KingOfTheHill, 625, 170, NO_OWNER); - goal->SetRadius(120); - goal->SetPointLimit(6); - - // Weapon chests. - CreateObject(Chest, 690, 210, NO_OWNER); - CreateObject(Chest, 680, 360, NO_OWNER); - CreateObject(Chest, 430, 440, NO_OWNER); - CreateObject(Chest, 200, 760, NO_OWNER); - CreateObject(Chest, 970, 760, NO_OWNER); - CreateObject(Chest, 860, 560, NO_OWNER); - CreateObject(Chest, 670, 610, NO_OWNER); - AddEffect("IntFillChests", nil, 100, 70, this); - - // Brick edges. - var edges = [ - // Left outside part of pyramid. - [190,560],[200,550],[210,540],[220,530],[280,470],[290,460],[300,450],[310,440],[360,390],[370,380],[380,370],[390,360],[400,350],[410,340],[420,330],[480,270],[490,260],[500,250],[510,240],[520,230],[530,220],[580,170],[590,160],[600,150],[610,140],[620,130] - // Right outside part of pyramid. - ,[640,130],[650,140],[660,150],[670,160],[680,170],[730,220],[740,230],[790,280],[800,290],[810,300],[820,310],[830,320],[840,330],[850,340],[900,390],[910,400],[920,410],[930,420],[940,430],[950,440],[960,450],[1010,500],[1020,510],[1030,520],[1040,530],[1050,540],[1060,550],[1070,560],[1080,570] - // Left bottom inside and middle "stairs". - ,[400,530],[420,540],[440,550],[340,440],[450,450],[530,550],[540,540],[550,530],[560,520],[570,510],[580,500],[590,490],[600,480],[480,490],[490,480],[500,470],[510,460],[520,450],[530,440] - // Right bottom inside. - ,[630,560],[720,560],[890,570],[730,510],[740,500],[750,490],[760,480],[780,470],[800,460],[820,450],[850,450],[860,460],[870,470],[880,480],[890,490],[950,520],[970,510],[980,500] - // Top inside area. - ,[470,330],[520,330],[710,310],[730,300],[740,290],[750,280],[630,400],[640,390],[650,380],[660,370],[710,370],[720,400],[730,410],[490,280] - // Lower and underground area. - ,[630,610],[400,640],[410,630],[420,620],[430,610] - ]; - for(var i = 0; i < GetLength(edges); i++) - CreateObject(BrickEdge, edges[i][0], edges[i][1], NO_OWNER)->PermaEdge(); - - - return; -} - -/*-- Relaunch & spawn player --*/ - -protected func InitializePlayer(int plr) -{ - JoinPlayer(plr); - return; -} - -protected func RelaunchPlayer(int plr) -{ - var clonk = CreateObject(Clonk, 0, 0, plr); - clonk->MakeCrewMember(plr); - SetCursor(plr, clonk); - JoinPlayer(plr); - return; -} - -protected func JoinPlayer(int plr) -{ - var clonk = GetCrew(plr); - clonk->DoEnergy(100000); - var x = Random(LandscapeWidth()), y = 590; - clonk->SetPosition(x, y); - return; -} - -/*-- Fill chests --*/ - -global func FxIntFillChestsStart() -{ - var chests = FindObjects(Find_ID(Chest)); - var w_list = [Bow,Musket,Shield,Sword,Club,Javelin,Bow,Musket,Shield,Sword,Club,Javelin,DynamiteBox,JarOfWinds]; - - for(var chest in chests) - for(var i=0; i<4; ++i) - chest->CreateChestContents(w_list[Random(GetLength(w_list))]); -} - -global func FxIntFillChestsTimer() -{ - var chest = FindObjects(Find_ID(Chest), Sort_Random())[0]; - var w_list = [Boompack,Dynamite,Loam,Firestone,Bow,Musket,Sword,Javelin,JarOfWinds]; - - if (chest && chest->ContentsCount() < 5) - chest->CreateChestContents(w_list[Random(GetLength(w_list))]); -} - -global func CreateChestContents(id obj_id) -{ - if (!this) - return; - var obj = CreateObject(obj_id); - if (obj_id == Bow) - obj->CreateContents(Arrow); - if (obj_id == Musket) - obj->CreateContents(LeadShot); - obj->Enter(this); - return; -} diff --git a/planet/Tests.ocf/Pyramid.ocs/Title.txt b/planet/Tests.ocf/Pyramid.ocs/Title.txt deleted file mode 100644 index a63aa113b..000000000 --- a/planet/Tests.ocf/Pyramid.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:König der Pyramide -US:King of the Pyramid \ No newline at end of file diff --git a/planet/Tests.ocf/ScriptError1.ocs/Scenario.txt b/planet/Tests.ocf/ScriptError1.ocs/Scenario.txt new file mode 100644 index 000000000..0519ecba6 --- /dev/null +++ b/planet/Tests.ocf/ScriptError1.ocs/Scenario.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/planet/Tests.ocf/ScriptError1.ocs/Script.c b/planet/Tests.ocf/ScriptError1.ocs/Script.c new file mode 100644 index 000000000..899c019a1 --- /dev/null +++ b/planet/Tests.ocf/ScriptError1.ocs/Script.c @@ -0,0 +1,28 @@ +local MENU = +{ + left = + { + Wdt = 500, + title = + { + Wdt = 500, + Decoration = GUI_MenuDeco + } + }, + + right = + { + X = 500, + objects = + { + o1 = {Symbol = Rock, X = [0, 50], Y = [0, 40], Wdt = [0, 50 ERROR HERE! 64], Hgt=[0, 40 + 64]}, + o2 = {Symbol = Gold, X = [500, 50 - 32], Y = [500, 40 - 32], Wdt = [500, 50 +32], Hgt = [500, 40 + 32]}, + o3 = {Symbol = Wood, X = [1000, -64], Y = [1000, -64], Wdt = [1000, 0], Hgt = [500, 0]}, + }, + text = + { + Y = [1000, -300], + Hgt = 1000 + } + } +}; diff --git a/planet/Tests.ocf/Settlement.ocs/Landscape.txt b/planet/Tests.ocf/Settlement.ocs/Landscape.txt deleted file mode 100644 index 594795ce2..000000000 --- a/planet/Tests.ocf/Settlement.ocs/Landscape.txt +++ /dev/null @@ -1,59 +0,0 @@ -/*-- - Settlement - Author: Maikel - - Landscape suited for testing all kinds of settlement concepts. ---*/ - -// -overlay Mat { - algo=rndchecker; a=8; - zoomX=-50; zoomY=-50; - turbulence=100; loosebounds=1; -}; - -// Fills the specified region with some random materials. -overlay MatFiller { - overlay { mat=Earth; tex=earth; loosebounds=1; }; - Mat { mat=Granite; tex=granite; a=25; }; - Mat { mat=Ore; tex= ore; a=20; }; - Mat { mat=Tunnel; tex=tunnel; a=20; }; - Mat { mat=Rock; tex=rock; a=20; }; - Mat { mat=Sulphur; tex=sulphur; a=20; }; - Mat { mat=Gold; tex=gold; a=20; }; - Mat { mat=Coal; tex=coal; a=20; }; - Mat { mat=Tunnel; tex=tunnel; a=20; }; - Mat { mat=Earth; tex=earth_dry; }; - Mat { mat=Earth; tex=earth_rough; }; -}; - -// A map with sky islands, a lake and some resources. -map Settlement { - // Raise water level. - overlay { - mat=Water; tex=water; - x=0; wdt=100; y=60; hgt=40; - }; - // Sin algorithm to create a lake. - overlay { - mat=Earth; tex=earth; - algo=sin; - ox=30; oy=55; - zoomX=80; zoomY=-10; - MatFiller; - MatFiller; - }; - // Sky islands. - overlay { - x=5; wdt=90; y=10; hgt=30; - algo=rndchecker; a=4; - zoomX=-20; zoomY=10; - turbulence=100; loosebounds=1; - } | overlay { - x=5; wdt=90; y=10; hgt=30; - algo=rndchecker; a=5; - zoomX=-20; zoomY=10; - turbulence=100; loosebounds=1; - MatFiller; - }; -}; \ No newline at end of file diff --git a/planet/Tests.ocf/Settlement.ocs/Scenario.txt b/planet/Tests.ocf/Settlement.ocs/Scenario.txt deleted file mode 100644 index 348dc08eb..000000000 --- a/planet/Tests.ocf/Settlement.ocs/Scenario.txt +++ /dev/null @@ -1,44 +0,0 @@ -[Head] -Icon=14 -Title=Settlement -Version=5,2,0,1 - -[Definitions] -Definition1=Objects.ocd - -[Game] -Rules=Rule_EnergyNeed=1 - -[Player1] -Wealth=250 -Crew=Clonk=2 -Buildings=Flagpole=1;ToolsWorkshop=1;WindGenerator=2;SteamEngine=1;WoodenCabin=1;Pump=1;Foundry=1; - -[Player2] -Wealth=50,0,0,250 -Crew=Clonk=1 - -[Player3] -Wealth=50,0,0,250 -Crew=Clonk=1 - -[Player4] -Wealth=50,0,0,250 -Crew=Clonk=1 - -[Landscape] -Vegetation=Tree_Coniferous=2;Fern=2;Mushroom=1; -VegetationLevel=20,0,0,100 -InEarth=Rock=1;Firestone=4;Loam=2 -InEarthLevel=65,0,0,100 -Sky=Clouds2 -MapWidth=240 -MapHeight=160 -MapZoom=10 -Amplitude=10 - -[Weather] -Climate=0 -YearSpeed=0 -Wind=1,100,-100,100 - diff --git a/planet/Tests.ocf/Settlement.ocs/Script.c b/planet/Tests.ocf/Settlement.ocs/Script.c deleted file mode 100644 index afcb35798..000000000 --- a/planet/Tests.ocf/Settlement.ocs/Script.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-- - Settlement - Author: Maikel - - A nice round to test the settlement objects. ---*/ - -protected func Initialize() -{ - // Goal: Resource extraction, set to gold mining. - var goal = CreateObject(Goal_ResourceExtraction); - goal->SetResource("Gold"); - goal->SetResource("Ore"); - DoEnvironment(); -} - -protected func InitializePlayer(int plr) -{ - // No FoW needed for now. - SetFoW(false, plr); - // Give clonk shovel and a lorry with some equipment. - var clonk = GetCrew(plr); - clonk->CreateContents(Shovel); - var lorry = CreateObject(Lorry, clonk->GetX(), clonk->GetY(), plr); - lorry->CreateContents(Pipe, 2); - return; -} - -private func DoEnvironment() -{ - Cloud->Place(30); - CreateObject(Environment_Celestial); - CreateObject(Environment_Time); - Sound("BirdsLoop",true,100,nil,+1); -} diff --git a/planet/Tests.ocf/Settlement.ocs/Title.txt b/planet/Tests.ocf/Settlement.ocs/Title.txt deleted file mode 100644 index a030aa7f5..000000000 --- a/planet/Tests.ocf/Settlement.ocs/Title.txt +++ /dev/null @@ -1,2 +0,0 @@ -DE:Siedlung -US:Settlement \ No newline at end of file diff --git a/planet/Tutorial.ocf/DescDE.rtf b/planet/Tutorial.ocf/DescDE.rtf index 57d600b80..63a100ee2 100644 Binary files a/planet/Tutorial.ocf/DescDE.rtf and b/planet/Tutorial.ocf/DescDE.rtf differ diff --git a/planet/Tutorial.ocf/DescUS.rtf b/planet/Tutorial.ocf/DescUS.rtf index b7698d6f8..4e5c5be97 100644 Binary files a/planet/Tutorial.ocf/DescUS.rtf and b/planet/Tutorial.ocf/DescUS.rtf differ diff --git a/planet/Tutorial.ocf/Folder.txt b/planet/Tutorial.ocf/Folder.txt new file mode 100644 index 000000000..772df804b --- /dev/null +++ b/planet/Tutorial.ocf/Folder.txt @@ -0,0 +1,2 @@ +[Head] +Index=1 \ No newline at end of file diff --git a/planet/Tutorial.ocf/Title.png b/planet/Tutorial.ocf/Title.png index 2a5fc94be..04d266fe8 100644 Binary files a/planet/Tutorial.ocf/Title.png and b/planet/Tutorial.ocf/Title.png differ diff --git a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/Graphics.png b/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/Graphics.png deleted file mode 100644 index a2258fd42..000000000 Binary files a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/Script.c b/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/Script.c deleted file mode 100644 index b14f07240..000000000 --- a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/Script.c +++ /dev/null @@ -1,173 +0,0 @@ -/*-- - Object restorer - Author: Maikel - - Restores an object and transports it back to its original position or container, - can be used to prevent players from messing up tutorials by wasting items. ---*/ - - -/*-- Object Restoration --*/ - -protected func Initialize() -{ - return; -} - -public func SetRestoreObject(object to_restore, object to_container, int to_x, int to_y, string ctrl_string) -{ - to_restore->Enter(this); - var effect = AddEffect("Restore", this, 100, 1, this); - effect.to_restore = to_restore; - effect.to_container = to_container; - effect.to_x = to_x; - effect.to_y = to_y; - effect.ctrl_string = ctrl_string; - return; -} - -protected func FxRestoreStart(object target, effect, int temporary) -{ - effect.init_x = target->GetX(); - effect.init_y = target->GetY(); - return 1; -} - -protected func FxRestoreTimer(object target, effect, int time) -{ - // Remove effect if there is nothing to restore. - if (!effect.to_restore) - return -1; - // Get coordinates. - var init_x = effect.init_x; - var init_y = effect.init_y; - var to_container = effect.to_container; - if (to_container) - { - var to_x = to_container->GetX(); - var to_y = to_container->GetY(); - } - else - { - var to_x = effect.to_x; - var to_y = effect.to_y; - } - // Are the coordinates specified now, if not remove effect. - if (to_x == nil || to_y == nil) - { - effect.to_restore->RemoveObject(); - return -1; - } - // Move to the object with a weighed sin-wave centered around the halfway point. - var length = Distance(init_x, init_y, to_x, to_y); - // Remove effect if animation is done. - if (2 * time > length || length == 0) - return -1; - var angle = Angle(init_x, init_y, to_x, to_y); - var std_dev = Min(length / 16, 40); - var dev; - if (time < length / 4) - dev = 4 * std_dev * time / length; - else - dev = 2 * std_dev - 4 * std_dev * time / length; - // Set container to current location to shift view. - var x = init_x + Sin(angle, 2 * time); - var y = init_y - Cos(angle, 2 * time); - target->SetPosition(x, y); - // Draw Particles. - x = init_x + Sin(angle, 2 * time) + Cos(angle, Sin(20 * time, dev)) - target->GetX(); - y = init_y - Cos(angle, 2 * time) + Sin(angle, Sin(20 * time, dev)) - target->GetY(); - var color = RGB(128 + Cos(4 * time, 127), 128 + Cos(4 * time + 120, 127), 128 + Cos(4 * time + 240, 127)); - CreateParticle("PSpark", x, y, 0, 0, 32, color); - x = init_x + Sin(angle, 2 * time) - Cos(angle, Sin(20 * time, dev)) - target->GetX(); - y = init_y - Cos(angle, 2 * time) - Sin(angle, Sin(20 * time, dev)) - target->GetY(); - CreateParticle("PSpark", x, y, 0, 0, 32, color); - return 1; -} - -protected func FxRestoreStop(object target, effect, int reason, bool temporary) -{ - var to_restore = effect.to_restore; - var to_container = effect.to_container; - var to_x = effect.to_x; - var to_y = effect.to_y; - var ctrl_string = effect.ctrl_string; - // Only if there is something to restore. - if (to_restore) - { - to_restore->Exit(); - if (to_container) - to_restore->Enter(to_container); - else - to_restore->SetPosition(to_x, to_y); - // Restored object might have been removed on enter (Stackable). - if (to_restore) - { - // Add new restore mode, either standard one or effect supplied in EffectVar 4. - if (ctrl_string) - { - var new_effect = AddEffect(ctrl_string, to_restore, 100, 10); - new_effect.to_container = to_container; - new_effect.to_x = to_x; - new_effect.to_y = to_y; - } - else - to_restore->AddRestoreMode(to_container, to_x, to_y); - } - // Add particle effect. - for (var i = 0; i < 20; i++) - { - if (to_container) - { - to_x = to_container->GetX(); - to_y = to_container->GetY(); - } - var color = RGB(128 + Cos(18 * i, 127), 128 + Cos(18 * i + 120, 127), 128 + Cos(18 * i + 240, 127)); - CreateParticle("PSpark", to_x - GetX(), to_y - GetY(), RandomX(-10, 10), RandomX(-10, 10), 32, color); - } - // Sound. - //TODO new sound. - } - // Remove restoral object. - if (target) - target->RemoveObject(); - return 1; -} - -/*-- Global restoration on destruction --*/ - -// Adds an effect to restore an item on destruction. -global func AddRestoreMode(object to_container, int to_x, int to_y) -{ - if (!this) - return; - var effect = AddEffect("RestoreMode", this, 100); - effect.to_container = to_container; - effect.to_x = to_x; - effect.to_y = to_y; - return; -} - -// Destruction check, uses Fx*Stop to detect item removal. -// Effectvar 0: Container to which must be restored. -// Effectvar 1: x-coordinate to which must be restored. -// Effectvar 2: y-coordinate to which must be restored. -global func FxRestoreModeStop(object target, effect, int reason, bool temporary) -{ - if (reason == 3) - { - var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER); - var x = BoundBy(target->GetX(), 0, LandscapeWidth()); - var y = BoundBy(target->GetY(), 0, LandscapeHeight()); - restorer->SetPosition(x, y); - var to_container = effect.to_container; - var to_x = effect.to_x; - var to_y = effect.to_y; - var restored = CreateObject(target->GetID(), 0, 0, target->GetOwner()); - restorer->SetRestoreObject(restored, to_container, to_x, to_y); - } - return 1; -} - -local Name = "$Name$"; -local Description = "$Description$"; diff --git a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/StringTblDE.txt b/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/StringTblDE.txt deleted file mode 100644 index 20d89f48a..000000000 --- a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/StringTblDE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Objektregenerierung -Description=Setzt ein Objekt zu sein vorherigen Position oder Container zurück. diff --git a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/StringTblUS.txt b/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/StringTblUS.txt deleted file mode 100644 index 2b8d9193b..000000000 --- a/planet/Tutorial.ocf/Tutorial.ocd/ObjectRestorer.ocd/StringTblUS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Name=Object restorer -Description=Restores a lost object to its original location or container. diff --git a/planet/Tutorial.ocf/Tutorial.ocd/TutorialArrow.ocd/Script.c b/planet/Tutorial.ocf/Tutorial.ocd/TutorialArrow.ocd/Script.c index 83949de97..5c0a5ca1f 100644 --- a/planet/Tutorial.ocf/Tutorial.ocd/TutorialArrow.ocd/Script.c +++ b/planet/Tutorial.ocf/Tutorial.ocd/TutorialArrow.ocd/Script.c @@ -53,6 +53,14 @@ global func TutArrowShowPos(int x, int y, int angle, int dist) */ global func TutArrowShowTarget(object target, int angle, int dist) { + var container = target->Contained(), index; + if (container && + container.Prototype == Clonk && + (index = GetIndexOf(container.inventory, target)) != -1) // Is the object inventory in a clonk? + { + var itemslot = container.HUDcontroller.inventory[index]; + return TutArrowShowGUIPos(itemslot->GetX(), itemslot->GetY(), -90, itemslot->GetDefHeight() / 2); + } if (angle == nil) angle = 135; if (dist == nil) diff --git a/planet/Tutorial.ocf/Tutorial01.ocs/DescUS.rtf b/planet/Tutorial.ocf/Tutorial01.ocs/DescUS.rtf index d3aef4bbf..9c9cf3b7b 100644 Binary files a/planet/Tutorial.ocf/Tutorial01.ocs/DescUS.rtf and b/planet/Tutorial.ocf/Tutorial01.ocs/DescUS.rtf differ diff --git a/planet/Tutorial.ocf/Tutorial01.ocs/Script.c b/planet/Tutorial.ocf/Tutorial01.ocs/Script.c index 417c24570..c9305b816 100644 --- a/planet/Tutorial.ocf/Tutorial01.ocs/Script.c +++ b/planet/Tutorial.ocf/Tutorial01.ocs/Script.c @@ -107,7 +107,7 @@ global func FxTutorialScaleTimer(object target, effect, int timer) RemoveEffect("TutorialIntro*"); guide->ClearGuideMessage(); guide->AddGuideMessage("$MsgTutScale$"); - AddEffect("TutorialHangle", 0, 100, 18); + AddEffect("TutorialHangle", nil, 100, 18); return -1; } } @@ -117,7 +117,7 @@ global func FxTutorialHangleTimer(object target, effect, int timer) if (FindObject(Find_ID(Clonk), Find_InRect(820, 940, 190, 140))) { guide->AddGuideMessage("$MsgTutHangle$"); - AddEffect("TutorialSwim", 0, 100, 18); + AddEffect("TutorialSwim", nil, 100, 18); return -1; } } @@ -127,7 +127,7 @@ global func FxTutorialSwimTimer(object target, effect, int timer) if (FindObject(Find_ID(Clonk), Find_InRect(1120, 1030, 140, 60))) { guide->AddGuideMessage("$MsgTutSwim$"); - AddEffect("TutorialDig", 0, 100, 18); + AddEffect("TutorialDig", nil, 100, 18); return -1; } } @@ -154,8 +154,8 @@ global func FxShovelGetTimer(object target, effect, int timer) if (GetEffect("TutorialDig")) RemoveEffect("TutorialDig"); guide->AddGuideMessage("$MsgTutTools$"); - AddEffect("TutorialChest", 0, 100, 18); - AddEffect("TutorialFlint", 0, 100, 18); + AddEffect("TutorialChest", nil, 100, 18); + AddEffect("TutorialFlint", nil, 100, 18); return -1; } } @@ -175,7 +175,7 @@ global func FxLoamGetTimer(object target, effect, int timer) { guide->AddGuideMessage("$MsgTutLoam$"); RemoveEffect("TutorialChest"); - AddEffect("TutorialFlint", 0, 100, 18); + AddEffect("TutorialFlint", nil, 100, 18); return -1; } } @@ -212,8 +212,8 @@ protected func OnGuideMessageShown(int plr, int index) // Show inventory slots. if (index == 9) { - TutArrowShowGUIPos(248 + GUI_ObjectSelector->GetDefHeight() / 2, -16 - GUI_ObjectSelector->GetDefHeight() / 2, 180, 60); - TutArrowShowGUIPos(341 + GUI_ObjectSelector->GetDefHeight() / 2, -16 - GUI_ObjectSelector->GetDefHeight() / 2, 180, 60); + TutArrowShowGUIPos(78 - GUI_ObjectSelector->GetDefHeight() / 2, 153 + GUI_ObjectSelector->GetDefHeight() / 2, 270, 60); + TutArrowShowGUIPos(78 - GUI_ObjectSelector->GetDefHeight() / 2, 225 + GUI_ObjectSelector->GetDefHeight() / 2, 270, 60); } return; } @@ -260,7 +260,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar clonk->GrabObjectInfo(target); SetCursor(plr, clonk); clonk->DoEnergy(100000); - restorer->SetRestoreObject(clonk, nil, to_x, to_y, "ClonkRestore"); + restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); } return 1; } \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial01.ocs/StringTblDE.txt b/planet/Tutorial.ocf/Tutorial01.ocs/StringTblDE.txt index bc64d2ebc..4dcf387e4 100644 --- a/planet/Tutorial.ocf/Tutorial01.ocs/StringTblDE.txt +++ b/planet/Tutorial.ocf/Tutorial01.ocs/StringTblDE.txt @@ -1,20 +1,20 @@ # Dialogue options -MsgNextTutorial=&Nächste Lernrunde -MsgNextTutorialDesc=Die nächste Lernrunde starten. +MsgNextTutorial=&Nächste Lernrunde +MsgNextTutorialDesc=Die nächste Lernrunde starten. MsgRepeatRound=&Lernrunde wiederholen MsgRepeatRoundDesc=Diese Lernrunde wiederholen. # Tutorial messages MsgTutIntro0=Willkommen bei OpenClonk! MsgTutIntro1=Dies ist dein Clonk. -MsgTutIntro2=Das Ziel der Lernrunde ist, mit deinem Clonk durch die Höhle an den rechten Kartenrand zu kommen. Das Spielziel wird in jeder Runde in der oberen rechten Ecke des Bildschirms angezeigt. -MsgTutIntro3=Wenn du an einer Stelle einen Tipp brauchst, klicke auf mein Bildchen in der oberen linken Ecke des Bildschirms. Klicke nochmal, um den Tipp wieder zu schließen. -MsgTutMovement=Clonks werden durch die WASD Tasten gesteuert. Drücke [A] oder [D], um nach links oder rechts zu gehen. Mit [W] springst du. -MsgTutScale=Hier musst du an der Wand hochklettern, um weiterzukommen. Dein Clonk fängt automatisch an zu klettern, wenn du gegen eine Wand läufst oder springst. Dann kannst du mit [W] hoch- und [S] runterklettern. -MsgTutHangle=Um zu hangeln, springe einfach an die Decke. Dann kannst du normal nach links oder rechts hangeln. Um schließlich loszulassen, drücke [S]. -MsgTutSwim=Im Wasser kannst du in jede Richtung schwimmen. Wenn du untertauchst, hält dein Clonk den Atem an. Pass auf, rechtzeitig wieder aufzutauchen, sonst ertringt er. +MsgTutIntro2=Das Ziel der Lernrunde ist, mit deinem Clonk durch die Höhle an den rechten Kartenrand zu kommen. Das Spielziel wird in jeder Runde in der oberen rechten Ecke des Bildschirms angezeigt. +MsgTutIntro3=Wenn du an einer Stelle einen Tipp brauchst, klicke auf mein Bildchen in der oberen rechten Ecke des Bildschirms. Klicke nochmal, um den Tipp wieder zu schließen. +MsgTutMovement=Clonks werden durch die WASD Tasten gesteuert. Drücke [A] oder [D], um nach links oder rechts zu gehen. Mit [W] springst du. +MsgTutScale=Hier musst du an der Wand hochklettern, um weiterzukommen. Dein Clonk fängt automatisch an zu klettern, wenn du gegen eine Wand läufst oder springst. Dann kannst du mit [W] hoch- und [S] runterklettern. +MsgTutHangle=Um zu hangeln, springe einfach an die Decke. Dann kannst du normal nach links oder rechts hangeln. Um schließlich loszulassen, drücke [S]. +MsgTutSwim=Im Wasser kannst du in jede Richtung schwimmen. Wenn du untertauchst, hält dein Clonk den Atem an. Pass auf, rechtzeitig wieder aufzutauchen, sonst ertrinkt er. MsgTutDig=Hier brauchst du eine Schaufel um hindurchzugraben. Was ist das da unter Wasser? -MsgTutTools=Das Inventar deines Clonks in der unteren linken Bildschirmecke zeigt nun die Schaufel. Ist sie in der linken Hand (linker Slot), benutzt du sie mit der linken Maustaste. Ist sie in der rechten Hand (rechter Slot), mit der rechten Maustaste.||Ein Klick mit der rechten Maustaste auf die Schaufel im Inventar zeigt eine kurze Beschreibung an, wie sie funktioniert. -MsgTutChest=Um hier weiterzukommen, musst du eine Lehmbrücke bauen. In der Truhe ist ein Lehmklumpen. Stell dich vor die Truhe und drücke die [E], um das Inventarmenü zu öffnen. Sobald der Inhalt der Truhe angezeigt wird, kannst du ihn in dein Inventar holen. || Wenn du ein Objekt aus deinem Rucksack holen möchtest, drück [Q]. Mit Rechts- oder Linksklick kannst du nun ein Objekt in die entsprechende Hand nehmen. Mit [Q] lässt sich das Menü schließen. -MsgTutLoam=Um eine Lehmbrücke zu bauen, halte die Maustaste gedrückt. Die Konstruktion funktioniert wie das Graben, nur statt einem Tunnel wird eine Lehmbrücke gebaut. -MsgTutFlint=Oh, was ist das? Der Höhlenausgang ist durch solides Gestein versperrt. Mit der Schaufel kommst du da nicht durch.|In der Truhe sind Feuersteine, die bei Aufprall explodieren. Hole sie dir und wirf sie auf die Felswand, um dir einen Weg freizusprengen (ziele und werfe mit der Maus). Wenn du beide einsammeln willst, könntest du die Schaufel vorher in deinen Rucksack tun.||Erinnerung: Drücke [Q], um deinen Rucksack zu öffnen. \ No newline at end of file +MsgTutTools=Das Inventar deines Clonks am linken Bildschirmrand zeigt nun die Schaufel. Dieses hat mehrere Slots, zwei davon können als aktiv markiert werden. Mit der linken Maustaste weist du den Slot der linken Hand zu; mit der rechten Maustaste der rechten Hand.||Wenn du mit der Maus über die Schaufel im Inventar fährst, wird eine eine kurze Beschreibung angezeigt, die erklärt wie sie funktioniert. +MsgTutChest=Um hier weiterzukommen, musst du eine Lehmbrücke bauen. In der Truhe ist ein Lehmklumpen. Stell dich vor die Truhe und drücke [E], um das Inventarmenü zu öffnen. Um den Lehmklumpen dann einzusammeln, klicke im Menü darauf oder ziehe ihn in den Kreis vom Clonk. Drücke nochmal [E] um das Menü wieder zu schließen. +MsgTutLoam=Um eine Lehmbrücke zu bauen, halte die Maustaste gedrückt. Die Konstruktion funktioniert wie das Graben, nur statt einem Tunnel wird eine Lehmbrücke gebaut. +MsgTutFlint=Oh! was ist das? Der Höhlenausgang ist durch solides Gestein versperrt. Mit der Schaufel kommst du da nicht durch.|In der Truhe sind Feuersteine, die bei Aufprall explodieren. Hole sie dir und wirf sie auf die Felswand, um dir einen Weg freizusprengen (ziele und werfe mit der Maus). \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial01.ocs/StringTblUS.txt b/planet/Tutorial.ocf/Tutorial01.ocs/StringTblUS.txt index 7d759c18a..b0d2bdb1d 100644 --- a/planet/Tutorial.ocf/Tutorial01.ocs/StringTblUS.txt +++ b/planet/Tutorial.ocf/Tutorial01.ocs/StringTblUS.txt @@ -7,14 +7,14 @@ MsgRepeatRoundDesc=Restart this scenario. # Tutorial messages MsgTutIntro0=Welcome to OpenClonk! MsgTutIntro1=This is your clonk. -MsgTutIntro2=Travel through the cave to the right to complete the tutorial, your current goal is always shown in the upper right corner of the screen. +MsgTutIntro2=Travel through the cave to the right to complete the tutorial. Your current goal is always shown in the upper right corner of the screen. MsgTutIntro3=If at any time you need help, click on my icon in the upper right corner of the screen. Once you're done reading, click again on the icon to hide the message. MsgTutMovement=Clonks are controlled with the WASD keys. Press [A] or [D] to make the clonk walk left or right. Pressing [W] will make the clonk jump. MsgTutScale=Here you will need to scale the wall to advance. To scale, walk towards the wall until your clonk grabs on. Once you have grabbed on, you may scale up or down the wall by holding [W] or [S]. MsgTutHangle=To hangle, jump towards the ceiling. When your clonk grabs on, you will be able to move left or right. To release, press [S]. MsgTutSwim=Swimming is controlled simply by pressing in the direction you wish your clonk to move. While underwater make certain you resurface before your breath runs out, otherwise you will drown! MsgTutDig=You'll need a shovel to dig through here. What's that under the water? -MsgTutTools=The shovel is now shown in your clonk's inventory on the lower left of the screen. You can use it with the left mouse button if it is in your left hand (left slot) and with the right mouse button if it is in your right hand (right slot). || Right click on the shovel in your inventory slot to get a brief description on how it works. -MsgTutChest=You'll need to make a loam bridge to cross this obstacle. In the chest there is a chunk of loam. Go in front of the chest and press [E] to open the inventory menu. Once the chest's contents appear, you can click the left or right mouse button to collect items into your inventory.||If you want to get items from your bagpack, press [Q]. Either right or left click an item, and it will be swapped with whatever you have in that hand. Press [Q] again to close the menu. +MsgTutTools=The shovel is now shown in your clonk's inventory on the left side of the screen. It has several slots, of which two can be selected as active. Left-clicking assigns the slot to the left hand; right-clicking, to the right. To use a item, simply click the corresponding button.||Place the mouse over the shovel in your inventory slot to get a brief description on how it works. +MsgTutChest=You'll need to make a loam bridge to cross this obstacle. In the chest there is a chunk of loam. Go in front of the chest and press [E] to open the contents-menu. It will show the contents of the clonk's inventory and the chest. In this menu, click on the chunk of loam or drag it into the clonk's circle to collect it.||Press [E] again to close the menu. MsgTutLoam=Hold down the mouse button to build a loam bridge. Building a loam bridge works like digging with the shovel, only that you don't dig a tunnel but build a bridge out of loam. -MsgTutFlint=Oh, what's this? The cave's exit has been blocked with solid rock. You can't dig through solid rock with the shovel. In the chest are firestones which explode on impact. Collect them and throw them onto the wall to blow a hole into it (aim and throw with the mouse). To collect both, you'll want to put your shovel into your backpack.||Reminder: To access your backpack, press [Q]. \ No newline at end of file +MsgTutFlint=Oh! What's this? The cave's exit has been blocked with solid rock. You can't dig through solid rock with the shovel. In the chest are firestones which explode on impact. Collect them and throw them at the wall to blow a hole into it (aim and throw with the mouse). \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial01.ocs/Title.png b/planet/Tutorial.ocf/Tutorial01.ocs/Title.png index fd5797e7b..03fb5472c 100644 Binary files a/planet/Tutorial.ocf/Tutorial01.ocs/Title.png and b/planet/Tutorial.ocf/Tutorial01.ocs/Title.png differ diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/Script.c b/planet/Tutorial.ocf/Tutorial02.ocs/Script.c index 0a06b3b80..3dd00c4d0 100644 --- a/planet/Tutorial.ocf/Tutorial02.ocs/Script.c +++ b/planet/Tutorial.ocf/Tutorial02.ocs/Script.c @@ -15,7 +15,7 @@ protected func Initialize() goal->CreateGoalFlag(2950, 280); // Create all objects, vehicles, chests used by the player. - var effect, firestone, chest, powderkeg, grapple, dynamite; + var effect, firestone, chest, grapple, dynamite; // Dynamite box to blast through mine. var dyn1 = CreateObject(Dynamite, 242, 665, NO_OWNER); @@ -31,7 +31,7 @@ protected func Initialize() CreateObject(Fuse, 240, 685, NO_OWNER)->Connect(dyn5, igniter); igniter->SetGraphics("0", Fuse, 1, GFXOV_MODE_Picture); - // Miner's hut and chest with cannon stuff. + // Miner's hut and chest with catapult stuff. //var hut = CreateObject(WoodenCabin, 570, 740, NO_OWNER); //hut->SetObjectLayer(hut); chest = CreateObject(Chest, 510, 740, NO_OWNER); @@ -41,31 +41,17 @@ protected func Initialize() firestone->Enter(chest); firestone->AddRestoreMode(chest); } - powderkeg = CreateObject(PowderKeg, 0, 0, NO_OWNER); - powderkeg->Enter(chest); - powderkeg->AddRestoreMode(chest); - /* Decoration for the mine. - var pickaxe; - pickaxe = CreateObject(Pickaxe, 185, 680, NO_OWNER); - pickaxe->SetObjectLayer(pickaxe); - pickaxe->SetR(-60); - pickaxe->SetClrModulation(RGB(120, 120, 120)); - pickaxe = CreateObject(Pickaxe, 316, 678, NO_OWNER); - pickaxe->SetObjectLayer(pickaxe); - pickaxe->SetClrModulation(RGB(120, 120, 120)); - pickaxe->SetR(70); - pickaxe = CreateObject(Pickaxe, 156, 666, NO_OWNER); - pickaxe->SetObjectLayer(pickaxe); - pickaxe->SetClrModulation(RGB(120, 120, 120)); - pickaxe->SetR(-10); - var lorry = CreateObject(Lorry, 320, 680, NO_OWNER); - lorry->SetObjectLayer(lorry); - lorry->SetClrModulation(RGB(120, 120, 120)); */ - + // Cannon to blast through rock & chest with powderkeg and firestones. - var cannon = CreateObject(Cannon, 700, 420, NO_OWNER); +/* var cannon = CreateObject(Cannon, 700, 420, NO_OWNER); effect = AddEffect("CannonRestore", cannon, 100, 10); effect.to_x = 700; + effect.to_y = 420;*/ + + // Catapult to blast through rock & chest with firestones. + var catapult = CreateObject(Catapult, 700, 420, NO_OWNER); + effect = AddEffect("CatapultRestore", catapult, 100, 10); + effect.to_x = 700; effect.to_y = 420; // Chest with flints and dynamite to blast underwater rocks. @@ -140,7 +126,7 @@ protected func InitializePlayer(int plr) SetPlayerZoomByViewRange(plr, 400, nil, PLRZOOM_Direct); // First clonk. - clonk = GetCrew(plr, 1); + clonk = GetCrew(plr, 0); clonk->SetPosition(200, 440); effect = AddEffect("ClonkOneRestore", clonk, 100, 10); effect.to_x = 200; @@ -149,20 +135,24 @@ protected func InitializePlayer(int plr) grapple->Enter(clonk); effect = AddEffect("ClonkContentRestore", grapple, 100, 10); effect.to_container = clonk; + effect = AddEffect("EquipmentRestore", grapple, 100, 10); + effect.to_container = clonk; ropeladder = CreateObject(Ropeladder, 0, 0, NO_OWNER); ropeladder->Enter(clonk); effect = AddEffect("ClonkContentRestore", ropeladder, 100, 10); effect.to_container = clonk; + effect = AddEffect("EquipmentRestore", ropeladder, 100, 10); + effect.to_container = clonk; // Second clonk. - clonk = GetCrew(plr, 0); + clonk = GetCrew(plr, 1); clonk->SetPosition(30, 680); effect = AddEffect("ClonkTwoRestore", clonk, 100, 10); effect.to_x = 30; effect.to_y = 680; // Select first clonk - SetCursor(plr, GetCrew(plr, 1)); + SetCursor(plr, GetCrew(plr, 0)); // Create tutorial guide, add messages, show first. guide = CreateTutorialGuide(plr); @@ -233,27 +223,27 @@ global func FxTutorialBlastedThroughTimer() global func FxTutorialFoundInteractableTimer(object target, effect) { var clonk = GetCursor(GetPlayerByIndex(0)); - var cannon = FindObject(Find_ID(Cannon)); + var catapult = FindObject(Find_ID(Catapult)); //var chest = FindObject(Find_ID(Chest), Find_Distance(40, 510, 740)); if (clonk->GetAction() == "Push") { var act_trg = clonk->GetActionTarget(0); - if (act_trg == cannon) + if (act_trg == catapult) { - if (clonk->FindContents(PowderKeg) && clonk->FindContents(Firestone)) + if (clonk->FindContents(Firestone)) { - if (!effect.toldabout_cannon) - guide->AddGuideMessage("$MsgTutCannon$"); + if (!effect.toldabout_catapult) + guide->AddGuideMessage("$MsgTutCatapult$"); if (!effect.toldabout_chest) guide->AddGuideMessage("$MsgTutExplosivesChest$"); - guide->AddGuideMessage("$MsgTutFireCannon$"); + guide->AddGuideMessage("$MsgTutFireCatapult$"); AddEffect("TutorialRockBlasted", nil, 100, 5); return -1; } - else if (!effect.toldabout_cannon) + else if (!effect.toldabout_catapult) { - guide->AddGuideMessage("$MsgTutCannon$"); - effect.toldabout_cannon = true; + guide->AddGuideMessage("$MsgTutCatapult$"); + effect.toldabout_catapult = true; } } } @@ -354,7 +344,7 @@ protected func OnGuideMessageShown(int plr, int index) if (detonator) TutArrowShowTarget(detonator, 225, 16); } - // Show where to shoot with cannon. + // Show where to shoot with catapult. if (index == 7) TutArrowShowPos(380, 240, 270); // Show grapple jump & hook position. @@ -410,7 +400,7 @@ global func FxClonkOneRestoreTimer(object target, effect, int time) restorer->SetPosition(x, y); var to_x = effect.to_x; var to_y = effect.to_y; - restorer->SetRestoreObject(target, nil, to_x, to_y, "ClonkOneRestore"); + restorer->SetRestoreObject(target, nil, to_x, to_y, 0, "ClonkOneRestore"); return -1; } // Respawn to new location if reached cliff to grapple from. @@ -472,7 +462,7 @@ global func FxClonkOneRestoreStop(object target, effect, int reason, bool tempo var new_effect = AddEffect("ClonkContentRestore", obj, 100, 10); new_effect.to_container = clonk; } - restorer->SetRestoreObject(clonk, nil, to_x, to_y, "ClonkOneRestore"); + restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkOneRestore"); } return 1; } @@ -532,7 +522,7 @@ global func FxClonkTwoRestoreStop(object target, effect, int reason, bool tempo var new_effect = AddEffect("ClonkContentRestore", obj, 100, 10); new_effect.to_container = clonk; } - restorer->SetRestoreObject(clonk, nil, to_x, to_y, "ClonkTwoRestore"); + restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkTwoRestore"); } return 1; } @@ -556,7 +546,7 @@ global func FxDynamiteRestoreStop(object target, effect, int reason, bool tempo restorer->SetPosition(x, y); var to_container = effect.to_container; var restored = CreateObject(DynamiteBox, 0, 0, target->GetOwner()); - restorer->SetRestoreObject(restored, to_container, nil, nil, "DynamiteRestore"); + restorer->SetRestoreObject(restored, to_container, nil, nil, nil, "DynamiteRestore"); } return 1; } @@ -567,8 +557,8 @@ global func FxDynamiteRestoreTimer(object target, effect, int time) return 1; } -// Cannon, restore position if pushed to far to the right. -global func FxCannonRestoreTimer(object target, effect, int time) +// Catapult, restore position if pushed to far to the right. +global func FxCatapultRestoreTimer(object target, effect, int time) { if ((target->GetX() < 595 && target->GetY() > 415) && !target->Contained()) { @@ -578,47 +568,14 @@ global func FxCannonRestoreTimer(object target, effect, int time) restorer->SetPosition(x, y); var to_x = effect.to_x; var to_y = effect.to_y; - restorer->SetRestoreObject(target, nil, to_x, to_y, "CannonRestore"); + restorer->SetRestoreObject(target, nil, to_x, to_y, 0, "CatapultRestore"); return -1; } return 1; } -// Catapult, restore position if pushed to far to the left or right. -global func FxCataRestoreTimer(object target, effect, int time) -{ - if ((target->GetX() < 1110 || target->GetX() > 1650 || target->GetY() > 460) && !target->Contained()) - { - var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER); - var x = BoundBy(target->GetX(), 0, LandscapeWidth()); - var y = BoundBy(target->GetY(), 0, LandscapeHeight()); - restorer->SetPosition(x, y); - var to_x = effect.to_x; - var to_y = effect.to_y; - restorer->SetRestoreObject(target, nil, to_x, to_y, "CataRestore"); - return -1; - } - return 1; -} - -// Catapult, might be dropped within 1100 X-coordinate. -global func FxCataRestoreStop(object target, effect, int reason, bool temporary) -{ - if (reason == 3) - { - var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER); - var x = BoundBy(target->GetX(), 0, LandscapeWidth()); - var y = BoundBy(target->GetY(), 0, LandscapeHeight()); - restorer->SetPosition(x, y); - var to_x = effect.to_x; - var to_y = effect.to_y; - restorer->SetRestoreObject(target, nil, to_x, to_y, "CataRestore"); - } - return 1; -} - // Ropeladder, restore if thrown away to unreachable location. -global func FxRopeladderRestoreTimer(object target, effect, int time) +global func FxEquipmentRestoreTimer(object target, effect, int time) { if (target->GetX() < 680 && target->GetY() > 340 && !target->Contained()) { @@ -627,7 +584,7 @@ global func FxRopeladderRestoreTimer(object target, effect, int time) var y = BoundBy(target->GetY(), 0, LandscapeHeight()); restorer->SetPosition(x, y); var to_container = effect.to_container; - restorer->SetRestoreObject(target, to_container, nil, nil, "RopeladderRestore"); + restorer->SetRestoreObject(target, to_container, nil, nil, 0, "RopeladderRestore"); return -1; } return 1; @@ -644,7 +601,7 @@ global func FxRopeladderRestoreStop(object target, effect, int reason, bool tem restorer->SetPosition(x, y); var to_container = effect.to_container; var restored = CreateObject(Ropeladder, 0, 0, target->GetOwner()); - restorer->SetRestoreObject(restored, to_container, nil, nil, "RopeladderRestore"); + restorer->SetRestoreObject(restored, to_container, nil, nil, 0, "RopeladderRestore"); } return 1; } @@ -670,7 +627,7 @@ global func FxClonkContentRestoreStop(object target, effect, int reason, bool t restorer->SetPosition(x, y); var to_container = effect.to_container; var restored = CreateObject(target->GetID(), 0, 0, target->GetOwner()); - restorer->SetRestoreObject(restored, to_container, nil, nil, "ClonkContentRestore"); + restorer->SetRestoreObject(restored, to_container, nil, nil, 0, "ClonkContentRestore"); } return 1; } diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/StringTblDE.txt b/planet/Tutorial.ocf/Tutorial02.ocs/StringTblDE.txt index 01eae9902..5e7dde0e5 100644 --- a/planet/Tutorial.ocf/Tutorial02.ocs/StringTblDE.txt +++ b/planet/Tutorial.ocf/Tutorial02.ocs/StringTblDE.txt @@ -7,16 +7,15 @@ MsgRepeatRoundDesc=Diese Runde wiederholen. # Tutorial messages MsgTutWelcome=Willkommen zur zweiten Lernrunde. In dieser Lernrunde hast Du zwei Clonks zur Verfügung. Das Spielziel dieser Runde ist wieder, den Fahnenmast am rechten Rand der Karte zu erreichen, diesmal aber mit beiden Clonks. Klicke auf mein Bildchen in der oberen linken Ecke des Bildschirmes für Tipps. Du kannst jederzeit mit dem Mausrad oder mit F5/F6 zoomen. MsgTutGrappleUp=Der Clonk kann nicht hoch genug springen, um über die Klippe zu kommen. Ziele und schieße mit dem Enterhaken in deinem Inventar an die angezeigte Position. Du kannst mit [W] und [S] das Seil hoch- und runterklettern sowie mit [A] und [D] hin- und herschaukeln. -MsgTutCrewSelection=Es gibt momentan nichts mehr was du mit diesem Clonk machen kannst. Um ein anderes Crewmitglied anzuwählen, klicke entweder auf das Bildchen des Clonks in der linken oberen Ecke des Bildschirms, drücke [Shift] + die Nummer des auszuwählenden Clonks oder wähle den nächsten Clonk an indem du [R] oder [T] drückst. +MsgTutCrewSelection=Es gibt momentan nichts mehr was du mit diesem Clonk machen kannst. Um ein anderes Crewmitglied anzuwählen, klicke entweder auf das Bildchen des Clonks in der linken oberen Ecke des Bildschirms, drücke [Strg] + die Nummer des auszuwählenden Clonks oder wähle den nächsten Clonk an indem du [R] oder [T] drückst. MsgTutBlowUpGold=Sieht aus, als hätten Bergarbeiter einen verdrahteten Zünder in dieser Goldmine zurückgelassen. Sammle ihn auf und drücke [Benutzen], um das Gold, dass deinen Weg versperrt, wegzusprengen. MsgTutFreeOtherClonk=Jetzt wo sich dein Clonk freigesprengt hat, versuche einen Weg zu finden, wie du deinen anderen Clonk befreien kannst. Denk daran, dass dein Clonk mit vielen Dingen interagieren kann, die in der Landschaft herumstehen. Du kannst sie benutzen, indem du dich vor sie stellst und [Interagieren] (Leertaste) drückst. Objekte, mit denen dein Clonk interagieren kann, tauchen auch wie die Truhe als Bildchen unten am Bildschirmrand auf. -MsgTutCannon=Ah, du hast die Kanone gefunden. Mit der Kanone kann man Objekte über große Distanzen verschießen. Dazu brauchst du allerdings ein Pulverfass. Um ein Gegenstand mit der Kanone zu verschießen, fasse die Kanone mit der Leertaste an und halte die Maustaste gedrückt, um zu zielen. Mit der linken Maustaste verschießt du, was du in der linken Hand hast und mit der rechten Maustaste, was du in der rechten Hand hast. -MsgTutExplosivesChest=Die Bergarbeiter haben einige Sprengstoffe in der Truhe zurückgelassen. Stell dich vor die Truhe und drücke die [Leertaste], um die Truhe zu öffnen. Sobald der Inhalt der Truhe angezeigt wird, kannst du ihn in die Hand nehmen. || Wählst du den Feuerstein mit der linken Maustaste aus, nimmst du ihn in die linke Hand. Wählst du ihn mit der rechten Maustaste aus, nimmst du ihn in die rechte Hand. -MsgTutFireCannon=Du musst dich durch den Fels dort sprengen, um deinen anderen Clonk zu befreien. Suche nach einigen Feuersteinen in der Goldmine. +MsgTutCatapult=Ah, du hast das Katapult gefunden. Mit dem Katapult kann man Objekte über große Distanzen verschießen. +MsgTutExplosivesChest=Die Bergarbeiter haben einige Sprengstoffe in der Truhe zurückgelassen. Stell dich vor die Truhe und drücke die [Leertaste], um die Truhe zu öffnen. Sobald der Inhalt der Truhe angezeigt wird, kannst du ihn in die Hand nehmen. +MsgTutFireCatapult=Um ein Gegenstand mit dem Katapult zu verschießen, fasse das Katapult mit der Leertaste an und halte eine Maustaste gedrückt, um den Arm zu spannen. Je weiter du den Mauszeiger vom Katapult wegziehst, desto stärker schießt es. Mit der linken Maustaste verschießt du, was du in der linken Hand hast und mit der rechten Maustaste, was du in der rechten Hand hast. Du musst dich durch den Fels dort sprengen, um deinen anderen Clonk zu befreien. Suche nach einigen Feuersteinen in der Goldmine. MsgTutGrappleSwing=Wähle jetzt deinen anderen Clonk aus und bewege ihn an den Rand zum Pfeil. Springe und schieße mit dem Enterhaken an die Decke, dort wo der andere Pfeil ist. Dann kannst Du dich mit [A] und [D] über den Abgrund schwingen. MsgTutRopeladder=Gut gemacht! Jetzt kannst du deine Strickleiter benutzen um deinem Freund auf die Klippe zu helfen. Gehe zum Pfeil und lass die Strickleiter herab, indem du links neben deinen Clonk klickst. An Strickleitern kann man wie an normalen Wänden klettern. MsgTutDive=Um am nächsten Hindernis vorbeizukommen, musst du tauchen. Clonks können nur begrenzt lange die Luft anhalten, deshalb musst du regelmäßig auftauchen. Du kannst an den Stellen Luft holen, die von den Pfeilen angezeigt werden. In den Truhen unter dem See findest du Sprengstoff, welchen du brachst, um das Lernrunde zu schaffen. MsgTutBlastGranite=Benutze den Sprengstoff, den du unter dem See findest, um durch das Granit zu sprengen. Die beste Stelle wird vom Pfeil angezeigt. MsgTutBlastedGranite=Gut gemacht! Um die letzte Hürde zu bestehen, brauchst du zwei Enterhaken pro Clonk. Diese findest du im Tunnel, wenn du ein Stück zurück gehst. -MsgTutLastGrapple=Oh oh, das sieht ja wie ein Säuresee aus. Du hast keine Chance hier unbeschadet hinüber zu schwimmen. Der einfachste Weg hinüber ist mit Hilfe der Enterhaken: Schieß den ersten Enterhaken an die Himmelsinsel und während du am ersten Seil hoch kletterst, kannst du den anderen Enterhaken benutzen, indem du ihn weiter vorne befestigst. Wiederhole das bis du den ganzen Säuresee überquert hast. -MsgTutBackpack=Wie du vielleicht bereits weißt, kann der Clonk zwei Gegenstände in seinen Händen halten. Allerdings kann er noch mehr in seinem Rucksack verstauen. Der Rucksack kann mit [Q] geöffnet/geschlossen werden. Wenn er offen ist, kannst du einen der Gegenstände im Rucksack mit einem der Gegenstände in deiner Hand austauschen. Linke Maustaste für linke Hand, rechte Maustaste für rechte Hand. \ No newline at end of file +MsgTutLastGrapple=Oh oh, das sieht ja wie ein Säuresee aus. Du hast keine Chance hier unbeschadet hinüber zu schwimmen. Der einfachste Weg hinüber ist mit Hilfe der Enterhaken: Schieß den ersten Enterhaken an die Himmelsinsel und während du am ersten Seil hoch kletterst, kannst du den anderen Enterhaken benutzen, indem du ihn weiter vorne befestigst. Wiederhole das bis du den ganzen Säuresee überquert hast. \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/StringTblUS.txt b/planet/Tutorial.ocf/Tutorial02.ocs/StringTblUS.txt index 3ed62a08e..d9a3a9ca1 100644 --- a/planet/Tutorial.ocf/Tutorial02.ocs/StringTblUS.txt +++ b/planet/Tutorial.ocf/Tutorial02.ocs/StringTblUS.txt @@ -5,17 +5,17 @@ MsgRepeatRound=&Repeat this round MsgRepeatRoundDesc=Restart this scenario. # Tutorial messages -MsgTutWelcome=Welcome to the second tutorial. In this tutorial you have two clonks at your disposal, and your goal will be to reach the flag on the far right side with both clonks. At any time you can click on the guide for helpful hints, note that you can zoom in and out with F5/F6 or the mouse wheel. -MsgTutGrappleUp=The clonk is not able to jump that high, you can use the grappling hook in your inventory. Use the mouse to aim and shoot the hook into the rock at the indicated position. You can use [W] and [S] to climb the rope, and [A] and [D] to swing back and forth. -MsgTutCrewSelection=There is nothing else you can do with this clonk for the moment. To select another crew member you can either click on the clonk you want to control in the upper left part of the HUD, press [Shift] + the number key corresponding to the clonk, or cycle through your crew by pressing [R] or [T]. +MsgTutWelcome=Welcome to the second tutorial. In this tutorial you have two clonks at your disposal, and your goal will be to reach the flag on the far right side with both clonks. At any time you can click on the guide for helpful hints; note that you can zoom in and out with F5/F6 or the mouse wheel. +MsgTutGrappleUp=The clonk is not able to jump that high; you can use the grappling hook in your inventory. Use the mouse to aim and shoot the hook into the rock at the indicated position. You can use [W] and [S] to climb the rope, and [A] and [D] to swing back and forth. +MsgTutCrewSelection=There is nothing else you can do with this clonk for the moment. To select another crew member you can either click on the clonk you want to control in the upper left corner of the screen, press [Ctrl] + the number key corresponding to the clonk, or cycle through your crew by pressing [R] or [T]. MsgTutBlowUpGold=It seems like miners left behind a wired detonator in this gold mine. Collect it and press [Use] to blow up the gold blocking your way out. -MsgTutFreeOtherClonk=Now that this clonk is free, look for a way to free your other clonk. Note that your clonk can interact with many objects, most of them vehicles and buildings. You can interact with them by standing in front of them and pressing [Interact] (Space bar), also for every interactable a clickable icon will appear in the HUD. -MsgTutCannon=Ah you found the cannon, the cannon can be used to fire objects over great distances. It needs gunpowder, contained in a powder keg, to operate. This can be found in the chest near the blasted gold. -MsgTutExplosivesChest=The miners left some explosives in this chest. Open it with [Interact], the chest's contents will then appear. Click the with left or right mouse button on an item to swap/collect it into your hands. To carry more items the clonk has a backpack, press [Q] to open it. The backpack works similar to the chest and you can swap items between the backpack and your hands. -MsgTutFireCannon=Good, you have brought some ammunition. To fire an object with the cannon click in the landscape to aim the cannon, left click will shoot your left-hand item, right click your right-hand item. You need to blast through the rock over there to free your other clonk. -MsgTutGrappleSwing=Now select your other clonk and move to the edge indicated by the arrow. Jump from there and shoot with the grappler to the granite ceiling, the other arrow. Then use [A] and [D] to swing across the cliff. -MsgTutRopeladder=Well done! You can now use your ropeladder to help your friend up this ledge. Move to the arrow and release the ropeladder by clicking to the left of your clonk. Ropeladders can be climbed just as normal walls. -MsgTutDive=To make it past the next obstacle you would need to dive. Clonks have limited breath, so you need to resurface regularly. You can resurface at the locations indicated by the arrows. In the chests under the lake explosives can be found, these are crucial for completing the tutorial. +MsgTutFreeOtherClonk=Now that this clonk is free, look for a way to free your other clonk. Note that your clonk can interact with many objects, most of them containers, vehicles and buildings. You can interact with them by standing in front of them and pressing [Interact] (Space bar); also for every interactable, a clickable icon will appear on the lower side of the screen. +MsgTutCatapult=Ah! You found the catapult; it can be used to fire objects over great distances. But you will firestones to blast through the rock pillar. These can be found in the chest near the blasted gold. +MsgTutExplosivesChest=The miners left some explosives in this chest. Open it with [Interact]; the chest's contents will then appear. Click on an item to collect it into your inventory. +MsgTutFireCatapult=Good! You have brought some ammunition. To fire an object with the catapult, click in the landscape to winch the catapult. The farer away you move the mouse cursor, the more tension you put on the catapult. Left click will shoot your left-hand item, right click your right-hand one. You need to blast through the rock over there to free your other clonk. +MsgTutGrappleSwing=Now, select your other clonk and move to the edge indicated by the arrow. Jump from there and shoot with the grappler to the granite ceiling, the other arrow. Then, use [A] and [D] to swing across the cliff. +MsgTutRopeladder=Well done! You can now use your rope ladder to help your friend up to get on this ledge. Move to the arrow and release the rope ladder by clicking to the left of your clonk. Rope ladders can be climbed just as normal walls. +MsgTutDive=To make it past the next obstacle you would need to dive. Clonks have limited breath, so you need to resurface regularly. You can resurface at the locations indicated by the arrows. In the chests under the lake explosives can be found; these are crucial for completing the tutorial. MsgTutBlastGranite=Use the explosives, which can be found under the lake, to blast through the granite. The best location is indicated by the arrow. -MsgTutBlastedGranite=Good job, for the last hurdle you need some grapple bows. Two per clonk to be precise, these can be found a tunnel a little back. -MsgTutLastGrapple=Ouch, that looks like an acid lake. No chance swimming across here, the easiest way over is by alternate use of two grapple bows. Shoot the first hook into the granite, then while scaling the rope use the second grappler, repeat this till you crossed the acid lake. +MsgTutBlastedGranite=Good job! For the last hurdle you need some grappling hooks. Two per clonk, to be precise; these can be found a tunnel a little back. +MsgTutLastGrapple=Ouch! That looks like an acid lake. No chance swimming across here, the easiest way over is by alternate use of two grappling hooks. Shoot the first hook into the granite, then while scaling the rope, use the second one. Repeat this till you made your way across the acid lake. diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/Catapult.c b/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/Catapult.c new file mode 100644 index 000000000..2b1a8fe32 --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/Catapult.c @@ -0,0 +1,8 @@ +// Enter the catapult - not in this scenario! + +#appendto Catapult + +public func ActivateEntrance(object clonk) { + clonk->Message("$CatapultEntryDeactivated$"); + return; +} \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/StringTblDE.txt b/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/StringTblDE.txt new file mode 100644 index 000000000..19bd5ae6a --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/StringTblDE.txt @@ -0,0 +1 @@ +CatapultEntryDeactivated=Mit dieser Funktion könnte man sogar einen Clonk mit dem Katapult verschießen. Aber für die Lernrunde ist dies deaktiviert. \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/StringTblUS.txt b/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/StringTblUS.txt new file mode 100644 index 000000000..80684d39e --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial02.ocs/System.ocg/StringTblUS.txt @@ -0,0 +1 @@ +CatapultEntryDeactivated=This button is used to make the catapult shoot clonks. But it is deactived in this tutorial round. \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial02.ocs/Title.png b/planet/Tutorial.ocf/Tutorial02.ocs/Title.png index e88512e9c..2120e280b 100644 Binary files a/planet/Tutorial.ocf/Tutorial02.ocs/Title.png and b/planet/Tutorial.ocf/Tutorial02.ocs/Title.png differ diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Script.c b/planet/Tutorial.ocf/Tutorial03.ocs/Script.c index 53db6c9ce..cce78c425 100644 --- a/planet/Tutorial.ocf/Tutorial03.ocs/Script.c +++ b/planet/Tutorial.ocf/Tutorial03.ocs/Script.c @@ -180,12 +180,12 @@ private func MakeTarget(int x, int y, bool flying) { var balloon = CreateObject(TargetBalloon, x, y-30, NO_OWNER); target->SetAction("Attach", balloon); - CreateParticle("Flash", x, y - 50, 0, 0, 500, RGB(255, 255, 255)); + CreateParticle("Flash", x, y - 50, 0, 0, 8, Particles_Flash()); } if (flying == false) { - CreateParticle("Flash", x, y, 0, 0, 500, RGB(255, 255, 255)); + CreateParticle("Flash", x, y, 0, 0, 8, Particles_Flash()); target->SetAction("Float"); } return target; @@ -259,7 +259,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var transfer, index = target->ContentsCount(); while (transfer = target->Contents(--index)) transfer->Enter(clonk); - restorer->SetRestoreObject(clonk, nil, to_x, to_y, "ClonkRestore"); + restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); } return 1; } diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/System.ocg/WeaponFade.c b/planet/Tutorial.ocf/Tutorial03.ocs/System.ocg/WeaponFade.c index b41b36e97..702880cab 100644 --- a/planet/Tutorial.ocf/Tutorial03.ocs/System.ocg/WeaponFade.c +++ b/planet/Tutorial.ocf/Tutorial03.ocs/System.ocg/WeaponFade.c @@ -6,6 +6,8 @@ protected func Departure(object container) { + if (GetID() != Bow) return; + if (container->GetOCF() & OCF_CrewMember) AddEffect("Fade", this, 100, 1, this); return _inherited(container, ...); @@ -53,4 +55,23 @@ protected func FxFadeEffect(string new_name, object target) if (new_name == "Fade") return -1; return -2; +} + +protected func Destruction() +{ + if (Inside(GetX(), 0, LandscapeWidth()) && Inside(GetY(), 0, LandscapeHeight())) return; + + var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER); + var x = BoundBy(GetX(), 0, LandscapeWidth()); + var y = BoundBy(GetY(), 0, LandscapeHeight()); + var duplicate = CreateObject(GetID(), x, y, GetOwner()); + var cnt = this->~GetStackCount(); + duplicate->~SetStackCount(cnt); + if (GetID() == Bow) duplicate->CreateContents(Arrow)->SetStackCount(FindContents(Arrow)->GetStackCount()); + restorer->SetPosition(x, y); + var to_container = FindObject(Find_OCF(OCF_CrewMember)); + restorer->SetRestoreObject(duplicate, to_container); + + if (GetEffect("RestoreMode", this)) + RemoveEffect("RestoreMode", this, nil, true); } \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Script.c b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Script.c index 8b536af00..dca1bc743 100644 --- a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Script.c +++ b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Script.c @@ -1,9 +1,5 @@ /*-- Arrow target --*/ -func Definition(def) { - SetProperty("Name", "$Name$", def); -} - protected func Initialize() { SetAction("Attach"); @@ -29,8 +25,8 @@ public func OnProjectileHit() public func Burst() { + CreateParticle("Straw", 0, 0, PV_Random(-30, 30), PV_Random(-30,30), PV_Random(30, 120), Particles_Straw(), 200); RemoveObject(); - CastParticles("Straw",130,30,0,-3,30,40,RGB(255,255,255),RGB(255,255,255)); } public func Hit() @@ -44,6 +40,7 @@ protected func Tumble() } func Definition(def) { + SetProperty("Name", "$Name$", def); SetProperty("ActMap", { Fall = { diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Straw.ocd/Graphics.png b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Straw.ocd/Graphics.png deleted file mode 100644 index d8537fa34..000000000 Binary files a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Straw.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Straw.ocd/Particle.txt b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Straw.ocd/Particle.txt deleted file mode 100644 index be68d326a..000000000 --- a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/Straw.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Straw -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=50 -AlphaFade=0 -RByV=1 -Attach=1 \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/BurntBalloon.ocd/Script.c b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/BurntBalloon.ocd/Script.c index a5a0269c3..abad30c38 100644 --- a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/BurntBalloon.ocd/Script.c +++ b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/BurntBalloon.ocd/Script.c @@ -1,9 +1,5 @@ /*-- Burnt Target Balloon --*/ -func Definition(def) { - SetProperty("Name", "Burnt Balloon", def); -} - protected func Initialize() { SetRDir(-2+Random(4)); @@ -25,6 +21,7 @@ func FxFadeTimer(object target, effect, int time) } func Definition(def) { + SetProperty("Name", "Burnt Balloon", def); SetProperty("ActMap", { Fall = { diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/Script.c b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/Script.c index ab1fd26e4..4bc3034d5 100644 --- a/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/Script.c +++ b/planet/Tutorial.ocf/Tutorial03.ocs/Target.ocd/TargetBalloon.ocd/Script.c @@ -2,10 +2,6 @@ local ysin; -func Definition(def) { - SetProperty("Name", "$Name$", def); -} - protected func Initialize() { ysin = 0; @@ -31,7 +27,7 @@ public func IsProjectileTarget(target,shooter) public func OnProjectileHit() { - CastParticles("Air",20,5,0,-10,170,190,RGB(255,255,255),RGB(255,255,255)); + CreateParticle("Air", 0, -10, PV_Random(-30, 30), PV_Random(-30,30), PV_Random(30, 120), Particles_Air(), 10); Sound("BalloonPop"); RemoveObject(); } @@ -53,6 +49,7 @@ func FxFlyOffTimer(target, effect, time) } func Definition(def) { + SetProperty("Name", "$Name$", def); SetProperty("ActMap", { Float = { diff --git a/planet/Tutorial.ocf/Tutorial03.ocs/Title.png b/planet/Tutorial.ocf/Tutorial03.ocs/Title.png index c46a2c695..5ee33a421 100644 Binary files a/planet/Tutorial.ocf/Tutorial03.ocs/Title.png and b/planet/Tutorial.ocf/Tutorial03.ocs/Title.png differ diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/Graphics.png b/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/Graphics.png deleted file mode 100644 index 4e443af09..000000000 Binary files a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/Script.c b/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/Script.c deleted file mode 100644 index bb6bdb7cd..000000000 --- a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/Script.c +++ /dev/null @@ -1,65 +0,0 @@ -/*-- - Energy bars - Author: Maikel - - Displays an energy bar above an object, uses Library_Bars. ---*/ - - -#include Library_Bars - -private func EnergyBarWidth() { return 24; } -private func EnergyBarHeight() { return 6; } - -protected func Initialize() -{ - return; -} - -public func SetTarget(object target) -{ - // Attach energy bar to the object. - SetAction("Attach", target); - // Create energy bar. - SetBarLayers(2, 0); - SetBarOffset(0, - target->GetDefHeight() / 2, 0); - SetBarDimensions(EnergyBarWidth(), EnergyBarHeight(), 0); - SetClrModulation(RGB(200, 0, 0), 3); - UpdateEnergy(); - return; -} - -protected func UpdateEnergy() -{ - var target = GetActionTarget(); - var energy = target->GetEnergy(); - if (!energy) - return RemoveObject(); - var phys = target->GetMaxEnergy(); - var promille; - if (phys == 0) - promille = 0; - else - promille = 1000 * energy / phys; - SetBarProgress(promille, 0); - return; -} - -protected func AttachTargetLost() { RemoveObject(); } - -local Name = "$Name$"; -local ActMap = { - Attach = { - Prototype = Action, - Name = "Attach", - Procedure = DFA_ATTACH, - Length = 1, - Delay = 1, - X = 0, - Y = 0, - Wdt = 32, - Hgt = 32, - NextAction = "Attach", - StartCall = "UpdateEnergy", - }, -}; diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/StringTblDE.txt b/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/StringTblDE.txt deleted file mode 100644 index 68863c964..000000000 --- a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/StringTblDE.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Energy bar \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/StringTblUS.txt b/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/StringTblUS.txt deleted file mode 100644 index 68863c964..000000000 --- a/planet/Tutorial.ocf/Tutorial04.ocs/EnergyBar.ocd/StringTblUS.txt +++ /dev/null @@ -1 +0,0 @@ -Name=Energy bar \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/Script.c b/planet/Tutorial.ocf/Tutorial04.ocs/Script.c index 93805a9b2..e4ba50665 100644 --- a/planet/Tutorial.ocf/Tutorial04.ocs/Script.c +++ b/planet/Tutorial.ocf/Tutorial04.ocs/Script.c @@ -15,7 +15,7 @@ protected func Initialize() Cloud->Place(15); CreateObject(Environment_Celestial); var time = CreateObject(Environment_Time); - time->SetTime(1125); + time->SetTime(22*60); time->SetCycleSpeed(0); Sound("WindLoop", true, 40, nil, 1); @@ -28,7 +28,8 @@ protected func Initialize() CreateObject(SwordTarget, 340, 649, NO_OWNER)->SetR(RandomX(-10, 10)); CreateObject(SwordTarget, 430, 603, NO_OWNER)->SetR(RandomX(-10, 10) + 180); // Gate that opens if all targets have been destroyed. - var gate = CreateObject(StoneDoor, 557, 640, NO_OWNER); + var gate = CreateObject(StoneDoor, 556, 640, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", 552, 638, 552, 640, 560, 640, 560, 638); AddEffect("IntOpenGate", gate, 100, 5); // Script player as opponent. @@ -36,12 +37,14 @@ protected func Initialize() CreateScriptPlayer("$NameOpponent$", RGB(40,30,20), nil, CSPF_FixedAttributes); // Second section: gate that can be opened with a spin wheel. - var gate = CreateObject(StoneDoor, 1221, 552, NO_OWNER); + var gate = CreateObject(StoneDoor, 1220, 552, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", 1216, 550, 1216, 552, 1224, 552, 1224, 550); var wheel = CreateObject(SpinWheel, 1140, 568, NO_OWNER); wheel->SetStoneDoor(gate); // Third section: gate that can be opened with a spin wheel. - var gate = CreateObject(StoneDoor, 1853, 504, NO_OWNER); + var gate = CreateObject(StoneDoor, 1852, 504, NO_OWNER); + DrawMaterialQuad("Tunnel-brickback", 1848, 502, 1848, 504, 1856, 504, 1856, 502); var wheel = CreateObject(SpinWheel, 1782, 352, NO_OWNER); wheel->SetStoneDoor(gate); @@ -58,8 +61,7 @@ protected func Initialize() protected func OnGoalsFulfilled() { // Dialogue options -> next round. - // Uncomment if there is a 5th tutorial. - // SetNextMission("Tutorial.ocf\\Tutorial05.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$"); + SetNextMission("Tutorial.ocf\\Tutorial05.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$"); // Normal scenario ending by goal library. return false; } @@ -109,7 +111,7 @@ private func InitializeScriptPlayer(int plr) spearman1->CreateContents(Javelin); spearman1->AI_GuardArea(800, 400, 400, 250); AddEffect("IntContentRemoval", spearman1, 100, 0); - CreateObject(EnergyBar)->SetTarget(spearman1); + spearman1->AddEnergyBar(); // Third section: Two opponents in a tower. // Lower part: a weak spearman. @@ -119,7 +121,7 @@ private func InitializeScriptPlayer(int plr) spearman2->CreateContents(Javelin); spearman2->AI_GuardArea(1350, 200, 500, 400); AddEffect("IntContentRemoval", spearman2, 100, 0); - CreateObject(EnergyBar)->SetTarget(spearman2); + spearman2->AddEnergyBar(); // Upper part: a normal bowman. var bowman = CreateObject(Clonk, 1732, 352, plr); bowman->MakeCrewMember(plr); @@ -127,7 +129,7 @@ private func InitializeScriptPlayer(int plr) bowman->CreateContents(Bow)->CreateContents(Arrow); bowman->AI_GuardArea(1350, 200, 500, 400); AddEffect("IntContentRemoval", bowman, 100, 0); - CreateObject(EnergyBar)->SetTarget(bowman); + bowman->AddEnergyBar(); // Fourth section: Opponent with sword and shield. var swordman = CreateObject(Clonk, 2250, 360, plr); @@ -137,7 +139,7 @@ private func InitializeScriptPlayer(int plr) swordman->CreateContents(Sword); swordman->AI_GuardArea(2050, 300, 300, 100); AddEffect("IntContentRemoval", swordman, 100, 0); - CreateObject(EnergyBar)->SetTarget(swordman); + swordman->AddEnergyBar(); return; } @@ -332,7 +334,7 @@ global func FxClonkRestoreStop(object target, effect, int reason, bool temporar var transfer, index = target->ContentsCount(); while (transfer = target->Contents(--index)) transfer->Enter(clonk); - restorer->SetRestoreObject(clonk, nil, to_x, to_y, "ClonkRestore"); + restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); } return 1; } diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Script.c b/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Script.c index 2b5a48a26..d4d76ecf6 100644 --- a/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Script.c +++ b/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Script.c @@ -12,7 +12,7 @@ protected func Initialize() public func Burst() { - CastParticles("Straw", 100, 25, 0, -3, 30, 40, RGB(255,255,255), RGB(255,255,255)); + CreateParticle("Straw", 0, 0, PV_Random(-30, 30), PV_Random(-30,30), PV_Random(30, 120), Particles_Straw(), 200); RemoveObject(); return; } diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Straw.ocd/Graphics.png b/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Straw.ocd/Graphics.png deleted file mode 100644 index d8537fa34..000000000 Binary files a/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Straw.ocd/Graphics.png and /dev/null differ diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Straw.ocd/Particle.txt b/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Straw.ocd/Particle.txt deleted file mode 100644 index be68d326a..000000000 --- a/planet/Tutorial.ocf/Tutorial04.ocs/SwordTarget.ocd/Straw.ocd/Particle.txt +++ /dev/null @@ -1,16 +0,0 @@ -[Particle] -Name=Straw -MaxCount=1500 -InitFn=StdInit -ExecFn=StdExec -CollisionFn=Die -DrawFn=Std -Face=0,0,32,32,-16,-16 -Delay=0 -Repeats=1 -GravityAcc=100 -VertexCount=1 -VertexY=50 -AlphaFade=0 -RByV=1 -Attach=1 \ No newline at end of file diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIBowAttack.c b/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIBowAttack.c index 302df17ef..70753415f 100644 --- a/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIBowAttack.c +++ b/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIBowAttack.c @@ -126,7 +126,7 @@ protected func FxAI_BowAimStop(object clonk, effect, int reason, bool temporary) //returns an array of x, y or x, y, t private func AI_AimPos(int x, int y, int v, bool lob, bool t) { - var g = GetGravity()/5; //FnGetGravity() multiplies actual gravity by 500 + var g = GetGravity(); //FnGetGravity() multiplies actual gravity by 100 var root = (v**4 - g*(g*x*x - 2*y*v*v)); if(root < 0) return nil; @@ -145,4 +145,4 @@ private func AI_AimPos(int x, int y, int v, bool lob, bool t) return [xAng, yAng, time]; } return [Sin(angle, 100), Cos(angle, 100)]; -} \ No newline at end of file +} diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIJavelinAttack.c b/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIJavelinAttack.c index 71d0d5db8..75fee13f4 100644 --- a/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIJavelinAttack.c +++ b/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/AIJavelinAttack.c @@ -117,7 +117,7 @@ protected func FxAI_JavelinAimStop(object clonk, effect, int reason, bool tempor //returns an array of x, y or x, y, t private func AI_AimPos(int x, int y, int v, bool lob, bool t) { - var g = GetGravity()/5; //FnGetGravity() multiplies actual gravity by 500 + var g = GetGravity(); //FnGetGravity() multiplies actual gravity by 100 var root = (v**4 - g*(g*x*x - 2*y*v*v)); if(root < 0) return nil; diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/Ammo.c b/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/Ammo.c index 030024a27..2c7ac03d3 100644 --- a/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/Ammo.c +++ b/planet/Tutorial.ocf/Tutorial04.ocs/System.ocg/Ammo.c @@ -5,15 +5,11 @@ #appendto Javelin // Infinite ammo. -public func SetStackCount(int amount) +protected func Construction() { - count = MaxStackCount(); - Update(); -} - -public func UpdatePicture() -{ - SetGraphics("1"); + var ret = _inherited(...); + SetInfiniteStackCount(); + return ret; } // Ammo fades out after some time. diff --git a/planet/Tutorial.ocf/Tutorial04.ocs/Title.png b/planet/Tutorial.ocf/Tutorial04.ocs/Title.png index a3a2764bd..7146d92e4 100644 Binary files a/planet/Tutorial.ocf/Tutorial04.ocs/Title.png and b/planet/Tutorial.ocf/Tutorial04.ocs/Title.png differ diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/DescDE.rtf b/planet/Tutorial.ocf/Tutorial05.ocs/DescDE.rtf new file mode 100644 index 000000000..edd3d3f45 Binary files /dev/null and b/planet/Tutorial.ocf/Tutorial05.ocs/DescDE.rtf differ diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/DescUS.rtf b/planet/Tutorial.ocf/Tutorial05.ocs/DescUS.rtf new file mode 100644 index 000000000..5f09d8c27 Binary files /dev/null and b/planet/Tutorial.ocf/Tutorial05.ocs/DescUS.rtf differ diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/Map.bmp b/planet/Tutorial.ocf/Tutorial05.ocs/Map.bmp new file mode 100644 index 000000000..088b1aa6b Binary files /dev/null and b/planet/Tutorial.ocf/Tutorial05.ocs/Map.bmp differ diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/Scenario.txt b/planet/Tutorial.ocf/Tutorial05.ocs/Scenario.txt new file mode 100644 index 000000000..806a417c8 --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial05.ocs/Scenario.txt @@ -0,0 +1,30 @@ +[Head] +Icon=6 +Title=TutorialSettlement +Version=5,2,0,0 +MaxPlayer=1 +Difficulty=5 + +[Definitions] +Definition1=Objects.ocd + +[Player1] +Crew=Clonk=1 +Knowledge=Foundry=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Loam=1; + +[Landscape] +Sky=Clouds2 +MapZoom=10 +TopOpen=1 +BottomOpen=0 +SkyScrollMode=2 +Vegetation=Tree_Coniferous=1 +VegetationLevel=90 +InEarth=Firestone=3;Loam=2 +InEarthLevel=40 + +[Weather] +Climate=0,0,0,100 +StartSeason=0,0,0,100 +YearSpeed=0,0,0,100 +Wind=1,100,-100,100 diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/Script.c b/planet/Tutorial.ocf/Tutorial05.ocs/Script.c new file mode 100644 index 000000000..29fdb988f --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial05.ocs/Script.c @@ -0,0 +1,276 @@ +/*-- + Tutorial 05 + Author: Caesar + + Basic settlement tutorial: Foundry, Flagpole, Windmill +--*/ + +static guide; // guide object + +protected func Initialize() +{ + // Environment. + PlaceGrass(85); + + return; +} + +protected func InitializePlayer(int plr) +{ + var clonk = GetCrew(plr, 0); + clonk->SetPosition(300, -150); + clonk->Fling(0, 0); + clonk->SetDir(DIR_Right); + clonk->CreateContents(Shovel); + clonk->CreateContents(Hammer); + clonk->CreateContents(Axe); + var effect = AddEffect("ClonkRestore", clonk, 100, 10); + effect.var1 = 300; + effect.var2 = -10; + + // Create tutorial guide, add messages, show first. + guide = CreateTutorialGuide(plr); + guide->AddGuideMessage("@$MsgTutIntro0$"); + guide->ShowGuideMessage(0); + AddEffect("TutorialIntro1", nil, 1, 36 * 5); + AddEffect("TutorialFoundrySite", nil, 1, 18); + AddEffect("TutorialFoundryMaterialUse", nil, 1, 18); + return; +} + +/*-- Guide Messages --*/ +// Finds when the Clonk has done 'X', and changes the message. + +global func FxTutorialIntro1Stop() +{ + guide->AddGuideMessage("@$MsgTutIntro1$"); + guide->ShowGuideMessage(1); + AddEffect("TutorialIntro2", nil, 1, 36 * 6); + return 0; +} + +global func FxTutorialIntro2Stop() +{ + guide->AddGuideMessage("@$MsgTutIntro2$"); + guide->ShowGuideMessage(2); + AddEffect("TutorialIntro3", nil, 1, 36 * 4); + return 0; +} + +global func FxTutorialIntro3Stop() +{ + guide->AddGuideMessage("$MsgTutIntro3$"); + guide->ShowGuideMessage(3); + guide->AddGuideMessage("$MsgTutFoundrySite$"); + return 1; +} + +global func FxTutorialFoundrySiteTimer(object target, effect, int timer) +{ + if (FindObject(Find_ID(ConstructionSite))) + return -1; +} + +global func FxTutorialFoundrySiteStop(object target, effect, int timer) +{ + while (GetEffect("TutorialIntro*")) + RemoveEffect("TutorialIntro*"); + guide->ClearGuideMessage(); + guide->AddGuideMessage("$MsgTutFoundryChopTree$"); + AddEffect("TutorialFoundryChopTree", nil, 1, 18); + return 0; +} + +global func FxTutorialFoundryChopTreeTimer(object target, effect, int timer) +{ + if (FindObject(Find_ID(Tree_Coniferous), Find_Not(Find_Category(C4D_StaticBack)))) + return -1; +} + +global func FxTutorialFoundryChopTreeStop(object target, effect, int timer) +{ + guide->AddGuideMessage("$MsgTutFoundryHackTree$"); + AddEffect("TutorialFoundryHackTree", nil, 1, 18); +} + +global func FxTutorialFoundryHackTreeTimer(object target, effect, int timer) +{ + if (ObjectCount(Find_ID(Wood)) >= 2) + return -1; +} + +global func FxTutorialFoundryHackTreeStop(object target, effect, int timer) +{ + guide->AddGuideMessage("$MsgTutFoundryStoneBlast$"); + AddEffect("TutorialFoundryStoneBlast", nil, 1, 18); +} + +global func FxTutorialFoundryStoneBlastTimer(object target, effect, int timer) +{ + if (ObjectCount(Find_ID(Rock)) >= 4) + return -1; +} + +global func FxTutorialFoundryStoneBlastStop(object target, effect, int timer) +{ + guide->AddGuideMessage("$MsgTutFoundryMaterialUse$"); + AddEffect("TutorialFoundryMaterialUse", nil, 1, 18); +} + +global func FxTutorialFoundryMaterialUseTimer(object target, effect, int timer) +{ + if (FindObject(Find_ID(Foundry))) + return -1; +} + +global func FxTutorialFoundryMaterialUseStop(object target, effect, int timer) +{ + guide->AddGuideMessage("$MsgTutFlagpoleSite$"); + for(var i=0; iAddGuideMessage("$MsgTutFlagpoleIronComponents$"); + AddEffect("TutorialFlagpoleIronComponents", nil, 1, 18); +} + +global func FxTutorialFlagpoleIronComponentsTimer(object target, effect, int timer) +{ + if (ObjectCount(Find_ID(Coal)) >= 1 && ObjectCount(Find_ID(Ore))) + return -1; +} + +global func FxTutorialFlagpoleIronComponentsStop(object target, effect, int timer) +{ + guide->AddGuideMessage("$MsgTutFlagpoleIronSmelt$"); + AddEffect("TutorialFlagpoleIronSmelt", nil, 1, 18); +} + +global func FxTutorialFlagpoleIronSmeltTimer(object target, effect, int timer) +{ + if (ObjectCount(Find_ID(Metal)) >= 1) + return -1; +} + +global func FxTutorialFlagpoleIronSmeltStop(object target, effect, int timer) +{ + guide->AddGuideMessage("$MsgTutFlagpoleIronPraise$"); + AddEffect("TutorialFlagpoleBuild", nil, 1, 18); +} + +global func FxTutorialFlagpoleBuildTimer(object target, effect, int timer) +{ + if (FindObject(Find_ID(Flagpole))) + return -1; +} + +global func FxTutorialFlagpoleBuildStop(object target, effect, int timer) +{ + RemoveEffect("TutorialFlagpoleSite"); + RemoveEffect("TutorialFlagpoleIronComponents"); + RemoveEffect("TutorialFlagpoleIronSmelt"); + for(var i=0; iAddGuideMessage("$MsgTutEnergy$"); + AddEffect("TutorialEnergy", nil, 1, 18); +} + + +global func FxTutorialEnergyTimer(object tg, e, tm) { + for (var wg in FindObjects(Find_ID(Flagpole))) + if (wg.lflag && wg.lflag.power_helper && (wg.lflag.power_helper.power_balance > 0)) + return -1; +} + +global func FxTutorialEnergyStop(object tg, e, tm) { + for(var building in [SteamEngine, ToolsWorkshop, Sawmill, Elevator, Pump, Compensator, Windmill, WoodenCabin]) + for(var i = GetPlayerCount(); i--;) + SetPlrKnowledge(GetPlayerByIndex(i), building); + guide->ClearGuideMessage(); + GameOver(); +} + + +protected func OnGuideMessageShown(int plr, int index) +{ + // Show where the guide is located in the HUD. + if (index == 3) + TutArrowShowGUIPos(guide->GetX(), guide->GetY() / 2, 0, 10+guide->GetDefHeight()); + // Show the tools + if (index == 2) //show shovel + TutArrowShowTarget(FindObject(Find_ID(Shovel))); + if (index == 2 || index == 4) // show hammer + TutArrowShowTarget(FindObject(Find_ID(Hammer))); + if (index == 2 || index == 5) // show axe + TutArrowShowTarget(FindObject(Find_ID(Axe))); + // Show a tree, a chopped one if possible + if (index == 6) + { + var tree = FindObject(Find_ID(Tree_Coniferous), Find_Not(Find_Category(C4D_StaticBack))); + if (!tree) tree = FindObject(Find_ID(Tree_Coniferous), Sort_Distance(GetCursor(plr)->GetX(),GetCursor(plr)->GetY())); + if (tree) TutArrowShowTarget(tree, 225, 25); + } + // Show foundry + if (index == 14) + TutArrowShowTarget(FindObject(Find_ID(Foundry)), 225, 30); + // Show stone vein and flint close to it + if (index == 7) + { + TutArrowShowPos(200, 430, 225); + TutArrowShowTarget(FindObject(Find_ID(Firestone), Sort_Distance(200,350/*y arbitrary*/)), 0); + } + // Show ore/coal vein and flint close to it + if (index == 12) + { + TutArrowShowPos(540, 450, 135); + TutArrowShowTarget(FindObject(Find_ID(Firestone), Sort_Distance(540,350/*y arbitrary*/)), 0); + } + // Show crafted metal bar + if (index == 16 && FindObject(Find_ID(Metal))) + TutArrowShowTarget(FindObject(Find_ID(Metal)), 225); +} + +protected func OnGuideMessageRemoved(int plr, int index) +{ + TutArrowClear(); + return; +} + +/*-- Clonk restoring --*/ + +// Relaunches the clonk, from death or removal. +global func FxClonkRestoreStop(object target, effect, int reason, bool temporary) +{ + if (reason == 3 || reason == 4) + { + var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER); + var x = BoundBy(target->GetX(), 0, LandscapeWidth()); + var y = BoundBy(target->GetY(), 0, LandscapeHeight()); + restorer->SetPosition(x, y); + var to_x = effect.var1; + var to_y = effect.var2; + // Respawn new clonk. + var plr = target->GetOwner(); + var clonk = CreateObject(Clonk, 0, 0, plr); + clonk->GrabObjectInfo(target); + SetCursor(plr, clonk); + clonk->DoEnergy(100000); + restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore"); + } + return 1; +} diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/StringTblDE.txt b/planet/Tutorial.ocf/Tutorial05.ocs/StringTblDE.txt new file mode 100644 index 000000000..0d45b6106 --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial05.ocs/StringTblDE.txt @@ -0,0 +1,14 @@ +MsgTutIntro0=Wilkommen zum Siedlungstutorial von OpenClonk. +MsgTutIntro1=Ich habe dich in diese idyllische Landschaft katapultiert, um dir die ersten Schritte des Siedlungsbaus zu zeigen. +MsgTutIntro2=Alles was du brauchen wirst sind die Grundwerkzeuge, die du bereits bei dir hast. +MsgTutIntro3=Wenn du an einer Stelle einen Tipp brauchst, klicke auf mein Bildchen in der oberen rechten Ecke des Bildschirms. Klicke nochmal, um den Tipp wieder zu schließen. +MsgTutFoundrySite=Das erste Gebäude, das wir brauchen, ist der Hochofen. Benutze deinen Hammer um eine Baustelle zu errichten! +MsgTutFoundryChopTree=Wie du siehst braucht der Hochofen 4 Stein und 2 Holz. Nimm dir deine Axt und fang damit an einen Baum umzuhacken! +MsgTutFoundryHackTree=Du hast den Baum schon gefällt, jetzt musst du ihn noch in kleine Stücke zerhacken. Schwing einfach schön weiter deine Axt! +MsgTutFoundryStoneBlast=Nun brauchen wir noch Stein. Dazu gräbst du einen Feuerstein aus und sprengst damit etwas vom Vorkommen unten links ab. Wenn Du bei dem Feuerstein stehst, drücke [S] um ihn in einen leeren Slot einzusammeln. +MsgTutFoundryMaterialUse=Gut. Nimm nun das ganze Material und befördere es in die Baustelle. Du kannst es mit [E] in der Baustelle ablegen. Bau den Hochofen fertig. +MsgTutFlagpoleSite=Das nächste Gebäude, das wir brauchen, ist ein Flaggenmast. Such dir einen schönen Platz dafür aus und errichte eine Baustelle! +MsgTutFlagpoleIronComponents=Wie du siehst braucht die Flagge 4 Holz und 1 Eisen. Um das Eisen herzustellen musst du aus der rechten Ader Eisenerz freisprengen, wie bei den Steinen, und Kohle ausgraben. +MsgTutFlagpoleIronSmelt=Nun da du Kohle und Erz hast, bringe sie in den Hochofen. (Hinenlegen mit [E]) Mit [Leertaste] öffnest du das Produktionsmenü. Wähle das Metallstück aus und warte. +MsgTutFlagpoleIronPraise=Sehr gut. So wie hier funktioniert jeder Produktionsvorgang in OpenClonk!||Nun musst du nur noch ein wenig Holz fällen um die Flagge fertig zu bauen. +MsgTutEnergy=Wie du siehst überspannt der Flaggenmast ein gewisses Gebiet. Darin können Gegner nicht bauen und Gebäude versorgen sich gegenseitig mit Energie.|Meine letzte Aufgabe für dich ist: Baue ein Windrad, das den Flaggenmast versorgt. Danach kannst du ausprobieren was du willst, ein Sägewerk oder eine Werkstätte vielleicht? diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/StringTblUS.txt b/planet/Tutorial.ocf/Tutorial05.ocs/StringTblUS.txt new file mode 100644 index 000000000..228ef940e --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial05.ocs/StringTblUS.txt @@ -0,0 +1,21 @@ +# Dialogue options +MsgNextTutorial=&Next tutorial +MsgNextTutorialDesc=Start the next tutorial scenario. +MsgRepeatRound=&Repeat this round +MsgRepeatRoundDesc=Restart this scenario. + +# Tutorial messages +MsgTutIntro0=Welcome to the settlement tutorial of OpenClonk! +MsgTutIntro1=I've thrown you into this idyllic landscape to teach you the basic steps of creating a settlement. +MsgTutIntro2=All you need are the three basic tools you were given. +MsgTutIntro3=If at any time you need help, click on my icon in the upper right corner of the screen. Once you're done reading, click again on the icon to hide the message. +MsgTutFoundrySite=The first thing we are going to do is creating a construction site for a foundry. To do that, use the hammer and position the building somewhere to your liking. +MsgTutFoundryChopTree=As you can see, the the foundry requires 2 wood logs and 4 stones to be constructed. Take your axe and start by chopping down a tree with your axe to obtain wood. +MsgTutFoundryHackTree=Now that you chopped down the tree, you will have to chop it to pieces, just continue swinging your axe. +MsgTutFoundryStoneBlast=Now you will have to get some stones. Try using a firestone to mine some from the stone vein on the left side. When you stand next to the firestone, press [S] to pick it up into an empty slot. +MsgTutFoundryMaterialUse=Good! Now, collect the materials and carry them to the foundry's site.||Finish the construction either by just inserting the stones via contents menu [E] or selecting construction via [Space]+[Number]. +MsgTutFlagpoleSite=The next step is building a flagpole. Again, use the hammer to create a construction site, but make sure to select the flagpole from the menu. +MsgTutFlagpoleIronComponents=As you can see, the flag pole requires 4 wood and one metal. Start by digging out some coal and blasting free some chucks of ore from the vein on the right. +MsgTutFlagpoleIronSmelt=Now, place the coal and the iron in the foundry (contents menu with [E]) and select the iron bar in the production menu, which can be opened by pressing [Space] when standing in front of the foundry. +MsgTutFlagpoleIronPraise=Very good, you've produced the first good. All other goods production works the exact same way!||Now, process two trees for the remaining 4 wood you need and build the flagpole. +MsgTutEnergy=As you can see, the flagpole spans a certain area. Within this area, buildings power each other and enemies can't build. My last assignment for you is building a windmill, which will power further buildings like a tools workshop or a sawmill. diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/Title.png b/planet/Tutorial.ocf/Tutorial05.ocs/Title.png new file mode 100644 index 000000000..e9bc6cdc5 Binary files /dev/null and b/planet/Tutorial.ocf/Tutorial05.ocs/Title.png differ diff --git a/planet/Tutorial.ocf/Tutorial05.ocs/Title.txt b/planet/Tutorial.ocf/Tutorial05.ocs/Title.txt new file mode 100644 index 000000000..a062bec7b --- /dev/null +++ b/planet/Tutorial.ocf/Tutorial05.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Siedlungsbau +US:Settlement \ No newline at end of file diff --git a/planet/Worlds.ocf/AcidGoldMine.ocs/DescDE.rtf b/planet/Worlds.ocf/AcidGoldMine.ocs/DescDE.rtf new file mode 100644 index 000000000..1c20b6b4d Binary files /dev/null and b/planet/Worlds.ocf/AcidGoldMine.ocs/DescDE.rtf differ diff --git a/planet/Worlds.ocf/AcidGoldMine.ocs/DescUS.rtf b/planet/Worlds.ocf/AcidGoldMine.ocs/DescUS.rtf new file mode 100644 index 000000000..69795abd8 Binary files /dev/null and b/planet/Worlds.ocf/AcidGoldMine.ocs/DescUS.rtf differ diff --git a/planet/Worlds.ocf/AcidGoldMine.ocs/Landscape.txt b/planet/Worlds.ocf/AcidGoldMine.ocs/Landscape.txt new file mode 100644 index 000000000..a861f444e --- /dev/null +++ b/planet/Worlds.ocf/AcidGoldMine.ocs/Landscape.txt @@ -0,0 +1,118 @@ +/* Acid world - by Sven2 */ + +overlay VaryTex { turbulence=10; algo=rndchecker; zoomX=-100; zoomY=-100; }; +overlay Mats { algo=rndchecker; a=10; zoomX=-100; zoomY=-100; turbulence=100; y=48px; hgt=168px; }; +overlay GraniteTop { algo=border; a=0; b=2; mat=Granite; oy=2px; turbulence=0; }; +overlay LavaSurround { algo=border; a=0; b=2; mat=DuroLava; oy=14px; turbulence=10; }; +overlay SoilBorder { algo=border; a=1; b=1; mat=Earth; tex=earth_midSoil; loosebounds=1; }; +overlay SideLava { mat=DuroLava; algo=bozo; turbulence=100; }; +overlay Ground { algo=poly; + point { x=-50px; y=112px; }; + point { x=0px; y=112px; }; + point { x=24px; y=98px; }; + point { x=30px; y=28px; }; + point { x=60px; y=28px; }; + point { x=72px; y=140px; }; + point { x=90px; y=140px; }; + point { x=102px; y=98px; }; + point { x=200px; y=98px; }; + point { x=200px; y=420px; }; + point { x=-50px; y=420px; }; +}; + +map AcidWorld { + + // Acid lake + overlay { mat=Acid; y=42px; sub=0; }; + overlay { mat=Acid; y=126px; }; + + // Ground + Ground { + turbulence=10; + mat=Earth; tex=earth; + + // Dark earth border + SoilBorder { a=20; b=20; }; + SoilBorder { a=2; b=2; tex=earth_topSoil; }; + + // Rock border + overlay { algo=border; mat=Rock; tex=rock_cracked; a=1; b=1;}; + + // Light earth variation + VaryTex { mat=Earth; tex=earth_dry; }; + + // In earth acid + Mats { turbulence=10000; y=140px; hgt=70px; a=3; mat=Acid; }; + Mats { turbulence=10000; y=210px; hgt=25px; a=0; mat=Acid; }; + + // In earth water + Mats { turbulence=10000; y=182px; hgt=56px; a=5; zoomX=10; zoomY=10; mat=Water; SoilBorder; }; + + // Lava bottom + overlay { turbulence=10; y=238px; hgt=20px; mat=DuroLava; loosebounds=1; GraniteTop; }; + Mats { turbulence=10000; y=266px; a=0; mat=DuroLava; loosebounds=1; SoilBorder; }; + Mats { turbulence=100; algo=sin; y=266px; a=0; mat=DuroLava; loosebounds=1; SoilBorder; }; + + // Caves + overlay Caves { algo=rndchecker; a=2; zoomX=-100; zoomY=10; mask=1; turbulence=10; y=172px; hgt=64px; + overlay {algo=border; a=3; b=0; mat=Tunnel; invert=1; + overlay {mat=Earth; tex=earth_topSoil; algo=border; a=1; b=1;}; + }; + }; + + // Ground materials + Mats { mat=Firestone; y=84px; hgt=140px; turbulence=1000; }; + Mats { mat=Rock; zoomX=10; a=5; VaryTex { mat=rock; tex=rock_cracked;};}; + Mats { mat=Coal; y=56px; hgt=140px; turbulence=1000; }; + Mats { mat=Ore; y=84px; hgt=112px; turbulence=10; }; + Mats { mat=Granite; y=196px; }; + Mats { mat=Granite; y=244px; a=1; hgt=28px; }; + overlay { algo=bozo; mat=Gold; a=10; y=270px; hgt=55px; zoomX=10; zoomY=10; turbulence=100; }; + Mats { mat=Gold; a=4; y=270px; hgt=30px; zoomX=10; zoomY=10; }; + + // Ground border + Ground { mask=1; overlay {algo=border; mat=Rock; tex=rock_cracked; a=2; b=1; turbulence=10; };}; + + // Some safety granit in pit + overlay { x=60px; y=112px; wdt=36px; hgt=39px; mat=Granite; loosebounds=1; turbulence=10; VaryTex { mat=Rock; }; }; + + // Mid cave + overlay { x=45px; y=140px; wdt=10px; hgt=17px; turbulence=10; loosebounds=1; mat=Tunnel; + overlay { x=24; y=0px; wdt=72; hgt=280px; turbulence=10; loosebounds=1; }; + SoilBorder; + }; + + }; + + // Granite border + overlay BorderL { + mat=Granite; algo=poly; turbulence=10; + + point { x=-50px; y=168px; }; + point { x=6px; y=168px; }; + point { x=12px; y=224px; }; + point { x=36px; y=300px; }; + point { x=36px; y=420px; }; + point { x=-50px; y=420px; }; + }; + overlay BorderR { + mat=Granite; algo=poly; turbulence=10; + point { x=200px; y=168px; }; + point { x=114px; y=168px; }; + point { x=108px; y=224px; }; + point { x=84px; y=300px; }; + point { x=84px; y=420px; }; + point { x=200px; y=420px; }; + }; +// overlay {mat =Granite; y=260px; }; + + BorderL { mask=1; overlay { algo=border; a=5; b=5; invert=1; mask=1; SideLava; }; }; + BorderR { mask=1; overlay { algo=border; a=5; b=5; invert=1; mask=1; SideLava; }; }; + + overlay { mat=DuroLava; y=305px; turbulence=10; loosebounds=1; }; + + // Extra gold + overlay { x=102px; y=112px; wdt=12px; hgt=6px; mat=Gold; loosebounds=1; turbulence=10; }; + overlay { x=54px; y=255px; wdt=10px; hgt=12px; mat=Gold; loosebounds=1; turbulence=10; }; + +}; \ No newline at end of file diff --git a/planet/Worlds.ocf/AcidGoldMine.ocs/Scenario.txt b/planet/Worlds.ocf/AcidGoldMine.ocs/Scenario.txt new file mode 100644 index 000000000..db1f321c9 --- /dev/null +++ b/planet/Worlds.ocf/AcidGoldMine.ocs/Scenario.txt @@ -0,0 +1,52 @@ +[Head] +Title=AcidGoldMine +Icon=22 +Version=5,3,0,0 +Difficulty=120 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Goals=Goal_Wealth=1; +Rules=Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player2] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player3] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Player4] +Crew=Clonk=2 +Knowledge=Flagpole=1;Foundry=1;WindGenerator=1;SteamEngine=1;Compensator=1;Sawmill=1;ChemicalLab=1;Elevator=1;Pump=1;ToolsWorkshop=1;WallKit=1;GoldBar=1;Loam=1;Metal=1;Axe=1;Barrel=1;Bucket=1;Dynamite=1;Hammer=1;JarOfWinds=1;Pickaxe=1;Pipe=1;Shovel=1;TeleGlove=1 +HomeBaseMaterial=Clonk=5;Bread=5; +HomeBaseProduction=Clonk=5;Bread=5; + +[Landscape] +Sky=Clouds1 +SkyScrollMode=1 +TopOpen=1 +BottomOpen=0 +MapWidth=120 +MapHeight=315 +MapZoom=6 + +[Weather] +Climate=00,0,0,00 +StartSeason=0,0,0,00 +YearSpeed=0,0,0,000 +Wind=100,0,100,100 + diff --git a/planet/Worlds.ocf/AcidGoldMine.ocs/Script.c b/planet/Worlds.ocf/AcidGoldMine.ocs/Script.c new file mode 100644 index 000000000..4125ca0b4 --- /dev/null +++ b/planet/Worlds.ocf/AcidGoldMine.ocs/Script.c @@ -0,0 +1,129 @@ +/* Acid gold mine */ + +static g_highest_plr_count; // max number of players that were ever in the round + +func Initialize() +{ + // Goal + var goal = FindObject(Find_ID(Goal_Wealth)); + if (!goal) goal = CreateObject(Goal_Wealth); + goal->SetWealthGoal(200); // updated in InitializePlayer + // Rules + if (!ObjectCount(Find_ID(Rule_TeamAccount))) CreateObject(Rule_TeamAccount); + // Acid rain! + Cloud->Place(10); + Cloud->SetPrecipitation("Acid", 100); + // Earthquacks and lava! + Earthquake->SetChance(100); + Volcano->SetChance(2); + Volcano->SetMaterial("DuroLava"); + Meteor->SetChance(22); + // We aren't doing much outside anyway; celestials are a bit of a waste + /*CreateObject(Environment_Celestial); + var time = CreateObject(Environment_Time); + time->SetTime(60*12); + time->SetCycleSpeed(20);*/ + // Starting materials in lorry + var pos = FindTopSpot(); + var lorry = CreateObject(Lorry, pos.x, pos.y); + if (lorry) + { + lorry->CreateContents(WallKit,5); + lorry->CreateContents(Wood,12); + lorry->CreateContents(Metal,5); + lorry->CreateContents(Bread,8); + lorry->CreateContents(Firestone,5); + lorry->CreateContents(Dynamite,3); + lorry->CreateContents(DynamiteBox,2); + } + // Mushrooms before any earth materials, because they create their own caves + LargeCaveMushroom->Place(15, Rectangle(LandscapeWidth()/4,172*6,LandscapeWidth()/2,60*6)); + // Create earth materials + // Create them in big clusters so the whole object arrangement looks a bit less uniform and more interesting + PlaceBatches([Firestone], 3, 100, 5); + PlaceBatches([Rock, Loam, Loam], 10, 200, 10); + // Create some chests in caves + var chest_pos, chest; + var chest_sets = [[[DynamiteBox,2], [Dynamite,5], [Bread,5]], [[Loam,5], [WallKit,3], [Wood,8]], [[Bread,10],[Firestone,5],[Wood,8]]]; + for (var i=0; i<3; ++i) + if (chest_pos = FindLocation(Loc_Material("Tunnel"), Loc_Wall(CNAT_Bottom))) + if (chest = CreateObject(Chest, chest_pos.x, chest_pos.y)) + for (var chest_fill in chest_sets[i]) + chest->CreateContents(chest_fill[0],chest_fill[1]); + // A barrel + if (chest_pos = FindLocation(Loc_Material("Tunnel"), Loc_Wall(CNAT_Bottom))) + CreateObject(Barrel, chest_pos.x, chest_pos.y); + // Misc vegetation + SproutBerryBush->Place(5, Rectangle(0,LandscapeHeight()/4,LandscapeWidth(),LandscapeHeight()*3/4)); + Mushroom->Place(5, Rectangle(0,LandscapeHeight()/4,LandscapeWidth(),LandscapeHeight()*3/4)); + Tree_Coniferous_Burned->Place(2, Rectangle(0,0,LandscapeWidth(),LandscapeHeight()/4)); + // Bottom item killer + var fx = AddEffect("KeepAreaClear", nil, 1, 5); + fx.search_criterion=Find_And(Find_AtRect(0,LandscapeHeight()-10,LandscapeWidth(),10), Find_Not(Find_Category(C4D_StaticBack))); + return true; +} + +func InitializePlayer(int plr) +{ + // Harsh zoom range + for (var flag in [PLRZOOM_LimitMax, PLRZOOM_Direct]) + SetPlayerZoomByViewRange(plr,500,350,flag); + SetPlayerViewLock(plr, true); + // Position and materials + var i, crew; + for (i=0; crew=GetCrew(plr,i); ++i) + { + var pos = FindTopSpot(); + crew->SetPosition(pos.x, pos.y-10); + crew->CreateContents(Shovel); + if (!i) + { + crew->CreateContents(Hammer); + } + else if (i==1) + { + crew->CreateContents(Axe); + } + } + // Update goal: More players need to mine more gold + if (GetPlayerCount() > g_highest_plr_count) + { + g_highest_plr_count = GetPlayerCount(); + var goal = FindObject(Find_ID(Goal_Wealth)); + if (goal) + { + goal->SetWealthGoal(BoundBy(125+75*g_highest_plr_count, 225, 300)); + } + } + return true; +} + +func FindTopSpot() +{ + return FindLocation(Loc_InRect(LandscapeWidth()/4,0,LandscapeWidth()/2,LandscapeHeight()/9), Loc_Wall(CNAT_Bottom), Loc_Space(10)) ?? {x=LandscapeWidth()/3+Random(30), y=LandscapeHeight()/12 }; +} + + +global func FxKeepAreaClearTimer(object q, proplist fx, int time) +{ + for (var obj in FindObjects(fx.search_criterion)) + if (obj) obj->RemoveObject(); + return FX_OK; +} + +private func PlaceBatches(array item_ids, int n_per_batch, int batch_radius, int n_batches) +{ + // place a number (n_batches) of batches of objects of types item_ids. Each batch has n_per_batch objects. + // fewer batches and/or objects may be placed if no space is found + var loc,loc2,n_item_ids=GetLength(item_ids), n_created=0, obj; + for (var i=0; iSetPosition(loc2.x,loc2.y); + ++n_created; + } + return n_created; +} diff --git a/planet/Worlds.ocf/AcidGoldMine.ocs/Title.txt b/planet/Worlds.ocf/AcidGoldMine.ocs/Title.txt new file mode 100644 index 000000000..2ca7ca9c4 --- /dev/null +++ b/planet/Worlds.ocf/AcidGoldMine.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Säuregoldmine +US:Acid gold mine \ No newline at end of file diff --git a/planet/Worlds.ocf/DescDE.rtf b/planet/Worlds.ocf/DescDE.rtf new file mode 100644 index 000000000..98c2bc4f5 --- /dev/null +++ b/planet/Worlds.ocf/DescDE.rtf @@ -0,0 +1,23 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset1 Times New Roman;}{\f4\fswiss\fprq0\fcharset1 Arial;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Arial;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af5\langfe2052\dbch\af7\afs28\alang1081\loch\f4\fs28\lang1043 Heading;} +{\s16\sbasedon0\snext16\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Text body;} +{\s17\sbasedon16\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 List;} +{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf0\i\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\ai\loch\f3\fs24\lang1043 Caption;} +{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\nowidctlpar{\cf1\b\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033 +Welten} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\nowidctlpar\cf1\b\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +This scenario folder contains peaceful settlement rounds with dynamic and versatile landscapes. The players have to combine their efforts to fulfill }{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +simple }{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +goals like mining or expanding territory. After all goals have been completed, worlds can still be played to create large and complex settlements.} +\par } \ No newline at end of file diff --git a/planet/Worlds.ocf/DescUS.rtf b/planet/Worlds.ocf/DescUS.rtf new file mode 100644 index 000000000..318cd0f06 --- /dev/null +++ b/planet/Worlds.ocf/DescUS.rtf @@ -0,0 +1,23 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset1 Times New Roman;}{\f4\fswiss\fprq0\fcharset1 Arial;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Arial;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af5\langfe2052\dbch\af7\afs28\alang1081\loch\f4\fs28\lang1043 Heading;} +{\s16\sbasedon0\snext16\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Text body;} +{\s17\sbasedon16\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 List;} +{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf0\i\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\ai\loch\f3\fs24\lang1043 Caption;} +{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\nowidctlpar{\cf1\b\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033 +Worlds} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\nowidctlpar\cf1\b\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +This scenario folder contains peaceful settlement rounds with dynamic and versatile landscapes. The players have to combine their efforts to fulfill }{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +simple }{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +goals like mining or expanding territory. After all goals have been completed, worlds can still be played to create large and complex settlements.} +\par } \ No newline at end of file diff --git a/planet/Worlds.ocf/Folder.txt b/planet/Worlds.ocf/Folder.txt new file mode 100644 index 000000000..075a22a03 --- /dev/null +++ b/planet/Worlds.ocf/Folder.txt @@ -0,0 +1,2 @@ +[Head] +Index=2 \ No newline at end of file diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/DescDE.rtf b/planet/Worlds.ocf/GemGrabbers.ocs/DescDE.rtf new file mode 100644 index 000000000..e05b93f3e --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/DescDE.rtf @@ -0,0 +1,37 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset1 Times New Roman;}{\f4\fswiss\fprq0\fcharset1 Arial;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Arial;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af5\langfe2052\dbch\af7\afs28\alang1081\loch\f4\fs28\lang1043 Heading;} +{\s16\sbasedon0\snext16\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Text body;} +{\s17\sbasedon16\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 List;} +{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf0\i\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\ai\loch\f3\fs24\lang1043 Caption;} +{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033 +Gem Grabbers} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +A group of settlers set out for the skies, after a turbulent and rainy ride in their airship they stumbled upon an abandoned settlement. One divided among different islands. Unfortunately the airship got lost, but as the settlers arrived something shiny caught their eyes. Gems! These types of minerals are worth a lot back home, so this is a great opportunity to become wealthy.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +Goal: Mine a significant amount of gems.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +Hints:} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- There is heavy rain, be careful to not build tunnels which will flood.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- Don't waste too many gems into the abyss, this might spoil your chances to fulfill the goal.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- There are other sky islands besides the one you landed on, explore them.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- There are strong winds, take precautions and only go on a trip with the right equipment.} +\par } \ No newline at end of file diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/DescUS.rtf b/planet/Worlds.ocf/GemGrabbers.ocs/DescUS.rtf new file mode 100644 index 000000000..1aa1f1f87 --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/DescUS.rtf @@ -0,0 +1,39 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset1 Times New Roman;}{\f4\fswiss\fprq0\fcharset1 Arial;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Arial;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af5\langfe2052\dbch\af7\afs28\alang1081\loch\f4\fs28\lang1043 Heading;} +{\s16\sbasedon0\snext16\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Text body;} +{\s17\sbasedon16\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 List;} +{\s18\sbasedon0\snext18\ql\nowidctlpar\sb120\sa120\noline\ltrpar\cf0\i\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\ai\loch\f3\fs24\lang1043 Caption;} +{\s19\sbasedon0\snext19\ql\nowidctlpar\noline\ltrpar\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs20\lang1033 +Gem Grabbers} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +A group of settlers set out for the skies, after a turbulent and rainy ride in their airship they stumbled upon an abandoned settlement. One divided among different islands. Unfortunately the airship got lost, but as the settlers arrived something shiny caught their eyes. Gems! These types of minerals are worth a lot back home, so this is a great opportunity to become wealthy.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +Goal: Mine a significant amount of gems.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 + +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +Hints:} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- There is heavy rain, be careful to not build tunnels which will flood.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- Don't waste too many gems into the abyss, this might spoil your chances to fulfill the goal.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- There are other sky islands besides the one you landed on, explore them.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar{\cf1\b0\kerning1\langfe2052\dbch\af7\afs24\alang1081\rtlch \ltrch\loch\fs16\lang1033 +- There are strong winds, take precautions and only go on a trip with the right equipment.} +\par \pard\plain \s0\ql\nowidctlpar\ltrpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1043\ql\nowidctlpar\rtlch \ltrch\loch + +\par } \ No newline at end of file diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Map.c b/planet/Worlds.ocf/GemGrabbers.ocs/Map.c new file mode 100644 index 000000000..48b14be08 --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Map.c @@ -0,0 +1,191 @@ +/** + Gem Grabbers + Dynamic map with sky islands and hard to reach gems. There is a main island, with at the bottom hanging gems + and some smaller islands which also have gems hanging from the bottom. + + @authors Maikel +*/ + +#include Library_Map + + +// Scenario properties which can be set later by the lobby options. +static const SCENOPT_MapSize = 1; + +// Called be the engine: draw the complete map here. +protected func InitializeMap(proplist map) +{ + // Retrieve the settings according to the MapSize setting. + var map_size, main_size, nr_islands; + if (SCENOPT_MapSize == 1) + { + map_size = [240, 200]; main_size = 80; nr_islands = RandomX(6, 7); + } + if (SCENOPT_MapSize == 2) + { + map_size = [280, 220]; main_size = 90; nr_islands = RandomX(7, 8); + } + if (SCENOPT_MapSize == 3) + { + map_size = [320, 240]; main_size = 100; nr_islands = RandomX(8, 9); + } + + // Set the map size. + map->Resize(map_size[0], map_size[1]); + + // Draw the main island. + map->DrawMainIsland(map, main_size); + + // Draw a number of sky islands at random positions, each with different resources. + var resources = [["Coal", "Ore"], ["Coal", "Gold"], ["Firestone", "Coal"], ["Rock", "Ore"], ["Rock", "Coal", "Firestone"], ["Gold", "Ore", "Coal"]]; + while (nr_islands > 0) + { + var x = 12 + Random(map.Wdt - 24); + var y = 26 + Random(map.Hgt - 52); + var wdt = RandomX(35, 45); + var hgt = wdt - RandomX(16, 22); + // DrawIsland itself makes sure there is no other island nearby. + if (DrawIsland(map, x, y, wdt, hgt, resources[Random(6)])) + nr_islands--; + } + + // Fix the liquid borders with a library function. + FixLiquidBorders("Earth"); + + // Return true to tell the engine a map has been successfully created. + return true; +} + +// Draws the main island with all basic resources +public func DrawMainIsland(proplist map, int size) +{ + // Shape of the main island. + var island = {Algo = MAPALGO_Polygon}; + var x = map.Wdt / 2; + var y = map.Hgt / 2; + island.X = [x-size/3, x-size/2, x-size/3, x-size/6, x+size/6, x+size/3, x+size/2, x+size/3]; + island.Y = [y-size/6, y, y+size/3, y+size/6, y+size/6, y+size/3, y, y-size/6]; + + // Draw the earth patch of the island. + island = {Algo = MAPALGO_Turbulence, Iterations = 4, Seed = Random(65536), Op = island}; + Draw("Earth", island); + + // Overlay a set of materials inside the island. + DrawIslandMat("Earth-earth_dry", island, 4, 30); + DrawIslandMat("Earth-earth_midSoil", island, 3, 30); + DrawIslandMat("Tunnel", island, 3, 10); + DrawIslandMat("Water", island, 4, 8); + DrawIslandMat("Gold", island, 3, 6); + DrawIslandMat("Ore", island, 6, 12); + DrawIslandMat("Firestone", island, 6, 12); + DrawIslandMat("Coal", island, 6, 12); + + // Draw a top border out of sand and top soil. + var sand_border = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Border, Op = island, Top = [-1,2]}, {Algo = MAPALGO_RndChecker, Ratio = 50, Wdt = 4, Hgt = 3}]}; + var topsoil_border = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Border, Op = island, Top = [-1,3]}, {Algo = MAPALGO_RndChecker, Ratio = 40, Wdt = 4, Hgt = 2}]}; + Draw("Sand", sand_border); + Draw("Earth-earth_topSoil", topsoil_border); + + // Draw a bottom border out of granite and rock. + var granite_border = {Algo = MAPALGO_Border, Op = island, Bottom = [-4,3]}; + Draw("Granite", granite_border); + var rock_border = {Algo = MAPALGO_RndChecker, Ratio = 20, Wdt = 2, Hgt = 2}; + Draw("Rock", {Algo = MAPALGO_And, Op = [granite_border, rock_border]}); + Draw("Rock-rock_cracked", {Algo = MAPALGO_And, Op = [granite_border, rock_border]}); + + // Draw some gems attached at the bottom of the island. + var rect = [x - size / 2, y - size / 3, size / 2, 3 * size / 4]; + DrawGems("Ruby", rect, 3, map); + rect = [x, y - size / 3, size / 2, 3 * size / 4]; + DrawGems("Amethyst", rect, 3, map); + + return; +} + +// Draws a smaller island at the specified location if the location rectangle is free, returns whether succeeded. +public func DrawIsland(proplist map, int x, int y, int wdt, int hgt, array mats) +{ + // Don't draw an island if there is already something nearby. + var rect = [x - wdt, y - 3 * hgt / 2, 2 * wdt, 3 * hgt]; + if (GetPixelCount("Solid", rect) > 0) + return false; + + // An island is just an ellipse with turbulence. + var island = {Algo = MAPALGO_Ellipsis, X = x, Y = y, Wdt = wdt / 2, Hgt = hgt / 2}; + island = {Algo = MAPALGO_Turbulence, Iterations = 4, Amplitude = [6, 12], Seed = Random(65536), Op = island}; + Draw("Earth", island); + + // Overlay a set of materials inside the island. + DrawIslandMat("Earth-earth_dry", island, 4, 30); + DrawIslandMat("Earth-earth_midSoil", island, 3, 30); + DrawIslandMat("Tunnel", island, 3, 10); + for (var mat in mats) + { + DrawIslandMat(mat, island, 4, 18); + DrawIslandMat(mat, island, 6, 12); + } + + // Draw a top border out of sand and top soil. + var sand_border = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Border, Op = island, Top = [-1,2]}, {Algo = MAPALGO_RndChecker, Ratio = 50, Wdt = 4, Hgt = 3}]}; + var topsoil_border = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Border, Op = island, Top = [-1,3]}, {Algo = MAPALGO_RndChecker, Ratio = 40, Wdt = 4, Hgt = 2}]}; + Draw("Sand", sand_border); + Draw("Earth-earth_topSoil", topsoil_border); + + // Draw a bottom border out of granite and rock. + var granite_border = {Algo = MAPALGO_Border, Op = island, Bottom = [-2,3]}; + Draw("Granite", granite_border); + var rock_border = {Algo = MAPALGO_RndChecker, Ratio = 20, Wdt = 2, Hgt = 2}; + Draw("Rock", {Algo = MAPALGO_And, Op = [granite_border, rock_border]}); + Draw("Rock-rock_cracked", {Algo = MAPALGO_And, Op = [granite_border, rock_border]}); + + // Draw some gems attached at the bottom of the island. + var gem = ["Ruby", "Amethyst"][Random(2)]; + DrawGems(gem, rect, 3, map); + + return true; +} + +// Looks for a location at the bottom of a sky islands and places some gems. +public func DrawGems(string gem_mat, array rect, int size, proplist map) +{ + // Adapt rect to find at least a spot 8 * MapZoom pixel distance from the map borders. + rect[2] -= Max(0, 8 - rect[0]); rect[0] = Max(8, rect[0]); // Left boundary. + rect[2] = Min(rect[2], map.Wdt - rect[0] - 8); // Right boundary. + + var low_spot = {X = rect[0], Y = rect[1]}; + for (var i = 0; i < 250; i++) + { + var spot = {}; + this->FindPosition(spot, "Solid", rect); + if (spot.Y > low_spot.Y) + { + low_spot = spot; + } + } + var gems = {Algo = MAPALGO_Ellipsis, X = low_spot.X, Y = low_spot.Y + 1, Wdt = size - 1, Hgt = size}; + gems = {Algo = MAPALGO_Turbulence, Amplitude = 5, Scale = 5, Iterations = 2, Op = gems}; + Draw(gem_mat, gems); + + // Some granite border above the gems to be sure. + var gem_border = {Algo = MAPALGO_Border, Top = -4, Op = gems}; + Draw("Granite", gem_border); + + return; +} + +// Draws some material inside an island. +public func DrawIslandMat(string mat, proplist onto_mask, int speck_size, int ratio) +{ + if (!speck_size) + speck_size = 3; + if (!ratio) + ratio = 20; + // Use random checker algorithm to draw patches of the material. + var rnd_checker = {Algo = MAPALGO_RndChecker, Ratio = ratio, Wdt = speck_size, Hgt = speck_size}; + rnd_checker = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = rnd_checker}; + var mask_border = {Algo = MAPALGO_Border, Op = onto_mask, Wdt = 3}; + var algo = {Algo = MAPALGO_And, Op = [{Algo = MAPALGO_Xor, Op = [onto_mask, mask_border]}, rnd_checker]}; + Draw(mat, algo); + + return; +} diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Amethyst.jpg b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Amethyst.jpg new file mode 100644 index 000000000..36c0dd8a0 Binary files /dev/null and b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Amethyst.jpg differ diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Amethyst.ocm b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Amethyst.ocm new file mode 100644 index 000000000..0d64a3831 --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Amethyst.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Amethyst +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Amethyst +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Amethyst diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Ruby.jpg b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Ruby.jpg new file mode 100644 index 000000000..c84122ce9 Binary files /dev/null and b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Ruby.jpg differ diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Ruby.ocm b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Ruby.ocm new file mode 100644 index 000000000..c7a631d97 --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/Ruby.ocm @@ -0,0 +1,13 @@ +[Material] +Name=Ruby +Shape=Rough +Density=70 +Friction=15 +BlastFree=1 +Blast2Object=Ruby +Blast2ObjectRatio=100 +MaxAirSpeed=100 +MaxSlide=1 +Corrode=60 +Placement=21 +TextureOverlay=Ruby diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/TEXMAP.TXT b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/TEXMAP.TXT new file mode 100644 index 000000000..880820dff --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Material.ocg/TEXMAP.TXT @@ -0,0 +1,47 @@ +OverloadMaterials +OverloadTextures + +10=Tunnel-tunnel +12=Tunnel-brickback + +13=BrickSoft-brick1 + +19=DuroLava-lava_red +20=Water-water1-water2-water3-water1-water3-water2 +22=Acid-acid +23=Lava-lava_red +25=Water-water + +28=Earth-earth +29=Earth-earth_dry +30=Earth-earth_rough +31=Earth-earth_topsoil +32=Earth-earth_midsoil +33=Ashes-ashes + +36=Ore-ore + +40=Granite-granite +42=Granite-rock + +45=Gold-gold + +50=Rock-rock +51=Rock-rock_cracked + +53=Firestone-firestone + +54=Coal-coal + +55=Sand-sand_rough +56=Sand-sand_smooth + +60=Ruby-Ruby +61=Amethyst-Amethyst + +65=Ice-ice2 +67=Ice-ice3 + +70=Snow-snow1 + +73=Brick-brick1 diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Scenario.txt b/planet/Worlds.ocf/GemGrabbers.ocs/Scenario.txt new file mode 100644 index 000000000..1b160d98a --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Scenario.txt @@ -0,0 +1,44 @@ +[Head] +Title=GemGrabbers +Icon=35 +Version=5,3,0,0 +Difficulty=100 + +[Definitions] +Definition1=Objects.ocd + +[Game] +ValueOverloads=Ruby=10;Amethyst=10 + +[Player1] +Crew=Clonk=2 +HomeBaseMaterial=Clonk=1 + +[Player2] +Crew=Clonk=2 +HomeBaseMaterial=Clonk=1 + +[Player3] +Crew=Clonk=2 +HomeBaseMaterial=Clonk=1 + +[Player4] +Crew=Clonk=2 +HomeBaseMaterial=Clonk=1 + +[Landscape] +Sky=Clouds1 +TopOpen=1 +BottomOpen=1 +LeftOpen=2400 +RightOpen=2400 +AutoScanSideOpen=0 +MapWidth=240 +MapHeight=200 + +[Weather] +Climate=0 +StartSeason=0 +YearSpeed=0 +Wind=0,100,-100,100 + diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Script.c b/planet/Worlds.ocf/GemGrabbers.ocs/Script.c new file mode 100644 index 000000000..296aa6295 --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Script.c @@ -0,0 +1,398 @@ +/** + Gem Grabbers + Players need to grab gems from non trivial locations in a landscape with many sky islands. + There are many tools either available directly or for production on the other islands. + + Todo's: + * Rain and wind effects. + * Attacking birds on the islands with new buildings. + * Some other hurdles. + * Decoration on all the islands. + * Flatten the main islands surface a bit in Map.c + + @authors Maikel +*/ + + +// Scenario properties which can be set later by the lobby options. +static const SCENOPT_Material = 3; // Amount of material available from start. +static const SCENOPT_MapSize = 1; // Size of the map. +static const SCENOPT_Difficulty = 2; // Difficulty settings. + +protected func Initialize() +{ + // Rules: team account and buying at flagpole. + CreateObject(Rule_TeamAccount); + CreateObject(Rule_BuyAtFlagpole); + + // Goal: Sell Gems, amount depends on difficulty and availability. + var gems = (GetMaterialCount(Material("Ruby")) + GetMaterialCount(Material("Amethyst"))) / 125; + var percentage = 55 + 15 * SCENOPT_Difficulty; + var goal = CreateObject(Goal_SellGems); + goal->SetTargetAmount((gems * percentage) / 100); + + // Initialize different parts of the scenario. + InitEnvironment(); + InitVegetation(); + InitAnimals(); + InitMainIsland(SCENOPT_Material); + InitIslands(SCENOPT_Material); + + return; +} + +protected func InitializePlayer(int plr) +{ + // Harsh zoom range + SetPlayerZoomByViewRange(plr, 500, 350, PLRZOOM_LimitMax); + SetPlayerZoomByViewRange(plr, 500, 350, PLRZOOM_Direct); + SetPlayerViewLock(plr, true); + + // Position and materials + var i, crew; + for (i = 0; crew = GetCrew(plr, i); ++i) + { + var pos = FindMainIslandPosition(); + crew->SetPosition(pos[0], pos[1] - 11); + crew->CreateContents(Shovel); + } + + // Give the player its knowledge. + GivePlayerKnowledge(plr); + + // Only clonks for sale at the homebase. + DoHomebaseMaterial(plr, Clonk, Max(4 - SCENOPT_Difficulty, 1)); + + // Claim ownership of structures, last player who joins owns all the main island flags. + for (var structure in FindObjects(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole")))) + structure->SetOwner(plr); + + return; +} + +// Give the relevant knowledge to each player. +private func GivePlayerKnowledge(int plr) +{ + var structures = [Flagpole, WindGenerator, SteamEngine, Compensator, Foundry, Sawmill, Elevator, Pump, ToolsWorkshop, ChemicalLab, Armory, Chest, Windmill, Kitchen]; + var items = [Loam, GoldBar, Metal, Shovel, Axe, Hammer, Pickaxe, Barrel, Bucket, Dynamite, DynamiteBox, PowderKeg, Pipe, TeleGlove, WindBag, GrappleBow, Boompack, Balloon]; + var weapons = [Bow, Arrow, Club, Sword, Javelin, Shield, Musket, LeadShot, IronBomb, GrenadeLauncher]; + var vehicles = [Lorry, Catapult, Cannon, Airship, Plane]; + for (var structure in structures) + SetPlrKnowledge(plr, structure); + for (var item in items) + SetPlrKnowledge(plr, item); + for (var weapon in weapons) + SetPlrKnowledge(plr, weapon); + for (var vehicle in vehicles) + SetPlrKnowledge(plr, vehicle); + return; +} + +// Initializes environment and disasters. +private func InitEnvironment() +{ + // Set time to almost night and have stars. + CreateObject(Environment_Celestial); + var time = CreateObject(Environment_Time); + time->SetTime(20*60 + 15); + time->SetCycleSpeed(0); + + // Clouds and rain. + Cloud->Place(15); + Cloud->SetPrecipitation("Water", 100 + 25 * SCENOPT_Difficulty); + for (var cloud in FindObjects(Find_ID(Cloud))) + { + while (cloud->RemoveVertex()) + /* Empty */; + // Make some clouds appear in the foreground with high alpha. + if (Random(3) == 0) + { + cloud.Plane = 600; + cloud->SetCloudAlpha(40); + } + } + + // Set a certain parallax. + SetSkyParallax(0, 20, 20); + + // Disasters: meteors and lightning. + Meteor->SetChance(2 * SCENOPT_Difficulty); + Cloud->SetLightning(8 * SCENOPT_Difficulty); + + return; +} + +private func InitVegetation() +{ + // Grass on all islands. + PlaceGrass(85); + + // Place some cocont trees all around the island and some extra trees on the main island. + for (var i = 0; i < 40 + Random(8); i++) + PlaceVegetation(Tree_Coconut, 0, 0, LandscapeWidth(), LandscapeHeight(), 1000 * (61 + Random(40))); + for (var i = 0; i < 6 + Random(2); i++) + PlaceVegetation(Tree_Coconut, LandscapeWidth() - 300, LandscapeHeight() - 200, 600, 400, 1000 * (71 + Random(30))); + + // Create an effect to make sure there will always grow some new trees. + AddEffect("EnsureTreesOnMainIsland", nil, 100, 20, nil); + + // Some objects in the earth. + PlaceObjects(Rock, 35 + Random(10),"Earth"); + PlaceObjects(Firestone, 25 + Random(5), "Earth"); + + return; +} + +// Ensures that there will always grow some trees on the main island. +global func FxEnsureTreesOnMainIslandTimer() +{ + var wdt = LandscapeWidth(); + var hgt = LandscapeHeight(); + // Place a tree if there are less than eight trees, with increasing likelihood for lower amounts of trees. + var nr_trees = ObjectCount(Find_Func("IsTree"), Find_InRect(wdt / 2 - 300, hgt / 2 - 200, 600, 400)); + if (Random(9) >= nr_trees) + if (!Random(20)) + PlaceVegetation(Tree_Coconut, wdt / 2 - 300, hgt / 2 - 200, 600, 400, 3); + return FX_OK; +} + +private func InitAnimals() +{ + + + return; +} + +// Initializes the main island according to the material specification. +private func InitMainIsland(int amount) +{ + amount = BoundBy(amount, 1, 3); + var pos; + + // Always start with a lorry filled with: hammer(x2), axe(x2), wood(x6) and metal(x4). + var lorry_pos = FindMainIslandPosition(0, 80); + var lorry = CreateObject(Lorry, lorry_pos[0], lorry_pos[1] - 8); + lorry->CreateContents(Hammer, 2); + lorry->CreateContents(Axe, 2); + lorry->CreateContents(Wood, 6); + lorry->CreateContents(Metal, 4); + + // If more material is specified, create a small settlement: flag(x2) and windmill. + // Also fill lorry a bit more with: pickaxe(x1), dynamite(x4), wood(x4), metal(x2). + if (amount >= 2) + { + pos = FindMainIslandPosition(-120, 20); + CreateObject(Flagpole, pos[0], pos[1]); + pos = FindMainIslandPosition(120, 20); + CreateObject(Flagpole, pos[0], pos[1]); + pos = FindMainIslandPosition(nil, nil, true); + CreateObject(WindGenerator, pos[0], pos[1]); + lorry->CreateContents(Wood, 4); + lorry->CreateContents(Metal, 2); + lorry->CreateContents(Pickaxe, 1); + lorry->CreateContents(Dynamite, 4); + } + + // If still more material is specified, create a larger settlement: sawmill, chemical lab, tools workshop. + // Also fill lorry a bit more with: Barrel (x1), Bucket(x1), Loam(x4), DynamiteBox(x2). + if (amount >= 3) + { + pos = FindMainIslandPosition(nil, nil, true); + CreateObject(Sawmill, pos[0], pos[1]); + pos = FindMainIslandPosition(nil, nil, true); + CreateObject(ChemicalLab, pos[0], pos[1]); + pos = FindMainIslandPosition(nil, nil, true); + CreateObject(ToolsWorkshop, pos[0], pos[1]); + + lorry->CreateContents(Barrel, 1); + lorry->CreateContents(Bucket, 1); + lorry->CreateContents(Loam, 4); + lorry->CreateContents(DynamiteBox, 1); + lorry->CreateContents(Boompack, 1); + } + + return; +} + +// Tries to find a position on the main island. +private func FindMainIslandPosition(int xpos, int sep, bool no_struct) +{ + if (xpos == nil) + xpos = 0; + if (sep == nil) + sep = 250; + var wdt = LandscapeWidth(); + var hgt = LandscapeHeight(); + + for (var i = 0; i < 100; i++) + { + var x = RandomX(wdt / 2 + xpos - sep, wdt / 2 + xpos + sep); + var y = hgt / 2 - 220; + + while (!GBackSolid(x, y) && y < 3 * hgt / 4) + y++; + + if (!no_struct || !FindObject(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole")), Find_Distance(60, x, y))) + break; + } + + return [x, y]; +} + +// Initializes the smaller islands according to the material specification. +private func InitIslands(int amount) +{ + amount = BoundBy(amount, 1, 3); + + // Locate all islands and store them in an array. + var islands = FindIslands(); + + // Add some structures, materials and vegetation to each island depending on material specification. + var island_nr = 1; + for (var island in islands) + island_nr += ProvideIsland(island, island_nr, amount); + + return; +} + +// Returns an array with rectangles enclosing each of the islands. +private func FindIslands() +{ + var wdt = LandscapeWidth(); + var hgt = LandscapeHeight(); + var main = [wdt / 2 - 500, hgt / 2 - 225, 1000, 600]; + var spot = FindLocation(Loc_Solid(), Loc_Not(Loc_InRect(main[0], main[1], main[2], main[3]))); + var islands = []; var island_cond; + // Search for islands iteratively excluding the rectangle of the last found island. + do + { + var island = MakeIslandRect(spot.x, spot.y); + islands[GetLength(islands)] = island; + island_cond = Loc_Not(Loc_InRect(island[0], island[1], island[2], island[3])); + for (var i = 0; i < GetLength(islands) - 1; i++) + { + var island = islands[i]; + island_cond = Loc_And(island_cond, Loc_Not(Loc_InRect(island[0], island[1], island[2], island[3]))); + } + + } + while (spot = FindLocation(Loc_Solid(), Loc_Not(Loc_InRect(main[0], main[1], main[2], main[3])), island_cond)); + + return islands; +} + +private func MakeIslandRect(int x, int y) +{ + var x1 = x, x2 = x; + var y1 = y, y2 = y; + var lwdt = LandscapeWidth(); + var lhgt = LandscapeHeight(); + + // find some random spots until one finds the boundaries. + for (var i = 0; i < 200; i++) + { + var spot = FindLocation(Loc_Solid(), Loc_InRect(Max(0, x - 60), Max(0, y - 60), Min(120, lwdt - x + 60), Min(120, lhgt - y + 60))); + if (!spot) + continue; + x = spot.x; y = spot.y; + if (x < x1) x1 = x; + if (x > x2) x2 = x; + if (y < y1) y1 = y; + if (y > y2) y2 = y; + } + + // Make the rectangle somewhat bigger. + var x1 = Max(0, x1 - 100); + var y1 = Max(0, y1 - 100); + var wdt = x2 - x1 + 200; wdt = Min(wdt, lwdt - x1); + var hgt = y2 - y1 + 200; hgt = Min(hgt, lhgt - y1); + + var rect = [x1, y1, wdt, hgt]; + return rect; +} + +// Provides some stuff for each of the 6-9 other islands, dependent on the material settings. +private func ProvideIsland(array island, int number, int amount) +{ + var spot = FindLocation(Loc_InRect(island[0], island[1], island[2], island[3] / 2), Loc_Wall(CNAT_Bottom), Loc_Space(20), Loc_Sky()); + if (!spot) + return 0; + + // An inventors lab without power supply but with some rockets for the first island. + if (number == 1) + { + var lab = CreateObject(InventorsLab, spot.x, spot.y); + lab->MakeInvincible(); + lab->CreateContents(Boompack, amount); + } + + // A shipyard without materials and power supply for the second island. + if (number == 2) + { + var shipyard = CreateObject(Shipyard, spot.x, spot.y); + shipyard->CreateContents(Wood, 4); + shipyard->CreateContents(Metal, 2); + shipyard->MakeInvincible(); + } + + // A cannon with a powder keg for the third island. + if (number == 3) + { + var cannon = CreateObject(Cannon, spot.x, spot.y); + cannon->CreateContents(PowderKeg); + } + + // A catapult for the fourth island. + if (number == 4) + { + SproutBerryBush->Place(Random(amount + 1), Rectangle(island[0], island[1] - 80, island[2], island[3] / 2)); + CreateObject(Catapult, spot.x, spot.y); + } + + // A lorry with explosives, gold bars and loam. + if (number == 5) + { + var lorry = CreateObject(Lorry, spot.x, spot.y); + lorry->CreateContents(Loam, 2 + amount); + lorry->CreateContents(DynamiteBox, amount); + lorry->CreateContents(Dynamite, 4); + lorry->CreateContents(GoldBar, Random(amount + 1)); + } + + // For the other islands a chest with a few grapplers, loam, gold bars and dynamite. + if (number >= 6) + { + var chest = CreateObject(Chest, spot.x, spot.y); + if (!Random(2)) + chest->CreateContents(GrappleBow, Random(amount + 1)); + else + chest->CreateContents(Balloon, Random(amount + 1)); + chest->CreateContents(Loam, Random(amount + 1)); + chest->CreateContents(GoldBar, Random(amount + 1)); + chest->CreateContents(Dynamite, 2 + Random(amount + 1)); + SproutBerryBush->Place(amount + Random(2), Rectangle(island[0], island[1] - 80, island[2], island[3] / 2)); + } + + // For all the islands some decoration. + if (!Random(3)) + { + var spot = FindLocation(Loc_InRect(island[0], island[1], island[2], island[3] / 2), Loc_Wall(CNAT_Bottom), Loc_Space(20), Loc_Sky()); + if (spot) + CreateObject(Column, spot.x, spot.y); + } + + return 1; +} + +/*-- Some helper functions --*/ + +global func TestGemCount() +{ + var pos; + while (pos = FindLocation(Loc_Or(Loc_Material("Ruby"), Loc_Material("Amethyst")))) + { + var pos = CreateObject(Rock, pos.x, pos.y)->Explode(100); + } + var gem_count = ObjectCount(Find_Or(Find_ID(Ruby), Find_ID(Amethyst))); + return gem_count; +} diff --git a/planet/Worlds.ocf/GemGrabbers.ocs/Title.txt b/planet/Worlds.ocf/GemGrabbers.ocs/Title.txt new file mode 100644 index 000000000..a9a2f6324 --- /dev/null +++ b/planet/Worlds.ocf/GemGrabbers.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Gem Grabbers +US:Gem Grabbers \ No newline at end of file diff --git a/planet/Worlds.ocf/GoldRush.ocs/DescDE.rtf b/planet/Worlds.ocf/GoldRush.ocs/DescDE.rtf new file mode 100644 index 000000000..b74f95c73 --- /dev/null +++ b/planet/Worlds.ocf/GoldRush.ocs/DescDE.rtf @@ -0,0 +1,29 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset1 Times New Roman;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Mangal;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af5\dbch\af6\afs28\loch\f2\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af7 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af7\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af7 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 +Goldrausch} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\b0\kerning1\rtlch \ltrch\loch\fs20\lang4105\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +Clonker-Geologen haben k\u252\'fcrzlich entdeckt, dass ein alter Gletscher beachtliche Mengen Gold unter dem Wald von Orgos deponiert hat. Deine Expedition hat sich aufgemacht, um die begrabenen Sch\u228\'e4tze zu holen.} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +Ziel: Profitgewinn (erbeute Geldeinheiten um das Szenario abzuschlie\u223\'dfen)\line } +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +- Mehrere Spieler k\u246\'f6nnen kooperative zusammenarbeiten.} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +- Goldbarren und -klumpen k\u246\'f6nnen bei der Flagge verkauft werden (Barren sind aber wertvoller).} +\par } \ No newline at end of file diff --git a/planet/Worlds.ocf/GoldRush.ocs/DescUS.rtf b/planet/Worlds.ocf/GoldRush.ocs/DescUS.rtf new file mode 100644 index 000000000..13bd712e0 --- /dev/null +++ b/planet/Worlds.ocf/GoldRush.ocs/DescUS.rtf @@ -0,0 +1,31 @@ +{\rtf1\ansi\deff0\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset1 Times New Roman;}{\f4\froman\fprq0\fcharset1 Times New Roman;}{\f5\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f6\fnil\fprq2\fcharset0 Mangal;}{\f7\fnil\fprq0\fcharset1 Mangal;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043 Normal;} +{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af5\dbch\af6\afs28\loch\f2\fs28 Heading;} +{\s16\sbasedon0\snext16\sb0\sa120 Text body;} +{\s17\sbasedon16\snext17\sb0\sa120\dbch\af7 List;} +{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af7\afs24\ai\fs24 Caption;} +{\s19\sbasedon0\snext19\noline\dbch\af7 Index;} +}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3600}}\deftab720 +\viewscale100 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}} +\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\b\kerning1\rtlch \ltrch\loch\fs20\lang1033\loch\f4 +Gold Rush} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\b0\kerning1\rtlch \ltrch\loch\fs20\lang4105\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +Clonk geologists recently discovered that an ancient glacier deposited significant amounts of gold beneath the Forest of Orgos. Your expedition has set out to collect the reward buried deep below.} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +\line Goal: Profit (Gain clunkers to complete the scenario)} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 + +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +- Multiple players can work cooperatively towards the goal.} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +- Gold bars or nuggets may be dropped in front of flag for money (Press shift+the number for what you want to drop.)} +\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f0\fs24\lang1043\nowidctlpar{\cf1\b0\kerning1\rtlch \ltrch\loch\fs16\lang4105\loch\f4 +- Gold bars are worth more than gold nuggets.} +\par } \ No newline at end of file diff --git a/planet/Worlds.ocf/GoldRush.ocs/Map.c b/planet/Worlds.ocf/GoldRush.ocs/Map.c new file mode 100644 index 000000000..a4c79e3aa --- /dev/null +++ b/planet/Worlds.ocf/GoldRush.ocs/Map.c @@ -0,0 +1,120 @@ +/** + Gold Rush + Dynamic map a few layers of materials below a flat shaped earth surface. + + @authors Maikel +*/ + +#include Library_Map + + +// Scenario properties which can be set later by the lobby options. +static const SCENOPT_MapSize = 1; + +// Called be the engine: draw the complete map here. +protected func InitializeMap(proplist map) +{ + // Retrieve the settings according to the MapSize setting. + var map_size; + if (SCENOPT_MapSize == 1) + map_size = [100, 75]; + if (SCENOPT_MapSize == 2) + map_size = [125, 90]; + if (SCENOPT_MapSize == 3) + map_size = [150, 105]; + + // Set the map size. + map->Resize(map_size[0], map_size[1]); + + // Draw the main surface: a rectangle with some turbulence on top makes. + var rect = {X = 0, Y = 4 * map.Hgt / 10, Wdt = map.Wdt, Hgt = 6 * map.Hgt / 10}; + var surface = {Algo = MAPALGO_Rect, X = rect.X, Y = rect.Y, Wdt = rect.Wdt, Hgt = 8 * rect.Hgt / 6}; + surface = {Algo = MAPALGO_Turbulence, Iterations = 4, Amplitude = [0, 12], Seed = Random(65536), Op = surface}; + Draw("Earth", surface); + + // Draw materials inside the main surface. + DrawMaterials(rect, surface); + + // Return true to tell the engine a map has been successfully created. + return true; +} + +// Draws materials on the given surface. +public func DrawMaterials(proplist rect, proplist surface) +{ + var mask; + var x = rect.X; + var y = rect.Y; + var wdt = rect.Wdt; + var hgt = rect.Hgt; + + // A bit of different types of earth all around the surface. + mask = {Algo = MAPALGO_Rect, X = x, Y = y, Wdt = wdt, Hgt = hgt}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Earth-earth_topsoil", mask, 4, 12); + DrawMaterial("Earth-earth_rough", mask, 2, 16); + DrawMaterial("Earth-earth_dry", mask, 2, 16); + DrawMaterial("Earth-earth_midsoil", mask, 4, 12); + + // Coal and surface in the first layer. + mask = {Algo = MAPALGO_Rect, X = x, Y = y, Wdt = wdt, Hgt = hgt / 4}; + mask = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = mask}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Firestone", mask, 4, 5); + DrawMaterial("Coal", mask, 4, 5); + DrawMaterial("Firestone", mask); + DrawMaterial("Coal", mask); + + // Some small lakes as well in a second layer . + mask = {Algo = MAPALGO_Rect, X = x, Y = y + 1 * hgt / 4, Wdt = wdt, Hgt = hgt / 4}; + mask = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = mask}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Coal", mask, 3, 8); + DrawMaterial("Firestone", mask, 4, 5); + DrawMaterial("Water", mask, 4, 10); + + // Ore and rock in the third layer. + mask = {Algo = MAPALGO_Rect, X = x, Y = y + 2 * hgt / 4, Wdt = wdt, Hgt = hgt / 4}; + mask = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = mask}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Ore", mask, 3, 10); + DrawMaterial("Rock-rock_cracked", mask, 2, 8); + DrawMaterial("Granite", mask, 2, 8); + DrawMaterial("Rock", mask); + DrawMaterial("Ore", mask); + + // Gold in the last layer. + mask = {Algo = MAPALGO_Rect, X = x, Y = y + 3 * hgt / 4, Wdt = wdt, Hgt = hgt / 4}; + mask = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = mask}; + mask = {Algo = MAPALGO_And, Op = [surface, mask]}; + DrawMaterial("Gold", mask, 2, 5); + DrawMaterial("Coal", mask, 2, 10); + DrawMaterial("Gold", mask, 2, 5); + DrawMaterial("Gold", mask, 5, 10); + + // The top border consists of top soil and dry earth and a bit of sand. + var border = {Algo = MAPALGO_Border, Top = 4, Op = surface}; + Draw("Earth", border); + var rnd_checker = {Algo = MAPALGO_RndChecker, Ratio = 30, Wdt = 2, Hgt = 2}; + var rnd_border = {Algo = MAPALGO_And, Op = [border, rnd_checker]}; + Draw("Sand", rnd_border); + Draw("Earth-earth_topsoil", rnd_border); + + return; +} + +// Draws some material inside an island. +public func DrawMaterial(string mat, proplist onto_mask, int speck_size, int ratio) +{ + if (!speck_size) + speck_size = 4; + if (!ratio) + ratio = 15; + // Use random checker algorithm to draw patches of the material. + var rnd_checker = {Algo = MAPALGO_RndChecker, Ratio = ratio, Wdt = speck_size, Hgt = speck_size}; + rnd_checker = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = rnd_checker}; + var algo = {Algo = MAPALGO_And, Op = [onto_mask, rnd_checker]}; + Draw(mat, algo); + + return; +} diff --git a/planet/Worlds.ocf/GoldRush.ocs/Scenario.txt b/planet/Worlds.ocf/GoldRush.ocs/Scenario.txt new file mode 100644 index 000000000..4d21763f0 --- /dev/null +++ b/planet/Worlds.ocf/GoldRush.ocs/Scenario.txt @@ -0,0 +1,41 @@ +[Head] +Icon=15 +Title=GoldRush +Version=5,3,0,0 +Difficulty=10 + +[Definitions] +Definition1=Objects.ocd + +[Game] + +[Player1] +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Player2] +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Player3] +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Player4] +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Landscape] +Sky=Clouds2 +MapWidth=100 +MapHeight=75 + +[Weather] +Climate=0 +YearSpeed=0 +Wind=0,100,-100,100 + diff --git a/planet/Worlds.ocf/GoldRush.ocs/Script.c b/planet/Worlds.ocf/GoldRush.ocs/Script.c new file mode 100644 index 000000000..82f971f5c --- /dev/null +++ b/planet/Worlds.ocf/GoldRush.ocs/Script.c @@ -0,0 +1,153 @@ +/** + Gold Rush + A simple landscape with some gold, the goal is to mine some gold to gain wealth. + + @authors Maikel +*/ + + +// Scenario properties which can be set later by the lobby options. +static const SCENOPT_Material = 1; // Amount of material available from start. +static const SCENOPT_MapSize = 1; // Size of the map. +static const SCENOPT_Difficulty = 1; // Difficulty settings. + +protected func Initialize() +{ + // Rules: team account and buying at flagpole. + CreateObject(Rule_TeamAccount); + CreateObject(Rule_BuyAtFlagpole); + + // Goal: Gain Wealth, amount depends on difficulty, though bounded by availability. + var gold = GetMaterialCount(Material("Gold")) / GetMaterialVal("Blast2ObjectRatio", "Material", Material("Gold")); + var percentage = 70 + 10 * SCENOPT_Difficulty; + var wealth_goal = Min(200 + 200 * SCENOPT_Difficulty, gold * 5 * percentage / 100); + var goal = CreateObject(Goal_Wealth); + goal->SetWealthGoal(wealth_goal); + + // Initialize different parts of the scenario. + InitEnvironment(); + InitVegetation(); + InitAnimals(); + InitMaterial(SCENOPT_Material); + + return; +} + +protected func InitializePlayer(int plr) +{ + // Move clonks to location and give them a shovel. + var index = 0, crew; + while (crew = GetCrew(plr, index)) + { + var x = 250 + Random(100); + crew->SetPosition(x , FindHeight(x) - 20); + crew->CreateContents(Shovel); + // First clonk can construct, others can chop. + if (index == 0) + crew->CreateContents(Hammer); + else + crew->CreateContents(Axe); + index++; + } + + // Claim ownership of structures, last player who joins owns all the main island flags. + for (var structure in FindObjects(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole")))) + structure->SetOwner(plr); + + return; +} + +private func InitEnvironment() +{ + SetSkyParallax(0, 20, 20); + + CreateEnvironmentObjects("Temperate"); + + // Set time of day to evening and create some clouds and celestials. + Cloud->Place(10); + Cloud->SetPrecipitation("Water", 8); + CreateObject(Environment_Celestial); + var time = CreateObject(Environment_Time); + time->SetTime(60 * 12); + time->SetCycleSpeed(20); + return; +} + +private func InitVegetation() +{ + // Place some trees in a forest shape. + PlaceForest([Tree_Coniferous], 0, LandscapeHeight() / 2 + 50, nil, true); + + SproutBerryBush->Place(); + PlaceGrass(100); + + // Some objects in the earth. + PlaceObjects(Rock, 25 + 10 * SCENOPT_MapSize + Random(10),"Earth"); + PlaceObjects(Firestone, 20 + 10 * SCENOPT_MapSize + Random(5), "Earth"); + PlaceObjects(Loam, 20 + 10 * SCENOPT_MapSize + Random(5), "Earth"); + + return; +} + +private func InitAnimals() +{ + // Some butterflies as atmosphere. + for (var i = 0; i < 10 + 5 * SCENOPT_MapSize; i++) + PlaceAnimal(Butterfly); + return; +} + +private func InitMaterial(int amount) +{ + // No extra materials for little materials. + if (amount <= 1) + return; + + // For medium amount of materials provide a lorry with resources. + if (amount >= 2) + { + var x = 200 + Random(200); + var lorry = CreateObject(Lorry, x, FindHeight(x) - 20); + lorry->CreateContents(Wood, 10); + lorry->CreateContents(Metal, 6); + lorry->CreateContents(Rock, 6); + lorry->CreateContents(Dynamite, 4); + lorry->CreateContents(Pickaxe); + } + + // For large amount of materials provide some buildings as well. + if (amount >= 3) + { + // Build an elevator, flag and windmill. + var x = 250 + Random(100); + CreateObject(Flagpole, x, FindHeight(x)); + + var nx = x - 35 - Random(30); + CreateObject(WindGenerator, nx, FindHeight(nx)); + + var nx = x + 35 + Random(30); + CreateObject(Elevator, nx, FindHeight(nx)); + + // Remove some trees at the location of the structures. + for (var tree in FindObjects(Find_Func("IsTree"), Find_InRect(220, 0, 160, LandscapeHeight()))) + if (!!Random(3)) + tree->RemoveObject(); + } + + return; +} + + +/*-- Some helper functions --*/ + +global func TestGoldCount() +{ + var pos; + while (pos = FindLocation(Loc_Material("Gold"))) + { + var pos = CreateObject(Rock, pos.x, pos.y)->Explode(100); + } + var gold_count = ObjectCount(Find_ID(Nugget)); + return gold_count; +} + diff --git a/planet/Worlds.ocf/GoldRush.ocs/Title.jpg b/planet/Worlds.ocf/GoldRush.ocs/Title.jpg new file mode 100644 index 000000000..2fb3de993 Binary files /dev/null and b/planet/Worlds.ocf/GoldRush.ocs/Title.jpg differ diff --git a/planet/BeyondTheRocks.ocf/GoldRush.ocs/Title.txt b/planet/Worlds.ocf/GoldRush.ocs/Title.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/GoldRush.ocs/Title.txt rename to planet/Worlds.ocf/GoldRush.ocs/Title.txt diff --git a/planet/Worlds.ocf/Info.txt b/planet/Worlds.ocf/Info.txt new file mode 100644 index 000000000..53db08d2a --- /dev/null +++ b/planet/Worlds.ocf/Info.txt @@ -0,0 +1,15 @@ +[Developer/Maintainer] +Maikel + +[Folder Information] +When this folder is done it should contain 12 Worlds with varying landscapes and increasing difficulty. + +[Information for developers] +Worlds.ocf is a folder for settlement scenarios with a dynamic landscape (preferably Map.c landscapes). +Furthermore they have simple goals like mining or territorial expansion, and should be even fun to play +after completion. Keep in mind that with the introduction of lobby option (which will happen at some +point) we would like to introduce settings into these scenarios which the player can modify in the lobby. +Settings which come to mind are: map size, material available and difficulty of the goals. Please already +implement these options with a static const set to the standard value, you'd prefer to be played. + +If you want your scenario in this folder please add it or contact the maintainer in IRC or the forum. \ No newline at end of file diff --git a/planet/Worlds.ocf/IronPeak.ocs/DescDE.rtf b/planet/Worlds.ocf/IronPeak.ocs/DescDE.rtf new file mode 100644 index 000000000..1499dc40b Binary files /dev/null and b/planet/Worlds.ocf/IronPeak.ocs/DescDE.rtf differ diff --git a/planet/Worlds.ocf/IronPeak.ocs/DescUS.rtf b/planet/Worlds.ocf/IronPeak.ocs/DescUS.rtf new file mode 100644 index 000000000..d7b979632 Binary files /dev/null and b/planet/Worlds.ocf/IronPeak.ocs/DescUS.rtf differ diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Icon.png b/planet/Worlds.ocf/IronPeak.ocs/Icon.png similarity index 100% rename from planet/BeyondTheRocks.ocf/IronPeak.ocs/Icon.png rename to planet/Worlds.ocf/IronPeak.ocs/Icon.png diff --git a/planet/Worlds.ocf/IronPeak.ocs/Map.c b/planet/Worlds.ocf/IronPeak.ocs/Map.c new file mode 100644 index 000000000..7332e5ea5 --- /dev/null +++ b/planet/Worlds.ocf/IronPeak.ocs/Map.c @@ -0,0 +1,104 @@ +/** + Iron Peak + A mountain peak filled with iron ore, firestone and coal, the crust consists + of granite, rock, ice and some entrances. + + @authors Maikel +*/ + +#include Library_Map + + +// Scenario properties which can be set later by the lobby options. +static const SCENOPT_MapSize = 1; + +// Called be the engine: draw the complete map here. +protected func InitializeMap(proplist map) +{ + // Retrieve the settings according to the MapSize setting. + var map_size; + if (SCENOPT_MapSize == 1) + map_size = [150, 150]; + if (SCENOPT_MapSize == 2) + map_size = [150, 175]; + if (SCENOPT_MapSize == 3) + map_size = [150, 200]; + + // Set the map size. + map->Resize(map_size[0], map_size[1]); + + + // Draw the main surface: a mountain with the polygon algorithm. + var wdt = map.Wdt; + var hgt = map.Hgt; + var x_points = [14 * wdt / 100, 48 * wdt / 100, 52 * wdt / 100, 86 * wdt / 100]; + var y_points = [hgt + 10, 12 * hgt / 100, 12 * hgt / 100, hgt + 10]; + var surface = {Algo = MAPALGO_Polygon, X = x_points, Y = y_points}; + surface = {Algo = MAPALGO_Turbulence, Seed = Random(65536), Op = surface, Amplitude = [25, 15], Scale = 10, Iterations = 3}; + Draw("Earth", surface); + + // Draw the inner materials of the mountain. + DrawMountainMaterials(surface); + + // Draw a border on the mountain. + DrawMountainBorder(surface); + + // Return true to tell the engine a map has been successfully created. + return true; +} + +// Draws the inner materials of the mountain. +public func DrawMountainMaterials(proplist surface) +{ + // Draw all the materials. + DrawMaterial("Earth-earth_dry", surface); + DrawMaterial("Earth-earth_rough", surface); + DrawMaterial("Granite", surface); + DrawMaterial("Rock-rock_cracked", surface); + DrawMaterial("Snow-snow1", surface); + DrawMaterial("Ice-ice3", surface); + DrawMaterial("Rock-rock", surface); + DrawMaterial("Tunnel", surface); + DrawMaterial("Ore", surface); + DrawMaterial("Firestone", surface, 3, 15); + DrawMaterial("Coal", surface, 3, 15); + + // Draw some diagonal tunnels to allow the players to move. + var lines = {Algo = MAPALGO_Lines, X = 3, Y = 0, Distance = 20}; + var right = {Algo = MAPALGO_Rotate, R = 45, Op = lines}; + var left = {Algo = MAPALGO_Rotate, R = -45, Op = lines}; + lines = {Algo = MAPALGO_Or, Op = [right, left]}; + lines = {Algo = MAPALGO_And, Op = [surface, lines]}; + lines = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = lines}; + Draw("Tunnel", lines); + return; +} + +// Draws a border from granite, rock, etc. on the mountain. +public func DrawMountainBorder(proplist surface) +{ + var border = {Algo = MAPALGO_Border, Op = surface, Top = 5, Left = 5, Right = 5}; + DrawMaterial("Earth-earth_dry", border); + DrawMaterial("Ice-ice3", border, 3, 20); + DrawMaterial("Tunnel", border, 3, 20); + DrawMaterial("Granite", border, 3, 25); + DrawMaterial("Rock-rock", border, 2, 25); + DrawMaterial("Rock-rock_cracked", border, 3, 30); + return; +} + +// Draws some material inside an island. +public func DrawMaterial(string mat, proplist onto_mask, int speck_size, int ratio) +{ + if (!speck_size) + speck_size = 3; + if (!ratio) + ratio = 15; + // Use random checker algorithm to draw patches of the material. + var rnd_checker = {Algo = MAPALGO_RndChecker, Ratio = ratio, Wdt = speck_size, Hgt = speck_size}; + rnd_checker = {Algo = MAPALGO_Turbulence, Iterations = 4, Op = rnd_checker}; + var algo = {Algo = MAPALGO_And, Op = [onto_mask, rnd_checker]}; + Draw(mat, algo); + + return; +} diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Material.ocg/Rock.ocm b/planet/Worlds.ocf/IronPeak.ocs/Material.ocg/Rock.ocm similarity index 93% rename from planet/BeyondTheRocks.ocf/IronPeak.ocs/Material.ocg/Rock.ocm rename to planet/Worlds.ocf/IronPeak.ocs/Material.ocg/Rock.ocm index 7b5b90f85..11b4cbb99 100644 --- a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Material.ocg/Rock.ocm +++ b/planet/Worlds.ocf/IronPeak.ocs/Material.ocg/Rock.ocm @@ -1,7 +1,7 @@ [Material] Name=Rock Shape=Rough -Density=50 +Density=70 Friction=100 BlastFree=1 Blast2Object=Rock diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Material.ocg/TEXMAP.TXT b/planet/Worlds.ocf/IronPeak.ocs/Material.ocg/TEXMAP.TXT similarity index 97% rename from planet/BeyondTheRocks.ocf/IronPeak.ocs/Material.ocg/TEXMAP.TXT rename to planet/Worlds.ocf/IronPeak.ocs/Material.ocg/TEXMAP.TXT index 52a3f4177..73357dcb5 100644 --- a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Material.ocg/TEXMAP.TXT +++ b/planet/Worlds.ocf/IronPeak.ocs/Material.ocg/TEXMAP.TXT @@ -39,7 +39,7 @@ OverloadTextures 51=Rock-rock_cracked 52=Rock-rock -53=Sulphur-sulphur +53=Firestone-firestone 54=Coal-coal diff --git a/planet/Worlds.ocf/IronPeak.ocs/Scenario.txt b/planet/Worlds.ocf/IronPeak.ocs/Scenario.txt new file mode 100644 index 000000000..f032a6271 --- /dev/null +++ b/planet/Worlds.ocf/IronPeak.ocs/Scenario.txt @@ -0,0 +1,50 @@ +[Head] +Icon=1 +Title=IronPeak +Version=5,3,0,0 +Difficulty=40 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Rules=Rule_TeamAccount=1; + +[Player1] +Wealth=40 +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Ropeladder=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Player2] +Wealth=40 +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Ropeladder=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Player3] +Wealth=40 +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Ropeladder=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Player4] +Wealth=40 +Crew=Clonk=2 +Knowledge=Foundry=1;SteamEngine=1;ToolsWorkshop=1;ChemicalLab=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;Chest=1;Idol=1;Lorry=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;ToolsWorkshop_SplitFirestone=1;Barrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Ropeladder=1; +HomeBaseMaterial=Shovel=2;Pickaxe=2;Axe=2;Hammer=2;Dynamite=10;Loam=10;Wood=20;Metal=10;Clonk=2;Lorry=1; + +[Landscape] +InEarth=Rock=1;Firestone=3;Loam=2 +InEarthLevel=30,0,0,100 +Sky=Clouds2 +MapWidth=150 +MapHeight=150 +BottomOpen=2 + +[Weather] +Climate=100 +YearSpeed=0 +Wind=1,100,-100,100 +Rain=40 + diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Script.c b/planet/Worlds.ocf/IronPeak.ocs/Script.c similarity index 89% rename from planet/BeyondTheRocks.ocf/IronPeak.ocs/Script.c rename to planet/Worlds.ocf/IronPeak.ocs/Script.c index ba34be713..dedf0f0a5 100644 --- a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Script.c +++ b/planet/Worlds.ocf/IronPeak.ocs/Script.c @@ -6,6 +6,11 @@ */ +// Scenario properties which can be set later by the lobby options. +static const SCENOPT_Material = 1; // Amount of material available from start. +static const SCENOPT_MapSize = 1; // Size of the map. +static const SCENOPT_Difficulty = 1; // Difficulty settings. + // Spawn location for all players. static mountain_location; @@ -38,18 +43,16 @@ protected func Initialize() // TODO: Make sure lorry stays on mountains. // Place some coniferous trees, but only up to 2/3 of the mountain. - for (var i = 0; i < 16 + Random(5); i++) - PlaceVegetation(Tree_Coniferous, 0, LandscapeHeight() / 3, LandscapeWidth(), 2 * LandscapeHeight() / 3, 1000 * (61 + Random(40))); + Tree_Coniferous->Place(16+Random(5), Rectangle(0,LandscapeHeight()/3, LandscapeWidth(), 2*LandscapeHeight()/3)); // Some mushrooms as source of food. - for (var i = 0; i < 30 + Random(10); i++) - PlaceVegetation(Mushroom, 0, 0, LandscapeWidth(), LandscapeHeight()); + Mushroom->Place(30+Random(10)); // Set time of day to evening and create some clouds and celestials. Cloud->Place(20); CreateObject(Environment_Celestial); var time = CreateObject(Environment_Time); - time->SetTime(1125); + time->SetTime(60*22); time->SetCycleSpeed(0); // A light blue hue, to indicate the cold climate. @@ -57,8 +60,7 @@ protected func Initialize() SetGamma(RGB(0,0,blue), RGB(128-blue,128-blue,128+blue), RGB(255-blue,255-blue,255)); // Some natural disasters. - //var earthquakes = CreateObject(Earthquake); - // earthquakes->SetChance(30); + // Earthquake->SetChance(30); // TODO: Rockfall. //LogMatCounts(); @@ -172,6 +174,7 @@ protected func InitializePlayer(int plr) } index++; } + SetPlayerZoomByViewRange(plr, 5000, 3500, PLRZOOM_LimitMax); return; } diff --git a/planet/Worlds.ocf/IronPeak.ocs/Title.jpg b/planet/Worlds.ocf/IronPeak.ocs/Title.jpg new file mode 100644 index 000000000..1c70151d6 Binary files /dev/null and b/planet/Worlds.ocf/IronPeak.ocs/Title.jpg differ diff --git a/planet/BeyondTheRocks.ocf/IronPeak.ocs/Title.txt b/planet/Worlds.ocf/IronPeak.ocs/Title.txt similarity index 100% rename from planet/BeyondTheRocks.ocf/IronPeak.ocs/Title.txt rename to planet/Worlds.ocf/IronPeak.ocs/Title.txt diff --git a/planet/Worlds.ocf/Krakatoa.ocs/DescDE.rtf b/planet/Worlds.ocf/Krakatoa.ocs/DescDE.rtf new file mode 100644 index 000000000..8a156e8ac Binary files /dev/null and b/planet/Worlds.ocf/Krakatoa.ocs/DescDE.rtf differ diff --git a/planet/Worlds.ocf/Krakatoa.ocs/DescUS.rtf b/planet/Worlds.ocf/Krakatoa.ocs/DescUS.rtf new file mode 100644 index 000000000..dccfb7240 Binary files /dev/null and b/planet/Worlds.ocf/Krakatoa.ocs/DescUS.rtf differ diff --git a/planet/Worlds.ocf/Krakatoa.ocs/Landscape.txt b/planet/Worlds.ocf/Krakatoa.ocs/Landscape.txt new file mode 100644 index 000000000..4f0ed63af --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/Landscape.txt @@ -0,0 +1,166 @@ +/** + Krakatoa + A Volcano with lot's of small islands and chasms. + + @author Maikel +*/ + + +// Fills an overlay with random specks. +overlay RandomMat { + mask=1; invert=1; grp=1; + loosebounds=1; + // Combine multiple algortihms. + overlay { + algo=rndchecker; a=15; + zoomX=10; zoomY=-10; + turbulence=100; lambda=3; + mask=1; loosebounds=1; + } | overlay { + algo=bozo; a=15; + zoomX=10; zoomY=-10; + turbulence=1000; lambda=3; + mask=1; loosebounds=1; + } | overlay { + algo=bozo; a=12; + zoomX=-10; zoomY=10; + turbulence=1000; lambda=3; + mask=1; loosebounds=1; + }; +}; + +// Fills an overlay with some random spots. +overlay RandomSpots { + mask=1; invert=1; grp=1; + overlay { + algo=bozo; a=10; + zoomX=10; zoomY=-10; + turbulence=1000; lambda=3; + mask=1; loosebounds=1; + } & overlay { + algo=bozo; a=10; + zoomX=-10; zoomY=10; + turbulence=1000; lambda=3; + mask=1; loosebounds=1; + }; +}; + +// A nice volcano with some less nice places to settle. +map Volcano { + // The main volcano shape, by a sine. + overlay { + algo=sin; + ox=-44; oy=30; + zoomX=85; zoomY=70; + turbulence=10; lambda=2; + + // Earth as background material. + mat=Earth; tex=earth; + + // Different volcano layers are created with shifted sines. + // Outer volcano layer: Barely any materials, but lot's of earth. + overlay { + algo=sin; + ox=-44; oy=30; + zoomX=85; zoomY=70; + turbulence=10; lambda=2; + mat=Earth; tex=earth; + RandomMat & overlay { mat=Granite; tex=granite; }; + RandomMat & overlay { mat=Rock; tex=rock_cracked; }; + RandomMat & overlay { mat=Ore; tex=ore; }; + RandomMat & overlay { mat=Firestone; tex=firestone; }; + RandomMat & overlay { mat=Coal; tex=coal; }; + RandomMat & overlay { mat=Rock; tex=rock; }; + RandomSpots & overlay { mat=Ore; tex=ore; }; + RandomMat & overlay { algo=bozo; mat=Earth; tex=earth_rough; }; + RandomMat & overlay { algo=bozo; mat=Earth; tex=earth_dry; }; + RandomMat & overlay { algo=bozo; mat=Earth; tex=earth_topsoil; }; + RandomSpots & overlay { mat=Ashes; tex=ashes; }; + RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; + RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; + }; + + // Middle volcano layer: Mostly with necessary resources like ore, coal, firestone. + overlay { + algo=sin; + ox=-44; oy=50; + zoomX=85; zoomY=70; + turbulence=10; lambda=2; + mat=Earth; tex=earth; + RandomMat & overlay { mat=Rock; tex=rock_cracked; }; + RandomMat & overlay { mat=Granite; tex=granite; }; + RandomMat & overlay { mat=Earth; tex=earth_topsoil; }; + RandomMat & overlay { mat=Ore; tex=ore; }; + RandomMat & overlay { mat=Firestone; tex=firestone; }; + RandomMat & overlay { mat=Coal; tex=coal; }; + RandomMat & overlay { mat=Rock; tex=rock; }; + RandomSpots & overlay { mat=Ore; tex=ore; }; + RandomMat & overlay { algo=bozo; mat=Earth; tex=earth_rough; }; + RandomMat & overlay { algo=bozo; mat=Earth; tex=earth_dry; }; + RandomSpots & overlay { mat=Ashes; tex=ashes; }; + RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; + RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; + }; + + // Volcano core: Mostly rare materials like gold. + overlay { + algo=sin; + ox=-44; oy=70; + zoomX=85; zoomY=70; + turbulence=10; lambda=2; + mat=Earth; tex=earth; + RandomMat & overlay { mat=Granite; tex=granite; }; + RandomMat & overlay { mat=Earth; tex=earth_topsoil; }; + RandomMat & overlay { mat=Ore; tex=ore; }; + RandomMat & overlay { mat=Firestone; tex=firestone; }; + RandomMat & overlay { mat=Coal; tex=coal; }; + RandomMat & overlay { mat=Rock; tex=rock; }; + RandomMat & overlay { mat=Earth; tex=earth_rough; }; + RandomMat & overlay { mat=Earth; tex=earth_dry; }; + RandomMat & overlay { mat=Ashes; tex=ashes; }; + RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; + RandomSpots & overlay { mat=Earth; tex=earth_midsoil; }; + RandomMat & overlay { mat=Gold; tex=gold; }; + RandomMat & overlay { mat=Granite; tex=granite; }; + RandomSpots & overlay { mat=Gold; tex=gold; }; + }; + + // Create tilted tunnel shafts. + overlay { + algo=lines; a=8; b=24; + x=10; y=0; wdt=80; hgt=70; + rotate=40; + turbulence=100; lambda=2; + mat=Tunnel; tex=tunnel; + }; + overlay { + algo=lines; a=8; b=24; + x=10; y=0; wdt=80; hgt=70; + rotate=-40; + turbulence=100; lambda=2; + mat=Tunnel; tex=tunnel; + }; + + // Create tilted lava chasms. + overlay { + algo=sin; invert=1; mask=1; + ox=25; oy=65; + zoomX=82; zoomY=90; + turbulence=10; lambda=2; + overlay { + algo=lines; a=8; b=20; + x=0; y=70; wdt=100; hgt=30; + rotate=45; + turbulence=100; lambda=3; + mat=DuroLava; tex=lava_red; + }; + overlay { + algo=lines; a=8; b=20; + x=0; y=70; wdt=100; hgt=30; + rotate=-45; + turbulence=100; lambda=3; + mat=DuroLava; tex=lava_red; + }; + }; + }; +}; diff --git a/planet/Worlds.ocf/Krakatoa.ocs/Scenario.txt b/planet/Worlds.ocf/Krakatoa.ocs/Scenario.txt new file mode 100644 index 000000000..8c33a9d99 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/Scenario.txt @@ -0,0 +1,48 @@ +[Head] +Icon=23 +Title=Krakatoa +Version=5,3,0,0 +Difficulty=80 + +[Definitions] +Definition1=Objects.ocd + +[Game] +Rules=Rule_EnergyNeed=1;Rule_TeamAccount=1;Rule_BuyAtFlagpole=1; + +[Player1] +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;Lorry=1;Cannon=1;Catapult=1;Airship=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1; +HomeBaseMaterial=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; +HomeBaseProduction=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; + +[Player2] +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;Lorry=1;Cannon=1;Catapult=1;Airship=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1; +HomeBaseMaterial=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; +HomeBaseProduction=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; + +[Player3] +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;Lorry=1;Cannon=1;Catapult=1;Airship=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1; +HomeBaseMaterial=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; +HomeBaseProduction=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; + +[Player4] +Crew=Clonk=2 +Knowledge=Idol=1;Foundry=1;SteamEngine=1;ToolsWorkshop=1;WindGenerator=1;Flagpole=1;Sawmill=1;Elevator=1;Pump=1;ChemicalLab=1;Armory=1;Lorry=1;Cannon=1;Catapult=1;Airship=1;Pickaxe=1;Axe=1;Hammer=1;Shovel=1;Firestone=1;Barrel=1;MetalBarrel=1;Dynamite=1;DynamiteBox=1;Bucket=1;Pipe=1;GrappleBow=1;PowderKeg=1;Ropeladder=1; +HomeBaseMaterial=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; +HomeBaseProduction=Clonk=2;Shovel=2;Axe=1;Hammer=1;Loam=5;Barrel=2;Bread=2; + +[Landscape] +InEarth=Rock=1;Firestone=3;Loam=1 +InEarthLevel=20 +Sky=Clouds2 +MapWidth=200 +MapHeight=150 +SkyScrollMode=2 + +[Weather] +Climate=0 +StartSeason=50 +YearSpeed=0 diff --git a/planet/Worlds.ocf/Krakatoa.ocs/Script.c b/planet/Worlds.ocf/Krakatoa.ocs/Script.c new file mode 100644 index 000000000..a2555f6c9 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/Script.c @@ -0,0 +1,261 @@ +/** + Krakatoa + Entry for the "Let's Rock" settlement scenario design competetion. + Players are challenged to build up a settlement inside an active volcano. + The goal is to expand your reign by building flags to cover the landscape. + Also you need to gather some gold to show your skills of entering a volcano. + + @author Maikel +*/ + + +static volcano_location; +static plr_init; + +func Initialize() +{ + // Create expansion and wealth goal. + var goal = CreateObject(Goal_Wealth); + goal->SetWealthGoal(250); + goal = CreateObject(Goal_Expansion); + goal->SetExpansionGoal(250); + + // some rules + CreateObject(Rule_EnergyBarsAboveStructures, 0, 0, NO_OWNER); + + // Find start location and place lorry plus extras there. + FindVolcanoLocation(); + var lorry = CreateObject(Lorry); + lorry->SetPosition(volcano_location[0], volcano_location[1]); + lorry->CreateContents(Loam, 5); + lorry->CreateContents(Bread, 5); + lorry->CreateContents(Wood, 8); + lorry->CreateContents(Rock, 4); + lorry->CreateContents(Metal, 4); + for (var i = 0; i < 5; i++) + lorry->CreateContents(Barrel)->PutLiquid("Water", 300); + + // Adjust the mood, orange sky, darker feeling in general. + var dark = 40; + SetSkyAdjust(RGB(150, 42, 0)); + SetGamma(RGB(0,0,0), RGB(128-dark,128-dark,128-dark), RGB(255-2*dark,255-2*dark,255-2*dark)); + + // Time of days and celestials. + CreateObject(Environment_Celestial); + var time = CreateObject(Environment_Time); + time->SetTime(60*20); + time->SetCycleSpeed(20); + + // Some dark clouds which rain few ashes. + Cloud->Place(15); + Cloud->SetPrecipitation("Ashes", 10); + + // Some natural disasters, earthquakes, volcanos, meteorites. + Meteor->SetChance(15); + Earthquake->SetChance(2); + Volcano->SetChance(4); + Volcano->SetMaterial("DuroLava"); + + // Vegetation. + // Place some trees, rather with leaves. + var veg; + for (var i = 0; i < 20 + Random(4); i++) + PlaceVegetation(Tree_Coconut, 0, 0, LandscapeWidth(), LandscapeHeight(), 1000 * (61 + Random(40))); + // Create an effect to make sure there will always grow some new trees. + AddEffect("EnsureTrees", nil, 100, 20, nil); + // Some dead tree trunks. + for (var i = 0; i < 16 + Random(4); i++) + { + veg = PlaceVegetation(Trunk, 0, 0, LandscapeWidth(), LandscapeHeight(), 1000 * (61 + Random(20))); + if (veg) + veg->SetR(RandomX(-20, 20)); + } + // Some mushrooms as source of food. + for (var i = 0; i < 30 + Random(5); i++) + PlaceVegetation(Mushroom, 0, 0, LandscapeWidth(), LandscapeHeight()); + // Some ferns, to be burned soon. + for (var i = 0; i < 25 + Random(5); i++) + PlaceVegetation(Fern, 0, 0, LandscapeWidth(), LandscapeHeight()); + // Ranks as a nice additional source of wood. + for (var i = 0; i < 16 + Random(4); i++) + { + veg = PlaceVegetation(Rank, 0, 0, LandscapeWidth(), LandscapeHeight()); + if (veg) + veg->SetR(RandomX(-20, 20)); + } + + // Initialize the effect for controlling the big volcano. + AddEffect("BigVolcano", nil, 100, 5, nil); + + return; +} + +func InitializePlayer(int plr) +{ + // Move all crew to start position. + var index = 0, crew; + while (crew = GetCrew(plr, index++)) + crew->SetPosition(volcano_location[0] + RandomX(-5, 5), volcano_location[1]); + // Give only the first joined player some wealth. + if (!plr_init) + { + SetWealth(plr, 50); + plr_init = true; + } + // Give crew some equipment. + var index = 0; + while (crew = GetCrew(plr, index++)) + { + if (index == 1) + crew->CreateContents(Hammer); + if (index == 2) + crew->CreateContents(Axe); + crew->CreateContents(Shovel); + } + // We really want FoW for this scenario... + SetPlayerViewLock(plr, true); + SetPlayerZoomByViewRange(plr, 500, nil, PLRZOOM_Direct | PLRZOOM_LimitMax); + + // Increase difficulty of goal with player count. + var plr_cnt = Min(6, GetPlayerCount()); + var goal = FindObject(Find_ID(Goal_Wealth)); + goal->SetWealthGoal(200 + 50 * plr_cnt); + goal = FindObject(Find_ID(Goal_Expansion)); + goal->SetExpansionGoal(200 + 25 * plr_cnt); + + return; +} + +// Returns a suitable location to start the conquest. +private func FindVolcanoLocation() +{ + // Default to the middle of the map. + var wdt = LandscapeWidth(); + var hgt = LandscapeHeight(); + volcano_location = [wdt / 2, hgt / 2]; + var x, y, cnt = 1000; + for (var i = cnt; i > 0; i--) + { + // Random x coordinate, biased to the middle of the map. + var var_wdt = wdt * (200 - 100 * i / cnt) / 400; + var x = wdt / 2 + RandomX(-var_wdt, var_wdt); + var y = 0; + // Find corresponding y coordinate. + while (!GBackSolid(x, y) && y < 9 * hgt / 10) + y += 2; + // Check if surface is relatively flat (check for flatter surfaces first). + var d = i / 40 + 1; + if (!GBackSolid(x+d, y-4) && !GBackSolid(x-d, y-4) && GBackSolid(x+d, y+4) && GBackSolid(x-d, y+4)) + { + volcano_location = [x, y - 10]; + break; + } + } + return; +} + +// Ensures that there will always grow some trees. +global func FxEnsureTreesTimer() +{ + // Place a tree if there are less than eight trees, with increasing likelihood for lower amounts of trees. + var nr_trees = ObjectCount(Find_Func("IsTree")); + if (Random(9) >= nr_trees) + if (!Random(20)) + PlaceVegetation(Tree_Coconut, 0, 0, LandscapeWidth(), LandscapeHeight(), 3); + return FX_OK; +} + +/*-- Volcano Effect --*/ + +global func FxBigVolcanoStart(object target, proplist effect, int temporary) +{ + if (temporary) + return FX_OK; + // Ensure right effect interval. + effect.Interval = 5; + return FX_OK; +} + +global func FxBigVolcanoTimer(object target, proplist effect) +{ + // Insert some lava in the big body of lava in the core of the volcano. + // Find a surface on which we can release some lava pixels and bubbles. + for (var x = Random(250); x < LandscapeWidth(); x += RandomX(200, 300)) + { + // Find first tunnel from the bottom. + var y = LandscapeHeight(); + while (GBackSemiSolid(x, y) && y > 0) + y -= 2; + // Check if there is liquid below the tunnel. + if (GBackLiquid(x, y + 4)) + { + InsertMaterial(Material("DuroLava"), x, y + 4); + } + } + // At more rare occasions there will be a bigger eruption with chunks. + if (!Random(400)) + { + // Find a location to erupt. + for (var i = 0; i < 50; i++) + { + // Find lava suface for a random x position. + var x = Random(LandscapeWidth()); + var y = LandscapeHeight(); + while (GBackSemiSolid(x, y) && y > 0) + y -= 2; + // Check if there is enough room for an eruption. + if (GBackLiquid(x - 5, y + 8) && GBackLiquid(x + 5, y + 8) && !GBackSemiSolid(x - 5, y - 8) && !GBackSemiSolid(x + 5, y - 8)) + { + // Launch a big eruption from this location. + AddEffect("BigEruption", nil, 100, 1, nil, nil, x, y - 2); + break; + } + } + } + return FX_OK; +} + +global func FxBigEruptionStart(object target, proplist effect, int temporary, int x, int y) +{ + if (temporary) + return FX_OK; + // Ensure right effect interval. + effect.Interval = 1; + // Take over launch coordinates. + effect.X = x; + effect.Y = y; + // Duration of 2-5 seconds. + effect.Duration = 72 + Random(108); + return FX_OK; +} + +global func FxBigEruptionTimer(object target, proplist effect, int time) +{ + // Eruption lasts for some time. + if (time > effect.Duration) + return FX_Execute_Kill; + // Cast some lava pixels at surface. + for (var i = 0; i < 3; i++) + { + var x = effect.X + RandomX(-5, 5); + var y = effect.Y + 5; + while (GBackLiquid(x, y)) + y--; + CastPXS("DuroLava", 2, 60, x, y - 2, 0, 40); + } + // Throw around some lava chunks. + if (!Random(18)) + { + var angw = 40, lev = 60; + var obj = CreateObject(LavaChunk, effect.X + RandomX(-5, 5), effect.Y, NO_OWNER); + var ang = - 90 + RandomX(-angw / 2, angw / 2); + var xdir = Cos(ang, lev) + RandomX(-3, 3); + obj->SetR(Random(360)); + obj->SetXDir(xdir); + obj->SetYDir(Sin(ang, lev) + RandomX(-3, 3)); + obj->SetRDir(-10 + Random(21)); + obj->DoCon(RandomX(-20,40)); + } + // Some lava glow and smoke through particles. + return FX_OK; +} diff --git a/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/Cloud.c b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/Cloud.c new file mode 100644 index 000000000..b29c5a4e9 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/Cloud.c @@ -0,0 +1,12 @@ +// Clouds are a bit darker. +/* +#appendto Cloud + +// Shades the clouds according to ashes and landscape. +private func ShadeCloud() +{ + var shade = 127 - Min(127, rain / 5); + SetClrModulation(RGBa(shade, shade, shade, 80)); + return _inherited(...); +} +*/ \ No newline at end of file diff --git a/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/FlagRadius.c b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/FlagRadius.c new file mode 100644 index 000000000..f39d13863 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/FlagRadius.c @@ -0,0 +1,10 @@ +// Reduced flag radius to make expansion goal and settling a little harder. + +#appendto Library_Flag + +public func Construction() +{ + _inherited(...); + lflag.radius = 140; + return; +} \ No newline at end of file diff --git a/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/Generator.c b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/Generator.c new file mode 100644 index 000000000..38a54ecf0 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/Generator.c @@ -0,0 +1,5 @@ +// Windgenerators can stand fire better. + +#appendto WindGenerator + +local ContactIncinerate = 0; \ No newline at end of file diff --git a/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/MoreTrees.c b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/MoreTrees.c new file mode 100644 index 000000000..d004f7212 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/System.ocg/MoreTrees.c @@ -0,0 +1,7 @@ +// Trees spread a bit faster. + +#appendto Tree_Coconut + +// Should be done differently. +//private func SeedChance() { return 250; } + \ No newline at end of file diff --git a/planet/Worlds.ocf/Krakatoa.ocs/Title.png b/planet/Worlds.ocf/Krakatoa.ocs/Title.png new file mode 100644 index 000000000..c3b82542b Binary files /dev/null and b/planet/Worlds.ocf/Krakatoa.ocs/Title.png differ diff --git a/planet/Worlds.ocf/Krakatoa.ocs/Title.txt b/planet/Worlds.ocf/Krakatoa.ocs/Title.txt new file mode 100644 index 000000000..dfc550229 --- /dev/null +++ b/planet/Worlds.ocf/Krakatoa.ocs/Title.txt @@ -0,0 +1,2 @@ +DE:Bezwingung des Krakataus +US:Conquest of Krakatoa \ No newline at end of file diff --git a/planet/Worlds.ocf/Title.png b/planet/Worlds.ocf/Title.png new file mode 100644 index 000000000..e9bc6cdc5 Binary files /dev/null and b/planet/Worlds.ocf/Title.png differ diff --git a/planet/Worlds.ocf/Title.txt b/planet/Worlds.ocf/Title.txt new file mode 100644 index 000000000..294bf4052 --- /dev/null +++ b/planet/Worlds.ocf/Title.txt @@ -0,0 +1,2 @@ +DE:Welten +US:Worlds \ No newline at end of file diff --git a/scriptdefinitionsources.txt b/scriptdefinitionsources.txt new file mode 100644 index 000000000..b3bb399fd --- /dev/null +++ b/scriptdefinitionsources.txt @@ -0,0 +1,3 @@ +src/script/C4Script.cpp +src/gamescript/C4GameScript.cpp +src/object/C4ObjectScript.cpp \ No newline at end of file diff --git a/src/C4FullScreen.cpp b/src/C4FullScreen.cpp deleted file mode 100644 index 5a388e889..000000000 --- a/src/C4FullScreen.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 1998-2000, 2008 Matthes Bender - * Copyright (c) 2001-2003, 2005, 2008 Sven Eberhardt - * Copyright (c) 2005-2007, 2010-2011 Günther Brammer - * Copyright (c) 2006-2007 Julian Raschke - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2009-2010 Martin Plicht - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Main class to execute the game fullscreen mode */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#elif defined(USE_X11) -#include -#include -void C4FullScreen::HandleMessage (XEvent &e) -{ - // Parent handling - C4Window::HandleMessage(e); - - switch (e.type) - { - case KeyPress: - { - // Do not take into account the state of the various modifiers and locks - // we don't need that for keyboard control - DWORD key = XKeycodeToKeysym(e.xany.display, e.xkey.keycode, 0); - Game.DoKeyboardInput(key, KEYEV_Down, Application.IsAltDown(), Application.IsControlDown(), Application.IsShiftDown(), false, NULL); - break; - } - case KeyRelease: - { - DWORD key = XKeycodeToKeysym(e.xany.display, e.xkey.keycode, 0); - Game.DoKeyboardInput(key, KEYEV_Up, e.xkey.state & Mod1Mask, e.xkey.state & ControlMask, e.xkey.state & ShiftMask, false, NULL); - break; - } - case ButtonPress: - { - static int last_left_click, last_right_click; - switch (e.xbutton.button) - { - case Button1: - if (GetTime() - last_left_click < 400) - { - C4GUI::MouseMove(C4MC_Button_LeftDouble, - e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - last_left_click = 0; - } - else - { - C4GUI::MouseMove(C4MC_Button_LeftDown, - e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - last_left_click = GetTime(); - } - break; - case Button2: - C4GUI::MouseMove(C4MC_Button_MiddleDown, - e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - break; - case Button3: - if (GetTime() - last_right_click < 400) - { - C4GUI::MouseMove(C4MC_Button_RightDouble, - e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - last_right_click = 0; - } - else - { - C4GUI::MouseMove(C4MC_Button_RightDown, - e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - last_right_click = GetTime(); - } - break; - case Button4: - C4GUI::MouseMove(C4MC_Button_Wheel, - e.xbutton.x, e.xbutton.y, e.xbutton.state + (short(32) << 16), NULL); - break; - case Button5: - C4GUI::MouseMove(C4MC_Button_Wheel, - e.xbutton.x, e.xbutton.y, e.xbutton.state + (short(-32) << 16), NULL); - break; - default: - break; - } - } - break; - case ButtonRelease: - switch (e.xbutton.button) - { - case Button1: - C4GUI::MouseMove(C4MC_Button_LeftUp, e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - break; - case Button2: - C4GUI::MouseMove(C4MC_Button_MiddleUp, e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - break; - case Button3: - C4GUI::MouseMove(C4MC_Button_RightUp, e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - break; - default: - break; - } - break; - case MotionNotify: - C4GUI::MouseMove(C4MC_Button_None, e.xbutton.x, e.xbutton.y, e.xbutton.state, NULL); - break; - case FocusIn: - Application.Active = true; - if (pDraw) pDraw->TaskIn(); - break; - case FocusOut: case UnmapNotify: - Application.Active = false; - if (pDraw) pDraw->TaskOut(); - break; - } -} - -#endif // _WIN32, USE_X11, USE_SDL_MAINLOOP - -void C4FullScreen::CharIn(const char * c) { ::pGUI->CharIn(c); } - -C4FullScreen::C4FullScreen() -{ - pMenu = NULL; -} - -C4FullScreen::~C4FullScreen() -{ - if (pMenu) delete pMenu; - if (pSurface) delete pSurface; -} - - -C4Window * C4FullScreen::Init(C4AbstractApp * pApp) -{ - return Init(C4Window::W_Fullscreen, pApp, C4ENGINECAPTION); -} - -void C4FullScreen::Close() -{ - if (Game.IsRunning) - ShowAbortDlg(); - else - Application.Quit(); -} - -void C4FullScreen::Clear() -{ - if (pSurface) delete pSurface; - pSurface = 0; - C4Window::Clear(); -} - -void C4FullScreen::Execute() -{ - // Execute menu - if (pMenu) pMenu->Execute(); - // Draw - RequestUpdate(); -} - -bool C4FullScreen::ViewportCheck() -{ - int iPlrNum; C4Player *pPlr; - // Not active - if (!Active) return false; - // Determine film mode - bool fFilm = (Game.C4S.Head.Replay && Game.C4S.Head.Film); - // Check viewports - switch (::Viewports.GetViewportCount()) - { - // No viewports: create no-owner viewport - case 0: - iPlrNum = NO_OWNER; - // Film mode: create viewport for first player (instead of no-owner) - if (fFilm) - if ((pPlr = ::Players.First)) - iPlrNum = pPlr->Number; - // Create viewport - ::Viewports.CreateViewport(iPlrNum, iPlrNum==NO_OWNER); - // Non-film (observer mode) - if (!fFilm) - { - // Activate mouse control - ::MouseControl.Init(iPlrNum); - // Display message for how to open observer menu (this message will be cleared if any owned viewport opens) - StdStrBuf sKey; - sKey.Format("<%s>", Game.KeyboardInput.GetKeyCodeNameByKeyName("FullscreenMenuOpen", false).getData()); - ::GraphicsSystem.FlashMessage(FormatString(LoadResStr("IDS_MSG_PRESSORPUSHANYGAMEPADBUTT"), sKey.getData()).getData()); - } - break; - // One viewport: do nothing - case 1: - break; - // More than one viewport: remove all no-owner viewports - default: - ::Viewports.CloseViewport(NO_OWNER, true); - break; - } - // Look for no-owner viewport - C4Viewport *pNoOwnerVp = ::Viewports.GetViewport(NO_OWNER); - // No no-owner viewport found - if (!pNoOwnerVp) - { - // Close any open fullscreen menu - CloseMenu(); - } - // No-owner viewport present - else - { - // movie mode: player present, and no valid viewport assigned? - if (Game.C4S.Head.Replay && Game.C4S.Head.Film && (pPlr = ::Players.First)) - // assign viewport to joined player - pNoOwnerVp->Init(pPlr->Number, true); - } - // Done - return true; -} - -bool C4FullScreen::ShowAbortDlg() -{ - // abort dialog already shown - if (C4AbortGameDialog::IsShown()) return false; - // not while game over dialog is open - if (C4GameOverDlg::IsShown()) return false; - // show abort dialog - return ::pGUI->ShowRemoveDlg(new C4AbortGameDialog()); -} - -bool C4FullScreen::ActivateMenuMain() -{ - // Not during game over dialog - if (C4GameOverDlg::IsShown()) return false; - // Close previous - CloseMenu(); - // Open menu - pMenu = new C4MainMenu(); - return pMenu->ActivateMain(NO_OWNER); -} - -void C4FullScreen::CloseMenu() -{ - if (pMenu) - { - if (pMenu->IsActive()) pMenu->Close(false); - delete pMenu; - pMenu = NULL; - } -} - -void C4FullScreen::PerformUpdate() -{ - GraphicsSystem.Execute(); -} - -bool C4FullScreen::MenuKeyControl(BYTE byCom) -{ - if (pMenu) return pMenu->KeyControl(byCom); - return false; -} diff --git a/src/C4Globals.cpp b/src/C4Globals.cpp index da3c9da4c..9ea087f8d 100644 --- a/src/C4Globals.cpp +++ b/src/C4Globals.cpp @@ -1,33 +1,42 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Global interdependent objects */ #include #include "C4Application.h" +#include "C4Aul.h" #include "C4Console.h" -#include "C4FullScreen.h" -#include "C4MouseControl.h" -#include "C4GameObjects.h" #include +#include "C4FullScreen.h" #include "C4Game.h" +#include "C4GameObjects.h" +#include "C4MouseControl.h" #include "C4Network2.h" +#include "C4PropList.h" +#include "C4StringTable.h" +#ifdef _DEBUG +C4Set C4PropList::PropLists; +#endif +C4Set C4PropListNumbered::PropLists; +std::vector C4PropListNumbered::ShelvedPropLists; +int32_t C4PropListNumbered::EnumerationIndex = 0; +C4StringTable Strings; +C4AulScriptEngine ScriptEngine; C4Application Application; C4Console Console; C4FullScreen FullScreen; diff --git a/src/C4Include.cpp b/src/C4Include.cpp index 2fb2c39de..04446c0d0 100644 --- a/src/C4Include.cpp +++ b/src/C4Include.cpp @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (C) 2009 The OpenClonk Project + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Never put anything else in this file: MSVC will pretend diff --git a/src/C4Include.h b/src/C4Include.h index 762557538..e4852ab28 100644 --- a/src/C4Include.h +++ b/src/C4Include.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2005 Tobias Zwick - * Copyright (c) 2005, 2008, 2010 Sven Eberhardt - * Copyright (c) 2005-2006, 2010 Günther Brammer - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* This header is included first from every source file. It serves three purposes: @@ -36,22 +31,43 @@ don't need to include this file or any of the files it includes. */ #include #include -#ifdef DEBUGREC #define DEBUGREC_SCRIPT #define DEBUGREC_START_FRAME 0 #define DEBUGREC_PXS #define DEBUGREC_OBJCOM #define DEBUGREC_MATSCAN -//#define DEBUGREC_RECRUITMENT #define DEBUGREC_MENU #define DEBUGREC_OCF -#endif // solidmask debugging //#define SOLIDMASK_DEBUG -// debug memory management - must come after boost headers, -// because boost uses placement new +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// debug memory management - must come after standard and boost headers, +// because those libraries use placement new #ifndef NODEBUGMEM #if defined(_DEBUG) && defined(_MSC_VER) #if _MSC_VER <= 1200 @@ -73,38 +89,14 @@ inline void operator delete(void *p, const char *, long) #define new new(__FILE__, __LINE__) #endif #endif - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include #include "Standard.h" #include "C4Prototypes.h" #include "C4Real.h" #include "StdBuf.h" #include "StdFile.h" -#include "StdResStr2.h" +#include "C4Language.h" #include "C4Log.h" #include "C4Reloc.h" #include "C4Config.h" diff --git a/src/C4Prototypes.h b/src/C4Prototypes.h index 16f9e96cd..03ec88edb 100644 --- a/src/C4Prototypes.h +++ b/src/C4Prototypes.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2010-2011 Günther Brammer - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Forward declarations */ @@ -25,14 +21,15 @@ #define INC_C4Prototypes // class declarations +class C4AbstractApp; class C4Action; struct C4AulContext; class C4AulDefFunc; class C4AulFunc; +struct C4AulParSet; class C4AulScript; class C4AulScriptEngine; class C4AulScriptFunc; -struct C4AulParSet; class C4BltTransform; class C4ClientList; class C4ClientPlayerInfos; @@ -41,8 +38,9 @@ class C4Config; class C4Console; class C4Control; class C4Def; -class C4DefList; class C4DefGraphics; +class C4DefList; +class C4Draw; class C4Effect; class C4Facet; class C4FacetSurface; @@ -50,17 +48,16 @@ class C4FileMonitor; class C4Game; class C4GameMessage; class C4GameMessageList; +class C4GameOptionButtons; class C4GameOptionsList; class C4GamePadControl; class C4GamePadOpener; -class C4GamePadOpener; class C4GameParameters; class C4GameResList; class C4GameSec1Timer; class C4Graph; class C4GraphicsSystem; class C4Group; -class C4Group; class C4GroupSet; class C4IDList; class C4KeyboardInput; @@ -70,6 +67,8 @@ class C4League; class C4LoaderScreen; class C4LSector; class C4LSectors; +class C4MapCreatorS2; +class C4Markup; class C4MassMover; class C4MassMoverSet; class C4Material; @@ -83,8 +82,9 @@ class C4Network; class C4NetworkClient; class C4NetworkClientList; class C4Network2IRCClient; -class C4Network2Stats; class C4Network2Reference; +class C4Network2ResDlg; +class C4Network2Stats; class C4Object; class C4ObjectInfo; class C4ObjectInfoCore; @@ -98,6 +98,7 @@ class C4Player; class C4PlayerInfo; class C4PlayerInfoCore; class C4PlayerInfoList; +class C4PlayerInfoListBox; class C4PlayerList; class C4PropList; class C4PXS; @@ -105,18 +106,19 @@ class C4PXSSystem; class C4RankSystem; class C4Record; class C4Rect; -class C4Region; -class C4RegionList; class C4RoundResult; class C4RoundResults; class C4Scenario; class C4ScriptHost; +class C4SolidMask; class C4SoundSystem; class C4Stream; class C4String; class C4Surface; class C4SVal; class C4TargetFacet; +class C4TargetRect; +class C4Team; class C4TeamList; class C4TexMapEntry; class C4TexMgr; @@ -128,8 +130,10 @@ class C4ValueNumbers; class C4Viewport; class C4ViewportList; class C4ViewportWindow; -class C4Markup; +class C4Window; class CStdFont; +class CStdGLCtx; +struct CStdPalette; class CStdStream; class CStdVectorFont; class CSurface8; @@ -138,19 +142,15 @@ class StdMesh; class StdMeshBone; class StdMeshInstance; class StdMeshMaterial; +class StdMeshMatManager; class StdMeshMatrix; class StdMeshSkeletonLoader; -class C4Draw; -class C4AbstractApp; -class C4Window; -class C4Surface; -class CStdStream; -class CStdGLCtx; namespace C4GUI { - class Screen; + class ComboBox_FillCB; class Dialog; + class Screen; } typedef C4GUI::Screen C4GUIScreen; diff --git a/src/C4Version.h.in b/src/C4Version.h.in index 36d729aa1..81931d7b1 100644 --- a/src/C4Version.h.in +++ b/src/C4Version.h.in @@ -4,6 +4,7 @@ * Copyright (c) 2001-2002, 2010 Peter Wortmann * Copyright (c) 2005, 2009-2010 Günther Brammer * Copyright (c) 2009 Matthes Bender + * Copyright (c) 2013 Nicolas Hake * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de * * Portions might be copyrighted by other authors who have contributed @@ -36,7 +37,6 @@ #define C4XVER1 @C4XVER1@ #define C4XVER2 @C4XVER2@ #define C4XVER3 @C4XVER3@ -#define C4XVER4 @C4XVER4@ #define C4VERSIONBUILDNAME "@C4VERSIONBUILDNAME@" #define C4VERSIONEXTRA "@C4VERSIONEXTRA@" #define C4REVISION "@C4REVISION@" @@ -53,16 +53,17 @@ #define C4ENGINEINFOLONG "@C4ENGINENAME@@C4VERSIONBUILDNAME@@C4VERSIONEXTRA@" #define C4ENGINECAPTION "@C4ENGINENAME@@C4VERSIONBUILDNAME@" -#if C4XVER4 < 10 -#define C4XVER4S "00" C4XVERTOC4XVERS(C4XVER4) -#elif C4XVER4 < 100 -#define C4XVER4S "0" C4XVERTOC4XVERS(C4XVER4) -#else -#define C4XVER4S C4XVERTOC4XVERS(C4XVER4) -#endif - #define C4XVERTOC4XVERS(s) C4XVERTOC4XVERS2(s) #define C4XVERTOC4XVERS2(s) #s -#define C4VERSION C4XVERTOC4XVERS(C4XVER1) "." C4XVERTOC4XVERS(C4XVER2) "." C4XVERTOC4XVERS(C4XVER3) " [" C4XVER4S "]" C4VERSIONEXTRA C4BUILDOPT + +// if C4XVER3 >= 90, this is a pre-release version; add VCS revision +#if C4XVER3 >= 90 +#define C4VERSION C4XVERTOC4XVERS(C4XVER1) "." C4XVERTOC4XVERS(C4XVER2) "." C4XVERTOC4XVERS(C4XVER3) " [" C4REVISION "]" C4VERSIONEXTRA C4BUILDOPT +#else +#define C4VERSION C4XVERTOC4XVERS(C4XVER1) "." C4XVERTOC4XVERS(C4XVER2) "." C4XVERTOC4XVERS(C4XVER3) C4VERSIONEXTRA C4BUILDOPT +#endif + +// if this is set, add a build identifier to the logs and crash dumps +#define OC_BUILD_ID "@OC_BUILD_ID@" #endif diff --git a/src/c4group/C4ComponentHost.cpp b/src/c4group/C4ComponentHost.cpp index fe1b840bb..90b269706 100644 --- a/src/c4group/C4ComponentHost.cpp +++ b/src/c4group/C4ComponentHost.cpp @@ -1,30 +1,25 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004 Matthes Bender - * Copyright (c) 2002-2004 Peter Wortmann - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2005, 2007-2009, 2011 Günther Brammer - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Holds a single text file component from a group */ #include #include +#include #include diff --git a/src/c4group/C4ComponentHost.h b/src/c4group/C4ComponentHost.h index 2584178fc..b08c79319 100644 --- a/src/c4group/C4ComponentHost.h +++ b/src/c4group/C4ComponentHost.h @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004 Matthes Bender - * Copyright (c) 2005, 2007, 2009, 2011 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Holds a single text file component from a group */ @@ -23,7 +21,6 @@ #define INC_C4ComponentHost #include "C4GroupSet.h" -#include class C4ComponentHost { @@ -37,11 +34,6 @@ public: size_t GetDataSize() const { return Data.getLength(); } bool Load(C4Group &hGroup, const char *szFilename, const char *szLanguage=NULL); bool Load(C4GroupSet &hGroupSet, const char *szFilename, const char *szLanguage=NULL); - bool LoadEx(C4Group &hGroup, const char *szFilename, const char *szLanguage=NULL) - { - C4GroupSet hGroups = Languages.GetPackGroups(hGroup); - return Load(hGroups, szFilename, szLanguage); - } bool GetLanguageString(const char *szLanguage, class StdStrBuf &rTarget); protected: // The component host's Data has changed. This callback can be used by diff --git a/src/c4group/C4Components.h b/src/c4group/C4Components.h index 08e26c484..4d6f3bbc0 100644 --- a/src/c4group/C4Components.h +++ b/src/c4group/C4Components.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003-2004, 2008 Matthes Bender - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2009, 2011 Armin Burgmeier - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Known component file names */ @@ -26,8 +22,6 @@ //========================= Component File Names ============================================ -#define C4CFN_Engine "Clonk.exe" - #define C4CFN_Material "Material.ocg" #define C4CFN_Sound "Sound.ocg" #define C4CFN_Graphics "Graphics.ocg" @@ -65,11 +59,13 @@ #define C4CFN_DiffLandscape "DiffLandscape.bmp" #define C4CFN_Sky "Sky" #define C4CFN_Script "Script.c|Script%s.c|C4Script%s.c" +#define C4CFN_MapScript "Map.c" #define C4CFN_ScriptStringTbl "StringTbl.txt|StringTbl%s.txt" #define C4CFN_Info "Info.txt" #define C4CFN_Author "Author.txt" #define C4CFN_Version "Version.txt" #define C4CFN_Game "Game.txt" +#define C4CFN_ScenarioObjectsScript "Objects.c" #define C4CFN_PXS "PXS.ocb" #define C4CFN_MassMover "MassMover.ocb" #define C4CFN_CtrlRec "CtrlRec.ocb" @@ -79,22 +75,26 @@ #define C4CFN_MatMap "MatMap.txt" #define C4CFN_Title "Title%s.txt|Title.txt" #define C4CFN_WriteTitle "Title.txt" // file that is generated if a title is set automatically -#define C4CFN_ScenarioTitle "Title.bmp" -#define C4CFN_ScenarioTitlePNG "Title.png" +#define C4CFN_ScenarioTitle "Title" #define C4CFN_ScenarioIcon "Icon.bmp" #define C4CFN_IconPNG "Icon.png" #define C4CFN_ScenarioObjects "Objects.txt" #define C4CFN_ScenarioDesc "Desc%s.rtf" #define C4CFN_DefMaterials "*.material" -#define C4CFN_DefMesh "Graphics.mesh" -#define C4CFN_DefMeshXml (C4CFN_DefMesh ".xml") -#define C4CFN_DefGraphicsPNG "Graphics.png" -#define C4CFN_ClrByOwnerPNG "Overlay.png" -#define C4CFN_DefGraphicsEx "Graphics*.bmp" -#define C4CFN_DefGraphicsExPNG "Graphics*.png" -#define C4CFN_DefGraphicsScaled "Graphics.*.bmp" -#define C4CFN_DefGraphicsScaledPNG "Graphics.*.png" -#define C4CFN_ClrByOwnerExPNG "Overlay*.png" + +#define C4CFN_DefMesh "Graphics.mesh" +#define C4CFN_DefMeshXml C4CFN_DefMesh ".xml" +#define C4CFN_DefGraphicsExMesh "Graphics*.mesh" +#define C4CFN_DefGraphicsExMeshXml C4CFN_DefGraphicsExMesh ".xml" + +#define C4CFN_DefGraphics "Graphics.png" +#define C4CFN_ClrByOwner "Overlay.png" +#define C4CFN_DefGraphicsEx "Graphics*.png" +#define C4CFN_ClrByOwnerEx "Overlay*.png" + +#define C4CFN_DefGraphicsScaled "Graphics.*.png" +#define C4CFN_ClrByOwnerScaled "Graphics.*.png" + #define C4CFN_DefDesc "Desc%s.txt" #define C4CFN_BigIcon "BigIcon.png" #define C4CFN_UpperBoard "UpperBoard" @@ -107,6 +107,7 @@ #define C4CFN_RankNameFiles "Rank*.txt" #define C4CFN_RankFacesPNG "Rank.png" #define C4CFN_ClonkRank "Rank.png" // custom rank in info file: One rank image only +#define C4CFN_SolidMask "SolidMask.png" #define C4CFN_LeagueInfo "League.txt" // read by frontend only #define C4CFN_PlayerInfos "PlayerInfos.txt" #define C4CFN_SavePlayerInfos "SavePlayerInfos.txt" @@ -125,15 +126,13 @@ #define C4CFN_Language "Language*.txt" #define C4CFN_KeyConfig "KeyConfig.txt" -#define C4CFN_Log "Clonk.log" -#define C4CFN_LogEx "Clonk%d.log" // created if regular logfile is in use +#define C4CFN_Log "OpenClonk.log" +#define C4CFN_LogEx "OpenClonk%d.log" // created if regular logfile is in use #define C4CFN_Intro "Clonk4.avi" #define C4CFN_Names "Names.txt" #define C4CFN_Titles "Title*.txt|Title.txt" #define C4CFN_DefNameFiles "Names*.txt|Names.txt" -#define C4CFN_Splash "Splash.ocv" - #define C4CFN_TempMusic "~Music.tmp" #define C4CFN_TempMusic2 "~Music2.tmp" #define C4CFN_TempSky "~Sky.tmp" @@ -169,14 +168,14 @@ // TODO: proper sorting of scaled def graphics (once we know what order we might load them in...) -#define C4FLS_Scenario "Loader*.bmp|Loader*.png|Loader*.jpeg|Loader*.jpg|Fonts.txt|Scenario.txt|Title*.txt|Info.txt|Desc*.rtf|Icon.png|Icon.bmp|Game.txt|StringTbl*.txt|Teams.txt|Parameters.txt|Info.txt|Sect*.ocg|Music.ocg|*.mid|*.wav|Desc*.rtf|Title.bmp|Title.png|*.ocd|Material.ocg|MatMap.txt|Landscape.bmp|Landscape.png|" C4CFN_DiffLandscape "|Sky.bmp|Sky.png|Sky.jpeg|Sky.jpg|PXS.ocb|MassMover.ocb|CtrlRec.ocb|Strings.txt|Objects.txt|RoundResults.txt|Author.txt|Version.txt|Names.txt|*.ocd|Script.c|Script*.c|System.ocg" -#define C4FLS_Section "Scenario.txt|Game.txt|Landscape.bmp|Landscape.png|Sky.bmp|Sky.png|Sky.jpeg|Sky.jpg|PXS.ocb|MassMover.ocb|CtrlRec.ocb|Strings.txt|Objects.txt" +#define C4FLS_Scenario "Loader*.bmp|Loader*.png|Loader*.jpeg|Loader*.jpg|Fonts.txt|Scenario.txt|Title*.txt|Info.txt|Desc*.rtf|Icon.png|Icon.bmp|Game.txt|StringTbl*.txt|Teams.txt|Parameters.txt|Info.txt|Sect*.ocg|Music.ocg|*.mid|*.wav|Desc*.rtf|Title.png|Title.jpg|*.ocd|Material.ocg|MatMap.txt|Landscape.bmp|Landscape.png|" C4CFN_DiffLandscape "|Sky.bmp|Sky.png|Sky.jpeg|Sky.jpg|PXS.ocb|MassMover.ocb|CtrlRec.ocb|Strings.txt|Objects.txt|RoundResults.txt|Author.txt|Version.txt|Names.txt|*.ocd|Script.c|Script*.c|Map.c|Objects.c|System.ocg" +#define C4FLS_Section "Scenario.txt|Game.txt|Landscape.bmp|Landscape.png|Sky.bmp|Sky.png|Sky.jpeg|Sky.jpg|PXS.ocb|MassMover.ocb|CtrlRec.ocb|Strings.txt|Objects.txt|Objects.c" #define C4FLS_SectionLandscape "Scenario.txt|Landscape.bmp|Landscape.png|PXS.ocb|MassMover.ocb" -#define C4FLS_SectionObjects "Strings.txt|Objects.txt" -#define C4FLS_Def "Particle.txt|DefCore.txt|*.material|Graphics.png|Overlay.png|Graphics*.png|Overlay*.png|*.png|*.jpg|Graphics.mesh|*.skeleton|StringTbl*.txt|Script.c|Script*.c|C4Script.c|Names*.txt|Title*.txt|ClonkNames.txt|Rank.txt|Rank*.txt|Rank.png|Desc*.txt|Title.png|Icon.bmp|Author.txt|Version.txt|*.wav|*.ogg|*.ocd" +#define C4FLS_SectionObjects "Strings.txt|Objects.txt|Objects.c" +#define C4FLS_Def "Particle.txt|DefCore.txt|*.material|SolidMask.png|Graphics.png|Overlay.png|Graphics*.png|Overlay*.png|*.png|*.jpg|Graphics.mesh|*.skeleton|StringTbl*.txt|Script.c|Script*.c|C4Script.c|Names*.txt|Title*.txt|ClonkNames.txt|Rank.txt|Rank*.txt|Rank.png|Desc*.txt|Author.txt|Version.txt|*.wav|*.ogg|*.ocd" #define C4FLS_Player "Player.txt|*.oci" #define C4FLS_Object "ObjectInfo.txt" -#define C4FLS_Folder "Folder.txt|Title*.txt|Info.txt|Desc*.rtf|Title.png|Title.bmp|Icon.png|Icon.bmp|Author.txt|Version.txt|*.ocs|Loader*.bmp|Loader*.png|Loader*.jpeg|Loader*.jpg|FolderMap.txt|FolderMap.png" +#define C4FLS_Folder "Folder.txt|Title*.txt|Info.txt|Desc*.rtf|Title.png|Title.jpg|Icon.png|Icon.bmp|Author.txt|Version.txt|*.ocs|Loader*.bmp|Loader*.png|Loader*.jpeg|Loader*.jpg|FolderMap.txt|FolderMap.png" #define C4FLS_Material "TexMap.txt|*.bmp|*.png|*.ocm" #define C4FLS_Graphics "Loader*.bmp|Loader*.png|Loader*.jpeg|Loader*.jpg|Font*.png"\ "|Control.png|Fire.png|Background.png|Flag.png|Crew.png|Wealth.png|Player.png|Rank.png|Captain.png|Cursor.png|SelectMark.png|MenuSymbol.png|Menu.png|Logo.png|Construction.png|Energy.png|Options.png|UpperBoard.png|Arrow.png|Exit.png|Hand.png|Gamepad.png|Build.png"\ diff --git a/src/c4group/C4Extra.cpp b/src/c4group/C4Extra.cpp index ec51d59a3..99256edfa 100644 --- a/src/c4group/C4Extra.cpp +++ b/src/c4group/C4Extra.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2004 Sven Eberhardt - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2011 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // user-customizable multimedia package Extra.ocg @@ -46,7 +41,7 @@ bool C4Extra::InitGroup() // register extra root into game group set for(C4Reloc::iterator iter = Reloc.begin(); iter != Reloc.end(); ++iter) { - std::auto_ptr pGroup(new C4Group); + std::unique_ptr pGroup(new C4Group); if(pGroup->Open( ((*iter).strBuf + DirSep + C4CFN_Extra).getData())) ExtraGroups.push_back(pGroup.release()); } diff --git a/src/c4group/C4Extra.h b/src/c4group/C4Extra.h index f252c8c6d..d9c49abdc 100644 --- a/src/c4group/C4Extra.h +++ b/src/c4group/C4Extra.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // user-customizable multimedia package Extra.ocg diff --git a/src/c4group/C4Group.cpp b/src/c4group/C4Group.cpp index 8c5d517b9..e008b44ec 100644 --- a/src/c4group/C4Group.cpp +++ b/src/c4group/C4Group.cpp @@ -1,26 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003-2005, 2007 Matthes Bender - * Copyright (c) 2001-2003, 2005-2008 Sven Eberhardt - * Copyright (c) 2002-2008 Peter Wortmann - * Copyright (c) 2004-2009, 2011 Günther Brammer - * Copyright (c) 2005 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Carl-Philip Hänsch - * Copyright (c) 2010-2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles group files */ @@ -78,7 +70,7 @@ int iC4GroupRewindFilePtrNoWarn=0; //---------------------------- Global C4Group_Functions ------------------------------------------- char C4Group_TempPath[_MAX_PATH+1]=""; -char C4Group_Ignore[_MAX_PATH+1]="cvs;CVS;Thumbs.db"; +char C4Group_Ignore[_MAX_PATH+1]="cvs;CVS;Thumbs.db;.orig;.svn"; const char **C4Group_SortList = NULL; time_t C4Group_AssumeTimeOffset=0; bool (*C4Group_ProcessCallback)(const char *, int)=NULL; @@ -501,7 +493,7 @@ void C4Group::Init() SearchPtr=NULL; // Folder only //hFdt=-1; - FolderSearch.Reset(); + FolderSearch.Clear(); // Error status SCopy("No Error",ErrorString,C4GroupMaxError); } @@ -1041,13 +1033,13 @@ bool C4Group::AppendEntry2StdFile(C4GroupEntry *centry, CStdFile &hTarget) return true; } -void C4Group::ResetSearch() +void C4Group::ResetSearch(bool reload_contents) { switch (Status) { case GRPF_Folder: SearchPtr=NULL; - FolderSearch.Reset(FileName); + FolderSearch.Reset(FileName, reload_contents); if (*FolderSearch) { FolderSearchEntry.Set(FolderSearch,FileName); @@ -1465,6 +1457,8 @@ bool C4Group::DeleteEntry(const char *szFilename, bool fRecycle) if (!EraseItem(szPath)) return false; } break; + // refresh file list + ResetSearch(true); } return true; } @@ -1493,6 +1487,8 @@ bool C4Group::Rename(const char *szFile, const char *szNewName) char path2[_MAX_FNAME+1]; SCopy(FileName,path2,_MAX_PATH-1); AppendBackslash(path2); SAppend(szNewName,path2,_MAX_PATH); if (!RenameFile(path,path2)) return Error("Rename: Failure"); + // refresh file list + ResetSearch(true); break; } @@ -1585,7 +1581,7 @@ bool C4Group::ExtractEntry(const char *szFilename, const char *szExtractTo) case GRPF_File: // Copy entry to target // Get entry C4GroupEntry *pEntry; - if (!(pEntry=GetEntry(szFilename))) return false; + if (!(pEntry=GetEntry(szFilename))) return Error("Extract: Entry not found"); // Create dummy file to reserve target file name hDummy.Create(szTargetFName,false); hDummy.Write("Dummy",5); @@ -2094,7 +2090,7 @@ bool C4Group::EnsureChildFilePtr(C4Group *pChild) if ( !ItemIdentical( StdFile.Name, szChildPath ) ) { // Reopen correct child stdfile - if ( !SetFilePtr2Entry( GetFilename(pChild->FileName) ) ) + if ( !SetFilePtr2Entry( GetFilename(pChild->FileName), true ) ) return false; // Advance to child's old file ptr if ( !AdvanceFilePtr( pChild->EntryOffset + pChild->FilePtr ) ) @@ -2114,7 +2110,7 @@ StdStrBuf C4Group::GetFullName() const { if (*str) SInsert(str, sep, 0, _MAX_PATH); // Avoid double slash - if (SLen(pGroup->FileName) > 1 || pGroup->FileName[0] != '/') + if (pGroup == this || SLen(pGroup->FileName) > 1 || pGroup->FileName[0] != '/') SInsert(str, pGroup->FileName, 0, _MAX_PATH); if (pGroup->Status == GRPF_Folder) break; // Folder is assumed to have full path } diff --git a/src/c4group/C4Group.h b/src/c4group/C4Group.h index 95e12f0e0..39b8e5a08 100644 --- a/src/c4group/C4Group.h +++ b/src/c4group/C4Group.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004, 2007 Matthes Bender - * Copyright (c) 2002, 2005, 2007 Sven Eberhardt - * Copyright (c) 2004, 2006, 2008 Peter Wortmann - * Copyright (c) 2004-2005, 2007, 2009, 2011 Günther Brammer - * Copyright (c) 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles group files */ @@ -242,7 +237,7 @@ public: bool Read(void *pBuffer, size_t iSize); bool Advance(int iOffset); void SetStdOutput(bool fStatus); - void ResetSearch(); + void ResetSearch(bool reload_contents=false); // reset search pointer so calls to FindNextEntry find first entry again. if reload_contents is set, the file list for directories is also refreshed. const char *GetError(); const char *GetName(); StdStrBuf GetFullName() const; diff --git a/src/c4group/c4group_ng.cpp b/src/c4group/C4GroupMain.cpp similarity index 92% rename from src/c4group/c4group_ng.cpp rename to src/c4group/C4GroupMain.cpp index bc3c4e648..1240f32e6 100644 --- a/src/c4group/c4group_ng.cpp +++ b/src/c4group/C4GroupMain.cpp @@ -1,24 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2011 Sven Eberhardt - * Copyright (c) 2004, 2007 Matthes Bender - * Copyright (c) 2005-2007, 2009-2011 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* C4Group command line executable */ @@ -338,11 +331,11 @@ int RegisterShellExtensions() for (i = 0; SCopySegment(strClasses, i, strClass); i++) { // Unpack - swprintf(strCommand, 2048, L"\"%s\" \"%%1\" \"-u\"", strModule); + _snwprintf(strCommand, 2048, L"\"%s\" \"%%1\" \"-u\"", strModule); if (!SetRegShell(GetWideChar(strClass), L"MakeFolder", L"C4Group Unpack", strCommand)) return 0; // Explode - swprintf(strCommand, 2048, L"\"%s\" \"%%1\" \"-x\"", strModule); + _snwprintf(strCommand, 2048, L"\"%s\" \"%%1\" \"-x\"", strModule); if (!SetRegShell(GetWideChar(strClass), L"ExplodeFolder", L"C4Group Explode", strCommand)) return 0; } @@ -351,7 +344,7 @@ int RegisterShellExtensions() for (i = 0; SCopySegment(strClasses2, i, strClass); i++) { // Pack - swprintf(strCommand, 2048, L"\"%s\" \"%%1\" \"-p\"", strModule); + _snwprintf(strCommand, 2048, L"\"%s\" \"%%1\" \"-p\"", strModule); if (!SetRegShell(GetWideChar(strClass), L"MakeGroupFile", L"C4Group Pack", strCommand)) return 0; } diff --git a/src/c4group/C4GroupSet.cpp b/src/c4group/C4GroupSet.cpp index f19f309b1..14d2e0b4c 100644 --- a/src/c4group/C4GroupSet.cpp +++ b/src/c4group/C4GroupSet.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2004-2005, 2007 Sven Eberhardt - * Copyright (c) 2004 Matthes Bender - * Copyright (c) 2005, 2007, 2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a set of group files // manages system file overwriting by scearios or folders @@ -28,6 +23,7 @@ #include #include #include +#include "c4group/C4Language.h" C4GroupSetNode::C4GroupSetNode(C4GroupSet &rParent, C4GroupSetNode *pPrev, C4Group &rGroup, bool fGrpOwned, int32_t id) { diff --git a/src/c4group/C4GroupSet.h b/src/c4group/C4GroupSet.h index afe8de1ef..c97cfd119 100644 --- a/src/c4group/C4GroupSet.h +++ b/src/c4group/C4GroupSet.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2004-2005 Sven Eberhardt - * Copyright (c) 2004 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a set of group files // manages system file overwriting by scearios or folders @@ -53,16 +50,11 @@ #define C4GSCnt_All ~0 -// class predefs -class C4Group; -class C4GroupSet; -class C4GroupSetNode; - // one node in the group set holds one group class C4GroupSetNode { protected: - C4GroupSet *pParent; // owning set + class C4GroupSet *pParent; // owning set C4GroupSetNode *pPrev, *pNext; // linked list - always valid C4Group *pGroup; // ptr to group owned by this node @@ -71,7 +63,7 @@ protected: int32_t id; // group node ID public: - C4GroupSetNode(C4GroupSet &rParent, C4GroupSetNode *pPrev, C4Group &rGroup, bool fGrpOwned, int32_t id); // ctor + C4GroupSetNode(class C4GroupSet &rParent, C4GroupSetNode *pPrev, C4Group &rGroup, bool fGrpOwned, int32_t id); // ctor ~C4GroupSetNode(); // dtor int32_t Priority; // group priority diff --git a/src/c4group/C4LangStringTable.cpp b/src/c4group/C4LangStringTable.cpp index a2b52465c..cb6329daf 100644 --- a/src/c4group/C4LangStringTable.cpp +++ b/src/c4group/C4LangStringTable.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2005, 2007 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Loads StringTbl* and replaces $..$-strings by localized versions @@ -37,7 +32,7 @@ bool C4LangStringTable::HasTranslation(const std::string &text) const return strings.find(text) != strings.end(); } -std::string C4LangStringTable::Translate(const std::string &text) const +const std::string &C4LangStringTable::Translate(const std::string &text) const { if (strings.empty()) PopulateStringTable(); @@ -182,3 +177,5 @@ void C4LangStringTable::ReplaceStrings(StdStrBuf &rBuf) { ReplaceStrings(rBuf, rBuf); } + +C4LangStringTable C4LangStringTable::system_string_table; diff --git a/src/c4group/C4LangStringTable.h b/src/c4group/C4LangStringTable.h index fa91ee029..2dad9a812 100644 --- a/src/c4group/C4LangStringTable.h +++ b/src/c4group/C4LangStringTable.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Loads StringTbl* and replaces $..$-strings by localized versions @@ -35,7 +32,7 @@ class C4LangStringTable : public C4ComponentHost void PopulateStringTable() const; public: C4LangStringTable(); - std::string Translate(const std::string &text) const; + const std::string &Translate(const std::string &text) const; bool HasTranslation(const std::string &text) const; // do replacement in buffer // if any replacement is done, the buffer will be realloced @@ -47,8 +44,13 @@ public: public: NoSuchTranslation(const std::string &text) : std::runtime_error("No such translation: \"" + text + "\"") {} }; + + static inline C4LangStringTable &GetSystemStringTable() { return system_string_table; } protected: virtual void OnLoad() { strings.clear(); } // Make sure we re-populate when the string table is reloaded + +private: + static C4LangStringTable system_string_table; }; #endif // INC_C4LangStringTable diff --git a/src/c4group/C4Language.cpp b/src/c4group/C4Language.cpp index 8a01f916c..ef57c7d54 100644 --- a/src/c4group/C4Language.cpp +++ b/src/c4group/C4Language.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004 Matthes Bender - * Copyright (c) 2005-2007, 2009, 2011 Günther Brammer - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2011 Armin Burgmeier - * Copyright (c) 2011 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* @@ -37,6 +31,15 @@ #include #include +#ifdef USE_BOOST_REGEX +# undef new +# include + namespace re = boost; +#else +# include + namespace re = std; +#endif + #ifdef HAVE_ICONV #ifdef HAVE_LANGINFO_H #include @@ -363,6 +366,14 @@ C4GroupSet C4Language::GetPackGroups(C4Group & hGroup) return r; } +bool C4Language::LoadComponentHost(C4ComponentHost *host, C4Group &hGroup, const char *szFilename, const char *szLanguage) +{ + assert(host); + if (!host) return false; + C4GroupSet hGroups = ::Languages.GetPackGroups(hGroup); + return host->Load(hGroups, szFilename, szLanguage); +} + void C4Language::InitInfos() { C4Group hGroup; @@ -383,6 +394,49 @@ void C4Language::InitInfos() } } +namespace +{ + std::string GetResStr(const char *id, const char *stringtbl) + { + static re::regex line_pattern("^([^=]+)=(.*?)\r?$", static_cast(re::regex_constants::optimize | re::regex_constants::ECMAScript)); + assert(stringtbl); + if (!stringtbl) + { + return std::string(); + } + + // Get beginning and end iterators of stringtbl + const char *begin = stringtbl; + const char *end = begin + std::char_traits::length(begin); + + for (auto it = re::cregex_iterator(begin, end, line_pattern); it != re::cregex_iterator(); ++it) + { + assert(it->size() == 3); + if (it->size() != 3) + continue; + + std::string key = (*it)[1]; + if (key != id) + continue; + + std::string val = (*it)[2]; + return val; + } + + // If we get here, there was no such string in the string table + // return the input string so there's at least *something* + return id; + } + + template + void CopyResStr(const char *id, const char *stringtbl, char (&dest)[N]) + { + std::string value = GetResStr(id, stringtbl); + std::strncpy(dest, value.c_str(), N); + dest[N - 1] = '\0'; + } +} + void C4Language::LoadInfos(C4Group &hGroup) { char strEntry[_MAX_FNAME + 1]; @@ -403,9 +457,9 @@ void C4Language::LoadInfos(C4Group &hGroup) SCopy(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2, pInfo->Code, 2); SCapitalize(pInfo->Code); // Get language name, info, fallback from table - SCopy(GetResStr("IDS_LANG_NAME", strTable), pInfo->Name, C4MaxLanguageInfo); - SCopy(GetResStr("IDS_LANG_INFO", strTable), pInfo->Info, C4MaxLanguageInfo); - SCopy(GetResStr("IDS_LANG_FALLBACK", strTable), pInfo->Fallback, C4MaxLanguageInfo); + CopyResStr("IDS_LANG_NAME", strTable, pInfo->Name); + CopyResStr("IDS_LANG_INFO", strTable, pInfo->Info); + CopyResStr("IDS_LANG_FALLBACK", strTable, pInfo->Fallback); // Safety: pipe character is not allowed in any language info string SReplaceChar(pInfo->Name, '|', ' '); SReplaceChar(pInfo->Info, '|', ' '); @@ -481,11 +535,9 @@ bool C4Language::LoadStringTable(C4Group &hGroup, const char *strCode) char strEntry[_MAX_FNAME + 1]; sprintf(strEntry, "Language%s.txt", strCode); // ...should use C4CFN_Language here // Load string table - char *strTable; - if (!hGroup.LoadEntry(strEntry, &strTable, 0, true)) + if (!C4LangStringTable::GetSystemStringTable().Load(hGroup, strEntry)) return false; - // Set string table - SetResStrTable(strTable); + #ifdef HAVE_ICONV #ifdef HAVE_LANGINFO_H const char * const to_set = nl_langinfo(CODESET); @@ -505,7 +557,7 @@ bool C4Language::LoadStringTable(C4Group &hGroup, const char *strCode) void C4Language::ClearLanguage() { // Clear resource string table - ClearResStrTable(); + C4LangStringTable::GetSystemStringTable().Clear(); } // Closes any open language pack that has the specified path. diff --git a/src/c4group/C4Language.h b/src/c4group/C4Language.h index 1ac8f8974..a34cdc6d0 100644 --- a/src/c4group/C4Language.h +++ b/src/c4group/C4Language.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004 Matthes Bender - * Copyright (c) 2005-2007 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Language module controlling external language packs */ @@ -22,8 +19,9 @@ #ifndef INC_C4Language #define INC_C4Language -#include -#include +#include "c4group/C4Group.h" +#include "c4group/C4GroupSet.h" +#include "c4group/C4LangStringTable.h" #ifdef HAVE_ICONV #include @@ -31,8 +29,6 @@ const int C4MaxLanguageInfo = 1024; -class C4Language; - class C4LanguageInfo { friend class C4Language; @@ -42,7 +38,7 @@ public: char Info[C4MaxLanguageInfo + 1]; char Fallback[C4MaxLanguageInfo + 1]; //char Location[C4MaxLanguageInfo + 1]; ...store group name here -protected: +private: C4LanguageInfo* Next; }; @@ -51,11 +47,11 @@ class C4Language public: C4Language(); ~C4Language(); -protected: +private: C4Group PackDirectory; C4GroupSet Packs; C4GroupSet PackGroups; - C4LanguageInfo* Infos; + class C4LanguageInfo* Infos; char PackGroupLocation[_MAX_FNAME + 1]; public: bool CloseGroup(const char *strPath); @@ -66,6 +62,9 @@ public: // Handling of external language packs int GetPackCount(); C4GroupSet GetPackGroups(C4Group &); + // Load a C4ComponentHost from all loaded language packs + static bool LoadComponentHost(C4ComponentHost *host, C4Group &hGroup, const char *szFilename, const char *szLanguage); + // Handling of language info loaded from string tables int GetInfoCount(); C4LanguageInfo *GetInfo(int iIndex); @@ -75,7 +74,10 @@ public: // Encoding conversion functions static StdStrBuf IconvClonk(const char * string); static StdStrBuf IconvSystem(const char * string); -protected: + + inline bool HasStringTable() const { return !C4LangStringTable::GetSystemStringTable().GetDataBuf().isNull(); } + +private: // Handling of language info loaded from string tables void InitInfos(); void LoadInfos(C4Group &hGroup); @@ -91,4 +93,17 @@ protected: extern C4Language Languages; -#endif +inline const char *LoadResStr(const char *id) +{ + try + { + return C4LangStringTable::GetSystemStringTable().Translate(id).c_str(); + } + catch (C4LangStringTable::NoSuchTranslation &) + { + return id; + } +} +const char *LoadResStrNoAmp(const char *id); + +#endif \ No newline at end of file diff --git a/src/c4group/C4Update.cpp b/src/c4group/C4Update.cpp index 7f3528e12..0ceee97e6 100644 --- a/src/c4group/C4Update.cpp +++ b/src/c4group/C4Update.cpp @@ -1,24 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2004, 2008 Peter Wortmann - * Copyright (c) 2004, 2007 Matthes Bender - * Copyright (c) 2005-2007, 2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010-2011 Armin Burgmeier - * Copyright (c) 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include #include "C4Update.h" diff --git a/src/c4group/C4Update.h b/src/c4group/C4Update.h index 8c13d6056..6e5921e5b 100644 --- a/src/c4group/C4Update.h +++ b/src/c4group/C4Update.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Matthes Bender - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Update package support */ diff --git a/src/c4group/CStdFile.cpp b/src/c4group/CStdFile.cpp index a5f682a54..d8d3b8262 100644 --- a/src/c4group/CStdFile.cpp +++ b/src/c4group/CStdFile.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2004, 2008 Peter Wortmann - * Copyright (c) 2005, 2007, 2009, 2011 Günther Brammer - * Copyright (c) 2005-2006 Sven Eberhardt - * Copyright (c) 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A handy wrapper class to gzio files */ @@ -392,6 +387,6 @@ bool GetFileSHA1(const char *szFilename, BYTE *pSHA1) // close file File.Close(); // finish calculation - ctx.get_digest((sha1::digest_type) pSHA1); + ctx.get_digest((sha1::digest_type) *pSHA1); return true; } diff --git a/src/c4group/CStdFile.h b/src/c4group/CStdFile.h index 80e6d2957..f69d14c34 100644 --- a/src/c4group/CStdFile.h +++ b/src/c4group/CStdFile.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2004, 2007 Günther Brammer - * Copyright (c) 2008 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A handy wrapper class to gzio files */ diff --git a/src/c4group/Resource.rc b/src/c4group/Resource.rc index f760d95d5..521f36706 100644 --- a/src/c4group/Resource.rc +++ b/src/c4group/Resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_GERMAN, SUBLANG_GERMAN // VS_VERSION_INFO VERSIONINFO - FILEVERSION C4XVER1,C4XVER2,C4XVER3,C4XVER4 - PRODUCTVERSION C4XVER1,C4XVER2,C4XVER3,C4XVER4 + FILEVERSION C4XVER1,C4XVER2,C4XVER3,0 + PRODUCTVERSION C4XVER1,C4XVER2,C4XVER3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L diff --git a/src/c4group/gunzip4c4group.cpp b/src/c4group/gunzip4c4group.cpp index 7b81d5ba3..de03a8e90 100644 --- a/src/c4group/gunzip4c4group.cpp +++ b/src/c4group/gunzip4c4group.cpp @@ -1,18 +1,15 @@ /* - * Copyright (c) 2007, 2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * Copyright (c) 2007, Günther Brammer + * Copyright (c) 2010-2013, 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. */ #include diff --git a/src/config/C4Config.cpp b/src/config/C4Config.cpp index 077c2e5f0..1f2205f07 100644 --- a/src/config/C4Config.cpp +++ b/src/config/C4Config.cpp @@ -1,26 +1,17 @@ /* * OpenClonk, http://www.openclonk.org - * Copyright (c) 1998-2000, 2003-2004, 2007-2008 Matthes Bender - * Copyright (c) 2002, 2006-2008, 2011 Sven Eberhardt - * Copyright (c) 2003, 2005-2007 Peter Wortmann - * Copyright (c) 2005-2009, 2011 Günther Brammer - * Copyright (c) 2006 Alexander Post - * Copyright (c) 2006-2007 Julian Raschke - * Copyright (c) 2008, 2011 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Game configuration as stored in registry */ @@ -90,16 +81,16 @@ void C4ConfigDeveloper::CompileFunc(StdCompiler *pComp) void C4ConfigGraphics::CompileFunc(StdCompiler *pComp) { - pComp->Value(mkNamingAdapt(ResX, "ResolutionX", 800 ,false, true)); - pComp->Value(mkNamingAdapt(ResY, "ResolutionY", 600 ,false, true)); + pComp->Value(mkNamingAdapt(ResX, "ResolutionX", -1 ,false, true)); + pComp->Value(mkNamingAdapt(ResY, "ResolutionY", -1 ,false, true)); + pComp->Value(mkNamingAdapt(WindowX, "WindowX", 800 ,false, true)); + pComp->Value(mkNamingAdapt(WindowY, "WindowY", 600 ,false, true)); pComp->Value(mkNamingAdapt(RefreshRate, "RefreshRate", 0 )); - pComp->Value(mkNamingAdapt(GuiResX, "GuiResolutionX", 800 ,false, true)); - pComp->Value(mkNamingAdapt(GuiResY, "GuiResolutionY", 600 ,false, true)); pComp->Value(mkNamingAdapt(ShowAllResolutions, "ShowAllResolutions", 0 ,false, true)); pComp->Value(mkNamingAdapt(SplitscreenDividers, "SplitscreenDividers", 1 )); pComp->Value(mkNamingAdapt(ShowStartupMessages, "ShowStartupMessages", 1 ,false, true)); pComp->Value(mkNamingAdapt(ColorAnimation, "ColorAnimation", 0 ,false, true)); - pComp->Value(mkNamingAdapt(HighResLandscape, "HighResLandscape", 0 ,false, true)); + pComp->Value(mkNamingAdapt(HighResLandscape, "HighResLandscape", 1 ,false, true)); pComp->Value(mkNamingAdapt(SmokeLevel, "SmokeLevel", 200 ,false, true)); pComp->Value(mkNamingAdapt(VerboseObjectLoading, "VerboseObjectLoading", 0 )); pComp->Value(mkNamingAdapt(VideoModule, "VideoModule", 0 ,false, true)); @@ -111,7 +102,6 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(BitDepth, "BitDepth", 32 ,false, true)); pComp->Value(mkNamingAdapt(Windowed, "Windowed", 0 ,false, true)); pComp->Value(mkNamingAdapt(PXSGfx, "PXSGfx" , 1 )); - pComp->Value(mkNamingAdapt(Engine, "Engine" , 1 ,false, true)); pComp->Value(mkNamingAdapt(Gamma1, "Gamma1" , 0 )); pComp->Value(mkNamingAdapt(Gamma2, "Gamma2" , 0x808080 )); pComp->Value(mkNamingAdapt(Gamma3, "Gamma3" , 0xffffff )); @@ -357,10 +347,6 @@ bool C4Config::Load(const char *szConfigFile) if (fWinSock) WSACleanup(); #endif General.DefaultLanguage(); -#if defined USE_GL && !defined USE_DIRECTX - if (Graphics.Engine == GFXENGN_DIRECTX || Graphics.Engine == GFXENGN_DIRECTXS) - Graphics.Engine = GFXENGN_OPENGL; -#endif // bit depth sanity check (might be corrupted by resolution check bug in old version) if (Graphics.BitDepth < 16) { @@ -721,7 +707,6 @@ void C4ConfigStartup::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(HideMsgPlrNoTakeOver, "HideMsgPlrNoTakeOver", 0)); pComp->Value(mkNamingAdapt(HideMsgNoOfficialLeague, "HideMsgNoOfficialLeague", 0)); pComp->Value(mkNamingAdapt(HideMsgIRCDangerous, "HideMsgIRCDangerous", 0)); - pComp->Value(mkNamingAdapt(NoSplash, "NoSplash", 1)); pComp->Value(mkNamingAdapt(AlphabeticalSorting, "AlphabeticalSorting", 0)); pComp->Value(mkNamingAdapt(LastPortraitFolderIdx, "LastPortraitFolderIdx", 0)); } diff --git a/src/config/C4Config.h b/src/config/C4Config.h index bedf7a9d1..7d881653a 100644 --- a/src/config/C4Config.h +++ b/src/config/C4Config.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001, 2004, 2006-2007 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Game configuration as stored in registry */ @@ -62,6 +57,11 @@ public: char ScreenshotPath[CFG_MaxString+1]; bool GamepadEnabled; bool FirstStart; + int32_t DebugRec; + // if defined, the external file is used for debugrec writing. Otherwise read/check + int32_t DebugRecWrite; + // if defined, an external file is used for debugrec writing (replays only) + char DebugRecExternalFile[_MAX_PATH+1]; public: static int GetLanguageSequence(const char *strSource, char *strTarget); @@ -99,15 +99,14 @@ public: int32_t UpperBoard; int32_t ShowClock; int32_t ResX,ResY; + int32_t WindowX,WindowY; int32_t RefreshRate; // monitor vertical refresh rate - int32_t GuiResX,GuiResY; - int32_t Windowed; + int32_t Windowed; // 0: fullscreen, 1: windowed, 2: fullscreen in game, windowed in menu int32_t ShowAllResolutions; int32_t ShowCrewNames; // show player name above clonks? int32_t ShowCrewCNames; // show clonk names above clonks? int32_t BitDepth; // used bit depth for newgfx int32_t PXSGfx; // show PXS-graphics (instead of sole pixels) - int32_t Engine; // 0: D3D; 1: OpenGL; int32_t Gamma1, Gamma2, Gamma3; // gamma ramps int32_t Currency; // default wealth symbolseb int32_t RenderInactiveEM; // draw vieports even if inactive in CPEM @@ -185,7 +184,6 @@ public: int32_t HideMsgPlrNoTakeOver; int32_t HideMsgNoOfficialLeague; int32_t HideMsgIRCDangerous; - int32_t NoSplash; int32_t AlphabeticalSorting; // if set, Folder.txt-sorting is ignored in scenario selection int32_t LastPortraitFolderIdx; void CompileFunc(StdCompiler *pComp); @@ -195,7 +193,7 @@ class C4ConfigLobby { public: int32_t CountdownTime; - int32_t AllowPlayerSave; // whether save-to-disk function is enabled for player ressources + int32_t AllowPlayerSave; // whether save-to-disk function is enabled for player resources void CompileFunc(StdCompiler *pComp); }; diff --git a/src/config/C4Constants.h b/src/config/C4Constants.h index b1fb9ec29..2294f7a81 100644 --- a/src/config/C4Constants.h +++ b/src/config/C4Constants.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2005 Matthes Bender - * Copyright (c) 2002, 2006-2007, 2009 Sven Eberhardt - * Copyright (c) 2005, 2007 Günther Brammer - * Copyright (c) 2010-2011 Maikel de Vries - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Lots of constants */ @@ -198,7 +194,7 @@ const BYTE COM_CursorRight = 31; const BYTE - COM_Help = 35, +// COM_Help = 35, (obsolete, was: help-mode button) COM_PlayerMenu = 36, COM_Chat = 37; diff --git a/src/config/C4Reloc.cpp b/src/config/C4Reloc.cpp index 635e708fb..f207727b8 100644 --- a/src/config/C4Reloc.cpp +++ b/src/config/C4Reloc.cpp @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2011 Armin Burgmeier + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include @@ -87,4 +85,4 @@ bool C4Reloc::LocateItem(const char* filename, StdStrBuf& str) const } return false; -} \ No newline at end of file +} diff --git a/src/config/C4Reloc.h b/src/config/C4Reloc.h index 75d24291b..66ae400ce 100644 --- a/src/config/C4Reloc.h +++ b/src/config/C4Reloc.h @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2011 Armin Burgmeier + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef C4RELOC_H diff --git a/src/config/C4SecurityCertificates.cpp b/src/config/C4SecurityCertificates.cpp deleted file mode 100644 index 3761044d4..000000000 --- a/src/config/C4SecurityCertificates.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2003-2004 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Certificate used to verify registration keys. */ - -#include "C4Include.h" - -const char* Cert_Reg_XOR_Base64 = - "R0deRkkuNHZ/fEgwLjxnfjUicitmdx9eR0deYSklOHJcWCswKghQdDI6ZB12Y2s5IQUpIgwaEn93\n" - "Yy02KT9yQBQyWhJxSHM5KA09PSYtKGV3WTo1Jj8LQDc6aC44ZGMiIy8EMScPHGdCaD9HEypJdj0p\n" - "ViRkcHMQPigYIR02JgBaUAI2CCNxWDQqAD93cVo+Pj8ePQ86QwhFaAExLmRpbz0ba1gGVWBBWwMg\n" - "LyENPHNRdSlCPityTz45ZAdkWWRBUxkpAiYpK2l4QjJBXwliBzYTeQBzUXAUARsbAA0rewhBAiow\n" - "Oitkc0EHRDBfC3MQBzwYD1ZVAmtfBwMpPy9WcQRbRiR2cwA+LjsLJTAhQn9ieAk1HF5LeTcqAyd2\n" - "e0p5JD4+WCo4O1B7ey8mJj9AQDA6aC5kY2M0Lx05LjY4NGF7c1g0Kl9mcjApfC1jXHgfCD0lHik9\n" - "SUZyYzE3PT9if3kuRjBxUV8lHjAkXxwkNXBXcA89PSxyWCcuACBeaHQXHAg0MgM+NmdMUz8XHid2\n" - "UwcyWg1KeGYyACgUJTIuMHxiOCA2JR1RBUYZeC9kR2g0PAIXBl1dElh0YTIkDx5QBCESaDJgQlBB\n" - "XhI7ASUPM1ZdQwAYAikKQEMpcjt3ZXZBBh95MQlVMFJbZAMXWVdAbRpeWjBmcXAdECs9KQMHAFld\n" - "Wy9KHF5xdiIudytzfXAZOysEDD0HMlZvdykBKikCHCAaUmBbXGFDIAYrKiYaAwN+UysJDxRwQEUu\n" - "ZQh/AlQYAyUVMzMEPlVSCwQiOCBFXQFYAR5LYgMJDltKKC89CEtXCiQhYRkHbhsOeThrAlA4JxBE\n" - "OhIiAnkHBDAXPl0GBxhfHiBFR1YZHRkACS4pQWF8Uw1DWiZnAzQsVQUHBnkaLyMALwhmG3UHAT49\n" - "XAIFfzgTWTtocFsdJDk1CQ02FGhFQgYcJQgBYxgocB13c3MnKyQxDA8dGVpfdVEEWyxyZiItcCt9\n" - "cDgUOykQHk8FHUN4W1oiEiFHTRBAQTtiV0o8HCImOyVZIQdORCULEwN3TUFYYQVlcFRGHh4kHwFY\n" - "E1hCYzIaPS9BPQcTGjABA0InMygLPR0gAVRABS0xAzRqBCINYikEWUQDIgQAIlMGBHVwHQA9DCEG\n" - "e1w7W0FkXEInEAAdGSAmFVc8WxIeG1l6QVwABj50B14kHgAQQAcZR3Z6Zg0DLkVdVFwYQ1x9fEEl\n" - "Lwg0IRBfBgwLOEVeRkMecj0vESl3YGY6LCMwKjApXBwbH0V5\n" - ; - -const char* XOR_Cert_Reg = "jjskdlq162hskn37sk1j222s"; diff --git a/src/config/C4SecurityCertificates.h b/src/config/C4SecurityCertificates.h deleted file mode 100644 index 2483496f8..000000000 --- a/src/config/C4SecurityCertificates.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -extern const char* Cert_Reg_XOR_Base64; -extern const char* XOR_Cert_Reg; diff --git a/src/control/C4Control.cpp b/src/control/C4Control.cpp index 8af738ac2..2d4c14d13 100644 --- a/src/control/C4Control.cpp +++ b/src/control/C4Control.cpp @@ -1,28 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2001-2002, 2004-2009 Sven Eberhardt - * Copyright (c) 2004-2008 Peter Wortmann - * Copyright (c) 2006, 2009-2010 Günther Brammer - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2006, 2011 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Control packets contain all player input in the message queue */ @@ -33,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +39,8 @@ #include #include #include +#include "gui/C4MessageInput.h" +#include "object/C4DefList.h" #ifndef NOAULDEBUG #include @@ -175,18 +168,17 @@ void C4ControlSet::Execute() const ::GraphicsSystem.FlashMessage(FormatString(LoadResStr("IDS_NET_CONTROLRATE"),::Control.ControlRate,Game.FrameCounter).getData()); break; - case C4CVT_AllowDebug: // allow debug mode? + case C4CVT_DisableDebug: // force debug mode disabled { - bool fSet = !!iData; - // disable debug - if (!fSet && Game.DebugMode) + if (Game.DebugMode) { Game.DebugMode=false; ::GraphicsSystem.DeactivateDebugOutput(); } // save flag, log - Game.Parameters.AllowDebug = fSet; - Log(fSet ? "Debug ON" : "Debug OFF"); + Game.Parameters.AllowDebug = false; + C4Client *client = ::Game.Clients.getClientByID(iByClient); + LogF("Debug mode forced disabled by %s", client ? client->getName() : ""); break; } break; @@ -235,7 +227,10 @@ void C4ControlScript::Execute() const { const char *szScript = Script.getData(); // user script: from host only - if (!fInternal && (iByClient != C4ClientIDHost) && !Console.Active) return; + if ((iByClient != C4ClientIDHost) && !Console.Active) return; + // only allow scripts when debug mode is not forbidden + if (!Game.Parameters.AllowDebug) return; + // execute C4Object *pObj = NULL; C4AulScript *pScript; @@ -257,38 +252,100 @@ void C4ControlScript::Execute() const } #endif // show messages - if (!fInternal) + // print script + if (pObj) + LogF("-> %s::%s", pObj->Def->GetName(), szScript); + else + LogF("-> %s", szScript); + // print result + if (!LocalControl()) { - // print script - if (pObj) - LogF("-> %s::%s", pObj->Def->GetName(), szScript); + C4Network2Client *pClient = NULL; + if (::Network.isEnabled()) + pClient = ::Network.Clients.GetClientByID(iByClient); + if (pClient) + LogF(" = %s (by %s)", rVal.GetDataString().getData(), pClient->getName()); else - LogF("-> %s", szScript); - // print result - if (!LocalControl()) - { - C4Network2Client *pClient = NULL; - if (::Network.isEnabled()) - pClient = ::Network.Clients.GetClientByID(iByClient); - if (pClient) - LogF(" = %s (by %s)", rVal.GetDataString().getData(), pClient->getName()); - else - LogF(" = %s (by client %d)", rVal.GetDataString().getData(), iByClient); - } - else - LogF(" = %s", rVal.GetDataString().getData()); + LogF(" = %s (by client %d)", rVal.GetDataString().getData(), iByClient); } + else + LogF(" = %s", rVal.GetDataString().getData()); } void C4ControlScript::CompileFunc(StdCompiler *pComp) { pComp->Value(mkNamingAdapt(iTargetObj, "TargetObj", -1)); - pComp->Value(mkNamingAdapt(fInternal, "Internal", false)); pComp->Value(mkNamingAdapt(fUseVarsFromCallerContext, "UseVarsFromCallerContext", false)); pComp->Value(mkNamingAdapt(Script, "Script", "")); C4ControlPacket::CompileFunc(pComp); } +// *** C4ControlMsgBoardReply +void C4ControlMsgBoardReply::Execute() const +{ + C4Object *target_object = ::Objects.SafeObjectPointer(target); + C4Player *target_player = ::Players.Get(player); + + // remove query + if (!target_player) return; + if (!target_player->RemoveMessageBoardQuery(target_object)) return; + + // execute callback if answer present + if (!reply) return; + C4AulParSet pars(C4VString(reply), C4VInt(player)); + if (target_object) + target_object->Call(PSF_InputCallback, &pars); + else + ::GameScript.Call(PSF_InputCallback, &pars); +} + +void C4ControlMsgBoardReply::CompileFunc(StdCompiler *pComp) +{ + pComp->Value(mkNamingAdapt(target, "TargetObj", -1)); + pComp->Value(mkNamingAdapt(player, "Player", NO_OWNER)); + pComp->Value(mkNamingAdapt(reply, "Reply", nullptr)); + C4ControlPacket::CompileFunc(pComp); +} + +// *** C4ControlMsgBoardCmd +void C4ControlMsgBoardCmd::Execute() const +{ + C4Player *source_player = ::Players.Get(player); + + // don't handle this if the game isn't actually running + if (!::Game.IsRunning) return; + + // fetch command script + C4MessageBoardCommand *cmd = ::MessageInput.GetCommand(command.getData()); + if (!cmd) return; + StdCopyStrBuf script(cmd->Script); + + // interpolate parameters as required + script.Replace("%player%", FormatString("%d", player).getData()); + if (parameter) + { + script.Replace("%d", FormatString("%d", std::atoi(parameter.getData())).getData()); + StdCopyStrBuf escaped_param(parameter); + escaped_param.EscapeString(); + script.Replace("%s", escaped_param.getData()); + } + + // Run script + C4Value rv(::ScriptEngine.DirectExec(nullptr, script.getData(), "message board command")); +#ifndef NOAULDEBUG + C4AulDebug* pDebug = C4AulDebug::GetDebugger(); + if (pDebug) + pDebug->ControlScriptEvaluated(script.getData(), rv.GetDataString().getData()); +#endif +} + +void C4ControlMsgBoardCmd::CompileFunc(StdCompiler *pComp) +{ + pComp->Value(mkNamingAdapt(player, "Player", NO_OWNER)); + pComp->Value(mkNamingAdapt(command, "Command")); + pComp->Value(mkNamingAdapt(parameter, "Parameter")); + C4ControlPacket::CompileFunc(pComp); +} // *** C4ControlPlayerSelect C4ControlPlayerSelect::C4ControlPlayerSelect(int32_t iPlr, const C4ObjectList &Objs, bool fIsAlt) @@ -378,6 +435,75 @@ void C4ControlPlayerControl::CompileFunc(StdCompiler *pComp) C4ControlPacket::CompileFunc(pComp); } +// *** C4ControlPlayerMouse +C4ControlPlayerMouse *C4ControlPlayerMouse::Hover(const C4Player *player, const C4Object *target, const C4Object *old_target, const C4Object *drag) +{ + assert(player != nullptr); + if (!player) return nullptr; + + auto control = new C4ControlPlayerMouse(); + control->action = CPM_Hover; + control->player = player->Number; + control->drag_obj = drag ? drag->Number : 0; + control->target_obj = target ? target->Number : 0; + control->old_obj = old_target ? old_target->Number : 0; + return control; +} +C4ControlPlayerMouse *C4ControlPlayerMouse::DragDrop(const C4Player *player, const C4Object *target, const C4Object *drag) +{ + assert(player != nullptr); + if (!player) return nullptr; + + auto control = new C4ControlPlayerMouse(); + control->action = CPM_Drop; + control->player = player->Number; + control->drag_obj = drag ? drag->Number : 0; + control->target_obj = target ? target->Number : 0; + return control; +} + +void C4ControlPlayerMouse::Execute() const +{ + const char *callback_name = nullptr; + C4AulParSet pars(C4VInt(player)); + + switch (action) + { + case CPM_NoAction: + return; + + case CPM_Hover: + // Mouse movement, object hover state changed + callback_name = PSF_MouseHover; + pars[1] = C4VObj(::Objects.SafeObjectPointer(old_obj)); + pars[2] = C4VObj(::Objects.SafeObjectPointer(target_obj)); + pars[3] = C4VObj(::Objects.SafeObjectPointer(drag_obj)); + break; + + case CPM_Drop: + // Drag/Drop operation + callback_name = PSF_MouseDragDrop; + pars[1] = C4VObj(::Objects.SafeObjectPointer(drag_obj)); + pars[2] = C4VObj(::Objects.SafeObjectPointer(target_obj)); + break; + } + + // Do call + if (!callback_name) return; + if (callback_name[0] == '~') ++callback_name; + C4AulFunc *callback = ::ScriptEngine.GetFirstFunc(::Strings.RegString(callback_name)); + if (!callback) return; + callback->Exec(nullptr, &pars); +} + +void C4ControlPlayerMouse::CompileFunc(StdCompiler *pComp) +{ + pComp->Value(mkNamingAdapt(action, "Action")); + pComp->Value(mkNamingAdapt(player, "Player", NO_OWNER)); + pComp->Value(mkNamingAdapt(target_obj, "TargetObj")); + pComp->Value(mkNamingAdapt(drag_obj, "DragObj")); + pComp->Value(mkNamingAdapt(old_obj, "OldObj")); +} // *** C4ControlPlayerCommand @@ -418,6 +544,204 @@ void C4ControlPlayerCommand::CompileFunc(StdCompiler *pComp) C4ControlPacket::CompileFunc(pComp); } +// *** C4ControlPlayerAction +C4ControlPlayerAction::C4ControlPlayerAction(const C4Player *source) + : action(CPA_NoAction), source(source ? source->Number : NO_OWNER), target(NO_OWNER), param_int(0) +{ +} + +C4ControlPlayerAction *C4ControlPlayerAction::Surrender(const C4Player *source) +{ + assert(source); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_Surrender; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::Eliminate(const C4Player *source) +{ + assert(source); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_Eliminate; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::ActivateGoal(const C4Player *source, const C4Object *goal) +{ + assert(source); + assert(goal); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_ActivateGoal; + control->target = goal->Number; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::ActivateGoalMenu(const C4Player *source) +{ + assert(source); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_ActivateGoalMenu; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::SetHostility(const C4Player *source, const C4Player *target, bool hostile) +{ + assert(source); + assert(target); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_SetHostility; + control->target = target ? target->Number : NO_OWNER; + control->param_int = hostile; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::SetTeam(const C4Player *source, int32_t team) +{ + assert(source); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_SetTeam; + control->target = team; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::InitScenarioPlayer(const C4Player *source, int32_t team) +{ + assert(source); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_InitScenarioPlayer; + control->target = team; + return control; +} +C4ControlPlayerAction *C4ControlPlayerAction::InitPlayerControl(const C4Player *source, const C4PlayerControlAssignmentSet *ctrl_set) +{ + assert(source); + C4ControlPlayerAction *control = new C4ControlPlayerAction(source); + control->action = CPA_InitPlayerControl; + if (ctrl_set) + { + control->param_str = ctrl_set->GetName(); + if (ctrl_set->HasKeyboard()) + control->param_int |= CPA_IPC_HasKeyboard; + if (ctrl_set->HasMouse()) + control->param_int |= CPA_IPC_HasMouse; + if (ctrl_set->HasGamepad()) + control->param_int |= CPA_IPC_HasGamepad; + } + return control; +} + +void C4ControlPlayerAction::Execute() const +{ + // The originating player must exist + C4Player *source_player = ::Players.Get(source); + if (!source_player) return; + + switch (action) + { + case CPA_Surrender: + source_player->Surrender(); + break; + + case CPA_Eliminate: + source_player->Eliminate(); + break; + + case CPA_ActivateGoal: + { + // Make sure the object actually exists + C4Object *goal = ::Objects.SafeObjectPointer(target); + if (!goal) return; + // Call it + C4AulParSet pars(C4VInt(source_player->Number)); + goal->Call("Activate", &pars); + break; + } + + case CPA_ActivateGoalMenu: + // open menu + source_player->Menu.ActivateGoals(source_player->Number, source_player->LocalControl && !::Control.isReplay()); + break; + + case CPA_SetHostility: + { + // Can only set hostility towards a player that exists + C4Player *target_player = ::Players.Get(target); + if (!target_player) return; + + // Proxy the hostility change through C4Aul, in case a script wants to capture it + C4AulParSet pars(C4VInt(source_player->Number), C4VInt(target_player->Number), C4VBool(param_int != 0)); + C4AulFunc *callback = ::ScriptEngine.GetFirstFunc(::Strings.RegString("SetHostility")); + assert(callback); // this should always exist since the engine provides a default implementation + callback->Exec(nullptr, &pars); + break; + } + + case CPA_SetTeam: + { + // Make sure team switching is allowed in the first place + if (!::Game.Teams.IsTeamSwitchAllowed()) return; + + // We can't change teams to one that doesn't exist + C4Team *team = ::Game.Teams.GetTeamByID(target); + if (!team && target != TEAMID_New) return; + + // Proxy the team switch through C4Aul, in case a script wants to capture it + C4AulParSet pars(C4VInt(source_player->Number), C4VInt(target)); + C4AulFunc *callback = ::ScriptEngine.GetFirstFunc(::Strings.RegString("SetPlayerTeam")); + assert(callback); + callback->Exec(nullptr, &pars); + break; + } + + case CPA_InitScenarioPlayer: + { + // Proxy the call through C4Aul, in case a script wants to capture it + C4AulParSet pars(C4VInt(source_player->Number), C4VInt(target)); + C4AulFunc *callback = ::ScriptEngine.GetFirstFunc(::Strings.RegString("InitScenarioPlayer")); + assert(callback); + callback->Exec(nullptr, &pars); + break; + } + + case CPA_InitPlayerControl: + { + // Notify scripts about player control selection + const char *callback_name = PSF_InitializePlayerControl; + if (callback_name[0] == '~') ++callback_name; + C4AulFunc *callback = ::ScriptEngine.GetFirstFunc(::Strings.RegString(callback_name)); + if (!callback) return; + + C4AulParSet pars(C4VInt(source_player->Number)); + // If the player is using a control set, its name is stored in param_str + if (param_str) + { + pars[1] = C4VString(param_str); + pars[2] = C4VBool(CPA_IPC_HasKeyboard == (param_int & CPA_IPC_HasKeyboard)); + pars[3] = C4VBool(CPA_IPC_HasMouse == (param_int & CPA_IPC_HasMouse)); + pars[4] = C4VBool(CPA_IPC_HasGamepad == (param_int & CPA_IPC_HasGamepad)); + } + callback->Exec(nullptr, &pars); + break; + } + } +} + +void C4ControlPlayerAction::CompileFunc(StdCompiler *pComp) +{ + pComp->Value(mkNamingAdapt(source, "Player", NO_OWNER)); + const StdEnumEntry ActionNames[] = + { + { "Surrender", CPA_Surrender }, + { "ActivateGoal", CPA_ActivateGoal }, + { "ActivateGoalMenu", CPA_ActivateGoalMenu }, + { "Eliminate", CPA_Eliminate }, + { "SetHostility", CPA_SetHostility }, + { "SetTeam", CPA_SetTeam }, + { "InitScenarioPlayer", CPA_InitScenarioPlayer }, + { "InitPlayerControl", CPA_InitPlayerControl }, + { NULL, CPA_NoAction } + }; + pComp->Value(mkNamingAdapt(mkEnumAdapt(action, ActionNames), "Action", CPA_NoAction)); + pComp->Value(mkNamingAdapt(target, "Target", NO_OWNER)); + pComp->Value(mkNamingAdapt(param_int, "DataI", 0)); + pComp->Value(mkNamingAdapt(param_str, "DataS", nullptr)); + C4ControlPacket::CompileFunc(pComp); +} + // *** C4ControlSyncCheck C4ControlSyncCheck::C4ControlSyncCheck() @@ -756,7 +1080,7 @@ void C4ControlJoinPlayer::Execute() const } else if (::Control.isNetwork()) { - // Find ressource + // Find resource C4Network2Res::Ref pRes = ::Network.ResList.getRefRes(ResCore.getID()); if (pRes && pRes->isComplete()) Game.JoinPlayer(pRes->getFile(), iAtClient, pClient->getName(), pInfo); @@ -810,7 +1134,7 @@ bool C4ControlJoinPlayer::PreExecute() const if (!Game.Clients.getClientByID(iAtClient)) return true; // network only if (!::Control.isNetwork()) return true; - // search ressource + // search resource C4Network2Res::Ref pRes = ::Network.ResList.getRefRes(ResCore.getID()); // doesn't exist? start loading if (!pRes) { pRes = ::Network.ResList.AddByCore(ResCore, true); } @@ -861,11 +1185,18 @@ void C4ControlJoinPlayer::CompileFunc(StdCompiler *pComp) C4ControlEMMoveObject::C4ControlEMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, int32_t iObjectNum, int32_t *pObjects, const char *szScript) : eAction(eAction), tx(tx), ty(ty), iTargetObj(pTargetObj ? pTargetObj->Number : 0), - iObjectNum(iObjectNum), pObjects(pObjects), Script(szScript, true) + iObjectNum(iObjectNum), pObjects(pObjects), StringParam(szScript, true) { } +C4ControlEMMoveObject *C4ControlEMMoveObject::CreateObject(const C4ID &id, C4Real x, C4Real y) +{ + auto ctl = new C4ControlEMMoveObject(EMMO_Create, x, y, nullptr); + ctl->StringParam = id.ToString(); + return ctl; +} + C4ControlEMMoveObject::~C4ControlEMMoveObject() { delete [] pObjects; pObjects = NULL; @@ -926,7 +1257,7 @@ void C4ControlEMMoveObject::Execute() const { if (!pObjects) return; // execute script ... - C4ControlScript ScriptCtrl(Script.getData(), C4ControlScript::SCOPE_Global, false); + C4ControlScript ScriptCtrl(StringParam.getData(), C4ControlScript::SCOPE_Global); ScriptCtrl.SetByClient(iByClient); // ... for each object in selection for (int i=0; iExit(pObj->GetX(), pObj->GetY(), pObj->r); + pObj->Exit(pObj->GetX(), pObj->GetY(), pObj->GetR()); + } + break; + case EMMO_Select: + case EMMO_Deselect: + { + // callback to script + C4Object *target = ::Objects.SafeObjectPointer(iTargetObj); + if (!target) return; + target->Call(eAction == EMMO_Select ? PSF_EditCursorSelection : PSF_EditCursorDeselection); + } + break; + case EMMO_Create: + { + ::Game.CreateObject(C4ID(StringParam), nullptr, NO_OWNER, fixtoi(tx), fixtoi(ty)); } break; } @@ -972,7 +1317,9 @@ void C4ControlEMMoveObject::CompileFunc(StdCompiler *pComp) if (pComp->isCompiler()) { delete [] pObjects; pObjects = new int32_t [iObjectNum]; } pComp->Value(mkNamingAdapt(mkArrayAdapt(pObjects, iObjectNum), "Objs", -1)); if (eAction == EMMO_Script) - pComp->Value(mkNamingAdapt(Script, "Script", "")); + pComp->Value(mkNamingAdapt(StringParam, "Script", "")); + else if (eAction == EMMO_Create) + pComp->Value(mkNamingAdapt(StringParam, "ID", "")); C4ControlPacket::CompileFunc(pComp); } @@ -1022,7 +1369,11 @@ void C4ControlEMDrawTool::Execute() const int iMat = ::MaterialMap.Get(szMaterial); if (!MatValid(iMat)) return; for (int cnt=0; cntOnClientSound(Game.Clients.getClientByID(iByClient)); - } + C4Client *singer = Game.Clients.getClientByID(iByClient); + if (!singer || !singer->IsIgnored()) + if (!StartSoundEffect(szMessage, false, 100, NULL)) + // probably wrong sound file name + break; + // Sound icon even if someone you ignored just tried. So you know you still need to ignore. + if (pLobby) pLobby->OnClientSound(singer); + if (C4Network2ClientListDlg::GetInstance()) C4Network2ClientListDlg::GetInstance()->OnSound(singer); break; + } case C4CMT_Alert: // notify inactive users diff --git a/src/control/C4Control.h b/src/control/C4Control.h index b3f970539..2e05390f2 100644 --- a/src/control/C4Control.h +++ b/src/control/C4Control.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001-2002, 2005, 2009 Sven Eberhardt - * Copyright (c) 2004-2007 Peter Wortmann - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Control packets contain all player input in the message queue */ @@ -31,8 +27,6 @@ #include "C4KeyboardInput.h" #include "C4ObjectList.h" -class C4Record; - // *** control base classes class C4ControlPacket : public C4PacketBase @@ -107,7 +101,7 @@ enum C4CtrlValueType { C4CVT_None = -1, C4CVT_ControlRate = 0, - C4CVT_AllowDebug = 1, + C4CVT_DisableDebug = 1, C4CVT_MaxPlayer = 2, C4CVT_TeamDistribution = 3, C4CVT_TeamColors = 4, @@ -138,14 +132,13 @@ public: enum { SCOPE_Console=-2, SCOPE_Global=-1 }; // special scopes to be passed as target objects C4ControlScript() - : iTargetObj(-1), fInternal(true), fUseVarsFromCallerContext(false) + : iTargetObj(-1), fUseVarsFromCallerContext(false) { } - C4ControlScript(const char *szScript, int32_t iTargetObj = SCOPE_Global, bool fInternal = true, bool fUseVarsFromCallerContext = false) - : iTargetObj(iTargetObj), fInternal(fInternal), fUseVarsFromCallerContext(fUseVarsFromCallerContext), Script(szScript, true) + C4ControlScript(const char *szScript, int32_t iTargetObj, bool fUseVarsFromCallerContext = false) + : iTargetObj(iTargetObj), fUseVarsFromCallerContext(fUseVarsFromCallerContext), Script(szScript, true) { } protected: int32_t iTargetObj; - bool fInternal; // silent execute bool fUseVarsFromCallerContext; StdStrBuf Script; public: @@ -153,6 +146,44 @@ public: DECLARE_C4CONTROL_VIRTUALS }; +class C4ControlMsgBoardReply : public C4ControlPacket // sync +{ +public: + C4ControlMsgBoardReply() + : target(-1), player(NO_OWNER) + {} + C4ControlMsgBoardReply(const char *reply, int32_t target, int32_t player) + : reply(reply), target(target), player(player) + {} + +private: + StdCopyStrBuf reply; + int32_t target; + int32_t player; + +public: + DECLARE_C4CONTROL_VIRTUALS +}; + +class C4ControlMsgBoardCmd : public C4ControlPacket // sync +{ +public: + C4ControlMsgBoardCmd() + : player(NO_OWNER) + {} + C4ControlMsgBoardCmd(const char *command, const char *parameter, int32_t player) + : command(command), parameter(parameter), player(player) + {} + +private: + StdCopyStrBuf command; + StdCopyStrBuf parameter; + int32_t player; + +public: + DECLARE_C4CONTROL_VIRTUALS +}; + class C4ControlPlayerSelect : public C4ControlPacket // sync { public: @@ -203,6 +234,31 @@ public: void SetExtraData(const C4KeyEventData &new_extra_data) { ExtraData = new_extra_data; } }; +class C4ControlPlayerMouse : public C4ControlPacket // sync +{ +public: + enum Action + { + CPM_NoAction = 0, + + CPM_Hover = 0x01, + CPM_Drop = 0x02 + }; + + C4ControlPlayerMouse() : action(CPM_NoAction), player(NO_OWNER), target_obj(0), drag_obj(0), old_obj(0) {} + static C4ControlPlayerMouse *Hover(const C4Player *player, const C4Object *target, const C4Object *old_target, const C4Object *drag = nullptr); + static C4ControlPlayerMouse *DragDrop(const C4Player *player, const C4Object *target, const C4Object *drag); + +private: + int32_t action; + int32_t player; + int32_t target_obj; + int32_t drag_obj; + int32_t old_obj; +public: + DECLARE_C4CONTROL_VIRTUALS +}; + class C4ControlPlayerCommand : public C4ControlPacket // sync { public: @@ -216,6 +272,53 @@ public: DECLARE_C4CONTROL_VIRTUALS }; +class C4ControlPlayerAction : public C4ControlPacket // sync +{ +public: + enum Action + { + CPA_NoAction = 0, + + CPA_Surrender = 0x01, + CPA_ActivateGoal = 0x02, + CPA_ActivateGoalMenu = 0x03, + CPA_Eliminate = 0x04, + + CPA_SetHostility = 0x10, + CPA_SetTeam = 0x11, + + CPA_InitScenarioPlayer = 0x20, + CPA_InitPlayerControl = 0x21 + }; + + C4ControlPlayerAction(const C4Player *source = nullptr); + static C4ControlPlayerAction *Surrender(const C4Player *source); + static C4ControlPlayerAction *Eliminate(const C4Player *source); + static C4ControlPlayerAction *ActivateGoalMenu(const C4Player *source); + static C4ControlPlayerAction *ActivateGoal(const C4Player *source, const C4Object *target); + static C4ControlPlayerAction *SetHostility(const C4Player *source, const C4Player *target, bool hostile); + static C4ControlPlayerAction *SetTeam(const C4Player *source, int32_t team); + static C4ControlPlayerAction *InitScenarioPlayer(const C4Player *source, int32_t team); + static C4ControlPlayerAction *InitPlayerControl(const C4Player *source, const C4PlayerControlAssignmentSet *ctrl_set = nullptr); + +private: + Action action; + int32_t source; + int32_t target; + int32_t param_int; + StdCopyStrBuf param_str; + + enum IpcParam + { + CPA_IPC_HasKeyboard = 1<<0, + CPA_IPC_HasMouse = 1<<1, + CPA_IPC_HasGamepad = 1<<2 + }; + +public: + DECLARE_C4CONTROL_VIRTUALS +}; + class C4ControlSyncCheck : public C4ControlPacket // not sync { public: @@ -345,7 +448,10 @@ enum C4ControlEMObjectAction EMMO_Duplicate, // duplicate objects at same position; reset EditCursor EMMO_Script, // execute Script EMMO_Remove, // remove objects - EMMO_Exit // exit objects + EMMO_Exit, // exit objects + EMMO_Select, // select object + EMMO_Deselect, // deselect object + EMMO_Create // create a new object (used by C4Game::DropDef) }; class C4ControlEMMoveObject : public C4ControlPacket // sync @@ -354,6 +460,7 @@ public: C4ControlEMMoveObject() : eAction(EMMO_Move), tx(Fix0), ty(Fix0), iTargetObj(0), iObjectNum(0), pObjects(NULL) { } C4ControlEMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, int32_t iObjectNum = 0, int32_t *pObjects = NULL, const char *szScript = NULL); + static C4ControlEMMoveObject *CreateObject(const C4ID &id, C4Real x, C4Real y); ~C4ControlEMMoveObject(); protected: C4ControlEMObjectAction eAction; // action to be performed @@ -361,7 +468,7 @@ protected: int32_t iTargetObj; // enumerated ptr to target object int32_t iObjectNum; // number of objects moved int32_t *pObjects; // pointer on array of objects moved - StdStrBuf Script; // script to execute + StdStrBuf StringParam; // script to execute, or ID of object to create public: DECLARE_C4CONTROL_VIRTUALS }; diff --git a/src/control/C4GameControl.cpp b/src/control/C4GameControl.cpp index c591e6e5f..34975d96d 100644 --- a/src/control/C4GameControl.cpp +++ b/src/control/C4GameControl.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2008 Peter Wortmann - * Copyright (c) 2005-2010 Sven Eberhardt - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* control management */ @@ -52,7 +48,7 @@ C4GameControl::~C4GameControl() bool C4GameControl::InitLocal(C4Client *pLocal) { - eMode = CM_Local; fPreInit = fInitComplete = true; + eMode = CM_Local; fInitComplete = true; fHost = true; iClientID = pLocal->getID(); ControlRate = 1; // ok @@ -65,7 +61,7 @@ bool C4GameControl::InitNetwork(C4Client *pLocal) if (!Network.IsEnabled()) return false; // set mode - eMode = CM_Network; fPreInit = fInitComplete = true; + eMode = CM_Network; fInitComplete = true; fHost = pLocal->isHost(); iClientID = pLocal->getID(); // control rate by parameters ControlRate = Game.Parameters.ControlRate; @@ -184,9 +180,8 @@ void C4GameControl::RequestRuntimeRecord() fRecordNeeded = true; // request through a synchronize-call // currnetly do not request, but start record with next gamesync, so network runtime join can be debugged -#ifndef DEBUGREC - ::Control.DoInput(CID_Synchronize, new C4ControlSynchronize(false, true), CDT_Queue); -#endif + if (Config.General.DebugRec) + ::Control.DoInput(CID_Synchronize, new C4ControlSynchronize(false, true), CDT_Queue); } bool C4GameControl::IsRuntimeRecordPossible() const @@ -219,7 +214,7 @@ void C4GameControl::Default() Input.Clear(); Network.Clear(); eMode = CM_None; - fHost = fPreInit = fInitComplete = false; + fHost = fInitComplete = false; iClientID = C4ClientIDUnknown; pRecord = NULL; pPlayback = NULL; @@ -388,13 +383,11 @@ void C4GameControl::SetActivated(bool fnActivated) void C4GameControl::DoInput(C4PacketType eCtrlType, C4ControlPacket *pPkt, C4ControlDeliveryType eDelivery) { - assert(fPreInit); + assert(fInitComplete || pPkt->Lobby()); // check if the control can be executed if (eDelivery == CDT_Direct || eDelivery == CDT_Private) assert(!pPkt->Sync()); - if (!fInitComplete) - assert(pPkt->Lobby()); // decide control type if (eDelivery == CDT_Decide) @@ -424,18 +417,19 @@ void C4GameControl::DoInput(C4PacketType eCtrlType, C4ControlPacket *pPkt, C4Con void C4GameControl::DbgRec(C4RecordChunkType eType, const uint8_t *pData, size_t iSize) { -#ifdef DEBUGREC - if (DoNoDebugRec>0) return; - // record data - if (pRecord) + if (Config.General.DebugRec) { - C4PktDebugRec dr(eType, StdBuf(pData, iSize)); - pRecord->Rec(Game.FrameCounter, DecompileToBuf(dr), eType); + if (DoNoDebugRec>0) return; + // record data + if (pRecord) + { + C4PktDebugRec dr(eType, StdBuf(pData, iSize)); + pRecord->Rec(Game.FrameCounter, DecompileToBuf(dr), eType); + } + // check against playback + if (pPlayback) + pPlayback->Check(eType, pData, iSize); } - // check against playback - if (pPlayback) - pPlayback->Check(eType, pData, iSize); -#endif // DEBUGREC } C4ControlDeliveryType C4GameControl::DecideControlDelivery() diff --git a/src/control/C4GameControl.h b/src/control/C4GameControl.h index 85dc82cd1..ebfac9787 100644 --- a/src/control/C4GameControl.h +++ b/src/control/C4GameControl.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2005 Peter Wortmann - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* control management */ @@ -72,7 +69,7 @@ public: protected: C4ControlMode eMode; - bool fPreInit, fInitComplete; + bool fInitComplete; bool fHost; // (set for local, too) bool fActivated; bool fRecordNeeded; diff --git a/src/control/C4GameParameters.cpp b/src/control/C4GameParameters.cpp index dfaaa19c6..b886498ac 100644 --- a/src/control/C4GameParameters.cpp +++ b/src/control/C4GameParameters.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004, 2006-2007, 2009 Sven Eberhardt - * Copyright (c) 2005-2007 Peter Wortmann - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2006, 2009, 2011 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" #include "C4GameParameters.h" @@ -231,7 +226,7 @@ void C4GameResList::LoadFoldersWithLocalDefs(const char *szPath) // if we didn't handle this properly and the user would have no clue what was // going on. See also http://forum.openclonk.org/topic_show.pl?tid=905. char control[3] = { DirectorySeparator, AltDirectorySeparator, '\0' }; - const size_t len = strlen(szPath); + const int32_t len = (int32_t)strlen(szPath); for (int32_t iPrev=0; (iBackslash = strcspn(szPath+iPrev, control) + iPrev) < len; iPrev = iBackslash + 1) #else for (int32_t cnt=0; (iBackslash=SCharPos(DirectorySeparator,szPath,cnt)) > -1; cnt++) diff --git a/src/control/C4GameParameters.h b/src/control/C4GameParameters.h index 7408d81da..f0ad89f40 100644 --- a/src/control/C4GameParameters.h +++ b/src/control/C4GameParameters.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2007 Peter Wortmann - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Game parameters - game data that is valid before the game is started */ diff --git a/src/control/C4GameSave.cpp b/src/control/C4GameSave.cpp index d951444b6..f2034db13 100644 --- a/src/control/C4GameSave.cpp +++ b/src/control/C4GameSave.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2005, 2007-2008 Sven Eberhardt - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2008 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // game saving functionality @@ -68,7 +62,7 @@ bool C4GameSave::SaveCore() rC4S = Game.C4S; // Always mark current engine version rC4S.Head.C4XVer[0]=C4XVER1; rC4S.Head.C4XVer[1]=C4XVER2; - rC4S.Head.C4XVer[2]=C4XVER3; rC4S.Head.C4XVer[3]=C4XVER4; + rC4S.Head.C4XVer[2]=C4XVER3; // Some flags are not to be set for initial settings: // They depend on whether specific runtime data is present, which may simply not be stored into initial // saves, because they rely on any data present and up-to-date within the scenario! @@ -213,7 +207,7 @@ bool C4GameSave::SaveRuntimeData() if (GetSaveUserPlayers() || GetSaveScriptPlayers()) { // player infos - // the stored player info filenames will point into the scenario file, and no ressource information + // the stored player info filenames will point into the scenario file, and no resource information // will be saved. PlayerInfo must be saved first, because those will generate the storage filenames to be used by // C4PlayerList C4PlayerInfoList RestoreInfos; @@ -303,7 +297,7 @@ void C4GameSave::WriteDescGameTime(StdStrBuf &sBuf) void C4GameSave::WriteDescEngine(StdStrBuf &sBuf) { - char ver[5]; sprintf(ver, "%03d", (int) C4XVER4); + char ver[32]; sprintf(ver, "%d.%d.%d", (int)C4XVER1, (int)C4XVER2, (int)C4XVER3); sBuf.AppendFormat(LoadResStr("IDS_DESC_VERSION"), ver); WriteDescLineFeed(sBuf); } @@ -444,7 +438,7 @@ bool C4GameSave::Save(C4Group &hToGroup, bool fKeepGroup) // remove: Title text, image and icon if specified if (!GetKeepTitle()) { - pSaveGroup->Delete(C4CFN_ScenarioTitle); + pSaveGroup->Delete(FormatString("%s.*",C4CFN_ScenarioTitle).getData()); pSaveGroup->Delete(C4CFN_ScenarioIcon); pSaveGroup->Delete(FormatString(C4CFN_ScenarioDesc,"*").getData()); pSaveGroup->Delete(C4CFN_Titles); @@ -545,7 +539,7 @@ void C4GameSaveRecord::AdjustCore(C4Scenario &rC4S) rC4S.Head.Icon=29; // default record title char buf[1024 + 1]; - sprintf(buf, "%03i %s [%d]", iNum, Game.ScenarioTitle.getData(), (int) C4XVER4); + sprintf(buf, "%03i %s [%d.%d.%d]", iNum, Game.ScenarioTitle.getData(), (int)C4XVER1, (int)C4XVER2, (int)C4XVER3); SCopy(buf, rC4S.Head.Title, C4MaxTitle); } diff --git a/src/control/C4GameSave.h b/src/control/C4GameSave.h index e9e7e851f..2a33de6b0 100644 --- a/src/control/C4GameSave.h +++ b/src/control/C4GameSave.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004, 2007 Sven Eberhardt - * Copyright (c) 2008 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // game saving functionality // merely controls what to save when how - actual saving procedures reside in the subclasses diff --git a/src/control/C4PlayerControl.cpp b/src/control/C4PlayerControl.cpp index 0a24a1b1d..08c12a8ac 100644 --- a/src/control/C4PlayerControl.cpp +++ b/src/control/C4PlayerControl.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Sven Eberhardt - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Input to player control mapping @@ -38,9 +34,7 @@ #include -#ifdef DEBUGREC #include "C4Record.h" -#endif /* C4PlayerControlDef */ @@ -195,22 +189,11 @@ void C4PlayerControlAssignment::KeyComboItem::CompileFunc(StdCompiler *pComp) Key.dwShift = 0; sKeyName.Clear(); pComp->Value(mkParAdapt(Key, &sKeyName)); - if (!sKeyName) - { - // key was not assigned during compilation - this means it's a regular key (or undefined) - // store this as the name - UpdateKeyName(); - } - else if (Key.dwShift) - { - // key name and shift was assigned during compilation - keep both in key name for later decompilation - sKeyName.Take(FormatString("%s+%s", C4KeyCodeEx::KeyShift2String((C4KeyShiftState) Key.dwShift).getData(), sKeyName.getData())); - } } else { // decompiler: If there's a stored key name, just write it. Regardless of whether it's a key, undefined or a reference - // IF no key name is stored, it was probably assigned at runtime and sKeyName needs to be recreated + // If no key name is stored, it was probably assigned at runtime and sKeyName needs to be recreated if (!sKeyName) UpdateKeyName(); pComp->Value(mkParAdapt(sKeyName, StdCompiler::RCT_Idtf)); } @@ -220,6 +203,8 @@ void C4PlayerControlAssignment::KeyComboItem::UpdateKeyName() { // update key name from key sKeyName.Copy(Key.ToString(false, false)); + if (Key.dwShift) + sKeyName.Take(FormatString("%s+%s", C4KeyCodeEx::KeyShift2String((C4KeyShiftState) Key.dwShift).getData(), sKeyName.getData())); } void C4PlayerControlAssignment::CompileFunc(StdCompiler *pComp) @@ -228,14 +213,18 @@ void C4PlayerControlAssignment::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(mkSTLContainerAdapt(KeyCombo), "Key", KeyComboVec())); pComp->Value(mkNamingAdapt(fComboIsSequence, "ComboIsSequence", false)); pComp->Value(mkNamingAdapt(mkParAdapt(sControlName, StdCompiler::RCT_Idtf), "Control", "None")); + pComp->Value(mkNamingAdapt(mkParAdapt(sGUIName, StdCompiler::RCT_All), "GUIName", "")); + pComp->Value(mkNamingAdapt(mkParAdapt(sGUIDesc, StdCompiler::RCT_All), "GUIDesc", "")); + pComp->Value(mkNamingAdapt(iGUIGroup,"GUIGroup",0)); + pComp->Value(mkNamingAdapt(fGUIDisabled, "GUIDisabled", false)); pComp->Value(mkNamingAdapt(iPriority, "Priority", 0)); - pComp->Value(mkNamingAdapt(is_group_start, "Group", false)); const StdBitfieldEntry TriggerModeNames[] = { { "Default", CTM_Default }, { "Hold", CTM_Hold }, { "Release", CTM_Release }, { "AlwaysUnhandled", CTM_AlwaysUnhandled }, + { "ClearRecentKeys", CTM_ClearRecentKeys }, { NULL, 0 } }; pComp->Value(mkNamingAdapt(mkBitfieldAdapt< int32_t>(iTriggerMode, TriggerModeNames), "TriggerMode", CTM_Default)); @@ -281,12 +270,13 @@ void C4PlayerControlAssignment::CopyKeyFrom(const C4PlayerControlAssignment &src bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParentSet, C4PlayerControlDefs *pControlDefs) { // avoid circular chains - static C4PlayerControlAssignment *pCircularDetect = NULL; - if (!pCircularDetect) pCircularDetect = this; else if (pCircularDetect == this) + static int32_t recursion_check = 0; + if (recursion_check > 10) { - LogFatal(FormatString("Circular reference chain detected in player control assignments of set %s in assignment for key %s!", pParentSet->GetName(), GetControlName()).getData()); + LogFatal(FormatString("Maximum recursion limit reached while resolving player control assignments of set %s in assignment for key %s. This is probably due to a circular control chain.", pParentSet->GetName(), GetControlName()).getData()); return false; } + ++recursion_check; // resolve control name iControl = pControlDefs->GetControlIndexByIdentifier(sControlName.getData()); // resolve keys @@ -294,21 +284,29 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen for (KeyComboVec::iterator i = KeyCombo.begin(); i != KeyCombo.end(); ++i) { KeyComboItem &rKeyComboItem = *i; - if (rKeyComboItem.Key.Key == KEY_Default && rKeyComboItem.sKeyName.getLength()) + const char *szKeyName = rKeyComboItem.sKeyName.getData(); + // check if this is a key reference. A key reference must be preceded by CON_ + // it may also be preceded by modifiers (Shift+), which are already set in rKeyComboItem.Key.dwShift + bool is_key_reference = false; + int last_shift_delim_pos; + if (szKeyName && *szKeyName) + { + if ((last_shift_delim_pos=SCharLastPos('+', szKeyName)) > -1) szKeyName += last_shift_delim_pos+1; + if (SEqual2(szKeyName, "CON_")) + { + is_key_reference = true; + szKeyName +=4; + } + } + if (is_key_reference) { // this is a key reference - // it may be preceded by modifiers (Shift+), which are already set in rKeyComboItem.Key.dwShift - // it may be preceded by CON_ to avoid ambigous keus - const char *szKeyName = rKeyComboItem.sKeyName.getData(); - int last_shift_delim_pos; - if ((last_shift_delim_pos=SCharLastPos('+', szKeyName)) > -1) szKeyName += last_shift_delim_pos+1; - if (SEqual2(szKeyName, "CON_")) szKeyName +=4; - // - find it + // - find referenced target assignment C4PlayerControlAssignment *pRefAssignment = pParentSet->GetAssignmentByControlName(szKeyName); if (pRefAssignment) { // resolve itself if necessary - if (!pRefAssignment->IsRefsResolved()) if (!pRefAssignment->ResolveRefs(pParentSet, pControlDefs)) return false; + if (!pRefAssignment->IsRefsResolved()) if (!pRefAssignment->ResolveRefs(pParentSet, pControlDefs)) { --recursion_check; return false; } // insert all keys of that combo into own combo // add any extra shift states from reference DWORD ref_shift = rKeyComboItem.Key.dwShift; @@ -335,6 +333,12 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen } else { + // non-reference: check if the assignment was valid +#ifndef USE_CONSOLE + if (rKeyComboItem.Key == KEY_Default) + LogF("WARNING: Control %s of set %s contains undefined key \"%s\".", GetControlName(), pParentSet->GetName(), szKeyName); +#endif + // ...and just keep this item. NewCombo.push_back(rKeyComboItem); } } @@ -343,7 +347,7 @@ bool C4PlayerControlAssignment::ResolveRefs(C4PlayerControlAssignmentSet *pParen if (KeyCombo.size()) TriggerKey = KeyCombo.back().Key; else TriggerKey = C4KeyCodeEx(); // done fRefsResolved = true; - if (pCircularDetect == this) pCircularDetect = NULL; + --recursion_check; return true; } @@ -353,22 +357,28 @@ bool C4PlayerControlAssignment::IsComboMatched(const C4PlayerControlRecentKeyLis // check if combo is currently fulfilled (assuming TriggerKey is already matched) if (fComboIsSequence) { - DWORD tKeyLast = GetTime(); + C4TimeMilliseconds tKeyLast = C4TimeMilliseconds::Now(); // combo is a sequence: The last keys of RecentKeys must match the sequence // the last ComboKey is the TriggerKey, which is omitted because it has already been matched and is not to be found in RecentKeys yet - C4PlayerControlRecentKeyList::const_reverse_iterator ri = RecentKeys.rbegin(); - for (KeyComboVec::const_reverse_iterator i = KeyCombo.rbegin()+1; i!=KeyCombo.rend(); ++i,++ri) + KeyComboVec::const_reverse_iterator i = KeyCombo.rbegin()+1; + for (C4PlayerControlRecentKeyList::const_reverse_iterator ri = RecentKeys.rbegin(); i!=KeyCombo.rend(); ++ri) { // no more keys pressed but combo didn't end? -> no combo match if (ri == RecentKeys.rend()) return false; const C4PlayerControlRecentKey &rk = *ri; // user waited for too long? - DWORD tKeyRecent = rk.tTime; + C4TimeMilliseconds tKeyRecent = rk.tTime; if (tKeyLast - tKeyRecent > C4PlayerControl::MaxSequenceKeyDelay) return false; // key doesn't match? const KeyComboItem &k = *i; - if (!(rk.matched_key == k.Key)) return false; + if (!(rk.matched_key == k.Key)) + { + // mouse movement commands do not break sequences + if (Key_IsMouse(rk.matched_key.Key) && Key_GetMouseEvent(rk.matched_key.Key) == KEY_MOUSE_Move) continue; + return false; + } // key OK + ++i; } } else @@ -395,10 +405,67 @@ bool C4PlayerControlAssignment::operator ==(const C4PlayerControlAssignment &cmp // doesn't compare resolved TriggerKey/iControl return KeyCombo == cmp.KeyCombo && sControlName == cmp.sControlName + && sGUIName == cmp.sGUIName + && sGUIDesc == cmp.sGUIDesc + && fGUIDisabled == cmp.fGUIDisabled && iTriggerMode == cmp.iTriggerMode && iPriority == cmp.iPriority; } +StdStrBuf C4PlayerControlAssignment::GetKeysAsString(bool human_readable, bool short_name) const +{ + // create a short, human-readable string of the assigned key + // to be displayed e.g. in tutorial messages explaining controls + StdStrBuf result; + if (!KeyCombo.size()) return result; + // trigger key + KeyComboVec::const_iterator i=KeyCombo.begin(); + result.Take(i->Key.ToString(human_readable, short_name)); + // extra keys of combo + while (++i != KeyCombo.end()) + { + result.AppendChar(fComboIsSequence ? ',' : '+'); + result.Append(i->Key.ToString(human_readable, short_name)); + } + return result; +} + +const char *C4PlayerControlAssignment::GetGUIName(const C4PlayerControlDefs &defs) const +{ + // local name? + if (sGUIName.getLength()) + { + // special: None defaults to empty name + if (sGUIName == "None") return ""; + return sGUIName.getData(); + } + // otherwise, fall back to def + const C4PlayerControlDef *def = defs.GetControlByIndex(GetControl()); + if (def) return def->GetGUIName(); + // no def and no name... + return NULL; +} + +const char *C4PlayerControlAssignment::GetGUIDesc(const C4PlayerControlDefs &defs) const +{ + // local desc? + if (sGUIDesc.getLength()) return sGUIDesc.getData(); + // otherwise, fall back to def + const C4PlayerControlDef *def = defs.GetControlByIndex(GetControl()); + if (def) return def->GetGUIDesc(); + // no def and no desc... + return NULL; +} + +bool C4PlayerControlAssignment::IsGUIDisabled() const +{ + return fGUIDisabled; +} + +int32_t C4PlayerControlAssignment::GetGUIGroup() const +{ + return iGUIGroup; +} /* C4PlayerControlAssignmentSet */ @@ -426,6 +493,8 @@ void C4PlayerControlAssignmentSet::CompileFunc(StdCompiler *pComp) pComp->NameEnd(); } + + void C4PlayerControlAssignmentSet::MergeFrom(const C4PlayerControlAssignmentSet &Src, MergeMode merge_mode) { // take over all assignments defined in Src @@ -506,6 +575,9 @@ void C4PlayerControlAssignmentSet::RemoveAssignmentByControlName(const char *con bool C4PlayerControlAssignmentSet::ResolveRefs(C4PlayerControlDefs *pDefs) { + // reset all resolved flags to allow re-resolve after overloads + for (C4PlayerControlAssignmentVec::iterator i = Assignments.begin(); i != Assignments.end(); ++i) + (*i).ResetRefsResolved(); // resolve in order; ignore already resolved because they might have been resolved by cross reference for (C4PlayerControlAssignmentVec::iterator i = Assignments.begin(); i != Assignments.end(); ++i) if (!(*i).IsRefsResolved()) @@ -906,7 +978,7 @@ void C4PlayerControl::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(Sync, "PlayerControl", DefaultSync)); } -bool C4PlayerControl::ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, bool fUp, const C4KeyEventData &rKeyExtraData, bool reset_down_states_only) +bool C4PlayerControl::ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, bool fUp, const C4KeyEventData &rKeyExtraData, bool reset_down_states_only, bool *clear_recent_keys) { // collect all matching keys C4PlayerControlAssignmentPVec Matches; @@ -922,6 +994,8 @@ bool C4PlayerControl::ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4Ke const C4PlayerControlDef *pControlDef = ControlDefs.GetControlByIndex(iControlIndex); if (pControlDef && pControlDef->IsValid() && !Sync.IsControlDisabled(iControlIndex) && (!fUp || pControlDef->IsHoldKey())) { + // clear RecentKeys if requested by this assignment. Must be done before sync queue, so multiple combos can be issued in a single control frame. + if (clear_recent_keys && (pAssignment->GetTriggerMode() & C4PlayerControlAssignment::CTM_ClearRecentKeys)) *clear_recent_keys = true; // extra data from key or overwrite by current cursor pos if definition requires it if (pControlDef->IsAsync() && !pControlPacket) { @@ -959,15 +1033,19 @@ bool C4PlayerControl::ProcessKeyDown(const C4KeyCodeEx &pressed_key, const C4Key { // add key to local "down" list if it's not already in there // except for some mouse events for which a down state does not make sense - C4PlayerControlRecentKey RKey(pressed_key,matched_key,GetTime()); + C4PlayerControlRecentKey RKey(pressed_key,matched_key,C4TimeMilliseconds::Now()); if (!Key_IsMouse(pressed_key.Key) || Inside(Key_GetMouseEvent(pressed_key.Key), KEY_MOUSE_Button1, KEY_MOUSE_ButtonMax)) { if (std::find(DownKeys.begin(), DownKeys.end(), pressed_key) == DownKeys.end()) DownKeys.push_back(RKey); } // process! - bool fResult = ProcessKeyEvent(pressed_key, matched_key, false, Game.KeyboardInput.GetLastKeyExtraData()); - // add to recent list unless repeated - if (!pressed_key.IsRepeated()) RecentKeys.push_back(RKey); + bool clear_recent_keys = false; + bool fResult = ProcessKeyEvent(pressed_key, matched_key, false, Game.KeyboardInput.GetLastKeyExtraData(), false, &clear_recent_keys); + // unless assignment requests a clear, always add keys to recent list even if not handled + if (clear_recent_keys) + RecentKeys.clear(); + else if (!pressed_key.IsRepeated()) // events caused by holding down the key are not added to recent list (so you cannot cause "double-Q" just by holding down Q) + RecentKeys.push_back(RKey); return fResult; } @@ -995,12 +1073,13 @@ void C4PlayerControl::ExecuteControlPacket(const class C4ControlPlayerControl *p const C4PlayerControlDef *pCtrlDef = ControlDefs.GetControlByIndex(rItem.iControl); if (pCtrlDef) { -#ifdef DEBUGREC - if (pCtrlDef->IsSync()) + if (Config.General.DebugRec) { - AddDbgRec(RCT_PlrCom, &rItem.iControl, sizeof(rItem.iControl)); + if (pCtrlDef->IsSync()) + { + AddDbgRec(RCT_PlrCom, &rItem.iControl, sizeof(rItem.iControl)); + } } -#endif if (ExecuteControl(rItem.iControl, pCtrl->IsReleaseControl(), pCtrl->GetExtraData(), rItem.iTriggerMode, false, fHandleDownStateOnly)) if (pCtrlDef->IsSync()) { @@ -1204,8 +1283,8 @@ void C4PlayerControl::Execute() } } // cleanup old recent keys + C4TimeMilliseconds tNow = C4TimeMilliseconds::Now(); C4PlayerControlRecentKeyList::iterator irk; - DWORD tNow = GetTime(); for (irk = RecentKeys.begin(); irk != RecentKeys.end(); ++irk) { C4PlayerControlRecentKey &rk = *irk; diff --git a/src/control/C4PlayerControl.h b/src/control/C4PlayerControl.h index 7caf4fbf7..4c3a60732 100644 --- a/src/control/C4PlayerControl.h +++ b/src/control/C4PlayerControl.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Sven Eberhardt - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Input to player control mapping @@ -24,6 +21,7 @@ #include "C4KeyboardInput.h" #include "C4LangStringTable.h" #include "C4Id.h" +#include "C4TimeMilliseconds.h" #include @@ -133,8 +131,8 @@ public: struct C4PlayerControlRecentKey { C4KeyCodeEx pressed_key, matched_key; - DWORD tTime; - C4PlayerControlRecentKey(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, DWORD tTime) : pressed_key(pressed_key), matched_key(matched_key), tTime(tTime) {} + C4TimeMilliseconds tTime; + C4PlayerControlRecentKey(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, C4TimeMilliseconds tTime) : pressed_key(pressed_key), matched_key(matched_key), tTime(tTime) {} bool operator ==(const C4KeyCodeEx &cmp) { return pressed_key==cmp; } // comparison op for finding items in lists: Search for the pressed key only }; @@ -155,7 +153,7 @@ private: StdCopyStrBuf sKeyName; void CompileFunc(StdCompiler *pComp); void UpdateKeyName(); - bool operator ==(const KeyComboItem &cmp) const { return sKeyName==cmp.sKeyName; } + bool operator ==(const KeyComboItem &cmp) const { return Key==cmp.Key; } }; typedef std::vector KeyComboVec; KeyComboVec KeyCombo; @@ -165,10 +163,13 @@ private: C4KeyCodeEx TriggerKey; StdCopyStrBuf sControlName; // name of the control to be executed on this key + StdCopyStrBuf sGUIName; // name as displayed to player. If empty, name stored in control def should be used. + StdCopyStrBuf sGUIDesc; // key description displayed to player in config dialog. If empty, name stored in control def should be used. + bool fGUIDisabled; // whether this key can't be reassigned through the GUI dialogue + int32_t iGUIGroup; // in which this control is grouped in the gui int32_t iControl; // the control to be executed on this key, i.e. the resolved sControlName int32_t iPriority; // higher priority assignments get handled first bool fOverrideAssignments; // override all other assignments to the same key? - bool is_group_start; // true for first assignment in a group (for grouping in control config list box) const C4PlayerControlAssignment *inherited_assignment; // valid for assignments that were copied from a parent: source assignment bool is_inherited; // set for assignments that were copied from a parent set without modification @@ -181,7 +182,8 @@ public: CTM_Hold= 1<<0, // the control will be put into "down"-mode CTM_Release= 1<<1, // the hold mode of the control will be released CTM_AlwaysUnhandled= 1<<2, // the key will not block handling of other keys even if it got handled - CTM_HandleDownStatesOnly = 1<<3 // used when an already handled release key is processed to reset down states of overridden keys only + CTM_HandleDownStatesOnly = 1<<3, // used when an already handled release key is processed to reset down states of overridden keys only + CTM_ClearRecentKeys = 1<<4 // if this assignment is triggered, RecentKeys are reset so no more combos can be generated }; private: @@ -190,7 +192,7 @@ private: bool fRefsResolved; // set to true after sControlName and sKeyNames have been resolved to runtime values public: - C4PlayerControlAssignment() : TriggerKey(), iControl(CON_None), iPriority(0), fOverrideAssignments(false), iTriggerMode(CTM_Default), fRefsResolved(false), inherited_assignment(NULL),is_inherited(false), is_group_start(false) {} + C4PlayerControlAssignment() : TriggerKey(), iControl(CON_None), iPriority(0), fOverrideAssignments(false), iTriggerMode(CTM_Default), fRefsResolved(false), inherited_assignment(NULL),is_inherited(false), iGUIGroup(0) {} ~C4PlayerControlAssignment() {} void CompileFunc(StdCompiler *pComp); @@ -208,8 +210,12 @@ public: bool operator <(const C4PlayerControlAssignment &cmp) const { return iPriority > cmp.iPriority; } // assignments are processed in DESCENDING priority! const char *GetControlName() const { return sControlName.getData(); } int32_t GetControl() const { return iControl; } - bool IsGroupStart() const { return is_group_start; } + const char *GetGUIName(const C4PlayerControlDefs &defs) const; + const char *GetGUIDesc(const C4PlayerControlDefs &defs) const; + bool IsGUIDisabled() const; + int32_t GetGUIGroup() const; bool IsRefsResolved() const { return fRefsResolved; } + void ResetRefsResolved() { fRefsResolved = false; } // Mark references to other assignments as not resolved bool IsAlwaysUnhandled() const { return !!(iTriggerMode & CTM_AlwaysUnhandled); } int32_t GetTriggerMode() const { return iTriggerMode; } const C4KeyCodeEx &GetTriggerKey() const { return TriggerKey; } @@ -217,6 +223,7 @@ public: bool IsOverrideAssignments() const { return fOverrideAssignments; } bool IsInherited() const { return is_inherited; } const C4PlayerControlAssignment *GetInheritedAssignment() const { return inherited_assignment; } + StdStrBuf GetKeysAsString(bool human_readable, bool short_name) const; }; typedef std::vector C4PlayerControlAssignmentVec; @@ -229,7 +236,8 @@ class C4PlayerControlAssignmentSet private: StdCopyStrBuf sName, sGUIName, sParentSetName; const C4PlayerControlAssignmentSet *parent_set; - C4PlayerControlAssignmentVec Assignments; + C4PlayerControlAssignmentVec Assignments; // ordered by priority + bool has_keyboard; bool has_mouse; bool has_gamepad; @@ -253,7 +261,7 @@ public: const char *GetGUIName() const { return sGUIName.getData(); } bool IsWildcardName() const { return IsWildcardString(sName.getData()); } - C4PlayerControlAssignment *GetAssignmentByIndex(int32_t index); + C4PlayerControlAssignment *GetAssignmentByIndex(int32_t index); // assignments are ordered by priority C4PlayerControlAssignment *GetAssignmentByControlName(const char *szControlName); C4PlayerControlAssignment *GetAssignmentByControl(int32_t control); void GetAssignmentsByKey(const C4PlayerControlDefs &rDefs, const C4KeyCodeEx &key, bool fHoldKeysOnly, C4PlayerControlAssignmentPVec *pOutVec, const C4PlayerControlRecentKeyList &DownKeys, const C4PlayerControlRecentKeyList &RecentKeys) const; // match only by TriggerKey (last key of Combo) if fHoldKeysOnly @@ -376,7 +384,7 @@ private: CSync Sync; // callbacks from Game.KeyboardInput - bool ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, bool fUp, const C4KeyEventData &rKeyExtraData, bool reset_down_states_only=false); + bool ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, bool fUp, const C4KeyEventData &rKeyExtraData, bool reset_down_states_only=false, bool *clear_recent_keys=NULL); bool ProcessKeyDown(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key); bool ProcessKeyUp(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key); diff --git a/src/control/C4PlayerInfo.cpp b/src/control/C4PlayerInfo.cpp index 3f31f377b..268672c6b 100644 --- a/src/control/C4PlayerInfo.cpp +++ b/src/control/C4PlayerInfo.cpp @@ -1,26 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2004-2008, 2010 Sven Eberhardt - * Copyright (c) 2005-2007 Peter Wortmann - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2007 Julian Raschke - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2004-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2004-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // permanent player information management // see header for some additional information @@ -90,11 +82,11 @@ bool C4PlayerInfo::LoadFromLocalFile(const char *szFilename) this->szFilename = szFilename; dwColor = dwOriginalColor = 0xff000000 | (C4P.PrefColorDw & 0xffffff); // ignore alpha dwAlternateColor = 0xff000000 | (C4P.PrefColor2Dw & 0xffffff); // ignore alpha - // network: ressource (not for replays, because everyone has the player files there...) + // network: resource (not for replays, because everyone has the player files there...) if (::Network.isEnabled() && !Game.C4S.Head.Replay) { - // add ressource - // 2do: rejoining players need to update their ressource version when saving the player + // add resource + // 2do: rejoining players need to update their resource version when saving the player // otherwise, player file versions may differ pRes = ::Network.ResList.getRefRes(szFilename, true); // not found? add @@ -126,9 +118,9 @@ bool C4PlayerInfo::SetAsScriptPlayer(const char *szName, uint32_t dwColor, uint3 const char *C4PlayerInfo::GetLocalJoinFilename() const { - // preferred: by ressource + // preferred: by resource if (pRes) return pRes->getFile(); - // if no ressource is known (replay or non-net), return filename + // if no resource is known (replay or non-net), return filename return szFilename.getData(); } @@ -297,8 +289,8 @@ void C4PlayerInfo::LoadResource() if (IsRemoved() || !(dwFlags & PIF_HasRes) || pRes) return; // Ignore res if a local file is to be used // the PIF_InScenarioFile is not set for startup players in initial replays, - // because ressources are used for player joins but emulated in playback control - // if there will ever be ressources in replay mode, this special case can be removed + // because resources are used for player joins but emulated in playback control + // if there will ever be resources in replay mode, this special case can be removed if (Game.C4S.Head.Replay || (dwFlags & PIF_InScenarioFile)) dwFlags &= ~PIF_HasRes; else @@ -306,7 +298,7 @@ void C4PlayerInfo::LoadResource() if (!(pRes = ::Network.ResList.AddByCore(ResCore))) { dwFlags &= ~PIF_HasRes; - // add failed? invalid ressource??! -- TODO: may be too large to load + // add failed? invalid resource??! -- TODO: may be too large to load LogF("Error: Could not add resource %d for player %s! Player file too large to load?", (int) ResCore.getID(), (const char *) GetFilename()); } } @@ -406,11 +398,17 @@ C4ClientPlayerInfos::C4ClientPlayerInfos(const char *szJoinFilenames, bool fAdd, { C4PlayerInfo *pNewInfo = new C4PlayerInfo(); if (pNewInfo->LoadFromLocalFile(szPlrFile)) + { // player def loaded; register and count it ppPlayers[iPlayerCount++] = pNewInfo; + } else + { // loading failure; clear info class delete pNewInfo; + // + LogFatal(FormatString(LoadResStr("IDS_ERR_LOAD_PLAYER"), szPlrFile).getData()); + } } } if (pAddInfo) @@ -608,7 +606,7 @@ C4PlayerInfo *C4ClientPlayerInfos::GetPlayerInfoByRes(int32_t idResID) const { if ((pRes = (*ppCurrPlrInfo)->GetRes())) if (pRes->getResID() == idResID) - // only if the player is actually using the ressource + // only if the player is actually using the resource if ((*ppCurrPlrInfo)->IsUsingPlayerFile()) return *ppCurrPlrInfo; ++ppCurrPlrInfo; @@ -1493,7 +1491,7 @@ bool C4PlayerInfoList::RecreatePlayerFiles() else { // regular player in savegame being resumed in network or normal mode: - // the filenames and/or ressources should have been assigned + // the filenames and/or resources should have been assigned // a) either in lobby mode during player re-acquisition // b) or when players from rSavegamePlayers were taken over } @@ -1552,7 +1550,7 @@ bool C4PlayerInfoList::RecreatePlayers(C4ValueNumbers * numbers) { // get filename to join from const char *szFilename = pInfo->GetLocalJoinFilename(); - // ensure ressource is loaded, if joining from ressource + // ensure resource is loaded, if joining from resource // this may display a waiting dialog and block the thread for a while C4Network2Res *pJoinRes = pInfo->GetRes(); if (szFilename && pJoinRes && pJoinRes->isLoading()) @@ -1567,7 +1565,7 @@ bool C4PlayerInfoList::RecreatePlayers(C4ValueNumbers * numbers) { if (pInfo->GetType() == C4PT_User) { - // for user players, this could happen only if the user cancelled the ressource + // for user players, this could happen only if the user cancelled the resource const char *szPlrName = pInfo->GetName(); if (!szPlrName) szPlrName = "???"; LogF(LoadResStr("IDS_ERR_LOAD_RECR_NOFILEFROMNET"), szPlrName); continue; diff --git a/src/control/C4PlayerInfo.h b/src/control/C4PlayerInfo.h index 4deeac258..b11bcad37 100644 --- a/src/control/C4PlayerInfo.h +++ b/src/control/C4PlayerInfo.h @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2008 Sven Eberhardt - * Copyright (c) 2005-2007 Peter Wortmann - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2004-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2004-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // permanent player information management // @@ -24,7 +20,7 @@ // This list is used for: // -player information to be known before actual join // (player count for landscape width, team, color, etc.) -// -player file ressource association (network mode) +// -player file resource association (network mode) // -league information to be stored for each player; even after elimination // *-startup loader screen information; e.g. for replays // @@ -119,12 +115,12 @@ public: void SetColor(DWORD dwUseClr) { dwColor = dwUseClr; } // set color to be used void SetOriginalColor(DWORD dwUseClr) { dwOriginalColor = dwUseClr; } // set color the player wishes to have void SetFilename(const char *szToFilename); // set new player filename - void SetToScenarioFilename(const char *szScenFilename); // set to file within scenario; discard ressource + void SetToScenarioFilename(const char *szScenFilename); // set to file within scenario; discard resource void SetTempFile() { assert(!!szFilename); dwFlags |= PIF_TempFile; } // mark filename as temp, so it is deleted in dtor or after join void SetTeam(int32_t idToTeam) { idTeam = idToTeam; } void DeleteTempFile(); // delete filename if temp void LoadResource(); // network: Load resource if present and not being loaded yet - void DiscardResource(); // delete any source ressource for network player infos + void DiscardResource(); // delete any source resource for network player infos void SetAssociatedSavegamePlayer(int32_t aidSavegamePlayer) // link with savegame player from restore list { idSavegamePlayer=aidSavegamePlayer; } int32_t GetAssociatedSavegamePlayerID() const @@ -160,7 +156,7 @@ public: StdStrBuf GetLobbyName() const; // return player name including clan/team tag if known; fallback to regular player name const char *GetFilename() const { return szFilename.getData(); } // get filename for local games const char *GetLocalJoinFilename() const; // get name of file to join the player from - C4Network2Res *GetRes() const { return pRes; } // get player ressource for network games + C4Network2Res *GetRes() const { return pRes; } // get player resource for network games bool IsRemoved() const { return !!(dwFlags & PIF_Removed); } bool HasJoined() const { return !!(dwFlags & PIF_Joined); } // return whether player has joined bool IsJoined() const { return HasJoined() && !(dwFlags & PIF_Removed); } // return whether player is currently in the game @@ -250,7 +246,7 @@ public: C4PlayerInfo *GetPlayerInfo(int32_t iIndex) const; // get indexed player info C4PlayerInfo *GetPlayerInfo(int32_t iIndex, C4PlayerType eType) const; // get indexed player info of given type C4PlayerInfo *GetPlayerInfoByID(int32_t id) const; // get player info by unique player ID - C4PlayerInfo *GetPlayerInfoByRes(int32_t idResID) const; // get player info by ressource ID + C4PlayerInfo *GetPlayerInfoByRes(int32_t idResID) const; // get player info by resource ID int32_t GetClientID() const { return iClientID; } // get target client ID bool HasUnjoinedPlayers() const; // check all players and return whether one of them didn't join int32_t GetJoinedPlayerCount() const; // return number of players that are IsJoined() diff --git a/src/control/C4PlayerInfoConflicts.cpp b/src/control/C4PlayerInfoConflicts.cpp index 68127d8b9..ae8d74387 100644 --- a/src/control/C4PlayerInfoConflicts.cpp +++ b/src/control/C4PlayerInfoConflicts.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2007 Sven Eberhardt - * Copyright (c) 2005 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // player info attribute conflict resolving // e.g., changing colors if two players have the same diff --git a/src/control/C4Record.cpp b/src/control/C4Record.cpp index 6bb861c79..24bca59e1 100644 --- a/src/control/C4Record.cpp +++ b/src/control/C4Record.cpp @@ -1,24 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001-2002, 2004-2007, 2011 Sven Eberhardt - * Copyright (c) 2004-2008 Peter Wortmann - * Copyright (c) 2005-2009 Günther Brammer - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Julius Michaelis - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // scenario record functionality @@ -37,20 +30,13 @@ #define IMMEDIATEREC -//#define DEBUGREC_EXTFILE "DbgRec.ocb" // if defined, an external file is used for debugrec writing (replays only) -//#define DEBUGREC_EXTFILE_WRITE // if defined, the external file is used for debugrec writing. Otherwise read/check - -#ifdef DEBUGREC -#ifdef DEBUGREC_EXTFILE CStdFile DbgRecFile; -#endif int DoNoDebugRec=0; // debugrec disable counter void AddDbgRec(C4RecordChunkType eType, const void *pData, int iSize) { ::Control.DbgRec(eType, (const uint8_t *) pData, iSize); } -#endif C4DebugRecOff::C4DebugRecOff() : fDoOff(true) { @@ -216,9 +202,8 @@ bool C4Record::Stop(StdStrBuf *pRecordName, BYTE *pRecordSHA1) LogRec.Close(); // pack group -#ifndef DEBUGREC - if (!C4Group_PackDirectory(sFilename.getData())) return false; -#endif + if (!Config.General.DebugRec) + if (!C4Group_PackDirectory(sFilename.getData())) return false; // return record data if (pRecordName) @@ -409,9 +394,14 @@ bool C4Playback::Open(C4Group &rGrp) { // clean up Clear(); - fLoadSequential = !rGrp.IsPacked(); iLastSequentialFrame = 0; bool fStrip = false; + + // open group? Then do some sequential reading for large files + // Can't do this when a dump is forced, because the dump needs all data + // Also can't do this when stripping is desired + fLoadSequential = !rGrp.IsPacked() && !Game.RecordDumpFile.getLength() && !fStrip; + // get text record file StdStrBuf TextBuf; if (rGrp.LoadEntryString(C4CFN_CtrlRecText, &TextBuf)) @@ -421,10 +411,6 @@ bool C4Playback::Open(C4Group &rGrp) } else { - // open group? Then do some sequential reading for large files - // Can't do this when a dump is forced, because the dump needs all data - // Also can't do this when stripping is desired - if (!rGrp.IsPacked()) if (!Game.RecordDumpFile.getLength()) if (!fStrip) fLoadSequential = true; // get record file if (fLoadSequential) { @@ -501,23 +487,27 @@ bool C4Playback::Open(C4Group &rGrp) currChunk = chunks.begin(); Finished = false; // external debugrec file -#if defined(DEBUGREC_EXTFILE) && defined(DEBUGREC) -#ifdef DEBUGREC_EXTFILE_WRITE - if (!DbgRecFile.Create(DEBUGREC_EXTFILE)) + if (Config.General.DebugRecExternalFile[0] && Config.General.DebugRec) { - LogFatal("DbgRec: Creation of external file \"" DEBUGREC_EXTFILE "\" failed!"); - return false; + if (Config.General.DebugRecWrite) + { + if (!DbgRecFile.Create(Config.General.DebugRecExternalFile)) + { + LogFatal(FormatString("DbgRec: Creation of external file \"%s\" failed!", Config.General.DebugRecExternalFile).getData()); + return false; + } + else LogF("DbgRec: Writing to \"%s\"...", Config.General.DebugRecExternalFile); + } + else + { + if (!DbgRecFile.Open(Config.General.DebugRecExternalFile)) + { + LogFatal(FormatString("DbgRec: Opening of external file \"%s\" failed!", Config.General.DebugRecExternalFile).getData()); + return false; + } + else LogF("DbgRec: Checking against \"%s\"...", Config.General.DebugRecExternalFile); + } } - else Log("DbgRec: Writing to \"" DEBUGREC_EXTFILE "\"..."); -#else - if (!DbgRecFile.Open(DEBUGREC_EXTFILE)) - { - LogFatal("DbgRec: Opening of external file \"" DEBUGREC_EXTFILE "\" failed!"); - return false; - } - else Log("DbgRec: Checking against \"" DEBUGREC_EXTFILE "\"..."); -#endif -#endif // ok return true; } @@ -860,11 +850,12 @@ bool C4Playback::ExecuteControl(C4Control *pCtrl, int iFrame) // still playbacking? if (currChunk == chunks.end()) return false; if (Finished) { Finish(); return false; } -#ifdef DEBUGREC - if (DebugRec.firstPkt()) - DebugRecError("Debug rec overflow!"); - DebugRec.Clear(); -#endif + if (Config.General.DebugRec) + { + if (DebugRec.firstPkt()) + DebugRecError("Debug rec overflow!"); + DebugRec.Clear(); + } // return all control until this frame while (currChunk != chunks.end() && currChunk->Frame <= iFrame) { @@ -887,28 +878,22 @@ bool C4Playback::ExecuteControl(C4Control *pCtrl, int iFrame) Finished=true; break; -#ifdef DEBUGREC default: // expect it to be debug rec - // append to debug rec buffer - if (currChunk->pDbg) + if (Config.General.DebugRec) { - DebugRec.Add(CID_DebugRec, currChunk->pDbg); - // the debugrec buffer is now responsible for deleting the packet - currChunk->pDbg = NULL; + // append to debug rec buffer + if (currChunk->pDbg) + { + DebugRec.Add(CID_DebugRec, currChunk->pDbg); + // the debugrec buffer is now responsible for deleting the packet + currChunk->pDbg = NULL; + } + break; } - break; -#endif - } // next chunk NextChunk(); } - // Debug log -#ifdef DEBUGREC - //sprintf(OSTR, "-- Frame %d:", Game.FrameCounter); Log(OSTR); - //char Indent[256+1]; strcpy(Indent, ""); - //pCtrl->deb_print(Indent); -#endif return true; } @@ -937,13 +922,13 @@ void C4Playback::Clear() playbackFile.Close(); sequentialBuffer.Clear(); fLoadSequential = false; -#ifdef DEBUGREC - C4IDPacket *pkt; - while (pkt = DebugRec.firstPkt()) DebugRec.Delete(pkt); -#ifdef DEBUGREC_EXTFILE - DbgRecFile.Close(); -#endif -#endif + if (Config.General.DebugRec) + { + C4IDPacket *pkt; + while (pkt = DebugRec.firstPkt()) DebugRec.Delete(pkt); + if (Config.General.DebugRecExternalFile[0]) + DbgRecFile.Close(); + } // done Finished = true; } @@ -1012,7 +997,6 @@ StdStrBuf GetDbgRecPktData(C4RecordChunkType eType, const StdBuf & RawData) return r; } -#ifdef DEBUGREC void C4Playback::Check(C4RecordChunkType eType, const uint8_t *pData, int iSize) { // only if enabled @@ -1021,66 +1005,72 @@ void C4Playback::Check(C4RecordChunkType eType, const uint8_t *pData, int iSize) C4PktDebugRec PktInReplay; bool fHasPacketFromHead = false; -#ifdef DEBUGREC_EXTFILE -#ifdef DEBUGREC_EXTFILE_WRITE - // writing of external debugrec file - DbgRecFile.Write(&eType, sizeof eType); - int32_t iSize32 = iSize; - DbgRecFile.Write(&iSize32, sizeof iSize32); - DbgRecFile.Write(pData, iSize); - return; -#else - int32_t iSize32 = 0; - C4RecordChunkType eTypeRec = RCT_Undefined; - DbgRecFile.Read(&eTypeRec, sizeof eTypeRec); - DbgRecFile.Read(&iSize32, sizeof iSize32); - if (iSize32) + if (Config.General.DebugRecExternalFile[0]) { - StdBuf buf; - buf.SetSize(iSize32); - DbgRecFile.Read(buf.getMData(), iSize32); - PktInReplay = C4PktDebugRec(eTypeRec, buf); - } -#endif -#else - // check debug rec in list - C4IDPacket *pkt; - if (pkt = DebugRec.firstPkt()) - { - // copy from list - PktInReplay = *static_cast(pkt->getPkt()); - DebugRec.Delete(pkt); + if (Config.General.DebugRecWrite) + { + // writing of external debugrec file + DbgRecFile.Write(&eType, sizeof eType); + int32_t iSize32 = iSize; + DbgRecFile.Write(&iSize32, sizeof iSize32); + DbgRecFile.Write(pData, iSize); + return; + } + else + { + int32_t iSize32 = 0; + C4RecordChunkType eTypeRec = RCT_Undefined; + DbgRecFile.Read(&eTypeRec, sizeof eTypeRec); + DbgRecFile.Read(&iSize32, sizeof iSize32); + if (iSize32) + { + StdBuf buf; + buf.SetSize(iSize32); + DbgRecFile.Read(buf.getMData(), iSize32); + PktInReplay = C4PktDebugRec(eTypeRec, buf); + } + } } else { - // special sync check skip... - while (currChunk != chunks.end() && currChunk->Type == RCT_CtrlPkt) + // check debug rec in list + C4IDPacket *pkt; + if (pkt = DebugRec.firstPkt()) { - C4IDPacket Packet(*currChunk->pPkt); - C4ControlPacket *pCtrlPck = static_cast(Packet.getPkt()); - assert(!pCtrlPck->Sync()); - ::Control.ExecControlPacket(Packet.getPktType(), pCtrlPck); - NextChunk(); + // copy from list + PktInReplay = *static_cast(pkt->getPkt()); + DebugRec.Delete(pkt); } - // record end? - if (currChunk == chunks.end() || currChunk->Type == RCT_End || Finished) + else { - Log("DebugRec end: All in sync!"); - ++DoNoDebugRec; - return; - } - // unpack directly from head - if (currChunk->Type != eType) - { - DebugRecError(FormatString("Playback type %x, this type %x", currChunk->Type, eType).getData()); - return; - } - if (currChunk->pDbg) - PktInReplay = *currChunk->pDbg; + // special sync check skip... + while (currChunk != chunks.end() && currChunk->Type == RCT_CtrlPkt) + { + C4IDPacket Packet(*currChunk->pPkt); + C4ControlPacket *pCtrlPck = static_cast(Packet.getPkt()); + assert(!pCtrlPck->Sync()); + ::Control.ExecControlPacket(Packet.getPktType(), pCtrlPck); + NextChunk(); + } + // record end? + if (currChunk == chunks.end() || currChunk->Type == RCT_End || Finished) + { + Log("DebugRec end: All in sync!"); + ++DoNoDebugRec; + return; + } + // unpack directly from head + if (currChunk->Type != eType) + { + DebugRecError(FormatString("Playback type %x, this type %x", currChunk->Type, eType).getData()); + return; + } + if (currChunk->pDbg) + PktInReplay = *currChunk->pDbg; - fHasPacketFromHead = true; + fHasPacketFromHead = true; + } } -#endif // DEBUGREC_EXTFILE // record end? if (PktInReplay.getType() == RCT_End) { @@ -1121,7 +1111,6 @@ void C4Playback::DebugRecError(const char *szError) LogF("Playback error: %s", szError); BREAKPOINT_HERE; } -#endif bool C4Playback::StreamToRecord(const char *szStream, StdStrBuf *pRecordFile) { diff --git a/src/control/C4Record.h b/src/control/C4Record.h index 573b9a423..cc40605de 100644 --- a/src/control/C4Record.h +++ b/src/control/C4Record.h @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001-2002, 2004-2007 Sven Eberhardt - * Copyright (c) 2004-2006, 2008 Peter Wortmann - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // scenario record functionality @@ -27,17 +23,11 @@ class C4Record; #include "C4Group.h" #include "C4Control.h" -#ifdef DEBUGREC extern int DoNoDebugRec; // debugrec disable counter in C4Record.cpp #define DEBUGREC_OFF ++DoNoDebugRec; #define DEBUGREC_ON --DoNoDebugRec; -#else -#define DEBUGREC_OFF -#define DEBUGREC_ON -#endif - // turn off debugrecs in current block class C4DebugRecOff { @@ -93,15 +83,14 @@ enum C4RecordChunkType // record file chunk type RCT_OCF = 0xA3, // OCF setting of updating RCT_DirectExec = 0xA4, // a DirectExec-script RCT_Definition = 0xA5, // Definition callback + RCT_SetProperty= 0xA6, // set a property in a proplist RCT_Custom = 0xc0, // varies RCT_Undefined = 0xff }; -#ifdef DEBUGREC void AddDbgRec(C4RecordChunkType eType, const void *pData=NULL, int iSize=0); // record debug stuff -#endif #pragma pack(1) @@ -305,9 +294,7 @@ private: StdBuf sequentialBuffer; // buffer to manage sequential reads uint32_t iLastSequentialFrame; // frame number of last chunk read void Finish(); // end playback -#ifdef DEBUGREC C4PacketList DebugRec; -#endif public: C4Playback(); // constructor; init playback ~C4Playback(); // destructor; deinit playback @@ -323,11 +310,9 @@ public: bool ExecuteControl(C4Control *pCtrl, int iFrame); // assign control bool IsFinished() { return Finished; } void Clear(); -#ifdef DEBUGREC void Check(C4RecordChunkType eType, const uint8_t *pData, int iSize); // compare with debugrec void DebugRecError(const char *szError); -#endif static bool StreamToRecord(const char *szStream, StdStrBuf *pRecord); }; -#endif +#endif \ No newline at end of file diff --git a/src/control/C4RoundResults.cpp b/src/control/C4RoundResults.cpp index e4ea403ce..a6030e09b 100644 --- a/src/control/C4RoundResults.cpp +++ b/src/control/C4RoundResults.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004, 2008-2009 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2008 Julian Raschke - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2011 Maikel de Vries - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Round result information to be displayed in game over dialog diff --git a/src/control/C4RoundResults.h b/src/control/C4RoundResults.h index 0f6347f8b..b9bba5600 100644 --- a/src/control/C4RoundResults.h +++ b/src/control/C4RoundResults.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2008-2009 Sven Eberhardt - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Round result information to be displayed in game over dialog // Collects information from: @@ -32,8 +29,6 @@ #include "C4PacketBase.h" #include "C4FacetEx.h" -class C4Player; - // Contains additional data not present in C4PlayerInfo class C4RoundResultsPlayer { diff --git a/src/control/C4Teams.cpp b/src/control/C4Teams.cpp index 48d12b122..fa6131f86 100644 --- a/src/control/C4Teams.cpp +++ b/src/control/C4Teams.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2009 Sven Eberhardt - * Copyright (c) 2005-2006 Peter Wortmann - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // player team management for teamwork melees @@ -78,7 +72,7 @@ void C4Team::AddPlayer(C4PlayerInfo &rInfo, bool fAdjustPlayer) if (rInfo.IsJoined()) { C4Player *pJoinedPlr = ::Players.GetByInfoID(rInfo.GetID()); - assert(pJoinedPlr); + assert(pJoinedPlr || (rInfo.GetType() == C4PT_Script)); if (pJoinedPlr) { pJoinedPlr->Team = GetID(); diff --git a/src/control/C4Teams.h b/src/control/C4Teams.h index 915ceb90b..270e5ae38 100644 --- a/src/control/C4Teams.h +++ b/src/control/C4Teams.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2007 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // player team management for teamwork melees @@ -23,12 +20,6 @@ #include "C4InputValidation.h" -class C4Group; - -// class predec -class C4TeamList; -namespace C4GUI { class ComboBox_FillCB; } - // constant used by lobby to indicate invisible, random team const int32_t TEAMID_Unknown = -1; diff --git a/src/editor/C4Console.cpp b/src/editor/C4Console.cpp index 9881bccec..395170ae9 100644 --- a/src/editor/C4Console.cpp +++ b/src/editor/C4Console.cpp @@ -1,26 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003-2004, 2008 Matthes Bender - * Copyright (c) 2001-2002, 2004-2007 Sven Eberhardt - * Copyright (c) 2004, 2007, 2009 Peter Wortmann - * Copyright (c) 2005-2007, 2009-2011 Günther Brammer - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles engine execution in developer mode */ @@ -68,24 +60,6 @@ C4Console::~C4Console() { } -#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) -void C4Console::HandleMessage (XEvent & e) -{ - // Parent handling - C4ConsoleBase::HandleMessage(e); - - switch (e.type) - { - case FocusIn: - Application.Active = true; - break; - case FocusOut: - Application.Active = false; - break; - } -} -#endif // USE_X11 - C4Window * C4Console::Init(C4AbstractApp * pApp) { return C4ConsoleGUI::CreateConsoleWindow(pApp); @@ -101,7 +75,7 @@ bool C4Console::In(const char *szText) // done return true; } - // begins with '#'? then it's a message. Route cia ProcessInput to allow #/sound + // begins with '#'? then it's a message. Route via ProcessInput to allow #/sound if (*szText == '#') { ::MessageInput.ProcessInput(szText + 1); @@ -110,7 +84,7 @@ bool C4Console::In(const char *szText) // editing enabled? if (!EditCursor.EditingOK()) return false; // pass through network queue - ::Control.DoInput(CID_Script, new C4ControlScript(szText, C4ControlScript::SCOPE_Console, false), CDT_Decide); + ::Control.DoInput(CID_Script, new C4ControlScript(szText, C4ControlScript::SCOPE_Console), CDT_Decide); return true; } @@ -254,7 +228,7 @@ bool C4Console::FileSave() bool C4Console::FileSaveAs(bool fSaveGame) { // Do save-as dialog - StdStrBuf filename; + StdCopyStrBuf filename(""); filename.Copy(Game.ScenarioFile.GetName()); if (!FileSelect(&filename, "Clonk 4 Scenario\0*.ocs\0\0", @@ -277,7 +251,7 @@ bool C4Console::Message(const char *szMessage, bool fQuery) bool C4Console::FileOpen() { // Get scenario file name - StdStrBuf c4sfile (""); + StdCopyStrBuf c4sfile(""); if (!FileSelect(&c4sfile, FILE_SELECT_FILTER_FOR_C4S, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST)) @@ -291,13 +265,13 @@ bool C4Console::FileOpen() bool C4Console::FileOpenWPlrs() { // Get scenario file name - StdStrBuf c4sfile (""); + StdCopyStrBuf c4sfile(""); if (!FileSelect(&c4sfile, FILE_SELECT_FILTER_FOR_C4S, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST)) return false; // Get player file name(s) - StdStrBuf c4pfile (""); + StdCopyStrBuf c4pfile(""); if (!FileSelect(&c4pfile, "Clonk 4 Player\0*.ocp\0\0", OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER @@ -363,7 +337,7 @@ void C4Console::Default() void C4Console::Clear() { - C4ConsoleBase::Clear(); + C4Window::Clear(); EditCursor.Clear(); ToolsDlg.Clear(); PropertyDlgClose(); @@ -423,7 +397,7 @@ void C4Console::UpdateInputCtrl() { ClearInput(); // add global and standard functions - std::list functions = ::ScriptEngine.GetFunctionNames(&::GameScript); + std::list functions = ::ScriptEngine.GetFunctionNames(::GameScript.ScenPropList._getPropList()); SetInputFunctions(functions); } @@ -455,7 +429,7 @@ void C4Console::UpdateMenus() void C4Console::PlayerJoin() { // Get player file name(s) - StdStrBuf c4pfile (""); + StdCopyStrBuf c4pfile(""); if (!FileSelect(&c4pfile, "Clonk 4 Player\0*.ocp\0\0", OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER @@ -576,7 +550,7 @@ bool C4ConsoleGUI::ClearLog() {return 0;} void C4ConsoleGUI::ClearNetMenu() {} void C4ConsoleGUI::ClearPlayerMenu() {} void C4ConsoleGUI::ClearViewportMenu() {} -C4Window * C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp*) {return 0;} +C4Window * C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp*) { return this; } void C4ConsoleGUI::DisplayInfoText(C4ConsoleGUI::InfoTextType, StdStrBuf&) {} void C4ConsoleGUI::DoEnableControls(bool) {} bool C4ConsoleGUI::DoUpdateHaltCtrls(bool) {return 0;} diff --git a/src/editor/C4Console.h b/src/editor/C4Console.h index 79b5eaf74..4956f5c72 100644 --- a/src/editor/C4Console.h +++ b/src/editor/C4Console.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2005, 2009 Günther Brammer - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles engine execution in developer mode */ @@ -43,13 +38,6 @@ const int C4CNS_ModePlay = 0, #define IDM_VIEWPORT_NEW1 10400 #define IDM_VIEWPORT_NEW2 10500 -#ifdef WITH_DEVELOPER_MODE -#include -typedef C4GtkWindow C4ConsoleBase; -#else -typedef C4Window C4ConsoleBase; -#endif - class C4Console: public C4ConsoleGUI { public: @@ -58,7 +46,7 @@ public: void Default(); virtual void Clear(); virtual void Close(); - using C4ConsoleBase::Init; + using C4Window::Init; virtual C4Window * Init(C4AbstractApp * app); void Execute(); void ClearPointers(C4Object *pObj); @@ -101,13 +89,8 @@ public: int FrameCounter; int Time,FPS; -#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) - virtual void HandleMessage (XEvent &); -#endif }; -#define C4ConsoleWindowClassname "C4Console" - extern C4Console Console; #endif diff --git a/src/editor/C4ConsoleCocoa.mm b/src/editor/C4ConsoleCocoa.mm index ab0189735..37d77a38b 100644 --- a/src/editor/C4ConsoleCocoa.mm +++ b/src/editor/C4ConsoleCocoa.mm @@ -13,6 +13,8 @@ * See clonk_trademark_license.txt for full license. */ +#include + #include #include #include @@ -31,16 +33,15 @@ #include #include -#include #import -#import "ClonkAppDelegate.h" -#import "ConsoleWindowController.h" -#import "ClonkOpenGLView.h" +#import "C4AppDelegate.h" +#import "C4EditorWindowController.h" +#import "C4DrawGLMac.h" // implementation of C4Console GUI for Mac OS X -static inline ConsoleWindowController* ctrler(C4ConsoleGUI* gui) {return (ConsoleWindowController*)gui->GetController();} +static inline C4EditorWindowController* ctrler(C4ConsoleGUI* gui) {return gui->objectiveCObject();} class C4ConsoleGUI::State: public C4ConsoleGUI::InternalState { @@ -63,9 +64,9 @@ public: C4Window* C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp *application) { - ClonkWindowController* controller = [ConsoleWindowController new]; - this->controller = controller; - [NSBundle loadNibNamed:@"ConsoleWindow" owner:controller]; + C4WindowController* controller = [C4EditorWindowController new]; + setObjectiveCObject(controller); + [NSBundle loadNibNamed:@"Editor" owner:controller]; [controller setStdWindow:this]; this->Active = true; return this; @@ -73,11 +74,11 @@ C4Window* C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp *application) void C4ConsoleGUI::Out(const char* message) { - ConsoleWindowController* controller = ctrler(this); + C4EditorWindowController* controller = ctrler(this); if (controller) { NSTextStorage* textStorage = controller.outputTextView.textStorage; - [textStorage appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%s\n", message]] autorelease]]; + [textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%s\n", message]]]; [controller.outputTextView scrollRangeToVisible:NSMakeRange([textStorage length]-1, 1)]; } } @@ -134,16 +135,16 @@ bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD void C4ConsoleGUI::AddMenuItemForPlayer(C4Player* player, StdStrBuf& player_text) { NSMenuItem* item = [ - [ClonkAppDelegate instance].addViewportForPlayerMenuItem.submenu + [C4AppDelegate instance].addViewportForPlayerMenuItem.submenu addItemWithTitle:[NSString stringWithUTF8String:player_text.getData()] action:@selector(newViewportForPlayer:) keyEquivalent:@"" ]; [item setTag:player->Number]; - [item setTarget: ClonkAppDelegate.instance]; + [item setTarget: C4AppDelegate.instance]; } void C4ConsoleGUI::ClearViewportMenu() { - [[ClonkAppDelegate instance].addViewportForPlayerMenuItem.submenu removeAllItems]; + [[C4AppDelegate instance].addViewportForPlayerMenuItem.submenu removeAllItems]; } bool C4ConsoleGUI::Message(const char *message, bool query) @@ -175,7 +176,7 @@ void C4ConsoleGUI::PropertyDlgUpdate(C4ObjectList &rSelection) if (![ctrler(this).objectsPanel isVisible]) return; StdStrBuf text = rSelection.GetDataString(); - [ctrler(this).objectPropertiesText.textStorage setAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:text.getData()]] autorelease]]; + [ctrler(this).objectPropertiesText.textStorage setAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:text.getData()]]]; } void C4ConsoleGUI::ToolsDlgClose() @@ -205,7 +206,6 @@ void C4ConsoleGUI::ToolsDlgInitMaterialCtrls(class C4ToolsDlg *dlg) { [materialsPopup addItemWithTitle:s]; } - [ary release]; [materialsPopup selectItemWithTitle:[NSString stringWithUTF8String:dlg->Material]]; } @@ -382,17 +382,17 @@ void C4ConsoleGUI::SetCursor(C4ConsoleGUI::Cursor cursor) void C4ConsoleGUI::RecordingEnabled() { - [ClonkAppDelegate.instance.recordMenuItem setEnabled:NO]; + [C4AppDelegate.instance.recordMenuItem setEnabled:NO]; } void C4ConsoleGUI::AddNetMenu() { - [ClonkAppDelegate.instance.netMenu setHidden:NO]; + [C4AppDelegate.instance.netMenu setHidden:NO]; } void C4ConsoleGUI::ClearNetMenu() { - [ClonkAppDelegate.instance.netMenu setHidden:YES]; + [C4AppDelegate.instance.netMenu setHidden:YES]; } void C4ConsoleGUI::DoEnableControls(bool fEnable) @@ -423,17 +423,18 @@ void C4ConsoleGUI::AddNetMenuItemForPlayer(int32_t index, StdStrBuf &text) { NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:text.getData() encoding:NSUTF8StringEncoding] action:@selector(kickPlayer:) keyEquivalent:[NSString string]]; [item setTarget:ctrler(this)]; - [ClonkAppDelegate.instance.netMenu.submenu addItem:item]; + [C4AppDelegate.instance.netMenu.submenu addItem:item]; } void C4ConsoleGUI::SetInputFunctions(std::list &functions) { + [ctrler(this) setInputFunctions:functions]; } void C4ConsoleGUI::AddKickPlayerMenuItem(C4Player *player, StdStrBuf& player_text, bool enabled) { NSMenuItem* item = [ - [ClonkAppDelegate instance].kickPlayerMenuItem.submenu + [C4AppDelegate instance].kickPlayerMenuItem.submenu addItemWithTitle:[NSString stringWithUTF8String:player_text.getData()] action:@selector(kickPlayer:) keyEquivalent:@"" ]; [item setEnabled:enabled]; diff --git a/src/editor/C4ConsoleGTK.cpp b/src/editor/C4ConsoleGTK.cpp index 9fb3985e9..63f55f1b5 100644 --- a/src/editor/C4ConsoleGTK.cpp +++ b/src/editor/C4ConsoleGTK.cpp @@ -1,26 +1,27 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002, 2005 Sven Eberhardt - * Copyright (c) 2006-2007, 2010 Armin Burgmeier - * Copyright (c) 2007, 2009-2011 Günther Brammer - * Copyright (c) 2010 Martin Plicht - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2002, 2005, Sven Eberhardt + * Copyright (c) 2006-2007, Armin Burgmeier + * Copyright (c) 2007, Günther Brammer + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * "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. */ #include #include +#include +#include #include #include #include @@ -40,28 +41,9 @@ #include #include -# include -# include - -# include -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include - -# include -# include -# include - -# include -# include +#include +#include +#include using namespace OpenFileFlags; @@ -312,20 +294,15 @@ void C4ConsoleGUI::State::OnScriptActivate(GtkWidget* widget, gpointer data) C4Window* C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp* pApp) { - // Calls InitGUI - C4Window* retval = C4ConsoleBase::Init(C4Window::W_GuiWindow, pApp, LoadResStr("IDS_CNS_CONSOLE"), NULL, false); + C4Rect r(0, 0, 320, 320); + C4Window* retval = C4Window::Init(C4Window::W_Console, pApp, LoadResStr("IDS_CNS_CONSOLE"), &r); + state->InitGUI(); UpdateHaltCtrls(true); EnableControls(fGameOpen); ClearViewportMenu(); return retval; } -GtkWidget* C4ConsoleGUI::InitGUI() -{ - state->InitGUI(); - return C4ConsoleBase::InitGUI(); -} - void C4ConsoleGUI::State::InitGUI() { // ------------ Play/Pause and Mode --------------------- @@ -481,9 +458,8 @@ void C4ConsoleGUI::State::InitGUI() gtk_box_pack_start(GTK_BOX(box), txtScript, false, false, 3); gtk_box_pack_start(GTK_BOX(box), status_frame, false, false, 0); - gtk_window_set_default_size(GTK_WINDOW(GetOwner()->window), 320, 320); - gtk_container_add(GTK_CONTAINER(GetOwner()->window), box); + gtk_widget_show_all(GTK_WIDGET(GetOwner()->window)); // ------------ Signals --------------------- handlerDestroy = g_signal_connect(G_OBJECT(GetOwner()->window), "destroy", G_CALLBACK(OnDestroy), this); @@ -586,7 +562,7 @@ void C4ConsoleGUI::AddMenuItemForPlayer(C4Player *player, StdStrBuf &player_text void C4ConsoleGUI::SetCursor(Cursor cursor) { // Seems not to work. Don't know why... - GdkDisplay * display = gtk_widget_get_display(window); + GdkDisplay * display = gtk_widget_get_display(GTK_WIDGET(window)); GdkCursor * gdkcursor; if (cursor == CURSOR_Wait) @@ -594,11 +570,7 @@ void C4ConsoleGUI::SetCursor(Cursor cursor) else gdkcursor = NULL; -#if GTK_CHECK_VERSION(2,14,0) - GdkWindow* window_wnd = gtk_widget_get_window(window); -#else - GdkWindow* window_wnd = window->window; -#endif + GdkWindow* window_wnd = gtk_widget_get_window(GTK_WIDGET(window)); gdk_window_set_cursor(window_wnd, gdkcursor); gdk_display_flush(display); @@ -996,18 +968,14 @@ void C4ConsoleGUI::PropertyDlgUpdate(C4ObjectList &rSelection) { if (!state->propertydlg) return; if (!C4DevmodeDlg::GetWindow()) return; -#if GTK_CHECK_VERSION(2,18,0) if (!gtk_widget_get_visible(GTK_WIDGET(C4DevmodeDlg::GetWindow()))) return; -#else - if (!GTK_WIDGET_VISIBLE(GTK_WIDGET(C4DevmodeDlg::GetWindow()))) return; -#endif GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(state->propertydlg_textview)); gtk_text_buffer_set_text(buffer, rSelection.GetDataString().getData(), -1); if (PropertyDlgObject == rSelection.GetObject()) return; PropertyDlgObject = rSelection.GetObject(); - std::list functions = ::ScriptEngine.GetFunctionNames(PropertyDlgObject ? &PropertyDlgObject->Def->Script : 0); + std::list functions = ::ScriptEngine.GetFunctionNames(PropertyDlgObject); GtkEntryCompletion* completion = gtk_entry_get_completion(GTK_ENTRY(state->propertydlg_entry)); GtkListStore* store; @@ -1317,11 +1285,7 @@ void C4ToolsDlg::State::UpdatePreview() } } } -#if GTK_CHECK_VERSION(2,18,0) if (gtk_widget_is_sensitive(preview)) -#else - if (GTK_WIDGET_SENSITIVE(preview)) -#endif pDraw->DrawPatternedCircle( sfcPreview, iPrvWdt/2,iPrvHgt/2, dlg->Grade, @@ -1553,7 +1517,9 @@ void C4ConsoleGUI::State::OnPlrJoin(GtkWidget* item, gpointer data) void C4ConsoleGUI::State::OnPlrQuit(GtkWidget* item, gpointer data) { - ::Control.Input.Add(CID_Script, new C4ControlScript(FormatString("EliminatePlayer(%d)", GPOINTER_TO_INT(data)).getData())); + C4Player *plr = ::Players.Get(GPOINTER_TO_INT(data)); + if (!plr) return; + ::Control.Input.Add(CID_PlrAction, C4ControlPlayerAction::Eliminate(plr)); } void C4ConsoleGUI::State::OnViewNew(GtkWidget* item, gpointer data) diff --git a/src/editor/C4DevmodeDlg.cpp b/src/editor/C4ConsoleGTKDlg.cpp similarity index 82% rename from src/editor/C4DevmodeDlg.cpp rename to src/editor/C4ConsoleGTKDlg.cpp index 4e3e0d9b2..dd8377c0e 100644 --- a/src/editor/C4DevmodeDlg.cpp +++ b/src/editor/C4ConsoleGTKDlg.cpp @@ -1,27 +1,23 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007, 2010 Armin Burgmeier - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Common window for drawing and property tool dialogs in console mode */ #include -#include - -#ifdef WITH_DEVELOPER_MODE +#include #include @@ -90,11 +86,7 @@ void C4DevmodeDlg::RemovePage(GtkWidget* widget) void C4DevmodeDlg::SwitchPage(GtkWidget* widget) { -#if GTK_CHECK_VERSION(2,18,0) bool is_visible = gtk_widget_get_visible(GTK_WIDGET(window)); -#else - bool is_visible = GTK_WIDGET_VISIBLE(GTK_WIDGET(window)); -#endif // Remember window position if (window != NULL && is_visible) @@ -133,5 +125,3 @@ void C4DevmodeDlg::SetTitle(GtkWidget* widget, const char* title) if (gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), page_num) == widget) gtk_window_set_title(GTK_WINDOW(window), title); } - -#endif // WITH_DEVELOPER_MODE diff --git a/src/editor/C4DevmodeDlg.h b/src/editor/C4ConsoleGTKDlg.h similarity index 64% rename from src/editor/C4DevmodeDlg.h rename to src/editor/C4ConsoleGTKDlg.h index 46e13ed1c..e850b3bf1 100644 --- a/src/editor/C4DevmodeDlg.h +++ b/src/editor/C4ConsoleGTKDlg.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Common window for drawing and property tool dialogs in console mode */ diff --git a/src/editor/C4ConsoleGUI.h b/src/editor/C4ConsoleGUI.h index ee3842634..1630fbb53 100644 --- a/src/editor/C4ConsoleGUI.h +++ b/src/editor/C4ConsoleGUI.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2011 Günther Brammer - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Copyright (c) 2006, Armin Burgmeier + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * "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. */ #ifndef C4CONSOLEGUI_INC @@ -24,13 +22,6 @@ #include "C4GameControl.h" #include "StdBuf.h" -#ifdef WITH_DEVELOPER_MODE -#include -typedef C4GtkWindow C4ConsoleBase; -#else -typedef C4Window C4ConsoleBase; -#endif - namespace OpenFileFlags { const DWORD OFN_HIDEREADONLY = 1 << 0; @@ -42,7 +33,7 @@ namespace OpenFileFlags } // Separate class containing GUI code for C4Console while C4Console itself only contains functionality -class C4ConsoleGUI: public C4ConsoleBase +class C4ConsoleGUI: public C4Window { public: @@ -146,9 +137,6 @@ public: virtual bool Win32DialogMessageHandling(MSG *msg); void UpdateMenuText(HMENU hMenu); #endif -#ifdef WITH_DEVELOPER_MODE - virtual GtkWidget* InitGUI(); -#endif }; #endif diff --git a/src/editor/C4ConsoleGUICommon.h b/src/editor/C4ConsoleGUICommon.h index 6607630df..0dd3da201 100644 --- a/src/editor/C4ConsoleGUICommon.h +++ b/src/editor/C4ConsoleGUICommon.h @@ -1,18 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Günther Brammer - * Copyright (c) 2010 Martin Plicht - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Copyright (c) 2005, Günther Brammer + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * "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. */ // To be directly included by platform-specific implementations diff --git a/src/editor/C4ConsoleWin32.cpp b/src/editor/C4ConsoleWin32.cpp index 59590b60a..f6b08e418 100644 --- a/src/editor/C4ConsoleWin32.cpp +++ b/src/editor/C4ConsoleWin32.cpp @@ -1,63 +1,40 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003 Matthes Bender - * Copyright (c) 2004 Peter Wortmann - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2005-2007, 2009-2011 Günther Brammer - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2009, 2011 Nicolas Hake - * Copyright (c) 2010 Martin Plicht - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Copyright (c) 1998-2000, 2003, Matthes Bender + * Copyright (c) 2004, Peter Wortmann + * Copyright (c) 2005-2007, Günther Brammer + * Copyright (c) 2005, 2007, Sven Eberhardt + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * "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. */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef USE_GL -#include -#endif - -#ifdef USE_DIRECTX -#include -#endif - +#include #include "C4ConsoleGUI.h" +#include +#include +#include +#include +#include +#include #include "C4Viewport.h" +#include #include #include #include #include "resource.h" - #define GetWideLPARAM(c) reinterpret_cast(static_cast(GetWideChar(c))) inline StdStrBuf::wchar_t_holder LoadResStrW(const char *id) { return GetWideChar(LoadResStr(id)); } @@ -282,8 +259,9 @@ INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lPara // Remove player if (Inside((int) LOWORD(wParam),IDM_PLAYER_QUIT1,IDM_PLAYER_QUIT2)) { - ::Control.Input.Add(CID_Script, new C4ControlScript( - FormatString("EliminatePlayer(%d)", LOWORD(wParam)-IDM_PLAYER_QUIT1).getData())); + C4Player *plr = ::Players.Get(LOWORD(wParam) - IDM_PLAYER_QUIT1); + if (!plr) return true; + ::Control.Input.Add(CID_PlrAction, C4ControlPlayerAction::Eliminate(plr)); return true; } // Remove client @@ -303,6 +281,7 @@ INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lPara return false; //------------------------------------------------------------------------------------------------------------ case WM_COPYDATA: + { COPYDATASTRUCT* pcds = reinterpret_cast(lParam); if (pcds->dwData == WM_USER_RELOADFILE) { @@ -313,6 +292,10 @@ INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lPara Game.ReloadFile(szPath); } return false; + } + //------------------------------------------------------------------------------------------------------------ + case WM_INPUTLANGCHANGE: + ::Application.OnKeyboardLayoutChanged(); } return false; @@ -322,9 +305,7 @@ class C4ToolsDlg::State: public C4ConsoleGUI::InternalState { public: HWND hDialog; -#ifdef USE_GL CStdGLCtx* pGLCtx; -#endif friend INT_PTR CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); HBITMAP hbmBrush,hbmBrush2; HBITMAP hbmLine,hbmLine2; @@ -385,13 +366,11 @@ public: if (hbmFill) DeleteObject(hbmFill); if (hbmIFT) DeleteObject(hbmIFT); if (hbmNoIFT) DeleteObject(hbmNoIFT); -#ifdef USE_GL if (pGLCtx) { delete pGLCtx; pGLCtx = NULL; } -#endif if (hDialog) DestroyWindow(hDialog); hDialog=NULL; } @@ -772,6 +751,7 @@ bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD { enum { ArbitraryMaximumLength = 4096 }; wchar_t buffer[ArbitraryMaximumLength]; + sFilename->ReplaceChar('/', '\\'); // GetSaveFileNameW has trouble with forward slashes wcsncpy(buffer, sFilename->GetWideChar(), ArbitraryMaximumLength - 1); buffer[ArbitraryMaximumLength - 1] = 0; OPENFILENAMEW ofn; @@ -799,7 +779,6 @@ bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD fResult = !!GetSaveFileNameW(&ofn); else fResult = !!GetOpenFileNameW(&ofn); - // Reset working directory to exe path as Windows file dialog might have changed it SetCurrentDirectoryW(wd); delete[] wd; @@ -912,7 +891,7 @@ void C4ConsoleGUI::PropertyDlgUpdate(C4ObjectList &rSelection) if (PropertyDlgObject == rSelection.GetObject()) return; PropertyDlgObject = rSelection.GetObject(); - std::list functions = ::ScriptEngine.GetFunctionNames(PropertyDlgObject ? &PropertyDlgObject->Def->Script : 0); + std::list functions = ::ScriptEngine.GetFunctionNames(PropertyDlgObject); HWND hCombo = GetDlgItem(state->hPropertyDlg, IDC_COMBOINPUT); wchar_t szLastText[500+1]; // Remember old window text @@ -967,10 +946,8 @@ bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg) // Load bitmaps if necessary dlg->state->LoadBitmaps(Application.GetInstance()); // create target ctx for OpenGL rendering -#ifdef USE_GL if (pDraw && !dlg->state->pGLCtx) dlg->state->pGLCtx = pDraw->CreateContext(GetDlgItem(dlg->state->hDialog,IDC_PREVIEW), &Application); -#endif // Show window RestoreWindowPosition(dlg->state->hDialog, "Property", Config.GetSubkeyPath("Console")); SetWindowPos(dlg->state->hDialog,Console.hWindow,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE); @@ -1096,14 +1073,6 @@ void C4ToolsDlg::NeedPreviewUpdate() //Application.DDraw->AttachPrimaryPalette(sfcPreview); -#ifdef USE_DIRECTX - if (pD3D) - pD3D->BlitSurface2Window( sfcPreview, - 0,0,iPrvWdt,iPrvHgt, - GetDlgItem(state->hDialog,IDC_PREVIEW), - rect.left,rect.top,rect.right,rect.bottom); -#endif -#ifdef USE_GL // FIXME: This activates the wrong GL context. To avoid breaking the main window display, // FIXME: it has been disabled for the moment //if (pGLCtx->Select()) @@ -1111,7 +1080,6 @@ void C4ToolsDlg::NeedPreviewUpdate() // pGL->Blit(sfcPreview, 0,0,(float)iPrvWdt,(float)iPrvHgt, Application.pWindow->pSurface, rect.left,rect.top, iPrvWdt,iPrvHgt); // Application.pWindow->pSurface->PageFlip(); //} -#endif delete sfcPreview; } diff --git a/src/editor/C4ConsoleX11.cpp b/src/editor/C4ConsoleX11.cpp deleted file mode 100644 index 7d1a0708b..000000000 --- a/src/editor/C4ConsoleX11.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2010 Martin Plicht - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -namespace -{ - const DWORD OFN_HIDEREADONLY = 1 << 0; - const DWORD OFN_OVERWRITEPROMPT = 1 << 1; - const DWORD OFN_FILEMUSTEXIST = 1 << 2; - const DWORD OFN_ALLOWMULTISELECT = 1 << 3; - - const DWORD OFN_EXPLORER = 0; // ignored -} -#ifdef USE_X11 -#include -#include -#endif diff --git a/src/editor/C4EditCursor.cpp b/src/editor/C4EditCursor.cpp index 1defdaba4..d68292e2b 100644 --- a/src/editor/C4EditCursor.cpp +++ b/src/editor/C4EditCursor.cpp @@ -1,25 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003 Matthes Bender - * Copyright (c) 2001, 2005-2007 Sven Eberhardt - * Copyright (c) 2004-2005, 2007 Peter Wortmann - * Copyright (c) 2005-2011 Günther Brammer - * Copyright (c) 2006, 2010 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles viewport editing in console mode */ @@ -61,15 +54,6 @@ C4EditCursor::~C4EditCursor() void C4EditCursor::Execute() { - // alt check - bool fAltIsDown = Application.IsAltDown(); - if (fAltIsDown != fAltWasDown) - { - if ((fAltWasDown = fAltIsDown)) - AltDown(); - else - AltUp(); - } // drawing switch (Mode) { @@ -131,8 +115,23 @@ void C4EditCursor::ClearPointers(C4Object *pObj) OnSelectionChanged(); } -bool C4EditCursor::Move(float iX, float iY, WORD wKeyFlags) +bool C4EditCursor::Move(float iX, float iY, DWORD dwKeyState) { + // alt check + bool fAltIsDown = (dwKeyState & MK_ALT) != 0; + if (fAltIsDown != fAltWasDown) + { + if ((fAltWasDown = fAltIsDown)) + AltDown(); + else + AltUp(); + } + + // shift check + bool fShiftIsDown = (dwKeyState & MK_SHIFT) != 0; + if(fShiftIsDown != fShiftWasDown) + fShiftWasDown = fShiftIsDown; + // Offset movement float xoff = iX-X; float yoff = iY-Y; X=iX; Y=iY; @@ -145,18 +144,18 @@ bool C4EditCursor::Move(float iX, float iY, WORD wKeyFlags) if (!DragFrame && Hold) { MoveSelection(ftofix(xoff),ftofix(yoff)); - UpdateDropTarget(wKeyFlags); + UpdateDropTarget(dwKeyState); } // Update target // Shift always indicates a target outside the current selection else { - Target = ((wKeyFlags & MK_SHIFT) && Selection.Last) ? Selection.Last->Obj : NULL; + Target = ((dwKeyState & MK_SHIFT) && Selection.Last) ? Selection.Last->Obj : NULL; do { - Target = Game.FindObject(C4ID::None,X,Y,0,0,OCF_NotContained, NULL, NULL, NULL, NULL, ANY_OWNER, Target); + Target = Game.FindObject(C4ID::None,X,Y,0,0,OCF_NotContained, Target); } - while ((wKeyFlags & MK_SHIFT) && Target && Selection.GetLink(Target)); + while ((dwKeyState & MK_SHIFT) && Target && Selection.GetLink(Target)); } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -207,7 +206,38 @@ void C4EditCursor::OnSelectionChanged() Console.ObjectListDlg.Update(Selection); } -bool C4EditCursor::LeftButtonDown(bool fControl) +void C4EditCursor::AddToSelection(C4Object *add_obj) +{ + if (!add_obj || !add_obj->Status) return; + // add object to selection and do script callback + Selection.Add(add_obj, C4ObjectList::stNone); + ::Control.DoInput(CID_EMMoveObj, new C4ControlEMMoveObject(EMMO_Select, Fix0, Fix0, add_obj), CDT_Decide); +} + +bool C4EditCursor::RemoveFromSelection(C4Object *remove_obj) +{ + if (!remove_obj || !remove_obj->Status) return false; + // remove object from selection and do script callback + if (!Selection.Remove(remove_obj)) return false; + ::Control.DoInput(CID_EMMoveObj, new C4ControlEMMoveObject(EMMO_Deselect, Fix0, Fix0, remove_obj), CDT_Decide); + return true; +} + +void C4EditCursor::ClearSelection() +{ + // remove all objects from selection and do script callbacks + // iterate safely because callback might delete selected objects! + C4Object *obj; + while (obj = Selection.GetObject(0)) + { + Selection.Remove(obj); + if (obj->Status) + ::Control.DoInput(CID_EMMoveObj, new C4ControlEMMoveObject(EMMO_Deselect, Fix0, Fix0, obj), CDT_Decide); + } + Selection.Clear(); +} + +bool C4EditCursor::LeftButtonDown(DWORD dwKeyState) { // Hold @@ -217,12 +247,12 @@ bool C4EditCursor::LeftButtonDown(bool fControl) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4CNS_ModeEdit: - if (fControl) + if (dwKeyState & MK_CONTROL) { // Toggle target if (Target) - if (!Selection.Remove(Target)) - Selection.Add(Target, C4ObjectList::stNone); + if (!RemoveFromSelection(Target)) + AddToSelection(Target); } else { @@ -235,11 +265,11 @@ bool C4EditCursor::LeftButtonDown(bool fControl) break; } if(!it) // means loop didn't break - { Selection.Clear(); Selection.Add(Target, C4ObjectList::stNone); } + { ClearSelection(); AddToSelection(Target); } } // Click on nothing: drag frame if (!Target) - { Selection.Clear(); DragFrame=true; X2=X; Y2=Y; } + { ClearSelection(); DragFrame=true; X2=X; Y2=Y; } } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -265,14 +295,14 @@ bool C4EditCursor::LeftButtonDown(bool fControl) return true; } -bool C4EditCursor::RightButtonDown(bool fControl) +bool C4EditCursor::RightButtonDown(DWORD dwKeyState) { switch (Mode) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4CNS_ModeEdit: - if (!fControl) + if ( (dwKeyState & MK_CONTROL) == 0) { // Check whether cursor is on anything in the selection bool fCursorIsOnSelection = false; @@ -287,10 +317,10 @@ bool C4EditCursor::RightButtonDown(bool fControl) // Click on unselected if (Target && !Selection.GetLink(Target)) { - Selection.Clear(); Selection.Add(Target, C4ObjectList::stNone); + ClearSelection(); AddToSelection(Target); } // Click on nothing - if (!Target) Selection.Clear(); + if (!Target) ClearSelection(); } } break; @@ -301,7 +331,7 @@ bool C4EditCursor::RightButtonDown(bool fControl) return true; } -bool C4EditCursor::LeftButtonUp() +bool C4EditCursor::LeftButtonUp(DWORD dwKeyState) { // Finish edit/tool switch (Mode) @@ -336,6 +366,50 @@ bool C4EditCursor::LeftButtonUp() return true; } +bool C4EditCursor::KeyDown(C4KeyCode KeyCode, DWORD dwKeyState) +{ + // alt check + bool fAltIsDown = (dwKeyState & MK_ALT) != 0; + fAltIsDown = fAltIsDown || KeyCode == K_ALT_L || KeyCode == K_ALT_R; + if (fAltIsDown != fAltWasDown) + { + if ((fAltWasDown = fAltIsDown)) + AltDown(); + else + AltUp(); + } + + // shift check + bool fShiftIsDown = (dwKeyState & MK_SHIFT) != 0; + fShiftIsDown = fShiftIsDown || KeyCode == K_SHIFT_L || KeyCode == K_SHIFT_R; + if(fShiftIsDown != fShiftWasDown) + fShiftWasDown = fShiftIsDown; + + return true; +} + +bool C4EditCursor::KeyUp(C4KeyCode KeyCode, DWORD dwKeyState) +{ + // alt check + bool fAltIsDown = (dwKeyState & MK_ALT) != 0; + fAltIsDown = fAltIsDown && !( KeyCode == K_ALT_L || KeyCode == K_ALT_R); + if (fAltIsDown != fAltWasDown) + { + if ((fAltWasDown = fAltIsDown)) + AltDown(); + else + AltUp(); + } + + // shift check + bool fShiftIsDown = (dwKeyState & MK_SHIFT) != 0; + fShiftIsDown = fShiftIsDown && !(KeyCode == K_SHIFT_L || KeyCode == K_SHIFT_R); + if(fShiftIsDown != fShiftWasDown) + fShiftWasDown = fShiftIsDown; + + return true; +} + #ifdef USE_WIN32_WINDOWS bool SetMenuItemEnable(HMENU hMenu, WORD id, bool fEnable) { @@ -357,11 +431,11 @@ bool SetMenuItemText(HMENU hMenu, WORD id, const char *szText) } #endif -bool C4EditCursor::RightButtonUp() +bool C4EditCursor::RightButtonUp(DWORD dwKeyState) { Target=NULL; - DoContextMenu(); + DoContextMenu(dwKeyState); // Update UpdateStatusBar(); @@ -420,7 +494,7 @@ void C4EditCursor::Draw(C4TargetFacet &cgo) }; DrawSelectMark(cgo, frame); // highlight selection if shift is pressed - if (Application.IsShiftDown()) + if (fShiftWasDown) { uint32_t dwOldMod = cobj->ColorMod; uint32_t dwOldBlitMode = cobj->BlitMode; @@ -490,13 +564,13 @@ void C4EditCursor::MoveSelection(C4Real XOff, C4Real YOff) void C4EditCursor::FrameSelection() { - Selection.Clear(); + ClearSelection(); C4Object *cobj; C4ObjectLink *clnk; for (clnk=::Objects.First; clnk && (cobj=clnk->Obj); clnk=clnk->Next) if (cobj->Status) if (cobj->OCF & OCF_NotContained) { if (Inside(cobj->GetX(),Min(X,X2),Max(X,X2)) && Inside(cobj->GetY(),Min(Y,Y2),Max(Y,Y2))) - Selection.Add(cobj, C4ObjectList::stNone); + AddToSelection(cobj); } OnSelectionChanged(); } @@ -510,6 +584,7 @@ bool C4EditCursor::In(const char *szText) void C4EditCursor::Default() { fAltWasDown=false; + fShiftWasDown=false; Mode=C4CNS_ModePlay; X=Y=X2=Y2=0; Target=DropTarget=NULL; @@ -624,7 +699,7 @@ void C4EditCursor::ApplyToolFill() EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Fill, ::Landscape.Mode, X,Y,0,Y2, pTools->Grade, false, pTools->Material)); } -bool C4EditCursor::DoContextMenu() +bool C4EditCursor::DoContextMenu(DWORD dwKeyState) { bool fObjectSelected = !!Selection.ObjectCount(); #ifdef USE_WIN32_WINDOWS @@ -683,7 +758,7 @@ bool C4EditCursor::DoContextMenu() for(std::vector::iterator it = itemsObjselect.begin() + 1; it != itemsObjselect.end(); ++it) if(it->ItemId == iItem) { - DoContextObjsel(it->Object); + DoContextObjsel(it->Object, (dwKeyState & MK_SHIFT) == 0); break; } break; @@ -740,13 +815,13 @@ void C4EditCursor::GrabContents() EMMoveObject(EMMO_Exit, Fix0, Fix0, NULL, &Selection); } -void C4EditCursor::UpdateDropTarget(WORD wKeyFlags) +void C4EditCursor::UpdateDropTarget(DWORD dwKeyState) { C4Object *cobj; C4ObjectLink *clnk; DropTarget=NULL; - if (wKeyFlags & MK_CONTROL) + if (dwKeyState & MK_CONTROL) if (Selection.GetObject()) for (clnk=::Objects.First; clnk && (cobj=clnk->Obj); clnk=clnk->Next) if (cobj->Status) @@ -799,20 +874,24 @@ void C4EditCursor::ApplyToolPicker() switch (::Landscape.Mode) { case C4LSC_Static: - // Material-texture from map - if ((byIndex=::Landscape.GetMapIndex(X/::Landscape.MapZoom,Y/::Landscape.MapZoom))) { - const C4TexMapEntry *pTex = ::TextureMap.GetEntry(byIndex & (IFT-1)); - if (pTex) + bool material_set = false; + // Material-texture from map + if ((byIndex=::Landscape.GetMapIndex(X/::Landscape.MapZoom,Y/::Landscape.MapZoom))) { - Console.ToolsDlg.SelectMaterial(pTex->GetMaterialName()); - Console.ToolsDlg.SelectTexture(pTex->GetTextureName()); - Console.ToolsDlg.SetIFT(!!(byIndex & ~(IFT-1))); + const C4TexMapEntry *pTex = ::TextureMap.GetEntry(byIndex & (IFT-1)); + if (pTex && pTex->GetMaterialName() && *pTex->GetMaterialName()) + { + Console.ToolsDlg.SelectMaterial(pTex->GetMaterialName()); + Console.ToolsDlg.SelectTexture(pTex->GetTextureName()); + Console.ToolsDlg.SetIFT(!!(byIndex & ~(IFT-1))); + material_set = true; + } } + // default to sky, because invalid materials are always rendered as sky + if (!material_set) Console.ToolsDlg.SelectMaterial(C4TLS_MatSky); + break; } - else - Console.ToolsDlg.SelectMaterial(C4TLS_MatSky); - break; case C4LSC_Exact: // Material only from landscape if (MatValid(iMaterial=GBackMat(X,Y))) @@ -870,7 +949,19 @@ void C4EditCursor::OnGrabContents(GtkWidget* widget, gpointer data) void C4EditCursor::OnObjselect(GtkWidget* widget, gpointer data) { - static_cast(data)->EditCursor->DoContextObjsel(static_cast(data)->Object); + bool IsShiftDown = false; + GdkEvent* event = gtk_get_current_event(); + if(event) + { + if(event->type == GDK_BUTTON_PRESS) + IsShiftDown = ( ((GdkEventButton*)event)->state & MK_SHIFT) != 0; + else if(event->type == GDK_KEY_PRESS) + IsShiftDown = ( ((GdkEventKey*)event)->state & MK_SHIFT) != 0; + + gdk_event_free(event); + } + + static_cast(data)->EditCursor->DoContextObjsel(static_cast(data)->Object, !IsShiftDown); static_cast(data)->EditCursor->ObjselectDelItems(); } @@ -913,10 +1004,11 @@ bool C4EditCursor::AltUp() return false; } -void C4EditCursor::DoContextObjsel(C4Object * obj) +void C4EditCursor::DoContextObjsel(C4Object * obj, bool clear) { - if(!Application.IsControlDown()) + if(clear) Selection.Clear(); + Selection.Add(obj, C4ObjectList::stNone); OnSelectionChanged(); } diff --git a/src/editor/C4EditCursor.h b/src/editor/C4EditCursor.h index 2e8913e0c..1ea21f09f 100644 --- a/src/editor/C4EditCursor.h +++ b/src/editor/C4EditCursor.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles viewport editing in console mode */ @@ -40,6 +36,7 @@ public: ~C4EditCursor(); protected: bool fAltWasDown; + bool fShiftWasDown; int32_t Mode; float X,Y,X2,Y2; bool Hold,DragFrame,DragLine; @@ -79,11 +76,13 @@ public: bool OpenPropTools(); bool Delete(); void GrabContents(); - bool LeftButtonUp(); - bool LeftButtonDown(bool fControl); - bool RightButtonUp(); - bool RightButtonDown(bool fControl); - bool Move(float iX, float iY, WORD wKeyFlags); + bool LeftButtonUp(DWORD dwKeyState); + bool LeftButtonDown(DWORD dwKeyState); + bool RightButtonUp(DWORD dwKeyState); + bool RightButtonDown(DWORD dwKeyState); + bool KeyDown(C4KeyCode KeyCode, DWORD dwKeyState); + bool KeyUp(C4KeyCode KeyCode, DWORD dwKeyState); + bool Move(float iX, float iY, DWORD dwKeyState); bool Init(); bool EditingOK(); C4ObjectList &GetSelection() { return Selection; } @@ -96,8 +95,8 @@ protected: void ApplyToolPicker(); void ToolFailure(); void PutContents(); - void UpdateDropTarget(WORD wKeyFlags); - bool DoContextMenu(); + void UpdateDropTarget(DWORD dwKeyState); + bool DoContextMenu(DWORD dwKeyState); void ApplyToolFill(); void ApplyToolRect(); void ApplyToolLine(); @@ -107,9 +106,13 @@ protected: void MoveSelection(C4Real iXOff, C4Real iYOff); void EMMoveObject(enum C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, const C4ObjectList *pObjs = NULL, const char *szScript = NULL); void EMControl(enum C4PacketType eCtrlType, class C4ControlPacket *pCtrl); - void DoContextObjsel(C4Object *); + void DoContextObjsel(C4Object *, bool clear); void ObjselectDelItems(); + void AddToSelection(C4Object *add_obj); // add object to selection and do script callback. Doesn't do OnSelectionChanged(). + bool RemoveFromSelection(C4Object *remove_obj); // remove object from selection and do script callback. return true if object was in selection before. Doesn't do OnSelectionChanged(). + void ClearSelection(); // remove all objects from selection and do script callback. Doesn't do OnSelectionChanged(). + #ifdef WITH_DEVELOPER_MODE static void OnDelete(GtkWidget* widget, gpointer data); static void OnDuplicate(GtkWidget* widget, gpointer data); diff --git a/src/editor/C4EditorWindowController.h b/src/editor/C4EditorWindowController.h new file mode 100644 index 000000000..fe5ec9965 --- /dev/null +++ b/src/editor/C4EditorWindowController.h @@ -0,0 +1,56 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2010-2013, 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. + */ + +#import +#import +#import + +#ifdef USE_COCOA + +@class C4OpenGLView; +@class C4AppDelegate; + +@interface C4EditorWindowController : C4WindowController {} +@property NSTextField* frameLabel; +@property NSTextField* timeLabel; +@property NSTextView* outputTextView; +@property NSTextView* objectPropertiesText; +@property NSPopUpButton* materialsPopup; +@property NSPopUpButton* texturesPopup; +@property NSScrollView* outputScrollView; +@property IKImageView* previewView; +@property NSPanel* toolsPanel; +@property NSPanel* objectsPanel; +@property NSSegmentedControl* toolSelector; +@property NSSegmentedControl* modeSelector; +@property NSComboBox* objectCombo; +@property NSComboBox* consoleCombo; +- (IBAction) consoleIn:(id)sender; +- (IBAction) objectIn:(id)sender; +- (IBAction) selectMode:(id)sender; +- (IBAction) play:(id)sender; +- (IBAction) halt:(id)sender; +- (IBAction) selectMaterial:(id)sender; +- (IBAction) selectTexture:(id)sender; +- (IBAction) selectTool:(id)sender; +- (IBAction) selectIFT:(id)sender; +- (IBAction) selectMode:(id)sender; +- (IBAction) selectLandscapeMode:(id)sender; +- (IBAction) setGrade:(id)sender; +- (IBAction) kickPlayer:(id)sender; +- (void) setInputFunctions:(std::list)functions; +@end + +#endif diff --git a/src/platform/ConsoleWindowController.mm b/src/editor/C4EditorWindowController.mm similarity index 63% rename from src/platform/ConsoleWindowController.mm rename to src/editor/C4EditorWindowController.mm index 207129d9b..693a7bd43 100644 --- a/src/platform/ConsoleWindowController.mm +++ b/src/editor/C4EditorWindowController.mm @@ -13,6 +13,8 @@ * See clonk_trademark_license.txt for full license. */ +#include + #include #include #include @@ -20,13 +22,51 @@ #include #import -#import -#import -#import +#import +#import +#import #ifdef USE_COCOA -@implementation ConsoleWindowController +@interface InputFunctions : NSObject { + NSArray* items; +} +- (void) setFunctions:(std::list) functions; +@end +@implementation InputFunctions +- (void) setFunctions:(std::list)functions { + NSMutableArray* _items = [NSMutableArray arrayWithCapacity:functions.size()]; + for (auto f : functions) + if (f != NULL) + [_items addObject:[NSString stringWithUTF8String:f]];; + [_items sortUsingSelector:@selector(compare:)]; + items = _items; +} +- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox { + return [items count]; +} +- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index { + return [items objectAtIndex:index]; +} +- (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string { + return [items indexOfObject:string]; +} +- (NSString *)comboBox:(NSComboBox *)aComboBox completedString:(NSString *)string { + int x; + for (x = [string length]-1; + x >= 0 && [[NSCharacterSet letterCharacterSet] characterIsMember:[string characterAtIndex:x]]; x--); + x++; + auto pfx = [string substringWithRange:NSMakeRange(0, x)]; + auto sub = [string substringFromIndex:x]; + auto ndx = [items indexOfObjectPassingTest:^(NSString* item, NSUInteger x, BOOL* stop) { return [item hasPrefix:sub]; }]; + return ndx != NSNotFound ? [pfx stringByAppendingString:[items objectAtIndex:ndx]] : nil; +} +@end + +@implementation C4EditorWindowController +{ + InputFunctions* inputFunctions; +} @synthesize frameLabel, timeLabel, outputTextView, objectPropertiesText, @@ -36,12 +76,21 @@ - (void) awakeFromNib { [super awakeFromNib]; - ClonkAppDelegate.instance.consoleController = self; + C4AppDelegate.instance.editorWindowController = self; NSWindow* window = self.window; [window makeKeyAndOrderFront:self]; [window makeMainWindow]; [toolsPanel setBecomesKeyOnlyIfNeeded:YES]; [objectsPanel setBecomesKeyOnlyIfNeeded:YES]; + inputFunctions = [InputFunctions new]; + [consoleCombo setUsesDataSource:YES]; + [consoleCombo setDataSource:inputFunctions]; + [consoleCombo setCompletes:YES]; +} + +- (void) setInputFunctions:(std::list)functions { + [inputFunctions setFunctions:functions]; + [consoleCombo reloadData]; } - (void) windowWillClose:(NSNotification*)notification @@ -71,7 +120,7 @@ int indexFromSender(id sender) Console.EditCursor.SetMode(indexFromSender(sender)); for (NSWindow* w in [[NSApplication sharedApplication] windows]) { - if ([[w windowController] isKindOfClass:[ClonkWindowController class]]) + if ([[w windowController] isKindOfClass:[C4WindowController class]]) { [w invalidateCursorRectsForView:[[w windowController] openGLView]]; } @@ -123,14 +172,14 @@ int indexFromSender(id sender) - (IBAction) consoleIn:(id)sender { - if (![ClonkAppDelegate isEditorAndGameRunning]) + if (![C4AppDelegate isEditorAndGameRunning]) return; Console.In([[consoleCombo stringValue] cStringUsingEncoding:NSUTF8StringEncoding]); } - (IBAction) objectIn:(id)sender { - if (![ClonkAppDelegate isEditorAndGameRunning]) + if (![C4AppDelegate isEditorAndGameRunning]) return; Console.EditCursor.In([[objectCombo stringValue] cStringUsingEncoding:NSUTF8StringEncoding]); } @@ -157,7 +206,7 @@ int indexFromSender(id sender) while ((s = gameRunningInConsoleModeSelectors[i++]) != nil) { if (s == [item action]) - return [ClonkAppDelegate isEditorAndGameRunning]; + return [C4AppDelegate isEditorAndGameRunning]; } // always enabled diff --git a/src/editor/C4ObjectListDlg.cpp b/src/editor/C4ObjectListDlg.cpp index 74ea4972e..8b123980c 100644 --- a/src/editor/C4ObjectListDlg.cpp +++ b/src/editor/C4ObjectListDlg.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007, 2009, 2011 Günther Brammer - * Copyright (c) 2007 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A window listing all objects in the game */ diff --git a/src/editor/C4ObjectListDlg.h b/src/editor/C4ObjectListDlg.h index aa7062eb8..dd5713563 100644 --- a/src/editor/C4ObjectListDlg.h +++ b/src/editor/C4ObjectListDlg.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Günther Brammer - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A window listing all objects in the game */ diff --git a/src/editor/C4ToolsDlg.cpp b/src/editor/C4ToolsDlg.cpp index 985f0ab0d..aaee21135 100644 --- a/src/editor/C4ToolsDlg.cpp +++ b/src/editor/C4ToolsDlg.cpp @@ -1,25 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003 Matthes Bender - * Copyright (c) 2002, 2005-2007 Sven Eberhardt - * Copyright (c) 2005-2007, 2009 Günther Brammer - * Copyright (c) 2005, 2007 Peter Wortmann - * Copyright (c) 2006-2007 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Drawing tools dialog for landscape editing in console mode */ @@ -33,9 +26,8 @@ #include #include #include -#include -#ifdef USE_GL -#include +#ifndef USE_CONSOLE +#include #endif bool C4ToolsDlg::Open() diff --git a/src/editor/C4ToolsDlg.h b/src/editor/C4ToolsDlg.h index 6acf902f5..62f3da1e4 100644 --- a/src/editor/C4ToolsDlg.h +++ b/src/editor/C4ToolsDlg.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005, 2007 Sven Eberhardt - * Copyright (c) 2005, 2009 Günther Brammer - * Copyright (c) 2006-2007 Armin Burgmeier - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Drawing tools dialog for landscape editing in console mode */ diff --git a/src/editor/C4ViewportWindow.cpp b/src/editor/C4ViewportWindow.cpp new file mode 100644 index 000000000..681a7cdde --- /dev/null +++ b/src/editor/C4ViewportWindow.cpp @@ -0,0 +1,203 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ + +/* A viewport to each player */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_X11 +#ifdef WITH_DEVELOPER_MODE +#include +#endif +#endif + +#ifdef USE_WIN32_WINDOWS + +void UpdateWindowLayout(HWND hwnd) +{ + bool fMinimized = !!IsIconic(hwnd); + bool fMaximized = !!IsZoomed(hwnd); + RECT rect; + GetWindowRect(hwnd,&rect); + MoveWindow(hwnd,rect.left,rect.top,rect.right-rect.left-1,rect.bottom-rect.top,true); + MoveWindow(hwnd,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,true); +} + +bool C4Viewport::TogglePlayerLock() +{ + // Disable player lock + if (PlayerLock) + { + PlayerLock=false; + SetWindowLong(pWindow->hWindow,GWL_STYLE,C4ViewportWindowStyle | WS_HSCROLL | WS_VSCROLL); + UpdateWindowLayout(pWindow->hWindow); + ScrollBarsByViewPosition(); + } + // Enable player lock + else if (ValidPlr(Player)) + { + PlayerLock=true; + SetWindowLong(pWindow->hWindow,GWL_STYLE,C4ViewportWindowStyle); + UpdateWindowLayout(pWindow->hWindow); + } + return true; +} + +bool C4Viewport::ViewPositionByScrollBars() +{ + if (PlayerLock) return false; + SCROLLINFO scroll; + scroll.cbSize=sizeof(SCROLLINFO); + // Vertical + scroll.fMask=SIF_POS; + GetScrollInfo(pWindow->hWindow,SB_VERT,&scroll); + ViewY=float(scroll.nPos); + // Horizontal + scroll.fMask=SIF_POS; + GetScrollInfo(pWindow->hWindow,SB_HORZ,&scroll); + ViewX=float(scroll.nPos); + return true; +} + +bool C4Viewport::ScrollBarsByViewPosition() +{ + if (PlayerLock) return false; + SCROLLINFO scroll; + scroll.cbSize=sizeof(SCROLLINFO); + // Vertical + scroll.fMask=SIF_ALL; + scroll.nMin=0; + scroll.nMax=GBackHgt; + scroll.nPage=ViewHgt; + scroll.nPos=int(ViewY); + SetScrollInfo(pWindow->hWindow,SB_VERT,&scroll,true); + // Horizontal + scroll.fMask=SIF_ALL; + scroll.nMin=0; + scroll.nMax=GBackWdt; + scroll.nPage=ViewWdt; + scroll.nPos=int(ViewX); + SetScrollInfo(pWindow->hWindow,SB_HORZ,&scroll,true); + return true; +} + +#elif defined(WITH_DEVELOPER_MODE) +bool C4Viewport::TogglePlayerLock() +{ + if (PlayerLock) + { + PlayerLock = false; + gtk_widget_show(pWindow->h_scrollbar); + gtk_widget_show(pWindow->v_scrollbar); + ScrollBarsByViewPosition(); + } + else + { + PlayerLock = true; + gtk_widget_hide(pWindow->h_scrollbar); + gtk_widget_hide(pWindow->v_scrollbar); + } + + return true; +} + +bool C4Viewport::ScrollBarsByViewPosition() +{ + if (PlayerLock) return false; + + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(pWindow->render_widget), &allocation); + + GtkAdjustment* adjustment = gtk_range_get_adjustment(GTK_RANGE(pWindow->h_scrollbar)); + + gtk_adjustment_configure(adjustment, + ViewX, // value + 0, // lower + GBackWdt, // upper + ViewportScrollSpeed, // step_increment + allocation.width / Zoom, // page_increment + allocation.width / Zoom // page_size + ); + + adjustment = gtk_range_get_adjustment(GTK_RANGE(pWindow->v_scrollbar)); + gtk_adjustment_configure(adjustment, + ViewY, // value + 0, // lower + GBackHgt, // upper + ViewportScrollSpeed, // step_increment + allocation.height / Zoom, // page_increment + allocation.height / Zoom // page_size + ); + return true; +} + +bool C4Viewport::ViewPositionByScrollBars() +{ + if (PlayerLock) return false; + + GtkAdjustment* adjustment = gtk_range_get_adjustment(GTK_RANGE(pWindow->h_scrollbar)); + ViewX = static_cast(gtk_adjustment_get_value(adjustment)); + + adjustment = gtk_range_get_adjustment(GTK_RANGE(pWindow->v_scrollbar)); + ViewY = static_cast(gtk_adjustment_get_value(adjustment)); + + return true; +} + +#endif // WITH_DEVELOPER_MODE + +void C4ViewportWindow::PerformUpdate() +{ + if (cvp) + { + cvp->UpdateOutputSize(); + cvp->Execute(); + } +} + +C4Window * C4ViewportWindow::Init(int32_t Player) +{ + C4Window* result; + const char * Title = Player == NO_OWNER ? LoadResStr("IDS_CNS_VIEWPORT") : ::Players.Get(Player)->GetName(); + C4Rect r(0,0,800,500); + result = C4Window::Init(C4Window::W_Viewport, &Application, Title, &r); + + if (!result) return result; + + pSurface = new C4Surface(&Application, this); + // Position and size + RestorePosition(FormatString("Viewport%i", Player+1).getData(), Config.GetSubkeyPath("Console")); + return result; +} + +void C4ViewportWindow::Close() +{ + ::Viewports.CloseViewport(cvp); +} +void C4ViewportWindow::EditCursorMove(int X, int Y, uint32_t state) +{ + Console.EditCursor.Move(cvp->ViewX + X / cvp->Zoom, cvp->ViewY + Y / cvp->Zoom, state); +} diff --git a/src/editor/C4ViewportWindow.h b/src/editor/C4ViewportWindow.h new file mode 100644 index 000000000..16ce2abd8 --- /dev/null +++ b/src/editor/C4ViewportWindow.h @@ -0,0 +1,48 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ + +/* A viewport to each player */ + +#ifndef INC_C4ViewportWindow +#define INC_C4ViewportWindow + +#include +#include + +#ifdef WITH_DEVELOPER_MODE +#include +#endif +#define C4ViewportWindowStyle (WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX) +enum { ViewportScrollSpeed=10 }; + +class C4ViewportWindow: public C4Window +{ +public: + C4Viewport * cvp; + C4ViewportWindow(C4Viewport * cvp): cvp(cvp) { } +#if defined(WITH_DEVELOPER_MODE) + GtkWidget* h_scrollbar; + GtkWidget* v_scrollbar; +#endif + void EditCursorMove(int X, int Y, uint32_t); + using C4Window::Init; + C4Window * Init(int32_t iPlayer); + virtual void Close(); + virtual void PerformUpdate(); +}; + +#endif diff --git a/src/C4Application.cpp b/src/game/C4Application.cpp similarity index 84% rename from src/C4Application.cpp rename to src/game/C4Application.cpp index 6ff9e1f7b..6f74ca172 100644 --- a/src/C4Application.cpp +++ b/src/game/C4Application.cpp @@ -1,39 +1,31 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004-2005, 2007-2008 Matthes Bender - * Copyright (c) 2004-2008 Sven Eberhardt - * Copyright (c) 2005-2006, 2008-2011 Günther Brammer - * Copyright (c) 2005-2006, 2009 Peter Wortmann - * Copyright (c) 2009, 2011 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2011 Armin Burgmeier - * Copyright (c) 2011 Julius Michaelis - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Main class to initialize configuration and execute the game */ #include #include + #include #ifdef _WIN32 -#include #include #endif - #include "C4Game.h" +#include #include "C4GraphicsSystem.h" #include "C4GraphicsResource.h" #include "C4MessageInput.h" @@ -44,16 +36,12 @@ #include #include #include -#include #include #include - -#include // For DDraw emulation warning +#include #include -#include - static C4Network2IRCClient ApplicationIRCClient; C4Application::C4Application(): @@ -61,7 +49,6 @@ C4Application::C4Application(): IRCClient(ApplicationIRCClient), QuitAfterGame(false), CheckForUpdates(false), - NoSplash(false), restartAtEnd(false), pGamePadControl(NULL), AppState(C4AS_None), @@ -141,7 +128,7 @@ bool C4Application::DoInit(int argc, char * argv[]) // Load language string table if (!Languages.LoadLanguage(Config.General.LanguageEx)) // No language table was loaded - bad luck... - if (!IsResStrTableLoaded()) + if (!Languages.HasStringTable()) Log("WARNING: No language string table loaded!"); #if defined(WIN32) && defined(WITH_AUTOMATIC_UPDATE) @@ -178,16 +165,19 @@ bool C4Application::DoInit(int argc, char * argv[]) Log(C4ENGINEINFOLONG); LogF("Version: %s %s (%s)", C4VERSION, C4_OS, Revision.getData()); - // Initialize D3D/OpenGL - bool success = DDrawInit(this, isEditor, false, Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.Engine, Config.Graphics.Monitor); + // Initialize OpenGL + bool success = DDrawInit(this, !!isEditor, false, GetConfigWidth(), GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.Monitor); if (!success) { LogFatal(LoadResStr("IDS_ERR_DDRAW")); Clear(); ShowGfxErrorDialog(); return false; } if (!isEditor) { - if (!SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed)) - pWindow->SetSize(Config.Graphics.ResX, Config.Graphics.ResY); + if (!SetVideoMode(Application.GetConfigWidth(), Application.GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed)) + pWindow->SetSize(Config.Graphics.WindowX, Config.Graphics.WindowY); } + // after initializing graphics, the particle system can check for compatibility + ::Particles.DoInit(); + // Initialize gamepad if (!pGamePadControl && Config.General.GamepadEnabled) pGamePadControl = new C4GamePadControl(); @@ -226,7 +216,6 @@ void C4Application::ParseCommandLine(int argc, char * argv[]) {"editor", no_argument, &isEditor, 1}, {"fullscreen", no_argument, &isEditor, 0}, {"debugwait", no_argument, &Game.DebugWait, 1}, - {"nosplash", no_argument, &NoSplash, 1}, {"update", no_argument, &CheckForUpdates, 1}, {"noruntimejoin", no_argument, &Config.Network.NoRuntimeJoin, 1}, {"runtimejoin", no_argument, &Config.Network.NoRuntimeJoin, 0}, @@ -234,6 +223,9 @@ void C4Application::ParseCommandLine(int argc, char * argv[]) {"league", no_argument, &Config.Network.LeagueServerSignUp, 1}, {"nosignup", no_argument, &Config.Network.MasterServerSignUp, 0}, {"signup", no_argument, &Config.Network.MasterServerSignUp, 1}, + + {"debugrecread", required_argument, 0, 'K'}, + {"debugrecwrite", required_argument, 0, 'w'}, {"client", required_argument, 0, 'c'}, {"host", no_argument, 0, 'h'}, @@ -296,6 +288,28 @@ void C4Application::ParseCommandLine(int argc, char * argv[]) Game.NetworkActive = true; SCopy(optarg, Game.DirectJoinAddress, _MAX_PATH); break; + case 'K': + if (optarg && optarg[0]) + { + LogF("Reading from DebugRec file '%s'", optarg); + SCopy(optarg, Config.General.DebugRecExternalFile, _MAX_PATH); + } + else + Log("Reading DebugRec from CtrlRec file in scenario record"); + Config.General.DebugRec = 1; + Config.General.DebugRecWrite = 0; + break; + case 'w': + if (optarg && optarg[0]) + { + LogF("Writing to DebugRec file '%s'", optarg); + SCopy(optarg, Config.General.DebugRecExternalFile, _MAX_PATH); + } + else + Log("Writing DebugRec to CtrlRec file in scenario record"); + Config.General.DebugRec = 1; + Config.General.DebugRecWrite = 1; + break; case 'r': Game.Record = true; break; case 'n': Game.NetworkActive = true; break; case 'N': Game.NetworkActive = false; break; @@ -437,6 +451,9 @@ void C4Application::ParseCommandLine(int argc, char * argv[]) void C4Application::ApplyResolutionConstraints() { + // Not changing the resolution always works anyway + if (Config.Graphics.ResX == -1 && Config.Graphics.ResY == -1) + return; // Enumerate display modes int32_t idx = -1, iXRes, iYRes, iBitDepth, iRefreshRate; int32_t best_match = -1; @@ -485,9 +502,7 @@ bool C4Application::PreInit() // init loader: Black screen for first start if a video is to be shown; otherwise default spec if (fUseStartupDialog && !isEditor) { - //Log(LoadResStr("IDS_PRC_INITLOADER")); - bool fUseBlackScreenLoader = !C4Startup::WasFirstRun() && !Config.Startup.NoSplash && !NoSplash && FileExists(C4CFN_Splash); - if (!::GraphicsSystem.InitLoaderScreen(C4CFN_StartupBackgroundMain, fUseBlackScreenLoader)) + if (!::GraphicsSystem.InitLoaderScreen(C4CFN_StartupBackgroundMain)) { LogFatal(LoadResStr("IDS_PRC_ERRLOADER")); return false; } } Game.SetInitProgress(fUseStartupDialog ? 10.0f : 1.0f); @@ -539,14 +554,17 @@ void C4Application::Clear() Game.Clear(); NextMission.Clear(); // stop timer - Remove(pGameTimer); - delete pGameTimer; pGameTimer = NULL; + if (pGameTimer) + { + Remove(pGameTimer); + delete pGameTimer; pGameTimer = NULL; + } // quit irc IRCClient.Close(); // close system group (System.ocg) SystemGroup.Close(); // Log - if (IsResStrTableLoaded()) // Avoid (double and undefined) message on (second?) shutdown... + if (::Languages.HasStringTable()) // Avoid (double and undefined) message on (second?) shutdown... Log(LoadResStr("IDS_PRC_DEINIT")); // Clear external language packs and string table Languages.Clear(); @@ -624,6 +642,7 @@ void C4Application::GameTick() if (!PreInit()) Quit(); break; case C4AS_Startup: + SoundSystem.Execute(); // wait for the user to start a game break; case C4AS_StartGame: @@ -640,10 +659,14 @@ void C4Application::GameTick() QuitGame(); break; } + if(Config.Graphics.Windowed == 2 && FullScreenMode()) + Application.SetVideoMode(GetConfigWidth(), GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, true); break; case C4AS_AfterGame: // stop game Game.Clear(); + if(Config.Graphics.Windowed == 2 && !NextMission && !isEditor) + Application.SetVideoMode(GetConfigWidth(), GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, false); AppState = C4AS_PreInit; // if a next mission is desired, set to start it if (NextMission) @@ -695,8 +718,25 @@ void C4Application::OnResolutionChanged(unsigned int iXRes, unsigned int iYRes) Game.OnResolutionChanged(iXRes, iYRes); pDraw->OnResolutionChanged(iXRes, iYRes); } - if (pWindow && pWindow->pSurface) - pWindow->pSurface->UpdateSize(iXRes, iYRes); + if (pWindow) + { + if (pWindow->pSurface) + pWindow->pSurface->UpdateSize(iXRes, iYRes); + if (!FullScreenMode()) + { + C4Rect r; + pWindow->GetSize(&r); + Config.Graphics.WindowX = r.Wdt; + Config.Graphics.WindowY = r.Hgt; + } + } +} + +void C4Application::OnKeyboardLayoutChanged() +{ + // re-resolve all keys + Game.OnKeyboardLayoutChanged(); + if (AppState == C4AS_Startup) C4Startup::Get()->OnKeyboardLayoutChanged(); } bool C4Application::SetGameFont(const char *szFontFace, int32_t iFontSize) @@ -707,7 +747,7 @@ bool C4Application::SetGameFont(const char *szFontFace, int32_t iFontSize) // first, check if the selected font can be created at all // check regular font only - there's no reason why the other fonts couldn't be created CStdFont TestFont; - if (!::FontLoader.InitFont(TestFont, szFontFace, C4FontLoader::C4FT_Main, iFontSize, &::GraphicsResource.Files)) + if (!::FontLoader.InitFont(&TestFont, szFontFace, C4FontLoader::C4FT_Main, iFontSize, &::GraphicsResource.Files)) return false; // OK; reinit all fonts StdStrBuf sOldFont; sOldFont.Copy(Config.General.RXFontName); @@ -729,9 +769,13 @@ bool C4Application::SetGameFont(const char *szFontFace, int32_t iFontSize) void C4Application::OnCommand(const char *szCmd) { - // reroute to whatever seems to take commands at the moment if (AppState == C4AS_Game) ::MessageInput.ProcessInput(szCmd); + else if (AppState == C4AS_Startup) + { + AppState = C4AS_PreInit; + Game.SetScenarioFilename(szCmd); + } } void C4Application::Activate() @@ -777,11 +821,22 @@ void C4Application::NextTick() pGameTimer->Set(); } +bool C4Application::FullScreenMode() +{ + if(isEditor) + return false; + if(!Config.Graphics.Windowed) + return true; + if(Config.Graphics.Windowed == 2 && Game.IsRunning) + return true; + return false; +} + // *** C4ApplicationGameTimer C4ApplicationGameTimer::C4ApplicationGameTimer() : CStdMultimediaTimerProc(26), - iLastGameTick(0), iGameTickDelay(0) + tLastGameTick(0), iGameTickDelay(0) { } @@ -808,18 +863,18 @@ bool C4ApplicationGameTimer::Execute(int iTimeout, pollfd *) { // Check timer and reset if (!CheckAndReset()) return true; - unsigned int Now = GetTime(); + C4TimeMilliseconds tNow = C4TimeMilliseconds::Now(); // Execute - if (Now >= iLastGameTick + iGameTickDelay || Game.GameGo) + if (tNow >= tLastGameTick + iGameTickDelay || Game.GameGo) { if(iGameTickDelay) - iLastGameTick += iGameTickDelay; + tLastGameTick += iGameTickDelay; else - iLastGameTick = Now; + tLastGameTick = tNow; // Compensate if things get too slow - if (Now > iLastGameTick + iGameTickDelay) - iLastGameTick += (Now - iLastGameTick) / 2; + if (tNow > tLastGameTick + iGameTickDelay) + tLastGameTick += (tNow - tLastGameTick) / 2; Application.GameTick(); } diff --git a/src/C4Application.h b/src/game/C4Application.h similarity index 78% rename from src/C4Application.h rename to src/game/C4Application.h index 6552483d2..2bdbdc75c 100644 --- a/src/C4Application.h +++ b/src/game/C4Application.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001, 2004-2005, 2008 Sven Eberhardt - * Copyright (c) 2005-2006, 2010 Günther Brammer - * Copyright (c) 2007, 2009 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_C4Application @@ -30,7 +26,6 @@ #include class C4ApplicationGameTimer; -class C4GamePadControl; /* Main class to initialize configuration and execute the game */ @@ -50,6 +45,7 @@ public: C4InteractiveThread InteractiveThread; // IRC client for global chat C4Network2IRCClient &IRCClient; + // clear app void Clear(); void ClearCommandLine(); // Tick timing @@ -60,6 +56,7 @@ public: void CloseSystemGroup() { SystemGroup.Close(); } void SetGameTickDelay(int iDelay); virtual void OnResolutionChanged(unsigned int iXRes, unsigned int iYRes); + virtual void OnKeyboardLayoutChanged(); bool SetGameFont(const char *szFontFace, int32_t iFontSize); void NextTick(); @@ -74,12 +71,15 @@ public: // set by ParseCommandLine int isEditor; - // set by ParseCommandLine, only pertains to this program start - independent of Config.Startup.NoSplash - int NoSplash; // set by ParseCommandLine, for manually applying downloaded update packs StdStrBuf IncomingUpdate; // set by ParseCommandLine, for manually invoking an update check by command line or url - int CheckForUpdates; + int CheckForUpdates; + + bool FullScreenMode(); + int GetConfigWidth() { return (!FullScreenMode()) ? Config.Graphics.WindowX : Config.Graphics.ResX; } + int GetConfigHeight() { return (!FullScreenMode()) ? Config.Graphics.WindowY : Config.Graphics.ResY; } + protected: enum State { C4AS_None, C4AS_PreInit, C4AS_Startup, C4AS_StartGame, C4AS_Game, C4AS_AfterGame, C4AS_Quit } AppState; C4ApplicationGameTimer *pGameTimer; @@ -108,7 +108,8 @@ class C4ApplicationGameTimer : public CStdMultimediaTimerProc public: C4ApplicationGameTimer(); private: - unsigned int iLastGameTick, iGameTickDelay; + C4TimeMilliseconds tLastGameTick; + unsigned int iGameTickDelay; public: void SetGameTickDelay(uint32_t iDelay); diff --git a/src/game/C4FullScreen.cpp b/src/game/C4FullScreen.cpp new file mode 100644 index 000000000..c1805f623 --- /dev/null +++ b/src/game/C4FullScreen.cpp @@ -0,0 +1,179 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ + +/* Main class to execute the game fullscreen mode */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void C4FullScreen::CharIn(const char * c) { ::pGUI->CharIn(c); } + +C4FullScreen::C4FullScreen() +{ + pMenu = NULL; +} + +C4FullScreen::~C4FullScreen() +{ + if (pMenu) delete pMenu; + if (pSurface) delete pSurface; +} + + +C4Window * C4FullScreen::Init(C4AbstractApp * pApp) +{ + C4Rect r(0, 0, Application.GetConfigWidth(), Application.GetConfigHeight()); + return Init(C4Window::W_Fullscreen, pApp, C4ENGINECAPTION, &r); +} + +void C4FullScreen::Close() +{ + if (Game.IsRunning) + ShowAbortDlg(); + else + Application.Quit(); +} + +void C4FullScreen::Clear() +{ + if (pSurface) delete pSurface; + pSurface = 0; + C4Window::Clear(); +} + +void C4FullScreen::Execute() +{ + // Execute menu + if (pMenu) pMenu->Execute(); + // Draw + RequestUpdate(); +} + +bool C4FullScreen::ViewportCheck() +{ + int iPlrNum; C4Player *pPlr; + // Not active + if (!Active) return false; + // Determine film mode + bool fFilm = (Game.C4S.Head.Replay && Game.C4S.Head.Film); + // Check viewports + switch (::Viewports.GetViewportCount()) + { + // No viewports: create no-owner viewport + case 0: + iPlrNum = NO_OWNER; + // Film mode: create viewport for first player (instead of no-owner) + if (fFilm) + if ((pPlr = ::Players.First)) + iPlrNum = pPlr->Number; + // Create viewport + ::Viewports.CreateViewport(iPlrNum, iPlrNum==NO_OWNER); + // Non-film (observer mode) + if (!fFilm) + { + // Activate mouse control + ::MouseControl.Init(iPlrNum); + // Display message for how to open observer menu (this message will be cleared if any owned viewport opens) + StdStrBuf sKey; + sKey.Format("<%s>", Game.KeyboardInput.GetKeyCodeNameByKeyName("FullscreenMenuOpen", false).getData()); + ::GraphicsSystem.FlashMessage(FormatString(LoadResStr("IDS_MSG_PRESSORPUSHANYGAMEPADBUTT"), sKey.getData()).getData()); + } + break; + // One viewport: do nothing + case 1: + break; + // More than one viewport: remove all no-owner viewports + default: + ::Viewports.CloseViewport(NO_OWNER, true); + break; + } + // Look for no-owner viewport + C4Viewport *pNoOwnerVp = ::Viewports.GetViewport(NO_OWNER); + // No no-owner viewport found + if (!pNoOwnerVp) + { + // Close any open fullscreen menu + CloseMenu(); + } + // No-owner viewport present + else + { + // movie mode: player present, and no valid viewport assigned? + if (Game.C4S.Head.Replay && Game.C4S.Head.Film && (pPlr = ::Players.First)) + // assign viewport to joined player + pNoOwnerVp->Init(pPlr->Number, true); + } + // Done + return true; +} + +bool C4FullScreen::ShowAbortDlg() +{ + // abort dialog already shown + if (C4AbortGameDialog::IsShown()) return false; + // not while game over dialog is open + if (C4GameOverDlg::IsShown()) return false; + // show abort dialog + return ::pGUI->ShowRemoveDlg(new C4AbortGameDialog()); +} + +bool C4FullScreen::ActivateMenuMain() +{ + // Not during game over dialog + if (C4GameOverDlg::IsShown()) return false; + // Close previous + CloseMenu(); + // Open menu + pMenu = new C4MainMenu(); + return pMenu->ActivateMain(NO_OWNER); +} + +void C4FullScreen::CloseMenu() +{ + if (pMenu) + { + if (pMenu->IsActive()) pMenu->Close(false); + delete pMenu; + pMenu = NULL; + } +} + +void C4FullScreen::PerformUpdate() +{ + GraphicsSystem.Execute(); +} + +bool C4FullScreen::MenuKeyControl(BYTE byCom) +{ + if (pMenu) return pMenu->KeyControl(byCom); + return false; +} diff --git a/src/C4FullScreen.h b/src/game/C4FullScreen.h similarity index 53% rename from src/C4FullScreen.h rename to src/game/C4FullScreen.h index edc4e34fc..418a8f57e 100644 --- a/src/C4FullScreen.h +++ b/src/game/C4FullScreen.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Main class to execute the game fullscreen mode */ @@ -44,16 +41,11 @@ public: void CloseMenu(); bool MenuKeyControl(BYTE byCom); // direct keyboard callback using C4Window::Init; - virtual C4Window * Init(C4AbstractApp * pApp); + C4Window * Init(C4AbstractApp * pApp); // User requests close virtual void Close(); virtual void Clear(); virtual void CharIn(const char * c); -#ifdef USE_X11 - virtual void HandleMessage (XEvent &e); -#elif defined(USE_COCOA) - virtual void HandleMessage (/*NSEvent*/void* event); -#endif virtual void PerformUpdate(); }; diff --git a/src/C4Game.cpp b/src/game/C4Game.cpp similarity index 89% rename from src/C4Game.cpp rename to src/game/C4Game.cpp index b8f1ac57d..e41e1641d 100644 --- a/src/C4Game.cpp +++ b/src/game/C4Game.cpp @@ -1,28 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003-2005, 2007-2008 Matthes Bender - * Copyright (c) 2001-2009, 2011 Sven Eberhardt - * Copyright (c) 2001-2009 Peter Wortmann - * Copyright (c) 2004, 2011 Tobias Zwick - * Copyright (c) 2004-2011 Günther Brammer - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2008, 2010-2011 Armin Burgmeier - * Copyright (c) 2009-2010 Nicolas Hake - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Main class to run the game */ @@ -32,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -77,10 +67,11 @@ #include #include #include -#include #include - +#include #include +#include +#include class C4GameSec1Timer : public C4ApplicationSec1Timer { @@ -146,7 +137,7 @@ bool C4Game::InitDefs() if (!iDefs) { LogFatal(LoadResStr("IDS_PRC_NODEFS")); return false; } // Check def engine version (should be done immediately on def load) - iDefs=::Definitions.CheckEngineVersion(C4XVER1,C4XVER2,C4XVER3,C4XVER4); + iDefs=::Definitions.CheckEngineVersion(C4XVER1,C4XVER2,C4XVER3); if (iDefs>0) { LogF(LoadResStr("IDS_PRC_DEFSINVC4X"),iDefs); } // Check for unmet requirements @@ -155,9 +146,6 @@ bool C4Game::InitDefs() // build quick access table ::Definitions.BuildTable(); - // get default particles - Particles.SetDefParticles(); - // Done return true; } @@ -207,9 +195,9 @@ bool C4Game::OpenScenario() { LogFatal(LoadResStr("IDS_PRC_FILEINVALID")); return false; } // Check minimum engine version - if (CompareVersion(C4S.Head.C4XVer[0],C4S.Head.C4XVer[1],C4S.Head.C4XVer[2],C4S.Head.C4XVer[3]) > 0) + if (CompareVersion(C4S.Head.C4XVer[0],C4S.Head.C4XVer[1],C4S.Head.C4XVer[2]) > 0) { - LogFatal(FormatString(LoadResStr("IDS_PRC_NOREQC4X"), C4S.Head.C4XVer[0],C4S.Head.C4XVer[1],C4S.Head.C4XVer[2],C4S.Head.C4XVer[3]).getData()); + LogFatal(FormatString(LoadResStr("IDS_PRC_NOREQC4X"), C4S.Head.C4XVer[0],C4S.Head.C4XVer[1],C4S.Head.C4XVer[2]).getData()); return false; } @@ -243,17 +231,19 @@ bool C4Game::OpenScenario() if (pGrp) delete pGrp;*/ // Check mission access +#ifndef USE_CONSOLE if (C4S.Head.MissionAccess[0]) if (!SIsModule(Config.General.MissionAccess, C4S.Head.MissionAccess)) { LogFatal(LoadResStr("IDS_PRC_NOMISSIONACCESS")); return false; } +#endif // Title - Title.LoadEx(ScenarioFile, C4CFN_Title, Config.General.LanguageEx); + C4Language::LoadComponentHost(&Title, ScenarioFile, C4CFN_Title, Config.General.LanguageEx); if (!Title.GetLanguageString(Config.General.LanguageEx, ScenarioTitle)) ScenarioTitle.Copy(C4S.Head.Title); // String tables - ScenarioLangStringTable.LoadEx(ScenarioFile, C4CFN_ScriptStringTbl, Config.General.LanguageEx); + C4Language::LoadComponentHost(&ScenarioLangStringTable, ScenarioFile, C4CFN_ScriptStringTbl, Config.General.LanguageEx); // Load parameters (not as network client, because then team info has already been sent by host) if (!Network.isEnabled() || Network.isHost()) @@ -329,7 +319,12 @@ bool C4Game::PreInit() { LogFatal(LoadResStr("IDS_ERR_NOGFXSYS")); return false; } // load GUI - pGUI->Init(0, 0, Config.Graphics.ResX, Config.Graphics.ResY); + C4Rect r; + if (Application.isEditor) + Console.GetSize(&r); + else + FullScreen.GetSize(&r); + pGUI->Init(0, 0, r.Wdt, r.Hgt); fPreinited = true; @@ -341,7 +336,7 @@ bool C4Game::Init() C4ValueNumbers numbers; IsRunning = false; - InitProgress=0; LastInitProgress=0; LastInitProgressShowTime=0; + InitProgress=0; LastInitProgress=0; SetInitProgress(0); // reinit keyboard to reflect any config changes that might have been done @@ -376,7 +371,7 @@ bool C4Game::Init() { LogFatal(LoadResStr("IDS_PRC_ERREXTRA")); return false; } // init loader - if (!Application.isEditor && !GraphicsSystem.InitLoaderScreen(C4S.Head.Loader, false)) + if (!Application.isEditor && !GraphicsSystem.InitLoaderScreen(C4S.Head.Loader)) { LogFatal(LoadResStr("IDS_PRC_ERRLOADER")); return false; } } @@ -442,7 +437,7 @@ bool C4Game::Init() { LogFatal(LoadResStr("IDS_PRC_ERREXTRA")); return false; } // init loader - if (!Application.isEditor && !GraphicsSystem.InitLoaderScreen(C4S.Head.Loader, false)) + if (!Application.isEditor && !GraphicsSystem.InitLoaderScreen(C4S.Head.Loader)) { LogFatal(LoadResStr("IDS_PRC_ERRLOADER")); return false; } // Init network @@ -572,7 +567,7 @@ void C4Game::Clear() Control.Clear(); // Clear - VideoPlayer.Clear(); + if (pDraw) { pDraw->ResetGamma(); pDraw->ApplyGamma(); } Scoreboard.Clear(); MouseControl.Clear(); Players.Clear(); @@ -594,6 +589,8 @@ void C4Game::Clear() MessageInput.Clear(); Info.Clear(); Title.Clear(); + pScenarioObjectsScript = NULL; + ::MapScript.Clear(); ::GameScript.Clear(); Names.Clear(); GameText.Clear(); @@ -606,6 +603,7 @@ void C4Game::Clear() ::FontLoader.Clear(); #endif + C4PropListNumbered::ClearShelve(); // may be nonempty if there was a fatal error during section load ScriptEngine.Clear(); MainSysLangStringTable.Clear(); ScenarioLangStringTable.Clear(); @@ -618,7 +616,7 @@ void C4Game::Clear() PlayerControlDefaultAssignmentSets.Clear(); PlayerControlDefs.Clear(); ::MeshMaterialManager.Clear(); - Application.SoundSystem.Init(); // clear it up and re-init it for normal use + Application.SoundSystem.Init(); // clear it up and re-init it for startup menu use // global fullscreen class is not cleared, because it holds the carrier window // but the menu must be cleared (maybe move Fullscreen.Menu somewhere else?) @@ -631,7 +629,7 @@ void C4Game::Clear() // avoid double message by not printing it if no restbl is loaded // this would log an "[Undefined]" only, anyway // (could abort the whole clear-procedure here, btw?) - if (IsResStrTableLoaded()) Log(LoadResStr("IDS_CNS_GAMECLOSED")); + if (::Languages.HasStringTable()) Log(LoadResStr("IDS_CNS_GAMECLOSED")); // clear game starting parameters *DefinitionFilenames = *DirectJoinAddress = *ScenarioFilename = *PlayerFilenames = 0; @@ -644,6 +642,7 @@ void C4Game::Clear() fPreinited = false; C4PropListNumbered::ResetEnumerationIndex(); + // FIXME: remove this Default(); } @@ -677,7 +676,7 @@ C4ST_NEW(ControlStat, "C4Game::Execute ExecuteControl") C4ST_NEW(ExecObjectsStat, "C4Game::Execute ExecObjects") C4ST_NEW(GEStats, "C4Game::Execute pGlobalEffects->Execute") C4ST_NEW(PXSStat, "C4Game::Execute PXS.Execute") -C4ST_NEW(PartStat, "C4Game::Execute Particles.Execute") +C4ST_NEW(DynPartStat, "C4Game::Execute Particles.Execute") C4ST_NEW(MassMoverStat, "C4Game::Execute MassMover.Execute") C4ST_NEW(WeatherStat, "C4Game::Execute Weather.Execute") C4ST_NEW(PlayersStat, "C4Game::Execute Players.Execute") @@ -688,13 +687,8 @@ C4ST_NEW(MessagesStat, "C4Game::Execute Messages.Execute") #define EXEC_S(Expressions, Stat) \ { C4ST_START(Stat) Expressions C4ST_STOP(Stat) } -#ifdef DEBUGREC -#define EXEC_S_DR(Expressions, Stat, DebugRecName) { AddDbgRec(RCT_Block, DebugRecName, 6); EXEC_S(Expressions, Stat) } -#define EXEC_DR(Expressions, DebugRecName) { AddDbgRec(RCT_Block, DebugRecName, 6); Expressions } -#else -#define EXEC_S_DR(Expressions, Stat, DebugRecName) EXEC_S(Expressions, Stat) -#define EXEC_DR(Expressions, DebugRecName) Expressions -#endif +#define EXEC_S_DR(Expressions, Stat, DebugRecName) { if (Config.General.DebugRec) AddDbgRec(RCT_Block, DebugRecName, 6); EXEC_S(Expressions, Stat) } +#define EXEC_DR(Expressions, DebugRecName) { if (Config.General.DebugRec) AddDbgRec(RCT_Block, DebugRecName, 6); Expressions } bool C4Game::Execute() // Returns true if the game is over { @@ -713,9 +707,8 @@ bool C4Game::Execute() // Returns true if the game is over // Halt if (HaltCount) return false; -#ifdef DEBUGREC - Landscape.DoRelights(); -#endif + if (Config.General.DebugRec) + Landscape.DoRelights(); // Execute the control Control.Execute(); @@ -724,10 +717,12 @@ bool C4Game::Execute() // Returns true if the game is over // Ticks EXEC_DR( Ticks(); , "Ticks") -#ifdef DEBUGREC - // debugrec - AddDbgRec(RCT_DbgFrame, &FrameCounter, sizeof(int32_t)); -#endif + if (Config.General.DebugRec) + // debugrec + AddDbgRec(RCT_DbgFrame, &FrameCounter, sizeof(int32_t)); + + // allow the particle system to execute the next frame BEFORE the other game stuff is calculated since it will run in parallel to the main thread + Particles.CalculateNextStep(); // Game @@ -735,7 +730,6 @@ bool C4Game::Execute() // Returns true if the game is over if (pGlobalEffects) EXEC_S_DR( pGlobalEffects->Execute(NULL); , GEStats , "GEEx\0"); EXEC_S_DR( PXS.Execute(); , PXSStat , "PXSEx") - EXEC_S_DR( Particles.GlobalParticles.Exec(); , PartStat , "ParEx") EXEC_S_DR( MassMover.Execute(); , MassMoverStat , "MMvEx") EXEC_S_DR( Weather.Execute(); , WeatherStat , "WtrEx") EXEC_S_DR( Landscape.Execute(); , LandscapeStat , "LdsEx") @@ -765,11 +759,11 @@ bool C4Game::Execute() // Returns true if the game is over C4ST_RESETPART } -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "eGame", 6); - - Landscape.DoRelights(); -#endif + if (Config.General.DebugRec) + { + AddDbgRec(RCT_Block, "eGame", 6); + Landscape.DoRelights(); + } return true; } @@ -876,7 +870,7 @@ bool C4Game::InitMaterialTexture() TextureMap.Init(); // Cross map mats (after texture init, because Material-Texture-combinations are used) - if (!::MaterialMap.CrossMapMaterials()) return false; + if (!::MaterialMap.CrossMapMaterials(C4S.Landscape.Material)) return false; // get material script funcs ::MaterialMap.UpdateScriptPointers(); @@ -895,19 +889,20 @@ void C4Game::ClearObjectPtrs(C4Object *pObj) // check in inactive objects as well for (clnk=Objects.InactiveObjects.First; clnk && (cObj=clnk->Obj); clnk=clnk->Next) cObj->ClearPointers(pObj); - Application.SoundSystem.ClearPointers(pObj); } void C4Game::ClearPointers(C4Object * pObj) { + ::AulExec.ClearPointers(pObj); ::Objects.ForeObjects.ClearPointers(pObj); ::Messages.ClearPointers(pObj); ClearObjectPtrs(pObj); - Players.ClearPointers(pObj); + Application.SoundSystem.ClearPointers(pObj); + ::Players.ClearPointers(pObj); ::Viewports.ClearPointers(pObj); - MessageInput.ClearPointers(pObj); - Console.ClearPointers(pObj); - MouseControl.ClearPointers(pObj); + ::MessageInput.ClearPointers(pObj); + ::Console.ClearPointers(pObj); + ::MouseControl.ClearPointers(pObj); TransferZones.ClearPointers(pObj); if (pGlobalEffects) pGlobalEffects->ClearPointers(pObj); @@ -990,14 +985,15 @@ C4Object* C4Game::NewObject( C4PropList *pDef, C4Object *pCreator, { // Safety if (!pDef) return NULL; -#ifdef DEBUGREC - C4RCCreateObj rc; - memset(&rc, '\0', sizeof(rc)); - strncpy(rc.id, pDef->GetName(), 32+1); - rc.oei=C4PropListNumbered::GetEnumerationIndex()+1; - rc.x=iX; rc.y=iY; rc.ownr=iOwner; - AddDbgRec(RCT_CrObj, &rc, sizeof(rc)); -#endif + if (Config.General.DebugRec) + { + C4RCCreateObj rc; + memset(&rc, '\0', sizeof(rc)); + strncpy(rc.id, pDef->GetName(), 32+1); + rc.oei=C4PropListNumbered::GetEnumerationIndex()+1; + rc.x=iX; rc.y=iY; rc.ownr=iOwner; + AddDbgRec(RCT_CrObj, &rc, sizeof(rc)); + } // Create object C4Object *pObj; if (!(pObj=new C4Object)) return NULL; @@ -1131,10 +1127,6 @@ C4Object* C4Game::OverlapObject(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt C4Object* C4Game::FindObject(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, DWORD ocf, - const char *szAction, C4Object *pActionTarget, - C4Object *pExclude, - C4Object *pContainer, - int32_t iOwner, C4Object *pFindNext) { @@ -1159,12 +1151,9 @@ C4Object* C4Game::FindObject(C4ID id, pFindNext = NULL; } - bool bFindActIdle = SEqual(szAction, "Idle") || SEqual(szAction, "ActIdle"); - // Scan all objects for (cLnk=Objects.First; cLnk && (cObj=cLnk->Obj); cLnk=cLnk->Next) { - C4PropList* pActionDef = cObj->GetAction(); // Not skipping to find next if (!pFindNext) // Status @@ -1173,45 +1162,32 @@ C4Object* C4Game::FindObject(C4ID id, if ((id==C4ID::None) || (cObj->Def->id==id)) // OCF (match any specified) if (cObj->OCF & ocf) - // Exclude - if (cObj!=pExclude) - // Action - if (!szAction || !szAction[0] || (bFindActIdle && !pActionDef) || (pActionDef && SEqual(szAction,pActionDef->GetName())) ) - // ActionTarget - if (!pActionTarget || (pActionDef && ((cObj->Action.Target==pActionTarget) || (cObj->Action.Target2==pActionTarget)) )) - // Container - if ( !pContainer || (cObj->Contained == pContainer)) - // Owner - if ((iOwner==ANY_OWNER) || (cObj->Owner==iOwner)) - // Area - { - // Full range - if ((iX==0) && (iY==0) && (iWdt==0) && (iHgt==0)) - return cObj; - // Point - if ((iWdt==0) && (iHgt==0)) - { - if (Inside(iX-(cObj->GetX()+cObj->Shape.x),0,cObj->Shape.Wdt-1)) - if (Inside(iY-(cObj->GetY()+cObj->Shape.y),0,cObj->Shape.Hgt-1)) - return cObj; - continue; - } - // Closest - if ((iWdt==-1) && (iHgt==-1)) - { - iDistance = (cObj->GetX()-iX)*(cObj->GetX()-iX)+(cObj->GetY()-iY)*(cObj->GetY()-iY); - // same distance? - if ((iDistance == iFartherThan) && !pFindNextCpy) - return cObj; - // nearer than/first closest? - if (!pClosest || (iDistance < iClosest)) - if (iDistance > iFartherThan) - { pClosest=cObj; iClosest=iDistance; } - } - // Range - else if (Inside(cObj->GetX()-iX,0,iWdt-1) && Inside(cObj->GetY()-iY,0,iHgt-1)) - return cObj; - } + // Area + { + // Point + if ((iWdt==0) && (iHgt==0)) + { + if (Inside(iX-(cObj->GetX()+cObj->Shape.x),0,cObj->Shape.Wdt-1)) + if (Inside(iY-(cObj->GetY()+cObj->Shape.y),0,cObj->Shape.Hgt-1)) + return cObj; + continue; + } + // Closest + if ((iWdt==-1) && (iHgt==-1)) + { + iDistance = (cObj->GetX()-iX)*(cObj->GetX()-iX)+(cObj->GetY()-iY)*(cObj->GetY()-iY); + // same distance? + if ((iDistance == iFartherThan) && !pFindNextCpy) + return cObj; + // nearer than/first closest? + if (!pClosest || (iDistance < iClosest)) + if (iDistance > iFartherThan) + { pClosest=cObj; iClosest=iDistance; } + } + // Range + else if (Inside(cObj->GetX()-iX,0,iWdt-1) && Inside(cObj->GetY()-iY,0,iHgt-1)) + return cObj; + } // Find next mark reached if (cObj == pFindNextCpy) pFindNext = pFindNextCpy = NULL; @@ -1325,9 +1301,8 @@ void C4Game::ObjectRemovalCheck() // Every ::Game.iTick255 by ExecObjects void C4Game::ExecObjects() // Every Tick1 by Execute { -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "ObjEx", 6); -#endif + if (Config.General.DebugRec) + AddDbgRec(RCT_Block, "ObjEx", 6); // Execute objects - reverse order to ensure C4Object *cObj; C4ObjectLink *clnk; @@ -1339,19 +1314,14 @@ void C4Game::ExecObjects() // Every Tick1 by Execute // Status reset: process removal delay if (cObj->RemovalDelay>0) cObj->RemovalDelay--; -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "ObjCC", 6); -#endif - - // Can savely reset object marker here - Objects.LastUsedMarker = 0; + if (Config.General.DebugRec) + AddDbgRec(RCT_Block, "ObjCC", 6); // Cross check objects Objects.CrossCheck(); -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "ObjRs", 6); -#endif + if (Config.General.DebugRec) + AddDbgRec(RCT_Block, "ObjRs", 6); // Resort if (fResortAnyObject) @@ -1360,9 +1330,8 @@ void C4Game::ExecObjects() // Every Tick1 by Execute Objects.ResortUnsorted(); } -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "ObjRm", 6); -#endif + if (Config.General.DebugRec) + AddDbgRec(RCT_Block, "ObjRm", 6); // Removal if (!::Game.iTick255) ObjectRemovalCheck(); @@ -1405,9 +1374,7 @@ bool C4Game::DropDef(C4ID id, float X, float Y) C4Def *pDef; if ((pDef=C4Id2Def(id))) { - StdStrBuf str; - str.Format("CreateObject(%s,%d,%d,-1)", id.ToString(), int(X), int(Y)); - ::Control.DoInput(CID_Script, new C4ControlScript(str.getData()), CDT_Decide); + ::Control.DoInput(CID_EMMoveObj, C4ControlEMMoveObject::CreateObject(id, ftofix(X), ftofix(Y)), CDT_Decide); return true; } else @@ -1418,16 +1385,28 @@ bool C4Game::DropDef(C4ID id, float X, float Y) return false; } -void C4Game::CastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t level, int32_t tx, int32_t ty, int32_t iOwner, int32_t iController) +void C4Game::CastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t level, int32_t tx, int32_t ty, int32_t iOwner, int32_t iController, C4ValueArray *out_objects) { - int32_t cnt; + int32_t cnt, out_obj_size=0; + if (out_objects) + { + out_obj_size = out_objects->GetSize(); + out_objects->SetSize(out_obj_size + num); + } for (cnt=0; cntStatus && out_objects) (*out_objects)[out_obj_size+cnt] = C4VObj(obj); } } @@ -1457,7 +1436,7 @@ void C4Game::Default() TimeGo=false; Time=0; StartTime=0; - InitProgress=0; LastInitProgress=0; LastInitProgressShowTime=0; + InitProgress=0; LastInitProgress=0; FPS=cFPS=0; fScriptCreatedObjects=false; fLobby=fObserve=false; @@ -1549,7 +1528,7 @@ void C4Game::DrawCursors(C4TargetFacet &cgo, int32_t iPlayer) fctCursor.Draw(cgo.Surface,cgo.X+cox,cgo.Y+coy,cphase); if (cursor->Info) { - int32_t texthgt = ::GraphicsResource.FontRegular.iLineHgt; + int32_t texthgt = ::GraphicsResource.FontRegular.GetLineHeight(); StdStrBuf str; if (cursor->Info->Rank>0) { @@ -1645,6 +1624,10 @@ void C4Game::CompileFunc(StdCompiler *pComp, CompileSettings comp, C4ValueNumber pComp->Value(mkNamingAdapt(mkParAdapt(*pPlr, numbers), FormatString("Player%d", pPlr->ID).getData())); } + // Section load: Clear existing prop list numbering to make room for the new objects + // Numbers will be re-acquired in C4GameObjects::PostLoad + if (comp.fScenarioSection) C4PropListNumbered::ShelveNumberedPropLists(); + pComp->Value(mkParAdapt(Objects, !comp.fExact, numbers)); pComp->Name("Script"); @@ -1652,7 +1635,33 @@ void C4Game::CompileFunc(StdCompiler *pComp, CompileSettings comp, C4ValueNumber { pComp->Value(mkParAdapt(ScriptEngine, numbers)); } - pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers)); + if (comp.fScenarioSection && pComp->isCompiler()) + { + // loading scenario section: Merge effects + // Must keep old effects here even if they're dead, because the LoadScenarioSection call typically came from execution of a global effect + // and otherwise dead pointers would remain on the stack + C4Effect *pOldGlobalEffects, *pNextOldGlobalEffects=pGlobalEffects; + pGlobalEffects = NULL; + try + { + pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers)); + } + catch (...) + { + delete pNextOldGlobalEffects; + throw; + } + while ((pOldGlobalEffects=pNextOldGlobalEffects)) + { + pNextOldGlobalEffects = pOldGlobalEffects->pNext; + pOldGlobalEffects->Register(NULL, Abs(pOldGlobalEffects->iPriority)); + } + } + else + { + // Otherwise, just compile effects + pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers)); + } pComp->Value(mkNamingAdapt(*numbers, "Values")); pComp->NameEnd(); } @@ -1683,19 +1692,51 @@ bool C4Game::CompileRuntimeData(C4Group &hGroup, bool fLoadSection, bool exact, bool C4Game::SaveData(C4Group &hGroup, bool fSaveSection, bool fSaveExact, C4ValueNumbers * numbers) { - StdStrBuf Buf; - // Decompile (without players for scenario sections) - DecompileToBuf_Log(mkParAdapt(*this, CompileSettings(fSaveSection, !fSaveSection && fSaveExact, fSaveExact), numbers), &Buf, "Game"); - - // Empty? All default; just remove from group then - if (!Buf.getLength()) + if (fSaveExact) { - hGroup.Delete(C4CFN_Game); - return true; - } + StdStrBuf Buf; + // Decompile (without players for scenario sections) + DecompileToBuf_Log(mkParAdapt(*this, CompileSettings(fSaveSection, !fSaveSection && fSaveExact, fSaveExact), numbers), &Buf, "Game"); - // Save - return hGroup.Add(C4CFN_Game,Buf,false,true); + // Clear alternate saving method + hGroup.Delete(C4CFN_ScenarioObjectsScript); + + // Empty? All default; just remove from group then + if (!Buf.getLength()) + { + hGroup.Delete(C4CFN_Game); + return true; + } + + // Save + return hGroup.Add(C4CFN_Game,Buf,false,true); + } + else + { + // Clear alternate saving method + hGroup.Delete(C4CFN_Game); + + // Save objects to file using system scripts + int32_t objects_file_handle = ::ScriptEngine.CreateUserFile(); + C4AulParSet pars(C4VInt(objects_file_handle)); + bool result = !!::ScriptEngine.GetPropList()->Call(PSF_SaveScenarioObjects, &pars); + C4AulUserFile *file = ::ScriptEngine.GetUserFile(objects_file_handle); + if (!result || !file || !file->GetFileLength()) + { + // Nothing written? Then we don't have objects. + hGroup.Delete(C4CFN_ScenarioObjectsScript); + // That's OK; not an error. + result = true; + } + else + { + // Write objects script to file! + StdStrBuf data = file->GrabFileContents(); + result = hGroup.Add(C4CFN_ScenarioObjectsScript,data,false,true); + } + ::ScriptEngine.CloseUserFile(objects_file_handle); + return result; + } } bool C4Game::SaveGameTitle(C4Group &hGroup) @@ -1704,11 +1745,13 @@ bool C4Game::SaveGameTitle(C4Group &hGroup) // Game not running if (!FrameCounter) { - char *bpBytes; size_t iSize; - if (ScenarioFile.LoadEntry(C4CFN_ScenarioTitle,&bpBytes,&iSize)) - hGroup.Add(C4CFN_ScenarioTitle,bpBytes,iSize,false,true); - if (ScenarioFile.LoadEntry(C4CFN_ScenarioTitlePNG,&bpBytes,&iSize)) - hGroup.Add(C4CFN_ScenarioTitlePNG,bpBytes,iSize,false,true); + char* bpBytes; + size_t iSize; + StdStrBuf realFilename; + + if(ScenarioFile.FindEntry(FormatString("%s.*",C4CFN_ScenarioTitle).getData(),&realFilename,&iSize)) + if (ScenarioFile.LoadEntry(realFilename.getData(),&bpBytes,&iSize)) + hGroup.Add(realFilename.getData(),bpBytes,iSize,false,true); } // Fullscreen screenshot @@ -1719,15 +1762,14 @@ bool C4Game::SaveGameTitle(C4Group &hGroup) // Fullscreen pDraw->Blit(FullScreen.pSurface, - 0.0f,0.0f,float(C4GUI::GetScreenWdt()),float(C4GUI::GetScreenHgt()-::GraphicsResource.FontRegular.iLineHgt), + 0.0f,0.0f,float(C4GUI::GetScreenWdt()),float(C4GUI::GetScreenHgt()-::GraphicsResource.FontRegular.GetLineHeight()), sfcPic,0,0,iSfcWdt,iSfcHgt); bool fOkay=true; - const char *szDestFn; fOkay = sfcPic->SavePNG(Config.AtTempPath(C4CFN_TempTitle), false, true, false); - szDestFn = C4CFN_ScenarioTitlePNG; + StdStrBuf destFilename = FormatString("%s.png",C4CFN_ScenarioTitle); delete sfcPic; if (!fOkay) return false; - if (!hGroup.Move(Config.AtTempPath(C4CFN_TempTitle),szDestFn)) return false; + if (!hGroup.Move(Config.AtTempPath(C4CFN_TempTitle),destFilename.getData())) return false; } return true; @@ -1897,6 +1939,8 @@ bool C4Game::ReloadDef(C4ID id) // syncronize (close menus with dead surfaces, etc.) // no need to sync back player files, though Synchronize(false); + // SolidMasks might be updated + C4SolidMask::RemoveSolidMasks(); // reload def C4ObjectLink *clnk; C4Def *pDef = ::Definitions.ID2Def(id); @@ -1932,6 +1976,8 @@ bool C4Game::ReloadDef(C4ID id) } // update game messages ::Messages.UpdateDef(id); + // re-put removed SolidMasks + C4SolidMask::PutSolidMasks(); // done return fSucc; } @@ -1943,7 +1989,7 @@ bool C4Game::ReloadParticle(const char *szName) // safety if (!szName) return false; // get particle def - C4ParticleDef *pDef=Particles.GetDef(szName); + C4ParticleDef *pDef = Particles.definitions.GetDef(szName); if (!pDef) return false; // verbose LogF("Reloading particle %s from %s",pDef->Name.getData(),GetFilename(pDef->Filename.getData())); @@ -1951,7 +1997,7 @@ bool C4Game::ReloadParticle(const char *szName) if (!pDef->Reload()) { // safer: remove all particles - ParticleSystem.ClearParticles(); + ::Particles.ClearAllParticles(); // clear def delete pDef; // log @@ -1965,6 +2011,17 @@ bool C4Game::ReloadParticle(const char *szName) bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4ValueNumbers * numbers) { + // Activate debugger if requested + // needs to happen before any scripts are compiled to bytecode so AB_DEBUG chunks will be inserted + if (DebugPort) + { + if (Parameters.isLeague()) + Log("Debugger disabled. Not allowed in league."); + else + if (!::C4AulDebug::InitDebug(DebugPassword.getData(), DebugHost.getData())) + return false; + } + if (!fLoadSection) { @@ -2014,7 +2071,11 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4Value SetInitProgress(55); // Scenario scripts (and local system.ocg) - GameScript.Load(ScenarioFile, C4CFN_Script, Config.General.LanguageEx, &ScenarioLangStringTable); + ::GameScript.Load(ScenarioFile, C4CFN_Script, Config.General.LanguageEx, &ScenarioLangStringTable); + // Map scripts + ::MapScript.Load(ScenarioFile, C4CFN_MapScript, Config.General.LanguageEx, &ScenarioLangStringTable); + // Scenario objects + pScenarioObjectsScript->Load(ScenarioFile, C4CFN_ScenarioObjectsScript, Config.General.LanguageEx, &ScenarioLangStringTable); // After defs to get overloading priority if (!LoadAdditionalSystemGroup(ScenarioFile)) { LogFatal(LoadResStr("IDS_PRC_FAIL")); return false; } @@ -2036,14 +2097,10 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4Value // Materials if (!InitMaterialTexture()) { LogFatal(LoadResStr("IDS_PRC_MATERROR")); return false; } - SetInitProgress(59); - - // Videos - if (!VideoPlayer.PreloadVideos(hGroup)) return false; SetInitProgress(60); } - // Load setion sounds + // Load section sounds Application.SoundSystem.LoadEffects(hGroup); // determine startup player count @@ -2117,6 +2174,10 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4Value // Okay; everything in denumerated state from now on PointersDenumerated = true; + // scenario objects script + if (!GameText.GetData() && pScenarioObjectsScript && pScenarioObjectsScript->GetPropList()) + pScenarioObjectsScript->GetPropList()->Call(PSF_InitializeObjects); + // Environment if (!C4S.Head.NoInitialize && fLandscapeLoaded) { @@ -2204,6 +2265,7 @@ bool C4Game::InitScriptEngine() InitCoreFunctionMap(&ScriptEngine); InitObjectFunctionMap(&ScriptEngine); InitGameFunctionMap(&ScriptEngine); + ::MapScript.InitFunctionMap(&ScriptEngine); // system functions: check if system group is open if (!Application.OpenSystemGroup()) @@ -2225,6 +2287,10 @@ bool C4Game::InitScriptEngine() if (!File.IsPacked() && Game.pFileMonitor) Game.pFileMonitor->AddDirectory(File.GetFullName().getData()); + // Prepare host for Objects.c script + pScenarioObjectsScript = new C4ScenarioObjectsScriptHost(); + pScenarioObjectsScript->Reg2List(&::ScriptEngine); + // load standard clonk names Names.Load(File, C4CFN_Names); @@ -2238,10 +2304,9 @@ bool C4Game::LinkScriptEngine() // Set name list for globals ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames); - - // Activate debugger if requested - if (DebugPort) - if (!::C4AulDebug::InitDebug(DebugPort, DebugPassword.getData(), DebugHost.getData(), !!DebugWait)) + + if (C4AulDebug *pDebug = C4AulDebug::GetDebugger()) + if (!pDebug->Listen(DebugPort, !!DebugWait)) return false; return true; @@ -2278,7 +2343,7 @@ bool C4Game::InitPlayers(C4ValueNumbers * numbers) if (!PlayerInfos.RestoreSavegameInfos(RestorePlayerInfos)) { LogFatal(LoadResStr("IDS_ERR_NOPLRSAVEINFORECR")); return false; } RestorePlayerInfos.Clear(); - // try to associate local filenames (non-net+replay) or ressources (net) with all player infos + // try to associate local filenames (non-net+replay) or resources (net) with all player infos if (!PlayerInfos.RecreatePlayerFiles()) { LogFatal(LoadResStr("IDS_ERR_NOPLRFILERECR")); return false; } // recreate players by joining all players whose joined-flag is already set @@ -2419,13 +2484,13 @@ bool C4Game::PlaceInEarth(C4ID id) return false; } -C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth) +C4Object* C4Game::PlaceVegetation(C4PropList * PropList, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth) { int32_t cnt,iTx,iTy,iMaterial; // Get definition - C4Def *pDef; - if (!(pDef=C4Id2Def(id))) return NULL; + C4Def* pDef; + if (!PropList || !(pDef = PropList->GetDef())) return NULL; // No growth specified: full growth if (iGrowth<=0) @@ -2434,7 +2499,7 @@ C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, } // Place by placement type - switch (pDef->Placement) + switch (PropList->GetPropertyInt(P_Placement)) { // Surface soil @@ -2463,7 +2528,7 @@ C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, if (iMaterial!=MNone) if (::MaterialMap.Map[iMaterial].Soil) { iTy+=5; - return CreateObjectConstruction(C4Id2Def(id),NULL,NO_OWNER,iTx,iTy,iGrowth); + return CreateObjectConstruction(PropList,NULL,NO_OWNER,iTx,iTy,iGrowth); } } break; @@ -2480,7 +2545,7 @@ C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, if (!SemiAboveSolid(iTx,iTy)) return NULL; iTy+=3; // Create object - return CreateObjectConstruction(C4Id2Def(id),NULL,NO_OWNER,iTx,iTy,iGrowth); + return CreateObjectConstruction(PropList,NULL,NO_OWNER,iTx,iTy,iGrowth); break; // Underground/Tunnel @@ -2501,7 +2566,7 @@ C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, { // Create object iTy+=5; - return CreateObjectConstruction(C4Id2Def(id),NULL,NO_OWNER,iTx,iTy,iGrowth); + return CreateObjectConstruction(PropList,NULL,NO_OWNER,iTx,iTy,iGrowth); } } @@ -2526,7 +2591,7 @@ C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, if (iMaterial!=MNone) if (::MaterialMap.Map[iMaterial].Soil) { iTy+=5; - return CreateObjectConstruction(C4Id2Def(id),NULL,NO_OWNER,iTx,iTy,iGrowth); + return CreateObjectConstruction(PropList,NULL,NO_OWNER,iTx,iTy,iGrowth); } } @@ -2536,13 +2601,13 @@ C4Object* C4Game::PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, return NULL; } -C4Object* C4Game::PlaceAnimal(C4ID idAnimal) +C4Object* C4Game::PlaceAnimal(C4PropList* PropList) { - C4Def *pDef=C4Id2Def(idAnimal); - if (!pDef) return NULL; + C4Def * pDef; + if (!PropList || !(pDef = PropList->GetDef())) return NULL; int32_t iX,iY; // Placement - switch (pDef->Placement) + switch (PropList->GetPropertyInt(P_Placement)) { // Running free case C4D_Place_Surface: @@ -2568,7 +2633,7 @@ C4Object* C4Game::PlaceAnimal(C4ID idAnimal) return NULL; } // Create object - return CreateObject(idAnimal,NULL,NO_OWNER,iX,iY); + return CreateObject(PropList,NULL,NO_OWNER,iX,iY); } void C4Game::InitInEarth() @@ -2599,7 +2664,7 @@ void C4Game::InitVegetation() // Place vegetation if (vidnum>0) for (cnt=0; cntScenarioLoad(fn)) + if (!pSection->ScenarioLoad(ScenarioFile, fn)) { LogFatal(FormatString(LoadResStr("IDS_ERR_SCENSECTION"), fn).getData()); return false; } } @@ -2658,7 +2723,7 @@ bool C4Game::LoadAdditionalSystemGroup(C4Group &parent_group) if (SysGroup.OpenAsChild(&parent_group, C4CFN_System)) { C4LangStringTable SysGroupString; - SysGroupString.LoadEx(SysGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx); + C4Language::LoadComponentHost(&SysGroupString, SysGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx); // load custom scenario control definitions if (SysGroup.FindEntry(C4CFN_PlayerControls)) { @@ -2703,9 +2768,9 @@ bool C4Game::InitKeyboard() // globals KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F3 ), "MusicToggle", C4KeyScope(KEYSCOPE_Generic | KEYSCOPE_Gui), new C4KeyCB (Application.MusicSystem, &C4MusicSystem::ToggleOnOff))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F9 ), "Screenshot", C4KeyScope(KEYSCOPE_Fullscreen | KEYSCOPE_Gui), new C4KeyCBEx(GraphicsSystem, false, &C4GraphicsSystem::SaveScreenshot))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F9, KEYS_Control), "ScreenshotEx", KEYSCOPE_Fullscreen, new C4KeyCBEx(GraphicsSystem, true, &C4GraphicsSystem::SaveScreenshot))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(KEY_C, KEYS_Alt), "ToggleChat", C4KeyScope(KEYSCOPE_Generic | KEYSCOPE_Gui), new C4KeyCB (*this, &C4Game::ToggleChat))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F9 ), "Screenshot", C4KeyScope(KEYSCOPE_Fullscreen | KEYSCOPE_Gui), new C4KeyCBEx(GraphicsSystem, false, &C4GraphicsSystem::SaveScreenshotKey))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F9, KEYS_Control), "ScreenshotEx", KEYSCOPE_Fullscreen, new C4KeyCBEx(GraphicsSystem, true, &C4GraphicsSystem::SaveScreenshotKey))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_C, KEYS_Alt), "ToggleChat", C4KeyScope(KEYSCOPE_Generic | KEYSCOPE_Gui), new C4KeyCB (*this, &C4Game::ToggleChat))); // main ingame KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F1 ), "ToggleShowHelp", KEYSCOPE_Generic, new C4KeyCB (GraphicsSystem, &C4GraphicsSystem::ToggleShowHelp))); @@ -2776,10 +2841,10 @@ bool C4Game::InitKeyboard() KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SPACE ), "EditCursorModeToggle", KEYSCOPE_Console, new C4KeyCB (Console.EditCursor, &C4EditCursor::ToggleMode))); KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_ADD ), "ToolsDlgGradeUp", KEYSCOPE_Console, new C4KeyCBEx(Console.ToolsDlg, +5, &C4ToolsDlg::ChangeGrade))); KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SUBTRACT ), "ToolsDlgGradeDown", KEYSCOPE_Console, new C4KeyCBEx(Console.ToolsDlg, -5, &C4ToolsDlg::ChangeGrade))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(KEY_M, KEYS_Control), "ToolsDlgPopMaterial", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::PopMaterial))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(KEY_T, KEYS_Control), "ToolsDlgPopTextures", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::PopTextures))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(KEY_I, KEYS_Control), "ToolsDlgIFTToggle", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::ToggleIFT))); - KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(KEY_W, KEYS_Control), "ToolsDlgToolToggle", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::ToggleTool))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_M, KEYS_Control), "ToolsDlgPopMaterial", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::PopMaterial))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_T, KEYS_Control), "ToolsDlgPopTextures", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::PopTextures))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_I, KEYS_Control), "ToolsDlgIFTToggle", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::ToggleIFT))); + KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_W, KEYS_Control), "ToolsDlgToolToggle", KEYSCOPE_Console, new C4KeyCB (Console.ToolsDlg, &C4ToolsDlg::ToggleTool))); KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_DELETE ), "EditCursorDelete", KEYSCOPE_Console, new C4KeyCB (Console.EditCursor, &C4EditCursor::Delete))); // no default keys assigned @@ -2800,7 +2865,7 @@ bool C4Game::InitKeyboard() void C4Game::UpdateLanguage() { // Reload System.ocg string table - MainSysLangStringTable.LoadEx(Application.SystemGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx); + C4Language::LoadComponentHost(&MainSysLangStringTable, Application.SystemGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx); } bool C4Game::InitPlayerControlSettings() @@ -2920,7 +2985,7 @@ void C4Game::Synchronize(bool fSavePlayerFiles) // callback to network if (Network.isEnabled()) Network.OnGameSynchronized(); // TransferZone synchronization: Must do this after dynamic creation to avoid synchronization loss - // if UpdateTransferZone-callbacks do sync-relevant changes + // if OnSynchronized-callbacks do sync-relevant changes TransferZones.Synchronize(); } @@ -3137,7 +3202,6 @@ void C4Game::SetInitProgress(float fToProgress) if (InitProgress > LastInitProgress) { LastInitProgress=InitProgress; - LastInitProgressShowTime=GetTime(); GraphicsSystem.MessageBoard.LogNotify(); } // Cheap hack to get the Console window updated while loading @@ -3156,6 +3220,13 @@ void C4Game::OnResolutionChanged(unsigned int iXRes, unsigned int iYRes) ::Viewports.RecalculateViewports(); } +void C4Game::OnKeyboardLayoutChanged() +{ + // Layout changed: Re-resolve keys + PlayerControlDefaultAssignmentSets.ResolveRefs(&PlayerControlDefs); + PlayerControlUserAssignmentSets.ResolveRefs(&PlayerControlDefs); +} + bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags) { // note on scenario section saving: @@ -3182,6 +3253,7 @@ bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags) if (!pCurrentScenarioSection) { pCurrentScenarioSection = new C4ScenarioSection(CurrentScenarioSection); + pCurrentScenarioSection->pObjectScripts = Game.pScenarioObjectsScript; if (!*CurrentScenarioSection) SCopy(C4ScenSect_Main, CurrentScenarioSection, C4MaxName); } // save current section state @@ -3271,7 +3343,7 @@ bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags) } DeleteObjects(false); // remove global effects - if (pGlobalEffects) if (~dwFlags | C4S_KEEP_EFFECTS) + if (pGlobalEffects) if (!(dwFlags & C4S_KEEP_EFFECTS)) { pGlobalEffects->ClearAll(NULL, C4FxCall_RemoveClear); // scenario section call might have been done from a global effect @@ -3279,7 +3351,7 @@ bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags) //delete pGlobalEffects; pGlobalEffects=NULL; } // del particles as well - Particles.ClearParticles(); + Particles.ClearAllParticles(); // clear transfer zones TransferZones.Clear(); // backup old sky @@ -3289,6 +3361,8 @@ bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags) C4S.Load(*pGrp, true); // determine whether a new sky has to be loaded bool fLoadNewSky = !SEqualNoCase(szOldSky, C4S.Landscape.SkyDef) || pGrp->FindEntry(C4CFN_Sky ".*"); + // set new Objects.c source + Game.pScenarioObjectsScript = pLoadSect->pObjectScripts; // re-init game in new section C4ValueNumbers numbers; if (!InitGame(*pGrp, true, fLoadNewSky, &numbers)) @@ -3296,6 +3370,8 @@ bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags) DebugLog("LoadScenarioSection: Error reiniting game"); return false; } + // restore shelved proplists in case loading failed + C4PropListNumbered::UnshelveNumberedPropLists(); // set new current section pCurrentScenarioSection = pLoadSect; SCopy(pCurrentScenarioSection->szName, CurrentScenarioSection); diff --git a/src/C4Game.h b/src/game/C4Game.h similarity index 89% rename from src/C4Game.h rename to src/game/C4Game.h index 4803dc42a..623550854 100644 --- a/src/C4Game.h +++ b/src/game/C4Game.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007-2008 Matthes Bender - * Copyright (c) 2001-2002, 2004-2005, 2008-2009 Sven Eberhardt - * Copyright (c) 2004, 2006 Peter Wortmann - * Copyright (c) 2005, 2009, 2011 Günther Brammer - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Main class to run the game */ @@ -29,7 +24,6 @@ #include #include #include "C4Scoreboard.h" -#include #include class C4Game @@ -79,12 +73,12 @@ public: C4GroupSet GroupSet; C4Group *pParentGroup; C4Extra Extra; + class C4ScenarioObjectsScriptHost *pScenarioObjectsScript; C4ScenarioSection *pScenarioSections, *pCurrentScenarioSection; C4Effect *pGlobalEffects; C4PlayerControlDefs PlayerControlDefs; C4PlayerControlAssignmentSets PlayerControlUserAssignmentSets, PlayerControlDefaultAssignmentSets; C4Scoreboard Scoreboard; - C4VideoPlayer VideoPlayer; C4Network2Stats *pNetworkStatistics; // may be NULL if no statistics are recorded C4KeyboardInput &KeyboardInput; C4FileMonitor *pFileMonitor; @@ -159,6 +153,7 @@ public: bool QuickSave(const char *strFilename, const char *strTitle, bool fForceSave=false); void SetInitProgress(float fToProgress); void OnResolutionChanged(unsigned int iXRes, unsigned int iYRes); // update anything that's dependant on screen resolution + void OnKeyboardLayoutChanged(); void InitFullscreenComponents(bool fRunning); bool ToggleChat(); // Pause @@ -197,10 +192,6 @@ public: C4Object *FindObject(C4ID id, int32_t iX=0, int32_t iY=0, int32_t iWdt=0, int32_t iHgt=0, DWORD ocf=OCF_All, - const char *szAction=NULL, C4Object *pActionTarget=NULL, - C4Object *pExclude=NULL, - C4Object *pContainer=NULL, - int32_t iOwner=ANY_OWNER, C4Object *pFindNext=NULL); C4Object *FindVisObject( // find object in view at pos, regarding parallaxity and visibility (but not distance) float tx, float ty, int32_t iPlr, const C4Facet &fctViewportGame, const C4Facet &fctViewportGUI, @@ -215,9 +206,9 @@ public: C4Object *pContainer=NULL, int32_t iOwner=ANY_OWNER);*/ int32_t ObjectCount(C4ID id); - void CastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t level, int32_t tx, int32_t ty, int32_t iOwner=NO_OWNER, int32_t iController=NO_OWNER); - C4Object *PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth); - C4Object *PlaceAnimal(C4ID idAnimal); + void CastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t level, int32_t tx, int32_t ty, int32_t iOwner=NO_OWNER, int32_t iController=NO_OWNER, C4ValueArray *out_objects=NULL); + C4Object *PlaceVegetation(C4PropList *def, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth); + C4Object *PlaceAnimal(C4PropList *def); bool LoadScenarioSection(const char *szSection, DWORD dwFlags); bool SaveDesc(C4Group &hGroup, bool fSaveGame=false, bool fReference=false, bool fLobby=false, bool fUnregistered=false, bool fRecord=false); diff --git a/src/game/C4GameVersion.h b/src/game/C4GameVersion.h index f3878a537..af897a3bc 100644 --- a/src/game/C4GameVersion.h +++ b/src/game/C4GameVersion.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005, 2007 Peter Wortmann - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef C4GAMEVERSION_H @@ -28,14 +25,14 @@ struct C4GameVersion ValidatedStdCopyStrBuf sEngineName; // status only - not used for comparison int32_t iVer[4]; - C4GameVersion(const char *szEngine=C4ENGINENAME, int32_t iVer1=C4XVER1, int32_t iVer2=C4XVER2, int32_t iVer3=C4XVER3, int32_t iVer4=C4XVER4) - { Set(szEngine, iVer1, iVer2, iVer3, iVer4); } - void Set(const char *szEngine=C4ENGINENAME, int32_t iVer1=C4XVER1, int32_t iVer2=C4XVER2, int32_t iVer3=C4XVER3, int32_t iVer4=C4XVER4) - { sEngineName.CopyValidated(szEngine); iVer[0]=iVer1; iVer[1]=iVer2; iVer[2]=iVer3; iVer[3]=iVer4; } + C4GameVersion(const char *szEngine=C4ENGINENAME, int32_t iVer1=C4XVER1, int32_t iVer2=C4XVER2, int32_t iVer3=C4XVER3) + { Set(szEngine, iVer1, iVer2, iVer3); } + void Set(const char *szEngine=C4ENGINENAME, int32_t iVer1=C4XVER1, int32_t iVer2=C4XVER2, int32_t iVer3=C4XVER3) + { sEngineName.CopyValidated(szEngine); iVer[0]=iVer1; iVer[1]=iVer2; iVer[2]=iVer3; } StdStrBuf GetString() const - { return FormatString("%s %d.%d.%d [%03d]", sEngineName.getData(), (int)iVer[0], (int)iVer[1], (int)iVer[2], (int)iVer[3]); } + { return FormatString("%s %d.%d.%d", sEngineName.getData(), (int)iVer[0], (int)iVer[1], (int)iVer[2]); } bool operator == (const C4GameVersion &rCmp) const - { return /*sEngineName==rCmp.sEngineName &&*/ iVer[0]==rCmp.iVer[0] && iVer[1]==rCmp.iVer[1] && iVer[2]==rCmp.iVer[2] && iVer[3]==rCmp.iVer[3]; } + { return /*sEngineName==rCmp.sEngineName &&*/ iVer[0]==rCmp.iVer[0] && iVer[1]==rCmp.iVer[1] && iVer[2]==rCmp.iVer[2]; } void CompileFunc(StdCompiler *pComp, bool fEngineName) { @@ -46,18 +43,17 @@ struct C4GameVersion } else if (pComp->isCompiler()) sEngineName = ""; - pComp->Value(mkArrayAdapt(iVer,4,0));; + pComp->Value(mkArrayAdapt(iVer,3,0));; } }; // helper -inline int CompareVersion(int iVer1, int iVer2, int iVer3, int iVer4, - int iRVer1 = C4XVER1, int iRVer2 = C4XVER2, int iRVer3 = C4XVER3, int iRVer4 = C4XVER4) +inline int CompareVersion(int iVer1, int iVer2, int iVer3, + int iRVer1 = C4XVER1, int iRVer2 = C4XVER2, int iRVer3 = C4XVER3) { if (iVer1 > iRVer1) return 1; if (iVer1 < iRVer1) return -1; if (iVer2 > iRVer2) return 1; if (iVer2 < iRVer2) return -1; if (iVer3 > iRVer3) return 1; if (iVer3 < iRVer3) return -1; - if (iVer4 > iRVer4) return 1; if (iVer4 < iRVer4) return -1; return 0; } diff --git a/src/C4GraphicsSystem.cpp b/src/game/C4GraphicsSystem.cpp similarity index 92% rename from src/C4GraphicsSystem.cpp rename to src/game/C4GraphicsSystem.cpp index 4e1d2033e..cbf88b861 100644 --- a/src/C4GraphicsSystem.cpp +++ b/src/game/C4GraphicsSystem.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004, 2008 Matthes Bender - * Copyright (c) 2001-2003, 2005-2009 Sven Eberhardt - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2005-2006, 2008-2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Operates viewports, message board and draws the game */ @@ -195,11 +191,11 @@ void C4GraphicsSystem::ClearFullscreenBackground() --iRedrawBackground; } -bool C4GraphicsSystem::InitLoaderScreen(const char *szLoaderSpec, bool fDrawBlackScreenFirst) +bool C4GraphicsSystem::InitLoaderScreen(const char *szLoaderSpec) { // create new loader; overwrite current only if successful C4LoaderScreen *pNewLoader = new C4LoaderScreen(); - pNewLoader->SetBlackScreen(fDrawBlackScreenFirst); + pNewLoader->SetBlackScreen(false); if (!pNewLoader->Init(szLoaderSpec)) { delete pNewLoader; return false; } if (pLoaderScreen) delete pLoaderScreen; pLoaderScreen = pNewLoader; @@ -215,7 +211,7 @@ void C4GraphicsSystem::EnableLoaderDrawing() if (pLoaderScreen) pLoaderScreen->SetBlackScreen(false); } -bool C4GraphicsSystem::SaveScreenshot(bool fSaveAll) +bool C4GraphicsSystem::SaveScreenshot(bool fSaveAll, float fSaveAllZoom) { // Filename char szFilename[_MAX_PATH+1]; @@ -224,7 +220,7 @@ bool C4GraphicsSystem::SaveScreenshot(bool fSaveAll) do sprintf(szFilename,"Screenshot%03i.png",iScreenshotIndex++); while (FileExists(strFilePath = Config.AtScreenshotPath(szFilename))); - bool fSuccess=DoSaveScreenshot(fSaveAll, strFilePath); + bool fSuccess=DoSaveScreenshot(fSaveAll, strFilePath, fSaveAllZoom); // log if successful/where it has been stored if (!fSuccess) LogF(LoadResStr("IDS_PRC_SCREENSHOTERROR"), Config.AtUserDataRelativePath(Config.AtScreenshotPath(szFilename))); @@ -234,7 +230,7 @@ bool C4GraphicsSystem::SaveScreenshot(bool fSaveAll) return !!fSuccess; } -bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename) +bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename, float fSaveAllZoom) { // Fullscreen only if (Application.isEditor) return false; @@ -244,10 +240,12 @@ bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename) // save landscape if (fSaveAll) { + // Create full map screenshots at zoom 2x. Fractional zooms (like 1.7x) should work but might cause some trouble at screen borders. + float zoom = fSaveAllZoom; // get viewport to draw in C4Viewport *pVP=::Viewports.GetFirstViewport(); if (!pVP) return false; // create image large enough to hold the landcape - CPNGFile png; int32_t lWdt=GBackWdt,lHgt=GBackHgt; + CPNGFile png; int32_t lWdt=GBackWdt * zoom,lHgt=GBackHgt * zoom; if (!png.Create(lWdt, lHgt, false)) return false; // get backbuffer size int32_t bkWdt=C4GUI::GetScreenWdt(), bkHgt=C4GUI::GetScreenHgt(); @@ -269,7 +267,7 @@ bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename) if (iX+bkWdt2>lWdt) bkWdt2-=iX+bkWdt2-lWdt; if (iY+bkHgt2>lHgt) bkHgt2-=iY+bkHgt2-lHgt; // update facet - bkFct.Set(FullScreen.pSurface, 0, 0, bkWdt2, bkHgt2, iX, iY); + bkFct.Set(FullScreen.pSurface, 0, 0, ceil(float(bkWdt2)/zoom), ceil(float(bkHgt2)/zoom), iX/zoom, iY/zoom, zoom); // draw there pVP->Draw(bkFct, false); // render @@ -314,7 +312,7 @@ void C4GraphicsSystem::DrawHoldMessages() { pDraw->TextOut("Pause", ::GraphicsResource.FontRegular,1.0, FullScreen.pSurface, C4GUI::GetScreenWdt()/2, - C4GUI::GetScreenHgt()/2 - ::GraphicsResource.FontRegular.iLineHgt*2, + C4GUI::GetScreenHgt()/2 - ::GraphicsResource.FontRegular.GetLineHeight()*2, C4Draw::DEFAULT_MESSAGE_COLOR, ACenter); ::GraphicsSystem.OverwriteBg(); } diff --git a/src/C4GraphicsSystem.h b/src/game/C4GraphicsSystem.h similarity index 67% rename from src/C4GraphicsSystem.h rename to src/game/C4GraphicsSystem.h index b4c0152d1..c8b23e766 100644 --- a/src/C4GraphicsSystem.h +++ b/src/game/C4GraphicsSystem.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2008 Matthes Bender - * Copyright (c) 2001, 2005, 2008 Sven Eberhardt - * Copyright (c) 2005, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Operates viewports, message board and draws the game */ @@ -56,10 +53,11 @@ public: void FlashMessageOnOff(const char *strWhat, bool fOn); void DeactivateDebugOutput(); bool Init(); - bool InitLoaderScreen(const char *szLoaderSpec, bool fDrawBlackScreenFirst); + bool InitLoaderScreen(const char *szLoaderSpec); void EnableLoaderDrawing(); // reset black screen loader flag - bool SaveScreenshot(bool fSaveAll); - bool DoSaveScreenshot(bool fSaveAll, const char *szFilename); + bool SaveScreenshotKey(bool fSaveAll) { return SaveScreenshot(fSaveAll, 2.0f); } // keyboard callback for creating screenshot. create at default zoom. + bool SaveScreenshot(bool fSaveAll, float fSaveAllZoom); + bool DoSaveScreenshot(bool fSaveAll, const char *szFilename, float fSaveAllZoom); inline void InvalidateBg() { iRedrawBackground=2; } inline void OverwriteBg() { InvalidateBg(); } protected: diff --git a/src/game/C4Physics.h b/src/game/C4Physics.h index 4abf5b591..eabc48594 100644 --- a/src/game/C4Physics.h +++ b/src/game/C4Physics.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2002 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Some old constants and references */ @@ -34,5 +31,6 @@ const int CornerRange=AttachRange+2; extern const C4Real HitSpeed1,HitSpeed2,HitSpeed3,HitSpeed4; extern const C4Real FloatFriction; extern const C4Real RotateAccel; +extern const C4Real DefaultGravAccel; #endif diff --git a/src/gui/C4Viewport.cpp b/src/game/C4Viewport.cpp similarity index 90% rename from src/gui/C4Viewport.cpp rename to src/game/C4Viewport.cpp index 1496cd0b0..d6794d76e 100644 --- a/src/gui/C4Viewport.cpp +++ b/src/game/C4Viewport.cpp @@ -1,27 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004, 2007-2008 Matthes Bender - * Copyright (c) 2001-2003, 2005-2010 Sven Eberhardt - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2003-2005, 2007-2008 Peter Wortmann - * Copyright (c) 2005-2011 Günther Brammer - * Copyright (c) 2006, 2010 Armin Burgmeier - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A viewport to each player */ @@ -59,11 +50,7 @@ bool C4Viewport::UpdateOutputSize() #ifdef WITH_DEVELOPER_MODE GtkAllocation allocation; -#if GTK_CHECK_VERSION(2,18,0) - gtk_widget_get_allocation(pWindow->drawing_area, &allocation); -#else - allocation = pWindow->drawing_area->allocation; -#endif + gtk_widget_get_allocation(GTK_WIDGET(pWindow->render_widget), &allocation); // Use only size of drawing area without scrollbars rect.x = allocation.x; @@ -104,7 +91,6 @@ void C4Viewport::Clear() ViewWdt=ViewHgt=0; OutX=OutY=ViewWdt=ViewHgt=0; DrawX=DrawY=0; - Regions.Clear(); ViewOffsX = ViewOffsY = 0; } @@ -212,15 +198,16 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay) if (BorderTop) pDraw->BlitSurfaceTile(::GraphicsResource.fctBackground.Surface,cgo.Surface,DrawX+BorderLeft,DrawY,ViewWdt-BorderLeft-BorderRight,BorderTop,-DrawX-BorderLeft,-DrawY); if (BorderRight) pDraw->BlitSurfaceTile(::GraphicsResource.fctBackground.Surface,cgo.Surface,DrawX+ViewWdt-BorderRight,DrawY,BorderRight,ViewHgt,-DrawX-ViewWdt+BorderRight,-DrawY); if (BorderBottom)pDraw->BlitSurfaceTile(::GraphicsResource.fctBackground.Surface,cgo.Surface,DrawX+BorderLeft,DrawY+ViewHgt-BorderBottom,ViewWdt-BorderLeft-BorderRight,BorderBottom,-DrawX-BorderLeft,-DrawY-ViewHgt+BorderBottom); - - // Set clippers - cgo.X += BorderLeft; cgo.Y += BorderTop; cgo.Wdt -= int(float(BorderLeft+BorderRight)/cgo.Zoom); cgo.Hgt -= int(float(BorderTop+BorderBottom)/cgo.Zoom); - GameZoom.X = cgo.X; GameZoom.Y = cgo.Y; - cgo.TargetX += BorderLeft/Zoom; cgo.TargetY += BorderTop/Zoom; - // Apply Zoom - pDraw->SetZoom(GameZoom); - pDraw->SetPrimaryClipper(cgo.X,cgo.Y,DrawX+ViewWdt-1-BorderRight,DrawY+ViewHgt-1-BorderBottom); } + + // Set clippers + cgo.X += BorderLeft; cgo.Y += BorderTop; cgo.Wdt -= int(float(BorderLeft+BorderRight)/cgo.Zoom); cgo.Hgt -= int(float(BorderTop+BorderBottom)/cgo.Zoom); + GameZoom.X = cgo.X; GameZoom.Y = cgo.Y; + cgo.TargetX += BorderLeft/Zoom; cgo.TargetY += BorderTop/Zoom; + // Apply Zoom + pDraw->SetZoom(GameZoom); + pDraw->SetPrimaryClipper(cgo.X,cgo.Y,DrawX+ViewWdt-1-BorderRight,DrawY+ViewHgt-1-BorderBottom); + last_game_draw_cgo = cgo; // landscape mod by FoW @@ -259,9 +246,9 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay) ::Objects.Draw(cgo, Player, 1, 2147483647 /* INT32_MAX */); C4ST_STOP(ObjStat) - // draw global particles - C4ST_STARTNEW(PartStat, "C4Viewport::Draw: Particles") - ::Particles.GlobalParticles.Draw(cgo,NULL); + // draw global dynamic particles + C4ST_STARTNEW(PartStat, "C4Viewport::Draw: Dynamic Particles") + ::Particles.DrawGlobalParticles(cgo); C4ST_STOP(PartStat) // Draw PathFinder @@ -314,11 +301,12 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay) C4ST_STOP(OvrStat) - // Remove zoom n clippers - pDraw->SetZoom(0, 0, 1.0); - pDraw->NoPrimaryClipper(); } + // Remove zoom n clippers + pDraw->SetZoom(0, 0, 1.0); + pDraw->NoPrimaryClipper(); + } void C4Viewport::BlitOutput() @@ -334,17 +322,6 @@ void C4Viewport::BlitOutput() void C4Viewport::Execute() { - // Update regions - static int32_t RegionUpdate=0; - SetRegions=NULL; - RegionUpdate++; - if (RegionUpdate>=5) - { - RegionUpdate=0; - Regions.Clear(); - Regions.SetAdjust(-OutX,-OutY); - SetRegions=&Regions; - } // Adjust position AdjustPosition(); // Current graphics output @@ -363,24 +340,36 @@ void C4Viewport::Execute() BlitOutput(); } +/* This method is called whenever the viewport size is changed. Thus, its job + is to recalculate the zoom and zoom limits with the new values for ViewWdt + and ViewHgt. */ +void C4Viewport::CalculateZoom() +{ + if(!ZoomInitialized) + InitZoom(); + + C4Player *plr = Players.Get(Player); + if (plr) + plr->ZoomLimitsToViewport(this); + else + SetZoomLimits(0.8*Min(float(ViewWdt)/GBackWdt,float(ViewHgt)/GBackHgt), 8); + +} + void C4Viewport::InitZoom() { - // player viewport: Init zoom by view range parameters C4Player *plr = Players.Get(Player); if (plr) { - // Note this affects all viewports for this player (not just - // this one), but it is a noop for the others. - plr->ZoomLimitsToViewport(this); plr->ZoomToViewport(this, true); } else { - // general viewport? Default zoom parameters ZoomTarget = Max(float(ViewWdt)/GBackWdt, 1.0f); Zoom = ZoomTarget; - SetZoomLimits(0.8*Min(float(ViewWdt)/GBackWdt,float(ViewHgt)/GBackHgt), 12); } + + ZoomInitialized = true; } void C4Viewport::ChangeZoom(float by_factor) @@ -456,7 +445,7 @@ void C4Viewport::AdjustPosition() float ViewportScrollBorder = fIsNoOwnerViewport ? 0 : float(C4ViewportScrollBorder); C4Player *pPlr = ::Players.Get(Player); - if (ZoomTarget < 0.000001f) InitZoom(); + if (ZoomTarget < 0.000001f) CalculateZoom(); // Change Zoom assert(Zoom>0); assert(ZoomTarget>0); @@ -587,12 +576,11 @@ void C4Viewport::Default() DrawX=DrawY=0; Zoom = 1.0; ZoomTarget = 0.0; + ZoomInitialized = false; ZoomLimitMin=ZoomLimitMax=0; // no limit Next=NULL; PlayerLock=true; ResetMenuPositions=false; - SetRegions=NULL; - Regions.Default(); ViewOffsX = ViewOffsY = 0; fIsNoOwnerViewport = false; last_game_draw_cgo.Default(); @@ -650,11 +638,6 @@ void C4Viewport::DrawPlayerStartup(C4TargetFacet &cgo) // Control // unnecessary with the current control sets -/* if (pPlr->MouseControl) - GfxR->fctMouse.Draw(cgo.Surface, - cgo.X+(cgo.Wdt-GfxR->fctKeyboard.Wdt)/2+55, - cgo.Y+cgo.Hgt * 2/3 - 10 + DrawMessageOffset, - 0,0);*/ if (pPlr && pPlr->ControlSet) { C4Facet controlset_facet = pPlr->ControlSet->GetPicture(); @@ -680,7 +663,7 @@ void C4Viewport::SetOutputSize(int32_t iDrawX, int32_t iDrawY, int32_t iOutX, in DrawX=iDrawX; DrawY=iDrawY; OutX=iOutX; OutY=iOutY; ViewWdt=iOutWdt; ViewHgt=iOutHgt; - InitZoom(); + CalculateZoom(); UpdateViewPosition(); // Reset menus ResetMenuPositions=true; @@ -697,7 +680,7 @@ void C4Viewport::SetOutputSize(int32_t iDrawX, int32_t iDrawY, int32_t iOutX, in void C4Viewport::ClearPointers(C4Object *pObj) { - Regions.ClearPointers(pObj); + } void C4Viewport::NextPlayer() @@ -868,11 +851,14 @@ bool C4ViewportList::CloseViewport(int32_t iPlayer, bool fSilent) else prev=cvp; } - // Recalculate viewports - RecalculateViewports(); - // Action sound - if (GetViewportCount()!=iLastCount) if (!fSilent) - StartSoundEffect("CloseViewport"); + // Anything was done? + if (GetViewportCount()!=iLastCount) + { + // Recalculate viewports + RecalculateViewports(); + // Action sound + if (!fSilent) StartSoundEffect("CloseViewport"); + } return true; } @@ -1044,14 +1030,12 @@ bool C4ViewportList::FreeScroll(C4Vec2D vScrollBy) bool C4ViewportList::ViewportZoomOut() { for (C4Viewport *vp = FirstViewport; vp; vp = vp->Next) vp->ChangeZoom(1.0f/C4GFX_ZoomStep); - if (FirstViewport) ::GraphicsSystem.FlashMessage(FormatString("%s: %f", "[!]Zoom", (float)FirstViewport->ZoomTarget).getData()); return true; } bool C4ViewportList::ViewportZoomIn() { for (C4Viewport *vp = FirstViewport; vp; vp = vp->Next) vp->ChangeZoom(C4GFX_ZoomStep); - if (FirstViewport) ::GraphicsSystem.FlashMessage(FormatString("%s: %f", "[!]Zoom", (float)FirstViewport->ZoomTarget).getData()); return true; } diff --git a/src/gui/C4Viewport.h b/src/game/C4Viewport.h similarity index 85% rename from src/gui/C4Viewport.h rename to src/game/C4Viewport.h index 6b76e48d8..080efdcff 100644 --- a/src/gui/C4Viewport.h +++ b/src/game/C4Viewport.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005, 2010 Sven Eberhardt - * Copyright (c) 2005-2006, 2008-2010 Günther Brammer - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A viewport to each player */ @@ -24,8 +20,6 @@ #ifndef INC_C4Viewport #define INC_C4Viewport -#include - #include class C4Viewport @@ -34,7 +28,6 @@ class C4Viewport public: C4Viewport(); ~C4Viewport(); - C4RegionList Regions; // "landscape" coordinates float ViewX,ViewY; int32_t ViewOffsX, ViewOffsY; @@ -56,7 +49,7 @@ public: void ClearPointers(C4Object *pObj); void SetOutputSize(int32_t iDrawX, int32_t iDrawY, int32_t iOutX, int32_t iOutY, int32_t iOutWdt, int32_t iOutHgt); void UpdateViewPosition(); // update view position: Clip properly; update border variables - void InitZoom(); + void CalculateZoom(); void ChangeZoom(float by_factor); void SetZoom(float to_zoom, bool direct=false); void SetZoomLimits(float to_min_zoom, float to_max_zoom); @@ -67,6 +60,7 @@ public: bool Init(int32_t iPlayer, bool fSetTempOnly); void DropFile(const char* fileName, float x, float y); bool TogglePlayerLock(); + bool GetPlayerLock() { return PlayerLock; } void NextPlayer(); C4Rect GetOutputRect() { return C4Rect(OutX, OutY, ViewWdt, ViewHgt); } bool IsViewportMenu(class C4Menu *pMenu); @@ -77,11 +71,11 @@ protected: float Zoom; float ZoomTarget; float ZoomLimitMin,ZoomLimitMax; + bool ZoomInitialized; int32_t Player; bool PlayerLock; int32_t OutX,OutY; bool ResetMenuPositions; - C4RegionList *SetRegions; C4Viewport *Next; class C4ViewportWindow * pWindow; C4FogOfWar ClrModMap; // color modulation map for viewport drawing @@ -90,6 +84,7 @@ protected: void DrawOverlay(C4TargetFacet &cgo, const ZoomData &GameZoom); void DrawMenu(C4TargetFacet &cgo); void DrawPlayerInfo(C4TargetFacet &cgo); + void InitZoom(); void BlitOutput(); void AdjustPosition(); public: diff --git a/src/C4WinMain.cpp b/src/game/ClonkMain.cpp similarity index 80% rename from src/C4WinMain.cpp rename to src/game/ClonkMain.cpp index 74069f23d..42f6b217f 100644 --- a/src/C4WinMain.cpp +++ b/src/game/ClonkMain.cpp @@ -1,26 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005, 2007-2008, 2010-2011 Günther Brammer - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2005, 2008 Peter Wortmann - * Copyright (c) 2006 Armin Burgmeier - * Copyright (c) 2007 Julian Raschke - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Main program entry point */ @@ -33,11 +25,11 @@ #include #include "C4Network2.h" -void InstallCrashHandler(); - #ifdef _WIN32 #include +void InstallCrashHandler(); + int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, @@ -48,6 +40,23 @@ int WINAPI WinMain (HINSTANCE hInst, _CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif + // This should be handled in an application manifest, but that is + // decidedly non-trivial to do portably across compilers and compiler + // versions, so we do it in code instead. + // Also we aren't really DPI aware (we'd have to default ingame zoom + // differently and scale the menus), but this is better than clipping. + // Fixes #891. + HMODULE user32 = LoadLibrary(L"user32"); + if (user32) + { + typedef BOOL (WINAPI *SETPROCESSDPIAWAREPROC)(); + SETPROCESSDPIAWAREPROC SetProcessDPIAware = + reinterpret_cast(GetProcAddress(user32, "SetProcessDPIAware")); + if (SetProcessDPIAware) + SetProcessDPIAware(); + FreeLibrary(user32); + } + InstallCrashHandler(); // Split wide command line to wide argv array diff --git a/src/game/landscape/C4Particles.cpp b/src/game/landscape/C4Particles.cpp deleted file mode 100644 index f43910405..000000000 --- a/src/game/landscape/C4Particles.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2002, 2004-2005 Sven Eberhardt - * Copyright (c) 2005, 2009-2010 Tobias Zwick - * Copyright (c) 2005-2006, 2008, 2010 Günther Brammer - * Copyright (c) 2008 Peter Wortmann - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ -// newgfx particle system for smoke, sparks, ... - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void C4ParticleDefCore::CompileFunc(StdCompiler * pComp) -{ - pComp->Value(mkNamingAdapt(toC4CStrBuf(Name), "Name", "")); - pComp->Value(mkNamingAdapt(MaxCount, "MaxCount", C4Px_MaxParticle)); - pComp->Value(mkNamingAdapt(MinLifetime, "MinLifetime", 0)); - pComp->Value(mkNamingAdapt(MaxLifetime, "MaxLifetime", 0)); - pComp->Value(mkNamingAdapt(toC4CStrBuf(InitFn), "InitFn", "")); - pComp->Value(mkNamingAdapt(toC4CStrBuf(ExecFn), "ExecFn", "")); - pComp->Value(mkNamingAdapt(toC4CStrBuf(CollisionFn),"CollisionFn","")); - pComp->Value(mkNamingAdapt(toC4CStrBuf(DrawFn), "DrawFn", "")); - pComp->Value(mkNamingAdapt(GfxFace, "Face")); - pComp->Value(mkNamingAdapt(YOff, "YOff", 0)); - pComp->Value(mkNamingAdapt(Delay, "Delay", 0)); - pComp->Value(mkNamingAdapt(Repeats, "Repeats", 0)); - pComp->Value(mkNamingAdapt(Reverse, "Reverse", 0)); - pComp->Value(mkNamingAdapt(FadeOutLen, "FadeOutLen", 0)); - pComp->Value(mkNamingAdapt(FadeOutDelay, "FadeOutDelay",0)); - pComp->Value(mkNamingAdapt(RByV, "RByV", 0)); - pComp->Value(mkNamingAdapt(GravityAcc, "GravityAcc", 0)); - pComp->Value(mkNamingAdapt(WindDrift, "WindDrift", 0)); - pComp->Value(mkNamingAdapt(VertexCount, "VertexCount", 0)); - pComp->Value(mkNamingAdapt(VertexY, "VertexY", 0)); - pComp->Value(mkNamingAdapt(Additive, "Additive", 0)); - pComp->Value(mkNamingAdapt(AlphaFade, "AlphaFade", 0)); - pComp->Value(mkNamingAdapt(FadeDelay, "FadeDelay", 0)); - pComp->Value(mkNamingAdapt(mkArrayAdaptDM(Parallaxity,100),"Parallaxity")); - pComp->Value(mkNamingAdapt(Attach, "Attach", 0)); -} - -C4ParticleDefCore::C4ParticleDefCore(): - MaxCount(C4Px_MaxParticle), - MinLifetime(0),MaxLifetime(0), - YOff(0), - Delay(0),Repeats(0),Reverse(0), - FadeOutLen(0),FadeOutDelay(0), - RByV(0), - Placement(0), - GravityAcc(0), - VertexCount(0),VertexY(0), - Additive(0), - Attach(0), - AlphaFade(0), - FadeDelay(0) -{ - GfxFace.Default(); - Parallaxity[0] = Parallaxity[1] = 100; -} - -bool C4ParticleDefCore::Compile(char *particle_source, const char *name) -{ - return CompileFromBuf_LogWarn(mkNamingAdapt(*this, "Particle"), - StdStrBuf(particle_source), name); -} - -C4ParticleDef::C4ParticleDef(): - C4ParticleDefCore(), - InitProc(&fxStdInit), - ExecProc(&fxStdExec), - CollisionProc(NULL), - DrawProc(&fxStdDraw), - Count(0) -{ - // zero fields - Gfx.Default(); - // link into list - if (!ParticleSystem.pDef0) - { - pPrev = NULL; - ParticleSystem.pDef0 = this; - } - else - { - pPrev = ParticleSystem.pDefL; - pPrev->pNext = this; - } - ParticleSystem.pDefL = this; - pNext = NULL; -} - -C4ParticleDef::~C4ParticleDef() -{ - // clear - Clear(); - // unlink from list - if (pPrev) pPrev->pNext = pNext; else ParticleSystem.pDef0 = pNext; - if (pNext) pNext->pPrev = pPrev; else ParticleSystem.pDefL = pPrev; -} - -void C4ParticleDef::Clear() -{ - Name.Clear(); -} - -bool C4ParticleDef::Load(C4Group &group) -{ - // store file - Filename.Copy(group.GetFullName()); - // load - char *particle_source; - if (group.LoadEntry(C4CFN_ParticleCore,&particle_source,NULL,1)) - { - if (!Compile(particle_source, Filename.getData())) - { - DebugLogF("invalid particle def at '%s'", group.GetFullName().getData()); - delete [] particle_source; return false; - } - delete [] particle_source; - // load graphics - if (!Gfx.Load(group, C4CFN_DefGraphicsPNG)) - { - DebugLogF("particle %s has no valid graphics defined", Name.getData()); - return false; - } - // set facet, if assigned - otherwise, assume full surface - if (GfxFace.Wdt) Gfx.Set(Gfx.Surface, GfxFace.x, GfxFace.y, GfxFace.Wdt, GfxFace.Hgt); - // set phase num - int32_t Q; Gfx.GetPhaseNum(PhasesX, Q); - Length = PhasesX * Q; - if (!Length) - { - DebugLogF("invalid facet for particle '%s'", Name.getData()); - return false; - } - // case fadeout from length - if (FadeOutLen) - { - Length = Max(Length - FadeOutLen, 1); - if (!FadeOutDelay) FadeOutDelay=1; - } - // if phase num is 1, no reverse is allowed - if (Length == 1) Reverse = 0; - // calc aspect - Aspect=(float) Gfx.Hgt/Gfx.Wdt; - // get proc pointers - if (!(InitProc = ParticleSystem.GetProc(InitFn.getData()))) - { - DebugLogF("init proc for particle '%s' not found: '%s'", Name.getData(), InitFn.getData()); - return false; - } - if (!(ExecProc = ParticleSystem.GetProc(ExecFn.getData()))) - { - DebugLogF("exec proc for particle '%s' not found: '%s'", Name.getData(), ExecFn.getData()); - return false; - } - if (CollisionFn && CollisionFn[0]) if (!(CollisionProc = ParticleSystem.GetProc(CollisionFn.getData()))) - { - DebugLogF("collision proc for particle '%s' not found: '%s'", Name.getData(), CollisionFn.getData()); - return false; - } - if (!(DrawProc = ParticleSystem.GetDrawProc(DrawFn.getData()))) - { - DebugLogF("draw proc for particle '%s' not found: '%s'", Name.getData(), DrawFn.getData()); - return false; - } - // particle overloading - C4ParticleDef *def_overload; - if ((def_overload = ParticleSystem.GetDef(Name.getData(), this))) - { - if (Config.Graphics.VerboseObjectLoading >= 1) - { char ostr[250]; sprintf(ostr,LoadResStr("IDS_PRC_DEFOVERLOAD"),def_overload->Name.getData(),""); Log(ostr); } - delete def_overload; - } - // success - return true; - } - return false; -} - -bool C4ParticleDef::Reload() -{ - // no file? - if (!Filename[0]) return false; - // open group - C4Group group; - if (!group.Open(Filename.getData())) return false; - // reset class - Clear(); - // load - return Load(group); -} - -void C4Particle::MoveList(C4ParticleList &from, C4ParticleList &to) -{ - // remove from current list - if (pPrev) - pPrev->pNext = pNext; - else - // is it the first item in the list? then set this to the next one - if (from.pFirst == this) from.pFirst = pNext; - if (pNext) pNext->pPrev = pPrev; - // add to the other list - insert before first - if ((pNext = to.pFirst)) pNext->pPrev = this; - to.pFirst = this; pPrev = NULL; -} - -C4ParticleChunk::C4ParticleChunk() -{ - // zero linked list - pNext=NULL; - // zero buffer - Clear(); -} - -C4ParticleChunk::~C4ParticleChunk() -{ - // list stuff done by C4ParticleSystem -} - -void C4ParticleChunk::Clear() -{ - // note that this method is called in ctor with uninitialized data! - // simply clear mem - this won't adjust any counts! - memset(Data, 0, sizeof(Data)); - // init list - C4Particle *particle=Data; - for (int32_t i=0; i < C4Px_BufSize; ++i) - { - particle->pPrev = particle-1; - particle->pNext = particle+1; - ++particle; - } - Data[0].pPrev=Data[C4Px_BufSize-1].pNext=NULL; - // all free - NumFree = C4Px_BufSize; -} - -void C4ParticleList::Exec(C4Object *object) -{ - // execute all particles - C4Particle *next_particle = pFirst, *particle; - while ((particle = next_particle)) - { - // get next now, because destruction could corrupt the list - next_particle = particle->pNext; - // execute it - if (!particle->pDef->ExecProc(particle,object)) - { - // sorry, life is over for you :P - --particle->pDef->Count; - particle->MoveList(*this, ::Particles.FreeParticles); - } - } - // done -} - -void C4ParticleList::Draw(C4TargetFacet &cgo, C4Object *object) -{ - // draw all particles - for (C4Particle *particle = pFirst; particle; particle = particle->pNext) - particle->pDef->DrawProc(particle, cgo, object); - // done -} - -void C4ParticleList::Clear() -{ - // remove all particles - C4Particle *next_particle = pFirst, *particle; - while ((particle = next_particle)) - { - // get next now, because destruction could corrupt the list - next_particle = particle->pNext; - // sorry, life is over for you :P - --particle->pDef->Count; - particle->MoveList(*this, ::Particles.FreeParticles); - } -} - -int32_t C4ParticleList::Remove(C4ParticleDef *of_def) -{ - int32_t num_removed = 0; - // check all particles for def - C4Particle *next_particle = pFirst, *particle; - while ((particle = next_particle)) - { - // get next now, because destruction could corrupt the list - next_particle = particle->pNext; - // execute it - if (!of_def || particle->pDef == of_def) - { - // sorry, life is over for you :P - --particle->pDef->Count; - particle->MoveList(*this, ::Particles.FreeParticles); - } - } - // done - return num_removed; -} - -C4ParticleSystem::C4ParticleSystem() -{ - // zero fields - pDef0=pDefL=NULL; - pSmoke=NULL; - pBlast=NULL; - pFSpark=NULL; - pFire1=NULL; - pFire2=NULL; -} - -C4ParticleSystem::~C4ParticleSystem() -{ - // clean up - Clear(); -} - -C4ParticleChunk *C4ParticleSystem::AddChunk() -{ - // add another chunk - C4ParticleChunk *new_chunk = new C4ParticleChunk(); - new_chunk->pNext = Chunk.pNext; - Chunk.pNext = new_chunk; - // register into free-particle-list - if ((new_chunk->Data[C4Px_BufSize-1].pNext = FreeParticles.pFirst)) - FreeParticles.pFirst->pPrev = &new_chunk->Data[C4Px_BufSize-1]; - FreeParticles.pFirst = &new_chunk->Data[0]; - // return it - return new_chunk; -} - -void C4ParticleSystem::PruneChunks() -{ - // check all chunks, but not the first - // that cannot be removed anyway - C4ParticleChunk *chunk = Chunk.pNext, *next_chunk, **previous_chunk_p; - previous_chunk_p = &Chunk.pNext; - do - { - next_chunk = chunk->pNext; - // chunk empty? - if (chunk->NumFree == C4Px_BufSize) - { - // move out all particles - C4ParticleList tmp; - for (int32_t i = 0; i < C4Px_BufSize; ++i) - chunk->Data[i].MoveList(FreeParticles, tmp); - // and remove the chunk - *previous_chunk_p = next_chunk; - delete chunk; - } - else - { - // keep this chunk - previous_chunk_p = &chunk->pNext; - } - } - while ((chunk = next_chunk)); -} - -void C4ParticleSystem::ClearParticles() -{ - // clear particle lists - C4ObjectLink *link; - for (link = ::Objects.First; link; link = link->Next) - link->Obj->FrontParticles.pFirst = link->Obj->BackParticles.pFirst = NULL; - for (link = ::Objects.InactiveObjects.First; link; link = link->Next) - link->Obj->FrontParticles.pFirst = link->Obj->BackParticles.pFirst = NULL; - GlobalParticles.pFirst = NULL; - // reset chunks - C4ParticleChunk *next_chunk = Chunk.pNext, *chunk; - while ((chunk = next_chunk)) - { - next_chunk = chunk->pNext; - delete chunk; - } - Chunk.pNext = NULL; - Chunk.Clear(); - FreeParticles.pFirst = Chunk.Data; - // adjust counts - for (C4ParticleDef *def=pDef0; def; def=def->pNext) - def->Count=0; -} - -void C4ParticleSystem::Clear() -{ - // clear particles first - ClearParticles(); - // clear defs - while (pDef0) delete pDef0; - // clear system particles - pSmoke = pBlast = pFSpark = pFire1 = pFire2 = NULL; - // done -} - -C4Particle *C4ParticleSystem::Create(C4ParticleDef *of_def, - float x, float y, - float xdir, float ydir, - float a, int32_t b, C4ParticleList *pxList, - C4Object *object) -{ - // safety - if (!of_def) return NULL; - // default to global list - if (!pxList) pxList = &GlobalParticles; - // check count - int32_t max_count = of_def->MaxCount * (Config.Graphics.SmokeLevel + 20) / 150; - int32_t room = max_count - of_def->Count; - if (room <= 0) return NULL; - // reduce creation if limit is nearly reached - if (room < (max_count >> 1)) - if (SafeRandom(room) < SafeRandom(max_count)) return NULL; - // get free particle - if (!FreeParticles.pFirst) AddChunk(); - C4Particle *particle = FreeParticles.pFirst; - if (!particle) return NULL; - // set values - particle->x = x; particle->y = y; - particle->xdir = xdir; particle->ydir = ydir; - particle->a = a; particle->b = b; - particle->pDef = of_def; - if (particle->pDef->Attach && object != NULL) - { - particle->x -= fixtof(object->GetFixedX()); - particle->y -= fixtof(object->GetFixedY()); - } - // call initialization - if (!of_def->InitProc(particle,object)) - // failed :( - return NULL; - // count particle - ++of_def->Count; - // more to desired list - particle->MoveList(::Particles.FreeParticles, *pxList); - // return newly created particle - return particle; -} - -bool C4ParticleSystem::Cast(C4ParticleDef *of_def, int32_t amount, - float x, float y, int32_t level, - float a0, DWORD b0, float a1, DWORD b1, C4ParticleList *pxList, C4Object *object) -{ - // safety - if (!of_def) return false; - // get range for a and b - int32_t iA0=(int32_t)(a0*100),iA1=(int32_t)(a1*100); - if (iA1>24), db2=BYTE(db>>16), db3=BYTE(db>>8), db4=BYTE(db); - // create them - for (int32_t i=amount; i > 0; --i) - Create(of_def, x, y, - (float)(SafeRandom(level+1)-level/2)/10.0f, - (float)(SafeRandom(level+1)-level/2)/10.0f, - (float)(iA0+SafeRandom(iAd))/100.0f, - b0+(SafeRandom(db1)<<24)+(SafeRandom(db2)<<16)+(SafeRandom(db3)<<8)+SafeRandom(db4), pxList, object); - // success - return true; -} - -C4ParticleProc C4ParticleSystem::GetProc(const char *name) -{ - // seek in map - for (int32_t i = 0; C4ParticleProcMap[i].Name[0]; ++i) - if (SEqual(C4ParticleProcMap[i].Name, name)) - return C4ParticleProcMap[i].Proc; - // nothing found... - return NULL; -} - -C4ParticleDrawProc C4ParticleSystem::GetDrawProc(const char *name) -{ - // seek in map - for (int32_t i = 0; C4ParticleDrawProcMap[i].Name[0]; ++i) - if (SEqual(C4ParticleDrawProcMap[i].Name, name)) - return C4ParticleDrawProcMap[i].Proc; - // nothing found... - return NULL; -} - -C4ParticleDef *C4ParticleSystem::GetDef(const char *name, C4ParticleDef *exclude) -{ - // seek list - for (C4ParticleDef *def = pDef0; def; def=def->pNext) - if (def != exclude && def->Name == name) - return def; - // nothing found - return NULL; -} - -void C4ParticleSystem::SetDefParticles() -{ - // get smoke - pSmoke = GetDef("Smoke"); - // get blast - pBlast = GetDef("Blast"); - pFSpark = GetDef("FSpark"); - // get fire, if fire particles are desired - if (Config.Graphics.FireParticles) - { - pFire1 = GetDef("Fire"); - pFire2 = GetDef("Fire2"); - } - else - pFire1 = pFire2 = NULL; - // if fire is drawn w/o background fct: unload fire face if both fire particles are assigned - // but this is not done here - //if (IsFireParticleLoaded()) - // ::GraphicsResource.fctFire.Clear(); -} - -int32_t C4ParticleSystem::Push(C4ParticleDef *of_def, float dxdir, float dydir) -{ - int32_t num_pushed = 0; - // go through all particle chunks - for (C4ParticleChunk *a_chunk = &Chunk; a_chunk; a_chunk = a_chunk->pNext) - { - // go through all particles - C4Particle *particle = a_chunk->Data; int32_t i=C4Px_BufSize; - while (i--) - { - // def fits? - if (!of_def || particle->pDef == of_def) - { - // push it! - particle->xdir += dxdir; - particle->ydir += dydir; - // count pushed - ++num_pushed; - } - // next particle - ++particle; - } - } - // done - return num_pushed; -} - -bool fxSmokeInit(C4Particle *particle, C4Object *target) -{ - // init lifetime - particle->life = particle->pDef->MinLifetime; - int32_t lifetime = particle->pDef->MaxLifetime - particle->pDef->MinLifetime; - if (lifetime) - particle->life += SafeRandom(lifetime); - // use high-word of life to store init-status - particle->life |= (particle->life/17)<<16; - // set kind - ydir is unused anyway; set last kind reeeaaally seldom - particle->ydir = (float) SafeRandom(15) + SafeRandom(300)/299; - // set color - if (!particle->b) - particle->b = 0x004b4b4b; - else - particle->b &= ~0xff000000; - // always OK - return true; -} - -bool fxSmokeExec(C4Particle *particle, C4Object *target) -{ - // lifetime - if (!--particle->life) return false; - bool is_building = !!(particle->life&0x7fff0000); - // still building? - if (is_building) - { - // decrease init-time - particle->life -= 0x010000; - // increase color value - particle->b += 0x10000000; - // if full-grown, adjust to lifetime - if (!(particle->life&0x7fff0000)) - particle->b = (particle->b&0xffffff)|((particle->life)<<24); - } - // color change - DWORD color = particle->b; - particle->b = (LightenClrBy(color, 1)&0xffffff) | Min((color>>24)-1, 255)<<24; - // wind to float - if (!(particle->b % 12) || is_building) - { - particle->xdir = 0.025f*::Weather.GetWind(int32_t(particle->x),int32_t(particle->y)); - if (particle->xdir < -2.0f) - particle->xdir = -2.0f; - else if (particle->xdir > 2.0f) - particle->xdir = 2.0f; - particle->xdir += 0.1f * SafeRandom(41) - 2.0f; - } - // float - if (GBackSolid(int32_t(particle->x), int32_t(particle->y-particle->a))) - { - // if stuck, decay; otherwise, move down - if (!GBackSolid(int32_t(particle->x), int32_t(particle->y))) - particle->y+=0.4f; - else - particle->a-=2; - } - else - --particle->y; - particle->x += particle->xdir; - // increase in size - particle->a *= 1.01f; - // done, keep - return true; -} - -void fxSmokeDraw(C4Particle *particle, C4TargetFacet &cgo, C4Object *target) -{ - C4ParticleDef *def = particle->pDef; - // apply parallaxity to target pos - int32_t tx = cgo.TargetX * def->Parallaxity[0]/100; - int32_t ty = cgo.TargetY * def->Parallaxity[1]/100; - // check if it's in screen range - if (!Inside(particle->x, tx-particle->a, tx+cgo.Wdt+particle->a)) return; - if (!Inside(particle->y, ty-particle->a, ty+cgo.Hgt+particle->a)) return; - // get pos - float cx = particle->x + cgo.X - tx; - float cy = particle->y + cgo.Y - ty; - // get phase by particle index - int32_t i = (int32_t) particle->ydir; - int32_t px = i/4; - int32_t py = i%4; - // draw at pos - pDraw->ActivateBlitModulation(particle->b); - - float fx = float(def->Gfx.X + def->Gfx.Wdt * px); - float fy = float(def->Gfx.Y + def->Gfx.Hgt * py); - float fwdt = float(def->Gfx.Wdt); - float fhgt = float(def->Gfx.Hgt); - - pDraw->Blit(def->Gfx.Surface,fx,fy,fwdt,fhgt, - cgo.Surface, cx - particle->a, cy - particle->a, particle->a * 2, particle->a * 2, - true); - - pDraw->DeactivateBlitModulation(); -} - -bool fxStdInit(C4Particle *particle, C4Object *target) -{ - if (particle->pDef->Delay) - // delay given: lifetime starts at zero - particle->life=0; - else - // init lifetime as phase - particle->life=SafeRandom(particle->pDef->Length); - // default color - if (!particle->b) particle->b=0xffffffff; - // always OK - return true; -} - -bool fxStdExec(C4Particle *particle, C4Object *target) -{ - - float dx = particle->x, dy = particle->y; - float dxdir = particle->xdir, dydir = particle->ydir; - // rel. position & movement - if (particle->pDef->Attach && target != NULL) - { - dx += fixtof(target->GetFixedX()); - dy += fixtof(target->GetFixedY()); - dxdir += fixtof(target->xdir); - dydir += fixtof(target->ydir); - } - - // move - if (particle->xdir || particle->ydir) - { - if (particle->pDef->VertexCount && GBackSolid(int32_t( dx + particle->xdir),int32_t( dy + particle->ydir + particle->pDef->VertexY* particle->a/100.0f) )) - { - // collision - if (particle->pDef->CollisionProc) - if (!particle->pDef->CollisionProc(particle,target)) return false; - } - else if (particle->pDef->RByV != 2) - { - particle->x += particle->xdir; - particle->y += particle->ydir; - } - else - { - // With RByV=2, the V is only used for rotation, not for movement - } - } - // apply gravity - if (particle->pDef->GravityAcc) particle->ydir+=fixtof(GravAccel * particle->pDef->GravityAcc)/100.0f; - // apply WindDrift - if (particle->pDef->WindDrift && !GBackSolid(int32_t(dx), int32_t(dy))) - { - // Air speed: Wind plus some random - int32_t wind_speed = GBackWind(int32_t(dx), int32_t(dy)); - //C4Real txdir = itofix(wind_speed, 15) + C4REAL256(Random(1200) - 600); - float txdir = wind_speed / 15.0f; - //C4Real tydir = C4REAL256(Random(1200) - 600); - float tydir = 0; - - // Air friction, based on WindDrift. - int32_t wind_drift = Max(particle->pDef->WindDrift - 20, 0); - particle->xdir += ((txdir - dxdir) * wind_drift) / 800; - particle->ydir += ((tydir - dydir) * wind_drift) / 800; - } - // fade out - int32_t fade = particle->pDef->AlphaFade; - if (fade < 0) - { - if (Game.FrameCounter % -fade == 0) fade = 1; - else fade = 0; - } - if (fade) - { - if (particle->pDef->FadeDelay == 0 || Game.FrameCounter % particle->pDef->FadeDelay == 0) - { - DWORD color = particle->b; - int32_t alpha = color>>24; - alpha -= particle->pDef->AlphaFade; - if (alpha <= 0x00) return false; - particle->b = (color&0xffffff) | (alpha<<24); - } - } - // if delay is given, advance lifetime - if (particle->pDef->Delay) - { - if (particle->life < 0) - { - // decay - return particle->life-- >= -particle->pDef->FadeOutLen * particle->pDef->FadeOutDelay; - } - ++particle->life; - // check if still alive - int32_t phase = particle->life / particle->pDef->Delay; - int32_t length = particle->pDef->Length - particle->pDef->Reverse; - if (phase >= length * particle->pDef->Repeats + particle->pDef->Reverse) - { - // do fadeout, if assigned - if (!particle->pDef->FadeOutLen) return false; - particle->life = -1; - } - return true; - } - // outside landscape range? - bool kp; - if (dxdir > 0) - kp = (dx - particle->a < GBackWdt); - else - kp = (dx + particle->a > 0); - - if (dydir > 0) - kp = kp && (dy - particle->a < GBackHgt); - else - kp = kp && (dy + particle->a > particle->pDef->YOff); - - return kp; -} - -bool fxBounce(C4Particle *particle, C4Object *target) -{ - // reverse xdir/ydir - particle->xdir=-particle->xdir; - particle->ydir=-particle->ydir; - return true; -} - -bool fxBounceY(C4Particle *particle, C4Object *target) -{ - // reverse ydir only - particle->ydir = -particle->ydir; - return true; -} - -bool fxStop(C4Particle *particle, C4Object *target) -{ - // zero xdir/ydir - particle->xdir = particle->ydir = 0; - return true; -} - -bool fxDie(C4Particle *particle, C4Object *target) -{ - // DIEEEEEE - return false; -} - -void fxStdDraw(C4Particle *particle, C4TargetFacet &cgo, C4Object *target) -{ - // get def - C4ParticleDef *def = particle->pDef; - - // apply parallaxity to target pos - int32_t tax = cgo.TargetX * def->Parallaxity[0] / 100; - int32_t tay = cgo.TargetY * def->Parallaxity[1] / 100; - - // get the phases per row - int32_t phases = def->PhasesX; - - float dx = particle->x, dy = particle->y; - float dxdir = particle->xdir, dydir = particle->ydir; - - // relative position & movement - if (def->Attach && target != NULL) - { - dx += fixtof(target->GetFixedX()); - dy += fixtof(target->GetFixedY()); - dxdir += fixtof(target->xdir); - dydir += fixtof(target->ydir); - } - - // check if it's in screen range - if (!Inside(dx, tax-particle->a, tax + cgo.Wdt + particle->a)) return; - if (!Inside(dy, tay-particle->a, tay + cgo.Hgt + particle->a)) return; - - // get pos - int32_t cgox = cgo.X - tax, cgoy = cgo.Y - tay; - float cx = dx + cgox; - float cy = dy + cgoy; - - // get phase - int32_t phase = particle->life; - if (def->Delay) - { - if (phase >= 0) - { - phase /= def->Delay; - int32_t length = def->Length; - if (def->Reverse) - { - --length; - phase %= length*2; - if (phase > length) - phase = length*2 + 1 - phase; - } - else phase %= length; - } - else phase = (phase+1) / -def->FadeOutDelay + def->Length; - } - // get rotation - int32_t r=0; - if ((def->RByV == 1) || (def->RByV == 2)) // rotation by direction - r = Angle(0,0, (int32_t) (dxdir*10.0f), (int32_t) (dydir*10.0f))*100; - if (def->RByV == 3) // random rotation - currently a pseudo random rotation by x/y position - r = (((int32_t)(particle->x * 23 + particle->y * 12)) % 360) * 100; - // draw at pos - pDraw->ActivateBlitModulation(particle->b); - pDraw->StorePrimaryClipper(); - pDraw->SubPrimaryClipper(cgox, cgoy+def->YOff, 100000, 100000); - if (def->Additive) - pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE); - - // draw - float draw_width = particle->a; - float draw_height = def->Aspect * draw_width; - - int32_t phaseX = phase%phases; - int32_t phaseY = phase/phases; - - float fx = float(def->Gfx.X + def->Gfx.Wdt * phaseX); - float fy = float(def->Gfx.Y + def->Gfx.Hgt * phaseY); - float fwdt = float(def->Gfx.Wdt); - float fhgt = float(def->Gfx.Hgt); - float tx = cx-draw_width; - float ty = cy-draw_height; - float twdt = draw_width*2; - float thgt = draw_height*2; - - if (r) - { - C4BltTransform rot; - rot.SetRotate(r, (float) (tx+tx+twdt)/2, (float) (ty+ty+thgt)/2); - pDraw->Blit(def->Gfx.Surface,fx,fy,fwdt,fhgt, - cgo.Surface,tx,ty,twdt,thgt, - true,&rot); - } - else - { - pDraw->Blit(def->Gfx.Surface,fx,fy,fwdt,fhgt, - cgo.Surface,tx,ty,twdt,thgt, - true); - } - - pDraw->ResetBlitMode(); - pDraw->RestorePrimaryClipper(); - pDraw->DeactivateBlitModulation(); -} - -C4ParticleProcRec C4ParticleProcMap[] = -{ - { "SmokeInit", fxSmokeInit }, - { "SmokeExec", fxSmokeExec }, - { "StdInit", fxStdInit }, - { "StdExec", fxStdExec }, - { "Bounce", fxBounce }, - { "BounceY", fxBounceY }, - { "Stop", fxStop }, - { "Die", fxDie }, - { "", 0 } -}; - -C4ParticleDrawProcRec C4ParticleDrawProcMap[] = -{ - { "Smoke", fxSmokeDraw }, - { "Std", fxStdDraw }, - { "", 0 } -}; - -C4ParticleSystem Particles; diff --git a/src/game/landscape/C4Particles.h b/src/game/landscape/C4Particles.h deleted file mode 100644 index 021c519f2..000000000 --- a/src/game/landscape/C4Particles.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2002, 2004-2005 Sven Eberhardt - * Copyright (c) 2004, 2006, 2008 Günther Brammer - * Copyright (c) 2005, 2010 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ -// newgfx particle system for smoke, sparks, ... -// - everything, that is not sync-relevant -// function pointers for drawing and executing are used -// instead of virtual classes and a hierarchy, because -// the latter ones couldn't be optimized using static -// chunks -// thus, more complex partivle behaviour should be solved via -// objects -// note: this particle system will always assume the owning def -// object to be a static class named ::Particles! - -#ifndef INC_C4Particles -#define INC_C4Particles - -#include -#include -#include - -class C4Object; - -// class predefs -class C4ParticleDefCore; -class C4ParticleDef; -class C4Particle; -class C4ParticleChunk; -class C4ParticleList; -class C4ParticleSystem; - -typedef bool (*C4ParticleProc)(C4Particle *, C4Object *); // generic particle proc -typedef C4ParticleProc C4ParticleInitProc; // particle init proc - init and return whether particle could be created -typedef C4ParticleProc C4ParticleExecProc; // particle execution proc - returns whether particle died -typedef C4ParticleProc C4ParticleCollisionProc; // particle collision proc - returns whether particle died -typedef void (*C4ParticleDrawProc)(C4Particle *, C4TargetFacet &, C4Object *); // particle drawing code - -#define ParticleSystem ::Particles - -const int -C4Px_MaxParticle = 256, // maximum number of particles of one type -C4Px_BufSize = 128, // number of particles in one buffer -C4Px_MaxIDLen = 30; // maximum length of internal identifiers - -// core for particle defs -class C4ParticleDefCore -{ -public: - StdStrBuf Name; // name - C4Rect GfxFace; // rect for graphics - int32_t MaxCount; // maximum number of particles that may coexist of this type - int32_t MinLifetime, MaxLifetime; // used by exec proc; number of frames this particle can exist - int32_t YOff; // Y-Offset for Std-particles - int32_t Delay; // frame delay between animation phases - int32_t Repeats; // number of times the animation is repeated - int32_t Reverse; // reverse action after it has been played - int32_t FadeOutLen,FadeOutDelay; // phases used for letting the particle fade out - int32_t RByV; // if set, rotation will be adjusted according to the movement; if 2, the particle does not move - int32_t Placement; // when is the particle to be drawn? - int32_t GravityAcc; // acceleration done by gravity - int32_t WindDrift; - int32_t VertexCount; // number of vertices - 0 or 1 - int32_t VertexY; // y-offset of vertex; 100 is object height - int32_t Additive; // whether particle should be drawn additively - int32_t Attach; // whether the particle moves relatively to the target - int32_t AlphaFade; // fadeout in each* frame - int32_t FadeDelay; // *each = well, can be redefined here. Standard is 1 - int32_t Parallaxity [2]; // parallaxity - - StdStrBuf InitFn; // proc to be used for initialization - StdStrBuf ExecFn; // proc to be used for frame-execution - StdStrBuf DrawFn; // proc to be used for drawing - StdStrBuf CollisionFn; // proc to be called upon collision with the landscape; may be left out - - C4ParticleDefCore(); // ctor - void CompileFunc(StdCompiler * compiler); - - bool Compile(char *particle_source, const char *name); // compile from def file -}; - -// one particle definition -class C4ParticleDef : public C4ParticleDefCore -{ -public: - C4ParticleDef *pPrev, *pNext; // linked list members - - StdStrBuf Filename; // path to group this particle was loaded from (for EM reloading) - - C4FacetSurface Gfx; // graphics - int32_t Length; // number of phases in gfx - int32_t PhasesX; // number of phases per line in gfx - float Aspect; // height:width - - C4ParticleInitProc InitProc; // procedure called once upon creation of the particle - C4ParticleExecProc ExecProc; // procedure used for execution of one particle - C4ParticleCollisionProc CollisionProc; // procedure called upon collision with the landscape; may be NULL - C4ParticleDrawProc DrawProc; // procedure used for drawing of one particle - - int32_t Count; // number of particles currently existant of this kind - - C4ParticleDef(); // ctor - ~C4ParticleDef(); // dtor - - void Clear(); // free mem associated with this class - - bool Load(C4Group &group); // load particle from group; assume file to be accessed already - bool Reload(); // reload particle from stored position -}; - -// one tiny little particle -// note: list management done by the chunk, which spares one ptr here -// the chunk initializes the values to zero here, too; so no ctors here... -class C4Particle -{ -protected: - C4Particle *pPrev,*pNext; // previous/next particle of the same list in the buffer - - void MoveList(C4ParticleList &from, C4ParticleList &to); // move from one list to another - -public: - C4ParticleDef *pDef; // kind of particle - float x,y,xdir,ydir; // position and movement - int32_t life; // lifetime remaining for this particle - float a; int32_t b; // all-purpose values - - friend class C4ParticleChunk; - friend class C4ParticleList; - friend class C4ParticleSystem; -}; - -// one chunk of particles -// linked list is managed by owner -class C4ParticleChunk -{ -protected: - C4ParticleChunk *pNext; // single linked list - C4Particle Data[C4Px_BufSize]; // the particles - - int32_t NumFree; // number of free particles - -public: - C4ParticleChunk(); // ctor - ~C4ParticleChunk(); // dtor - - C4Particle *Create(C4ParticleDef *of_def); // get a particle from this chunk - void Destroy(C4Particle *particle); // remove particle from this chunk - - void Clear(); // clear all particles - - friend class C4ParticleSystem; -}; - -// a subset of particles -class C4ParticleList -{ -public: - C4Particle *pFirst; // first particle in list - others follow in linked list - - C4ParticleList() { pFirst = NULL; } // ctor - - void Exec(C4Object *object = NULL); // execute all particles - void Draw(C4TargetFacet &cgo, C4Object *object = NULL); // draw all particles - void Clear(); // remove all particles - int32_t Remove(C4ParticleDef *of_def); // remove all particles of def - - operator bool() { return !!pFirst; } // checks whether list contains particles -}; - -// the main particle system -class C4ParticleSystem -{ -protected: - C4ParticleChunk Chunk; // linked list for particle chunks - C4ParticleDef *pDef0, *pDefL; // linked list for particle defs - - C4ParticleChunk *AddChunk(); // add a new chunk to the list - void PruneChunks(); // check if all chunks are needed; remove unused - - C4ParticleProc GetProc(const char *name); // get init/exec proc for a particle type - C4ParticleDrawProc GetDrawProc(const char *name); // get draw proc for a particle type - -public: - C4ParticleList FreeParticles; // list of free particles - C4ParticleList GlobalParticles; // list of free particles - - C4ParticleDef *pSmoke; // default particle: smoke - C4ParticleDef *pBlast; // default particle: blast - C4ParticleDef *pFSpark; // default particle: fiery spark - C4ParticleDef *pFire1; // default particle: fire base - C4ParticleDef *pFire2; // default particle: fire additive - - C4ParticleSystem(); // ctor - ~C4ParticleSystem(); // dtor - - void ClearParticles(); // remove all particles - void Clear(); // remove all particle definitions and particles - - C4Particle *Create(C4ParticleDef *of_def, // create one particle of given type - float x, float y, float xdir=0.0f, float ydir=0.0f, - float a=0.0f, int32_t b=0, C4ParticleList *pxList=NULL, C4Object *object=NULL); - bool Cast(C4ParticleDef *of_def, // create several particles with different speeds and params - int32_t amount, - float x, float y, int32_t level, - float a0=0.0f, DWORD b0=0, float a1=0.0f, DWORD b1=0, - C4ParticleList *pxList=NULL, C4Object *object=NULL); - - C4ParticleDef *GetDef(const char *name, C4ParticleDef *exclude=NULL); // get particle def by name - void SetDefParticles(); // seek and assign default particels (smoke, etc.) - - int32_t Push(C4ParticleDef *of_def, float dxdir, float dydir); // add movement to all particles of type - - bool IsFireParticleLoaded() { return pFire1 && pFire2; } - - friend class C4ParticleDef; - friend class C4Particle; - friend class C4ParticleChunk; -}; - -extern C4ParticleSystem Particles; - -// default particle execution/drawing functions -bool fxStdInit(C4Particle *particle, C4Object *target); -bool fxStdExec(C4Particle *particle, C4Object *target); -void fxStdDraw(C4Particle *particle, C4TargetFacet &cgo, C4Object *target); - -// structures used for static function maps -struct C4ParticleProcRec -{ - char Name[C4Px_MaxIDLen+1]; // name of procedure - C4ParticleProc Proc; // procedure -}; - -struct C4ParticleDrawProcRec -{ - char Name[C4Px_MaxIDLen+1]; // name of procedure - C4ParticleDrawProc Proc; // procedure -}; - -extern C4ParticleProcRec C4ParticleProcMap[]; // particle init/execution function map -extern C4ParticleDrawProcRec C4ParticleDrawProcMap[]; // particle drawing function map - - -#endif diff --git a/src/game/landscape/C4Region.cpp b/src/game/landscape/C4Region.cpp deleted file mode 100644 index b74aa2a55..000000000 --- a/src/game/landscape/C4Region.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Screen area marked for mouse interaction */ - -#include -#include - -#include - -C4Region::C4Region() -{ - Default(); -} - -C4Region::~C4Region() -{ - Clear(); -} - -void C4Region::Default() -{ - X=Y=Wdt=Hgt=0; - Caption[0]=0; - Com=RightCom=MoveOverCom=HoldCom=COM_None; - Data=0; - id=C4ID::None; - Target=NULL; -} - -void C4Region::Clear() -{ - -} - -C4RegionList::C4RegionList() -{ - Default(); -} - -C4RegionList::~C4RegionList() -{ - Clear(); -} - -void C4RegionList::Default() -{ - First=NULL; - AdjustX=AdjustY=0; -} - -void C4RegionList::Clear() -{ - C4Region *pRgn,*pNext; - for (pRgn=First; pRgn; pRgn=pNext) { pNext=pRgn->Next; delete pRgn; } - First=NULL; -} - -bool C4RegionList::Add(int iX, int iY, int iWdt, int iHgt, const char *szCaption, - int iCom, C4Object *pTarget, int iMoveOverCom, int iHoldCom, int iData) -{ - C4Region *pRgn = new C4Region; - pRgn->Set(iX+AdjustX,iY+AdjustY,iWdt,iHgt,szCaption,iCom,iMoveOverCom,iHoldCom,iData,pTarget); - pRgn->Next=First; - First=pRgn; - return true; -} - -bool C4RegionList::Add(C4Facet &fctArea, const char *szCaption, int iCom, C4Object *pTarget, int iMoveOverCom, int iHoldCom, int iData) -{ - return Add(fctArea.X,fctArea.Y,fctArea.Wdt,fctArea.Hgt,szCaption,iCom,pTarget,iMoveOverCom,iHoldCom,iData); -} - -bool C4RegionList::Add(C4Region &rRegion) -{ - C4Region *pRgn = new C4Region; - *pRgn = rRegion; - pRgn->X+=AdjustX; - pRgn->Y+=AdjustY; - pRgn->Next=First; - First=pRgn; - return true; -} - -void C4Region::Set(int iX, int iY, int iWdt, int iHgt, const char *szCaption, - int iCom, int iMoveOverCom, int iHoldCom, int iData, - C4Object *pTarget) -{ - X=iX; Y=iY; Wdt=iWdt; Hgt=iHgt; - SCopy(szCaption,Caption,C4RGN_MaxCaption); - Com=iCom; MoveOverCom=iMoveOverCom; HoldCom=iHoldCom; - Data=iData; - Target=pTarget; -} - -void C4RegionList::SetAdjust(int iX, int iY) -{ - AdjustX=iX; AdjustY=iY; -} - -C4Region* C4RegionList::Find(int iX, int iY) -{ - for (C4Region *pRgn=First; pRgn; pRgn=pRgn->Next) - if (Inside(iX-pRgn->X,0,pRgn->Wdt-1)) - if (Inside(iY-pRgn->Y,0,pRgn->Hgt-1)) - return pRgn; - return NULL; -} - -void C4Region::ClearPointers(C4Object *pObj) -{ - if (Target==pObj) Target=NULL; -} - -void C4RegionList::ClearPointers(C4Object *pObj) -{ - for (C4Region *pRgn=First; pRgn; pRgn=pRgn->Next) - pRgn->ClearPointers(pObj); -} - -void C4Region::Set(C4Facet &fctArea, const char *szCaption, C4Object *pTarget) -{ - X=fctArea.X; - Y=fctArea.Y; - Wdt=fctArea.Wdt; - Hgt=fctArea.Hgt; - if (szCaption) SCopy(szCaption,Caption,C4RGN_MaxCaption); - if (pTarget) Target=pTarget; -} - -bool C4RegionList::Add(C4RegionList &rRegionList, bool fAdjust) -{ - C4Region *pNewFirst=NULL,*pPrev=NULL; - for (C4Region *cRgn=rRegionList.First; cRgn; cRgn=cRgn->Next) - { - C4Region *pRgn = new C4Region; - *pRgn = *cRgn; - if (fAdjust) { pRgn->X+=AdjustX; pRgn->Y+=AdjustY; } - pRgn->Next=First; - if (!pNewFirst) pNewFirst=pRgn; - if (pPrev) pPrev->Next=pRgn; - pPrev=pRgn; - } - if (pNewFirst) First=pNewFirst; - return true; -} diff --git a/src/game/landscape/C4Region.h b/src/game/landscape/C4Region.h deleted file mode 100644 index 580ae576a..000000000 --- a/src/game/landscape/C4Region.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Screen area marked for mouse interaction */ - -#ifndef INC_C4Region -#define INC_C4Region - -#include -#include - -class C4Object; -class C4Facet; - -const int C4RGN_MaxCaption=256; - -class C4Region -{ - friend class C4RegionList; -public: - C4Region(); - ~C4Region(); -public: - int X,Y,Wdt,Hgt; - char Caption[C4RGN_MaxCaption+1]; - int Com,RightCom,MoveOverCom,HoldCom; - int Data; - C4ID id; - C4Object *Target; -protected: - C4Region *Next; -public: - void Set(C4Facet &fctArea, const char *szCaption=NULL, C4Object *pTarget=NULL); - void Clear(); - void Default(); - void Set(int iX, int iY, int iWdt, int iHgt, const char *szCaption, int iCom, int iMoveOverCom, int iHoldCom, int iData, C4Object *pTarget); -protected: - void ClearPointers(C4Object *pObj); -}; - -class C4RegionList -{ -public: - C4RegionList(); - ~C4RegionList(); -protected: - int AdjustX,AdjustY; - C4Region *First; -public: - void ClearPointers(C4Object *pObj); - void SetAdjust(int iX, int iY); - void Clear(); - void Default(); - C4Region* Find(int iX, int iY); - bool Add(int iX, int iY, int iWdt, int iHgt, const char *szCaption=NULL, int iCom=COM_None, C4Object *pTarget=NULL, int iMoveOverCom=COM_None, int iHoldCom=COM_None, int iData=0); - bool Add(C4Facet &fctArea, const char *szCaption=NULL, int iCom=COM_None, C4Object *pTarget=NULL, int iMoveOverCom=COM_None, int iHoldCom=COM_None, int iData=0); - bool Add(C4Region &rRegion); - bool Add(C4RegionList &rRegionList, bool fAdjust=true); -}; - -#endif diff --git a/src/game/script/C4Effect.cpp b/src/gamescript/C4Effect.cpp similarity index 90% rename from src/game/script/C4Effect.cpp rename to src/gamescript/C4Effect.cpp index 6080f6234..43c6a5db3 100644 --- a/src/game/script/C4Effect.cpp +++ b/src/gamescript/C4Effect.cpp @@ -1,31 +1,25 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004 Matthes Bender - * Copyright (c) 2001-2002, 2004-2007 Sven Eberhardt - * Copyright (c) 2004-2005, 2007 Peter Wortmann - * Copyright (c) 2006-2011 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // C4AulFun-based effects assigned to an object /* Also contains some helper functions for various landscape effects */ #include -#include +#include #include #include @@ -67,7 +61,6 @@ C4PropList * C4Effect::GetCallbackScript() C4Effect::C4Effect(C4Object *pForObj, C4String *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4) { - C4Effect *pPrev, *pCheck; // assign values iPriority = 0; // effect is not yet valid; some callbacks to other effects are done before iInterval = iTimerInterval; @@ -75,10 +68,16 @@ C4Effect::C4Effect(C4Object *pForObj, C4String *szName, int32_t iPrio, int32_t i CommandTarget = pCmdTarget; idCommandTarget = idCmdTarget; AcquireNumber(); + Register(pForObj, iPrio); + // Set name and callback functions + SetProperty(P_Name, C4VString(szName)); +} + +void C4Effect::Register(C4Object *pForObj, int32_t iPrio) +{ // get effect target C4Effect **ppEffectList = pForObj ? &pForObj->pEffects : &Game.pGlobalEffects; - // register into object - pPrev = *ppEffectList; + C4Effect *pCheck, *pPrev = *ppEffectList; if (pPrev && Abs(pPrev->iPriority) < iPrio) { while ((pCheck = pPrev->pNext)) @@ -93,8 +92,6 @@ C4Effect::C4Effect(C4Object *pForObj, C4String *szName, int32_t iPrio, int32_t i pNext = *ppEffectList; *ppEffectList = this; } - // Set name and callback functions - SetProperty(P_Name, C4VString(szName)); } C4Effect * C4Effect::New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4) @@ -341,7 +338,7 @@ void C4Effect::Kill(C4Object *pObj) // remove this effect int32_t iPrevPrio = iPriority; SetDead(); if (pFnStop) - if (pFnStop->Exec(CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(this))).getInt() == C4Fx_Stop_Deny) + if (pFnStop->Exec(CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(this), C4VInt(C4FxCall_Normal))).getInt() == C4Fx_Stop_Deny) // effect denied to be removed: recover iPriority = iPrevPrio; // reactivate other effects @@ -497,15 +494,15 @@ void C4Effect::SetPropertyByS(C4String * k, const C4Value & to) { case P_Name: if (!to.getStr() || !*to.getStr()->GetCStr()) - throw new C4AulExecError(0, "effect: Name has to be a nonempty string"); + throw new C4AulExecError("effect: Name has to be a nonempty string"); C4PropListNumbered::SetPropertyByS(k, to); ReAssignCallbackFunctions(); return; case P_Priority: - throw new C4AulExecError(0, "effect: Priority is readonly"); + throw new C4AulExecError("effect: Priority is readonly"); case P_Interval: iInterval = to.getInt(); return; case P_CommandTarget: - throw new C4AulExecError(0, "effect: CommandTarget is readonly"); + throw new C4AulExecError("effect: CommandTarget is readonly"); case P_Time: iTime = to.getInt(); return; } } @@ -519,12 +516,12 @@ void C4Effect::ResetProperty(C4String * k) switch(k - &Strings.P[0]) { case P_Name: - throw new C4AulExecError(0, "effect: Name has to be a nonempty string"); + throw new C4AulExecError("effect: Name has to be a nonempty string"); case P_Priority: - throw new C4AulExecError(0, "effect: Priority is readonly"); + throw new C4AulExecError("effect: Priority is readonly"); case P_Interval: iInterval = 0; return; case P_CommandTarget: - throw new C4AulExecError(0, "effect: CommandTarget is readonly"); + throw new C4AulExecError("effect: CommandTarget is readonly"); case P_Time: iTime = 0; return; } } @@ -556,6 +553,20 @@ bool C4Effect::GetPropertyByS(C4String *k, C4Value *pResult) const return C4PropListNumbered::GetPropertyByS(k, pResult); } +C4ValueArray * C4Effect::GetProperties() const +{ + C4ValueArray * a = C4PropList::GetProperties(); + int i; + i = a->GetSize(); + a->SetSize(i + 5); + (*a)[i++] = C4VString(&::Strings.P[P_Name]); + (*a)[i++] = C4VString(&::Strings.P[P_Priority]); + (*a)[i++] = C4VString(&::Strings.P[P_Interval]); + (*a)[i++] = C4VString(&::Strings.P[P_CommandTarget]); + (*a)[i++] = C4VString(&::Strings.P[P_Time]); + return a; +} + // Some other, internal effects ------------------------------------------------------------- static int32_t GetSmokeLevel() @@ -591,12 +602,18 @@ void Splash(int32_t tx, int32_t ty, int32_t amt, C4Object *pByObj) // Splash bubbles and liquid for (int32_t cnt=0; cntCall(P_Smoke, &pars); } diff --git a/src/game/script/C4Effects.h b/src/gamescript/C4Effect.h similarity index 92% rename from src/game/script/C4Effects.h rename to src/gamescript/C4Effect.h index 41d73bcb3..03c60ef30 100644 --- a/src/game/script/C4Effects.h +++ b/src/gamescript/C4Effect.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2004-2005 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // C4AulFun-based effects assigned to an object @@ -98,6 +95,7 @@ public: static C4Effect * New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4); ~C4Effect(); // dtor - deletes all following effects + void Register(C4Object *pForObj, int32_t iPrio); // add into effect list of object or global effect list void Denumerate(C4ValueNumbers *); // numbers to object pointers void ClearPointers(C4Object *pObj); // clear all pointers to object - may kill some effects w/o callback, because the callback target is lost @@ -133,6 +131,7 @@ public: virtual void SetPropertyByS(C4String * k, const C4Value & to); virtual void ResetProperty(C4String * k); virtual bool GetPropertyByS(C4String *k, C4Value *pResult) const; + virtual C4ValueArray * GetProperties() const; protected: void TempRemoveUpperEffects(C4Object *pObj, bool fTempRemoveThis, C4Effect **ppLastRemovedEffect); // temp remove all effects with higher priority diff --git a/src/game/script/C4FindObject.cpp b/src/gamescript/C4FindObject.cpp similarity index 88% rename from src/game/script/C4FindObject.cpp rename to src/gamescript/C4FindObject.cpp index f5be6e617..546e14475 100644 --- a/src/game/script/C4FindObject.cpp +++ b/src/gamescript/C4FindObject.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2008 Peter Wortmann - * Copyright (c) 2006-2009, 2011 Günther Brammer - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2009-2010 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include #include @@ -36,7 +30,7 @@ C4FindObject::~C4FindObject() delete pSort; } -C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject **ppSortObj) +C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject **ppSortObj, const C4Object *context) { // Must be an array C4ValueArray *pArray = C4Value(DataVal).getArray(); @@ -50,7 +44,7 @@ C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject * // sort condition not desired here? if (!ppSortObj) return NULL; // otherwise, create it! - *ppSortObj = C4SortObject::CreateByValue(iType, Data); + *ppSortObj = C4SortObject::CreateByValue(iType, Data, context); // done return NULL; } @@ -60,7 +54,7 @@ C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject * case C4FO_Not: { // Create child condition - C4FindObject *pCond = C4FindObject::CreateByValue(Data[1]); + C4FindObject *pCond = C4FindObject::CreateByValue(Data[1], nullptr, context); if (!pCond) return NULL; // wrap return new C4FindObjectNot(pCond); @@ -70,12 +64,12 @@ C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject * { // Trivial case (one condition) if (Data.GetSize() == 2) - return C4FindObject::CreateByValue(Data[1]); + return C4FindObject::CreateByValue(Data[1], nullptr, context); // Create all childs int32_t i; C4FindObject **ppConds = new C4FindObject *[Data.GetSize() - 1]; for (i = 0; i < Data.GetSize() - 1; i++) - ppConds[i] = C4FindObject::CreateByValue(Data[i+1]); + ppConds[i] = C4FindObject::CreateByValue(Data[i+1], nullptr, context); // Count real entries, move them to start of list int32_t iSize = 0; for (i = 0; i < Data.GetSize() - 1; i++) @@ -95,20 +89,75 @@ C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject * case C4FO_ID: return new C4FindObjectID(Data[1].getC4ID()); + + // #973: For all criteria using coordinates: If FindObject et al. are called in object context, offset by object center case C4FO_InRect: - return new C4FindObjectInRect(C4Rect(Data[1].getInt(), Data[2].getInt(), Data[3].getInt(), Data[4].getInt())); + { + int32_t x = Data[1].getInt(); + int32_t y = Data[2].getInt(); + int32_t w = Data[3].getInt(); + int32_t h = Data[4].getInt(); + if (context) + { + x += context->GetX(); + y += context->GetY(); + } + return new C4FindObjectInRect(C4Rect(x, y, w, h)); + } case C4FO_AtPoint: - return new C4FindObjectAtPoint(Data[1].getInt(), Data[2].getInt()); + { + int32_t x = Data[1].getInt(); + int32_t y = Data[2].getInt(); + if (context) + { + x += context->GetX(); + y += context->GetY(); + } + return new C4FindObjectAtPoint(x, y); + } case C4FO_AtRect: - return new C4FindObjectAtRect(Data[1].getInt(), Data[2].getInt(), Data[3].getInt(),Data[4].getInt()); + { + int32_t x = Data[1].getInt(); + int32_t y = Data[2].getInt(); + int32_t w = Data[3].getInt(); + int32_t h = Data[4].getInt(); + if (context) + { + x += context->GetX(); + y += context->GetY(); + } + return new C4FindObjectAtRect(x, y, w, h); + } case C4FO_OnLine: - return new C4FindObjectOnLine(Data[1].getInt(), Data[2].getInt(), Data[3].getInt(), Data[4].getInt()); + { + int32_t x1 = Data[1].getInt(); + int32_t y1 = Data[2].getInt(); + int32_t x2 = Data[3].getInt(); + int32_t y2 = Data[4].getInt(); + if (context) + { + x1 += context->GetX(); + x2 += context->GetX(); + y1 += context->GetY(); + y2 += context->GetY(); + } + return new C4FindObjectOnLine(x1, y1, x2, y2); + } case C4FO_Distance: - return new C4FindObjectDistance(Data[1].getInt(), Data[2].getInt(), Data[3].getInt()); + { + int32_t x = Data[1].getInt(); + int32_t y = Data[2].getInt(); + if (context) + { + x += context->GetX(); + y += context->GetY(); + } + return new C4FindObjectDistance(x, y, Data[3].getInt()); + } case C4FO_OCF: return new C4FindObjectOCF(Data[1].getInt()); @@ -256,7 +305,7 @@ int32_t C4FindObject::Count(const C4ObjectList &Objs, const C4LSectors &Sct) if (!Area.Next(pSct)) return Count(pSct->ObjectShapes); // Create marker, count over all areas - unsigned int iMarker = ++::Objects.LastUsedMarker; + uint32_t iMarker = ::Objects.GetNextMarker(); int32_t iCount = 0; for (; pLst; pLst=Area.NextObjectShapes(pLst, &pSct)) for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next) @@ -347,7 +396,7 @@ C4ValueArray *C4FindObject::FindMany(const C4ObjectList &Objs, const C4LSectors // Set up array pArray = new C4ValueArray(32); iSize = 0; // Create marker, search all areas - unsigned int iMarker = ++::Objects.LastUsedMarker; + uint32_t iMarker = ::Objects.GetNextMarker(); for (; pLst; pLst=Area.NextObjectShapes(pLst, &pSct)) for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next) if (pLnk->Obj->Status) @@ -721,24 +770,24 @@ bool C4FindObjectLayer::IsImpossible() // *** C4SortObject -C4SortObject *C4SortObject::CreateByValue(const C4Value &DataVal) +C4SortObject *C4SortObject::CreateByValue(const C4Value &DataVal, const C4Object *context) { // Must be an array const C4ValueArray *pArray = C4Value(DataVal).getArray(); if (!pArray) return NULL; const C4ValueArray &Data = *pArray; int32_t iType = Data[0].getInt(); - return CreateByValue(iType, Data); + return CreateByValue(iType, Data, context); } -C4SortObject *C4SortObject::CreateByValue(int32_t iType, const C4ValueArray &Data) +C4SortObject *C4SortObject::CreateByValue(int32_t iType, const C4ValueArray &Data, const C4Object *context) { switch (iType) { case C4SO_Reverse: { // create child sort - C4SortObject *pChildSort = C4SortObject::CreateByValue(Data[1]); + C4SortObject *pChildSort = C4SortObject::CreateByValue(Data[1], context); if (!pChildSort) return NULL; // wrap return new C4SortObjectReverse(pChildSort); @@ -749,14 +798,14 @@ C4SortObject *C4SortObject::CreateByValue(int32_t iType, const C4ValueArray &Dat // Trivial case (one sort) if (Data.GetSize() == 2) { - return C4SortObject::CreateByValue(Data[1]); + return C4SortObject::CreateByValue(Data[1], context); } // Create all children int32_t i; C4SortObject **ppSorts = new C4SortObject *[Data.GetSize() - 1]; for (i = 0; i < Data.GetSize() - 1; i++) { - ppSorts[i] = C4SortObject::CreateByValue(Data[i+1]); + ppSorts[i] = C4SortObject::CreateByValue(Data[i+1], context); } // Count real entries, move them to start of list int32_t iSize = 0; @@ -769,7 +818,16 @@ C4SortObject *C4SortObject::CreateByValue(int32_t iType, const C4ValueArray &Dat } case C4SO_Distance: - return new C4SortObjectDistance(Data[1].getInt(), Data[2].getInt()); + { + int32_t x = Data[1].getInt(); + int32_t y = Data[2].getInt(); + if (context) + { + x += context->GetX(); + y += context->GetY(); + } + return new C4SortObjectDistance(x, y); + } case C4SO_Random: return new C4SortObjectRandom(); diff --git a/src/game/script/C4FindObject.h b/src/gamescript/C4FindObject.h similarity index 92% rename from src/game/script/C4FindObject.h rename to src/gamescript/C4FindObject.h index a56f48f6e..12e8c9306 100644 --- a/src/game/script/C4FindObject.h +++ b/src/gamescript/C4FindObject.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2007 Peter Wortmann - * Copyright (c) 2006, 2008 Günther Brammer - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2009-2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef C4FINDOBJECT_H #define C4FINDOBJECT_H @@ -67,9 +62,6 @@ enum C4SortObjectCondID C4SO_Last = 200 // no sort condition larger than this }; -class C4LSectors; -class C4ObjectList; - // Base class class C4FindObject { @@ -82,7 +74,7 @@ public: C4FindObject() : pSort(NULL) { } virtual ~C4FindObject(); - static C4FindObject *CreateByValue(const C4Value &Data, C4SortObject **ppSortObj=NULL); // createFindObject or SortObject - if ppSortObj==NULL, SortObject is not allowed + static C4FindObject *CreateByValue(const C4Value &Data, C4SortObject **ppSortObj=NULL, const C4Object *context=NULL); // createFindObject or SortObject - if ppSortObj==NULL, SortObject is not allowed int32_t Count(const C4ObjectList &Objs); // Counts objects for which the condition is true C4Object *Find(const C4ObjectList &Objs); // Returns first object for which the condition is true @@ -136,6 +128,16 @@ protected: virtual bool UseShapes() { return fUseShapes; } virtual bool IsEnsured() { return !iCnt; } virtual bool IsImpossible(); + void ForgetConditions() { ppConds=NULL; iCnt=0; } +}; + +// Special variant of C4FindObjectAnd that does not free its conditions +class C4FindObjectAndStatic : public C4FindObjectAnd +{ +public: + C4FindObjectAndStatic(int32_t iCnt, C4FindObject **ppConds) + : C4FindObjectAnd(iCnt, ppConds, true) {} + virtual ~C4FindObjectAndStatic() {ForgetConditions(); } }; class C4FindObjectOr : public C4FindObject @@ -386,8 +388,8 @@ public: virtual int32_t CompareCache(int32_t iObj1, int32_t iObj2, C4Object *pObj1, C4Object *pObj2) { return Compare(pObj1, pObj2); } public: - static C4SortObject *CreateByValue(const C4Value &Data); - static C4SortObject *CreateByValue(int32_t iType, const C4ValueArray &Data); + static C4SortObject *CreateByValue(const C4Value &Data, const C4Object *context=NULL); + static C4SortObject *CreateByValue(int32_t iType, const C4ValueArray &Data, const C4Object *context=NULL); void SortObjects(C4ValueArray *pArray); }; diff --git a/src/game/script/C4GameScript.cpp b/src/gamescript/C4GameScript.cpp similarity index 60% rename from src/game/script/C4GameScript.cpp rename to src/gamescript/C4GameScript.cpp index 54884a156..0fcc8028e 100644 --- a/src/game/script/C4GameScript.cpp +++ b/src/gamescript/C4GameScript.cpp @@ -1,28 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004, 2008 Matthes Bender - * Copyright (c) 2001-2010 Sven Eberhardt - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2001-2008, 2010 Peter Wortmann - * Copyright (c) 2004-2005, 2007-2010 Armin Burgmeier - * Copyright (c) 2004-2011 Günther Brammer - * Copyright (c) 2009-2010 Nicolas Hake - * Copyright (c) 2009-2011 Tobias Zwick - * Copyright (c) 2009-2010 Richard Gerum - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Functions mapped by C4Script */ @@ -52,104 +42,109 @@ #include #include -static bool FnIncinerateLandscape(C4AulContext *cthr, long iX, long iY) +// undocumented! +static bool FnIncinerateLandscape(C4PropList * _this, long iX, long iY) { - if (cthr->Obj) { iX += cthr->Obj->GetX(); iY += cthr->Obj->GetY(); } + if (Object(_this)) { iX += Object(_this)->GetX(); iY += Object(_this)->GetY(); } return !!::Landscape.Incinerate(iX, iY); } -static C4Void FnSetGravity(C4AulContext *cthr, long iGravity) +static C4Void FnSetGravity(C4PropList * _this, long iGravity) { - ::Landscape.Gravity = itofix(BoundBy(iGravity,-300,300)) / 500; + ::Landscape.Gravity = C4REAL100(BoundBy(iGravity,-1000,1000)); return C4Void(); } -static long FnGetGravity(C4AulContext *cthr) +static long FnGetGravity(C4PropList * _this) { - return fixtoi(::Landscape.Gravity * 500); + return fixtoi(::Landscape.Gravity * 100); } -static C4Value FnPlayerObjectCommand(C4AulContext *cthr, C4Value *pPars) +// undocumented! +static bool FnPlayerObjectCommand(C4PropList * _this, int iPlr, C4String * szCommand, + C4Object * pTarget, int iTx, int iTy, + C4Object * pTarget2, const C4Value & Data) { - PAR(int, iPlr); PAR(string, szCommand); PAR(object, pTarget); PAR(int, iTx); PAR(int, iTy); - PAR(object, pTarget2); PAR(any, Data); // Player - if (!ValidPlr(iPlr) || !szCommand) return C4VFalse; + if (!ValidPlr(iPlr) || !szCommand) return false; C4Player *pPlr = ::Players.Get(iPlr); // Command - long iCommand = CommandByName(FnStringPar(szCommand)); if (!iCommand) return C4VFalse; + long iCommand = CommandByName(FnStringPar(szCommand)); if (!iCommand) return false; // Set pPlr->ObjectCommand(iCommand, pTarget, iTx, iTy, pTarget2, Data, C4P_Command_Set); // Success - return C4VTrue; + return true; } -static C4String *FnGetPlayerName(C4AulContext *cthr, long iPlayer) +static C4String *FnGetPlayerName(C4PropList * _this, long iPlayer) { if (!ValidPlr(iPlayer)) return NULL; return String(::Players.Get(iPlayer)->GetName()); } -static long FnGetPlayerType(C4AulContext *cthr, long iPlayer) +static long FnGetPlayerType(C4PropList * _this, long iPlayer) { C4Player *pPlr = ::Players.Get(iPlayer); if (!pPlr) return 0; return pPlr->GetType(); } -static long FnGetPlayerColor(C4AulContext *cthr, long iPlayer) +static long FnGetPlayerColor(C4PropList * _this, long iPlayer) { C4Player *plr = ::Players.Get(iPlayer); return plr ? plr->ColorDw : 0; } -static long FnGetPlrClonkSkin(C4AulContext *cthr, long iPlayer) +// undocumented! +static Nillable FnGetPlrClonkSkin(C4PropList * _this, long iPlayer) { C4Player *plr = ::Players.Get(iPlayer); - return plr ? plr->PrefClonkSkin : 0; + if (plr) + return plr->PrefClonkSkin; + return C4Void(); } -static Nillable FnGetX(C4AulContext *cthr, long iPrec) +static Nillable FnGetX(C4PropList * _this, long iPrec) { - if (!cthr->Obj) return C4Void(); + if (!Object(_this)) return C4Void(); if (!iPrec) iPrec = 1; - return fixtoi(cthr->Obj->fix_x, iPrec); + return fixtoi(Object(_this)->fix_x, iPrec); } -static Nillable FnGetY(C4AulContext *cthr, long iPrec) +static Nillable FnGetY(C4PropList * _this, long iPrec) { - if (!cthr->Obj) return C4Void(); + if (!Object(_this)) return C4Void(); if (!iPrec) iPrec = 1; - return fixtoi(cthr->Obj->fix_y, iPrec); + return fixtoi(Object(_this)->fix_y, iPrec); } -static C4Object *FnCreateObject(C4AulContext *cthr, +static C4Object *FnCreateObject(C4PropList * _this, C4PropList * PropList, long iXOffset, long iYOffset, Nillable owner) { - if (cthr->Obj) // Local object calls override + if (Object(_this)) // Local object calls override { - iXOffset+=cthr->Obj->GetX(); - iYOffset+=cthr->Obj->GetY(); + iXOffset+=Object(_this)->GetX(); + iYOffset+=Object(_this)->GetY(); } long iOwner = owner; if (owner.IsNil()) { - if (cthr->Obj) - iOwner = cthr->Obj->Controller; + if (Object(_this)) + iOwner = Object(_this)->Controller; else iOwner = NO_OWNER; } - C4Object *pNewObj = Game.CreateObject(PropList,cthr->Obj,iOwner,iXOffset,iYOffset); + C4Object *pNewObj = Game.CreateObject(PropList,Object(_this),iOwner,iXOffset,iYOffset); // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player - if (pNewObj && cthr->Obj && cthr->Obj->Controller > NO_OWNER) pNewObj->Controller = cthr->Obj->Controller; + if (pNewObj && Object(_this) && Object(_this)->Controller > NO_OWNER) pNewObj->Controller = Object(_this)->Controller; return pNewObj; } -static C4Object *FnCreateConstruction(C4AulContext *cthr, +static C4Object *FnCreateConstruction(C4PropList * _this, C4PropList * PropList, long iXOffset, long iYOffset, Nillable owner, long iCompletion, bool fTerrain, bool fCheckSite) { @@ -158,36 +153,36 @@ static C4Object *FnCreateConstruction(C4AulContext *cthr, return NULL; // Local object calls override position offset, owner - if (cthr->Obj) + if (Object(_this)) { - iXOffset+=cthr->Obj->GetX(); - iYOffset+=cthr->Obj->GetY(); + iXOffset+=Object(_this)->GetX(); + iYOffset+=Object(_this)->GetY(); } // Check site if (fCheckSite) - if (!ConstructionCheck(PropList,iXOffset,iYOffset,cthr->Obj)) + if (!ConstructionCheck(PropList,iXOffset,iYOffset,Object(_this))) return NULL; long iOwner = owner; if (owner.IsNil()) { - if (cthr->Obj) - iOwner = cthr->Obj->Controller; + if (Object(_this)) + iOwner = Object(_this)->Controller; else iOwner = NO_OWNER; } // Create site object - C4Object *pNewObj = Game.CreateObjectConstruction(PropList,cthr->Obj,iOwner,iXOffset,iYOffset,iCompletion*FullCon/100,fTerrain); + C4Object *pNewObj = Game.CreateObjectConstruction(PropList,Object(_this),iOwner,iXOffset,iYOffset,iCompletion*FullCon/100,fTerrain); // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player - if (pNewObj && cthr->Obj && cthr->Obj->Controller>NO_OWNER) pNewObj->Controller = cthr->Obj->Controller; + if (pNewObj && Object(_this) && Object(_this)->Controller>NO_OWNER) pNewObj->Controller = Object(_this)->Controller; return pNewObj; } -static C4ValueArray *FnFindConstructionSite(C4AulContext *cthr, C4PropList * PropList, int32_t v1, int32_t v2) +static C4ValueArray *FnFindConstructionSite(C4PropList * _this, C4PropList * PropList, int32_t v1, int32_t v2) { // Get def C4Def *pDef; @@ -207,35 +202,35 @@ static C4ValueArray *FnFindConstructionSite(C4AulContext *cthr, C4PropList * Pro return pArray; } -static bool FnCheckConstructionSite(C4AulContext *cthr, C4PropList * PropList, int32_t iXOffset, int32_t iYOffset) +static bool FnCheckConstructionSite(C4PropList * _this, C4PropList * PropList, int32_t iXOffset, int32_t iYOffset) { // Make sure parameters are valid if (!PropList || !PropList->GetDef()) return NULL; // Local object calls override position offset, owner - if (cthr->Obj) + if (Object(_this)) { - iXOffset+=cthr->Obj->GetX(); - iYOffset+=cthr->Obj->GetY(); + iXOffset+=Object(_this)->GetX(); + iYOffset+=Object(_this)->GetY(); } // Check construction site return ConstructionCheck(PropList, iXOffset, iYOffset); } -C4FindObject *CreateCriterionsFromPars(C4Value *pPars, C4FindObject **pFOs, C4SortObject **pSOs) +C4FindObject *CreateCriterionsFromPars(C4Value *pPars, C4FindObject **pFOs, C4SortObject **pSOs, const C4Object *context) { int i, iCnt = 0, iSortCnt = 0; // Read all parameters for (i = 0; i < C4AUL_MAX_Par; i++) { - PAR(any, Data); + C4Value Data = *(pPars++); // No data given? if (!Data) break; // Construct C4SortObject *pSO = NULL; - C4FindObject *pFO = C4FindObject::CreateByValue(Data, pSOs ? &pSO : NULL); + C4FindObject *pFO = C4FindObject::CreateByValue(Data, pSOs ? &pSO : NULL, context); // Add FindObject if (pFO) { @@ -272,14 +267,14 @@ C4FindObject *CreateCriterionsFromPars(C4Value *pPars, C4FindObject **pFOs, C4So return pFO; } -static C4Value FnObjectCount(C4AulContext *cthr, C4Value *pPars) +static C4Value FnObjectCount(C4PropList * _this, C4Value *pPars) { // Create FindObject-structure C4FindObject *pFOs[C4AUL_MAX_Par]; - C4FindObject *pFO = CreateCriterionsFromPars(pPars, pFOs, NULL); + C4FindObject *pFO = CreateCriterionsFromPars(pPars, pFOs, NULL, Object(_this)); // Error? if (!pFO) - throw new C4AulExecError(cthr->Obj, "ObjectCount: No valid search criterions supplied"); + throw new C4AulExecError("ObjectCount: No valid search criterions supplied"); // Search int32_t iCnt = pFO->Count(::Objects, ::Objects.Sectors); // Free @@ -288,15 +283,15 @@ static C4Value FnObjectCount(C4AulContext *cthr, C4Value *pPars) return C4VInt(iCnt); } -static C4Value FnFindObject(C4AulContext *cthr, C4Value *pPars) +static C4Value FnFindObject(C4PropList * _this, C4Value *pPars) { // Create FindObject-structure C4FindObject *pFOs[C4AUL_MAX_Par]; C4SortObject *pSOs[C4AUL_MAX_Par]; - C4FindObject *pFO = CreateCriterionsFromPars(pPars, pFOs, pSOs); + C4FindObject *pFO = CreateCriterionsFromPars(pPars, pFOs, pSOs, Object(_this)); // Error? if (!pFO) - throw new C4AulExecError(cthr->Obj, "FindObject: No valid search criterions supplied"); + throw new C4AulExecError("FindObject: No valid search criterions supplied"); // Search C4Object *pObj = pFO->Find(::Objects, ::Objects.Sectors); // Free @@ -305,15 +300,15 @@ static C4Value FnFindObject(C4AulContext *cthr, C4Value *pPars) return C4VObj(pObj); } -static C4Value FnFindObjects(C4AulContext *cthr, C4Value *pPars) +static C4Value FnFindObjects(C4PropList * _this, C4Value *pPars) { // Create FindObject-structure C4FindObject *pFOs[C4AUL_MAX_Par]; C4SortObject *pSOs[C4AUL_MAX_Par]; - C4FindObject *pFO = CreateCriterionsFromPars(pPars, pFOs, pSOs); + C4FindObject *pFO = CreateCriterionsFromPars(pPars, pFOs, pSOs, Object(_this)); // Error? if (!pFO) - throw new C4AulExecError(cthr->Obj, "FindObjects: No valid search criterions supplied"); + throw new C4AulExecError("FindObjects: No valid search criterions supplied"); // Search C4ValueArray *pResult = pFO->FindMany(::Objects, ::Objects.Sectors); // Free @@ -322,20 +317,35 @@ static C4Value FnFindObjects(C4AulContext *cthr, C4Value *pPars) return C4VArray(pResult); } -static bool FnSmoke(C4AulContext *cthr, long tx, long ty, long level, long dwClr) +static bool FnInsertMaterial(C4PropList * _this, long mat, long x, long y, long vx, long vy, C4PropList *insert_position) { - if (cthr->Obj) { tx+=cthr->Obj->GetX(); ty+=cthr->Obj->GetY(); } - Smoke(tx,ty,level,dwClr); + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } + int32_t insert_x=x, insert_y=y; + if (!::Landscape.InsertMaterial(mat,&insert_x,&insert_y,vx,vy)) return false; + // output insertion position if desired + if (insert_position && !insert_position->IsFrozen()) + { + insert_position->SetProperty(P_X, C4VInt(insert_x)); + insert_position->SetProperty(P_Y, C4VInt(insert_y)); + } return true; } -static bool FnInsertMaterial(C4AulContext *cthr, long mat, long x, long y, long vx, long vy) +static bool FnCanInsertMaterial(C4PropList * _this, long mat, long x, long y, C4PropList *insert_position) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } - return !!::Landscape.InsertMaterial(mat,x,y,vx,vy); + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } + int32_t insert_x=x, insert_y=y; + if (!::Landscape.InsertMaterial(mat,&insert_x,&insert_y,0,0,true)) return false; + // output insertion position if desired + if (insert_position && !insert_position->IsFrozen()) + { + insert_position->SetProperty(P_X, C4VInt(insert_x)); + insert_position->SetProperty(P_Y, C4VInt(insert_y)); + } + return true; } -static long FnGetMaterialCount(C4AulContext *cthr, long iMaterial, bool fReal) +static long FnGetMaterialCount(C4PropList * _this, long iMaterial, bool fReal) { if (!MatValid(iMaterial)) return -1; if (fReal || !::MaterialMap.Map[iMaterial].MinHeightCount) @@ -344,15 +354,15 @@ static long FnGetMaterialCount(C4AulContext *cthr, long iMaterial, bool fReal) return ::Landscape.EffectiveMatCount[iMaterial]; } -static long FnGetMaterial(C4AulContext *cthr, long x, long y) +static long FnGetMaterial(C4PropList * _this, long x, long y) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } return GBackMat(x,y); } -static C4String *FnGetTexture(C4AulContext* cthr, long x, long y) +static C4String *FnGetTexture(C4PropList * _this, long x, long y) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } // Get texture int32_t iTex = PixCol2Tex(GBackPix(x, y)); @@ -365,43 +375,52 @@ static C4String *FnGetTexture(C4AulContext* cthr, long x, long y) } // Note: Might be async in case of 16<->32 bit textures! -static Nillable FnGetAverageTextureColor(C4AulContext* cthr, C4String* Texture) +static Nillable FnGetAverageTextureColor(C4PropList * _this, C4String* Texture) { // Safety if(!Texture) return C4Void(); // Check texture - C4Texture* Tex = ::TextureMap.GetTexture(Texture->GetData().getData()); + StdStrBuf texture_name; + texture_name.Ref(Texture->GetCStr()); + const char* pch = strchr(texture_name.getData(), '-'); + if (pch != NULL) + { + size_t len = pch - texture_name.getData(); + texture_name.Copy(); + texture_name.SetLength(len); + } + C4Texture* Tex = ::TextureMap.GetTexture(texture_name.getData()); if(!Tex) return C4Void(); return Tex->GetAverageColor(); } -static bool FnGBackSolid(C4AulContext *cthr, long x, long y) +static bool FnGBackSolid(C4PropList * _this, long x, long y) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } return GBackSolid(x,y); } -static bool FnGBackSemiSolid(C4AulContext *cthr, long x, long y) +static bool FnGBackSemiSolid(C4PropList * _this, long x, long y) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } return GBackSemiSolid(x,y); } -static bool FnGBackLiquid(C4AulContext *cthr, long x, long y) +static bool FnGBackLiquid(C4PropList * _this, long x, long y) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } return GBackLiquid(x,y); } -static bool FnGBackSky(C4AulContext *cthr, long x, long y) +static bool FnGBackSky(C4PropList * _this, long x, long y) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } return !GBackIFT(x, y); } -static long FnExtractMaterialAmount(C4AulContext *cthr, long x, long y, long mat, long amount) +static long FnExtractMaterialAmount(C4PropList * _this, long x, long y, long mat, long amount) { - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } long extracted=0; for (; extracted iCausedBy) +static C4Void FnBlastFree(C4PropList * _this, long iX, long iY, long iLevel, Nillable iCausedBy, Nillable iMaxDensity) { - if (iCausedBy.IsNil() && cthr->Obj) iCausedBy = cthr->Obj->Controller; + if (iCausedBy.IsNil() && Object(_this)) iCausedBy = Object(_this)->Controller; + if (iMaxDensity.IsNil()) iMaxDensity = C4M_Vehicle; - ::Landscape.BlastFree(iX, iY, iLevel, iCausedBy, cthr->Obj); + ::Landscape.BlastFree(iX, iY, iLevel, iCausedBy, Object(_this), iMaxDensity); return C4Void(); } -static bool FnSound(C4AulContext *cthr, C4String *szSound, bool fGlobal, Nillable iLevel, Nillable iAtPlayer, long iLoop, bool fMultiple, long iCustomFalloffDistance) +static bool FnSoundAt(C4PropList * _this, C4String *szSound, long iX, long iY, Nillable iLevel, Nillable iAtPlayer, long iCustomFalloffDistance) +{ + // play here? + if (!iAtPlayer.IsNil()) + { + // get player to play at + C4Player *pPlr = ::Players.Get(iAtPlayer); + // not existant? fail + if (!pPlr) return false; + // network client: don't play here + // return true for network sync + if (!pPlr->LocalControl) return true; + } + // even less than nothing? + if (iLevel<0) return true; + // default sound level + if (iLevel.IsNil() || iLevel>100) + iLevel=100; + // target object + C4Object *pObj = Object(_this); + if (pObj) + { + iX += pObj->GetX(); + iY += pObj->GetY(); + } + StartSoundEffectAt(FnStringPar(szSound),iX,iY,iLevel,iCustomFalloffDistance); + // always return true (network safety!) + return true; +} + +static bool FnSound(C4PropList * _this, C4String *szSound, bool fGlobal, Nillable iLevel, Nillable iAtPlayer, long iLoop, long iCustomFalloffDistance) { // play here? if (!iAtPlayer.IsNil()) @@ -438,9 +488,9 @@ static bool FnSound(C4AulContext *cthr, C4String *szSound, bool fGlobal, Nillabl iLevel=100; // target object C4Object *pObj = NULL; - if (!fGlobal) pObj = cthr->Obj; + if (!fGlobal) pObj = Object(_this); // already playing? - if (iLoop >= 0 && !fMultiple && GetSoundInstance(FnStringPar(szSound), pObj)) + if (iLoop >= 0 && GetSoundInstance(FnStringPar(szSound), pObj)) return false; // try to play effect if (iLoop >= 0) @@ -451,7 +501,7 @@ static bool FnSound(C4AulContext *cthr, C4String *szSound, bool fGlobal, Nillabl return true; } -static bool FnMusic(C4AulContext *cthr, C4String *szSongname, bool fLoop) +static bool FnMusic(C4PropList * _this, C4String *szSongname, bool fLoop) { bool success; if (!szSongname) @@ -466,13 +516,13 @@ static bool FnMusic(C4AulContext *cthr, C4String *szSongname, bool fLoop) return success; } -static long FnMusicLevel(C4AulContext *cthr, long iLevel) +static long FnMusicLevel(C4PropList * _this, long iLevel) { Game.SetMusicLevel(iLevel); return Application.MusicSystem.SetVolume(iLevel); } -static long FnSetPlayList(C4AulContext *cth, C4String *szPlayList) +static long FnSetPlayList(C4PropList * _this, C4String *szPlayList) { long iFilesInPlayList = Application.MusicSystem.SetPlayList(FnStringPar(szPlayList)); Game.PlayList.Copy(FnStringPar(szPlayList)); @@ -481,94 +531,100 @@ static long FnSetPlayList(C4AulContext *cth, C4String *szPlayList) return iFilesInPlayList; } -static bool FnGameOver(C4AulContext *cthr, long iGameOverValue /* provided for future compatibility */) +static bool FnGameOver(C4PropList * _this, long iGameOverValue /* provided for future compatibility */) { return !!Game.DoGameOver(); } -static bool FnGainMissionAccess(C4AulContext *cthr, C4String *szPassword) +static bool FnGainMissionAccess(C4PropList * _this, C4String *szPassword) { if (std::strlen(Config.General.MissionAccess)+std::strlen(FnStringPar(szPassword))+3>CFG_MaxString) return false; SAddModule(Config.General.MissionAccess,FnStringPar(szPassword)); return true; } -static C4Value FnPlayerMessage_C4V(C4AulContext *cthr, C4Value * iPlayer, C4Value *c4vMessage, C4Value * iPar0, C4Value * iPar1, C4Value * iPar2, C4Value * iPar3, C4Value * iPar4, C4Value * iPar5, C4Value * iPar6, C4Value * iPar7) +static C4Value FnPlayerMessage(C4PropList * _this, C4Value * Pars) { - if (!cthr->Obj) throw new NeedObjectContext("PlayerMessage"); - char buf[MaxFnStringParLen+1]; - C4String * szMessage = c4vMessage->getStr(); + if (!Object(_this)) throw new NeedObjectContext("PlayerMessage"); + int iPlayer = Pars[0].getInt(); + C4String * szMessage = Pars[1].getStr(); if (!szMessage) return C4VBool(false); + StdStrBuf buf; + buf.SetLength(szMessage->GetData().getLength()); // Speech bool fSpoken=false; - if (SCopySegment(FnStringPar(szMessage),1,buf,'$')) - if (StartSoundEffect(buf,false,100, cthr->Obj)) + if (SCopySegment(FnStringPar(szMessage),1,buf.getMData(),'$')) + if (StartSoundEffect(buf.getData(),false,100, Object(_this))) fSpoken=true; // Text if (!fSpoken) - if (SCopySegment(FnStringFormat(cthr,FnStringPar(szMessage),iPar0,iPar1,iPar2,iPar3,iPar4,iPar5,iPar6,iPar7).getData(),0,buf,'$')) - { - GameMsgObjectPlayer(buf,cthr->Obj,iPlayer->getInt()); - } - + { + buf.Take(FnStringFormat(_this, szMessage, &Pars[2], 8)); + const char * dollar = strchr(buf.getData(), '$'); + if (dollar) buf.Shrink(dollar - buf.getData()); + GameMsgObjectPlayer(buf.getData(),Object(_this), iPlayer); + } return C4VBool(true); } -static C4Value FnMessage_C4V(C4AulContext *cthr, C4Value *c4vMessage, C4Value * iPar0, C4Value * iPar1, C4Value * iPar2, C4Value * iPar3, C4Value * iPar4, C4Value * iPar5, C4Value * iPar6, C4Value * iPar7, C4Value * iPar8) +static C4Value FnMessage(C4PropList * _this, C4Value * Pars) { - if (!cthr->Obj) throw new NeedObjectContext("Message"); - char buf[MaxFnStringParLen+1]; - C4String * szMessage = c4vMessage->getStr(); + if (!Object(_this)) throw new NeedObjectContext("Message"); + C4String * szMessage = Pars[0].getStr(); if (!szMessage) return C4VBool(false); + StdStrBuf buf; + buf.SetLength(szMessage->GetData().getLength()); // Speech bool fSpoken=false; - if (SCopySegment(FnStringPar(szMessage),1,buf,'$')) - if (StartSoundEffect(buf,false,100,cthr->Obj)) + if (SCopySegment(FnStringPar(szMessage),1,buf.getMData(),'$')) + if (StartSoundEffect(buf.getData(),false,100, Object(_this))) fSpoken=true; // Text if (!fSpoken) - if (SCopySegment(FnStringFormat(cthr,FnStringPar(szMessage),iPar0,iPar1,iPar2,iPar3,iPar4,iPar5,iPar6,iPar7,iPar8).getData(),0,buf,'$')) - { - GameMsgObject(buf,cthr->Obj); - } - + { + buf.Take(FnStringFormat(_this,szMessage, &Pars[1], 9)); + const char * dollar = strchr(buf.getData(), '$'); + if (dollar) buf.Shrink(dollar - buf.getData()); + GameMsgObject(buf.getData(),Object(_this)); + } return C4VBool(true); } -static C4Value FnAddMessage_C4V(C4AulContext *cthr, C4Value *c4vMessage, C4Value * iPar0, C4Value * iPar1, C4Value * iPar2, C4Value * iPar3, C4Value * iPar4, C4Value * iPar5, C4Value * iPar6, C4Value * iPar7, C4Value * iPar8) +// undocumented! +static C4Value FnAddMessage(C4PropList * _this, C4Value * Pars) { - if (!cthr->Obj) throw new NeedObjectContext("AddMessage"); - C4String * szMessage = c4vMessage->getStr(); + if (!Object(_this)) throw new NeedObjectContext("AddMessage"); + C4String * szMessage = Pars[0].getStr(); if (!szMessage) return C4VBool(false); - ::Messages.Append(C4GM_Target,FnStringFormat(cthr,FnStringPar(szMessage),iPar0,iPar1,iPar2,iPar3,iPar4,iPar5,iPar6,iPar7,iPar8).getData(),cthr->Obj,NO_OWNER,0,0,C4RGB(0xff, 0xff, 0xff)); - + ::Messages.Append(C4GM_Target, FnStringFormat(_this, szMessage, &Pars[1], 9).getData(), + Object(_this),NO_OWNER,0,0,C4RGB(0xff, 0xff, 0xff)); return C4VBool(true); } -static long FnMaterial(C4AulContext *cthr, C4String *mat_name) +static long FnMaterial(C4PropList * _this, C4String *mat_name) { return ::MaterialMap.Get(FnStringPar(mat_name)); } -C4Object* FnPlaceVegetation(C4AulContext *cthr, C4ID id, long iX, long iY, long iWdt, long iHgt, long iGrowth) +C4Object* FnPlaceVegetation(C4PropList * _this, C4PropList * Def, long iX, long iY, long iWdt, long iHgt, long iGrowth) { // Local call: relative coordinates - if (cthr->Obj) { iX+=cthr->Obj->GetX(); iY+=cthr->Obj->GetY(); } + if (Object(_this)) { iX+=Object(_this)->GetX(); iY+=Object(_this)->GetY(); } // Place vegetation - return Game.PlaceVegetation(id,iX,iY,iWdt,iHgt,iGrowth); + return Game.PlaceVegetation(Def,iX,iY,iWdt,iHgt,iGrowth); } -C4Object* FnPlaceAnimal(C4AulContext *cthr, C4ID id) +C4Object* FnPlaceAnimal(C4PropList * _this, C4PropList * Def) { - return Game.PlaceAnimal(id); + return Game.PlaceAnimal(Def? Def : _this); } -static bool FnHostile(C4AulContext *cthr, long iPlr1, long iPlr2, bool fCheckOneWayOnly) +static bool FnHostile(C4PropList * _this, long iPlr1, long iPlr2, bool fCheckOneWayOnly) { if (fCheckOneWayOnly) { @@ -578,7 +634,7 @@ static bool FnHostile(C4AulContext *cthr, long iPlr1, long iPlr2, bool fCheckOne return !!Hostile(iPlr1,iPlr2); } -static bool FnSetHostility(C4AulContext *cthr, long iPlr, long iPlr2, bool fHostile, bool fSilent, bool fNoCalls) +static bool FnSetHostility(C4PropList * _this, long iPlr, long iPlr2, bool fHostile, bool fSilent, bool fNoCalls) { C4Player *pPlr = ::Players.Get(iPlr); if (!pPlr) return false; @@ -596,28 +652,28 @@ static bool FnSetHostility(C4AulContext *cthr, long iPlr, long iPlr2, bool fHost return true; } -static bool FnSetPlrView(C4AulContext *cthr, long iPlr, C4Object *tobj) +static bool FnSetPlrView(C4PropList * _this, long iPlr, C4Object *tobj) { if (!ValidPlr(iPlr)) return false; ::Players.Get(iPlr)->SetViewMode(C4PVM_Target,tobj); return true; } -static long FnGetPlrViewMode(C4AulContext *cthr, long iPlr) +static long FnGetPlrViewMode(C4PropList * _this, long iPlr) { if (!ValidPlr(iPlr)) return -1; if (::Control.SyncMode()) return -1; return ::Players.Get(iPlr)->ViewMode; } -static C4Void FnResetCursorView(C4AulContext *cthr, long plr) +static C4Void FnResetCursorView(C4PropList * _this, long plr) { C4Player *pplr = ::Players.Get(plr); if (pplr) pplr->ResetCursorView(); return C4Void(); } -static C4Object *FnGetPlrView(C4AulContext *cthr, long iPlr) +static C4Object *FnGetPlrView(C4PropList * _this, long iPlr) { C4Player *pPlr = ::Players.Get(iPlr); if (!pPlr || pPlr->ViewMode != C4PVM_Target) return NULL; @@ -631,7 +687,7 @@ static const int PLRZOOM_Direct = 0x01, PLRZOOM_LimitMin = 0x10, PLRZOOM_LimitMax = 0x20; -static bool FnSetPlayerZoomByViewRange(C4AulContext *cthr, long plr_idx, long range_wdt, long range_hgt, long flags) +static bool FnSetPlayerZoomByViewRange(C4PropList * _this, long plr_idx, long range_wdt, long range_hgt, long flags) { // zoom size safety - both ranges 0 is fine, it causes a zoom reset to default if (range_wdt < 0 || range_hgt < 0) return false; @@ -640,7 +696,7 @@ static bool FnSetPlayerZoomByViewRange(C4AulContext *cthr, long plr_idx, long ra { for (C4Player *plr = ::Players.First; plr; plr=plr->Next) if (plr->Number != NO_OWNER) // can't happen, but would be a crash if it did... - FnSetPlayerZoomByViewRange(cthr, plr->Number, range_wdt, range_hgt, flags); + FnSetPlayerZoomByViewRange(_this, plr->Number, range_wdt, range_hgt, flags); return true; } else @@ -660,14 +716,14 @@ static bool FnSetPlayerZoomByViewRange(C4AulContext *cthr, long plr_idx, long ra return true; } -static bool FnSetPlayerViewLock(C4AulContext *cthr, long plr_idx, bool is_locked) +static bool FnSetPlayerViewLock(C4PropList * _this, long plr_idx, bool is_locked) { // special player NO_OWNER: apply to all players if (plr_idx == NO_OWNER) { for (C4Player *plr = ::Players.First; plr; plr=plr->Next) if (plr->Number != NO_OWNER) // can't happen, but would be a crash if it did... - FnSetPlayerViewLock(cthr, plr->Number, is_locked); + FnSetPlayerViewLock(_this, plr->Number, is_locked); return true; } C4Player *plr = ::Players.Get(plr_idx); @@ -676,7 +732,7 @@ static bool FnSetPlayerViewLock(C4AulContext *cthr, long plr_idx, bool is_locked return true; } -static bool FnDoHomebaseMaterial(C4AulContext *cthr, long iPlr, C4ID id, long iChange) +static bool FnDoHomebaseMaterial(C4PropList * _this, long iPlr, C4ID id, long iChange) { // validity check if (!ValidPlr(iPlr)) return false; @@ -687,7 +743,7 @@ static bool FnDoHomebaseMaterial(C4AulContext *cthr, long iPlr, C4ID id, long iC return ::Players.Get(iPlr)->HomeBaseMaterial.SetIDCount(id,iLastcount+iChange,true); } -static bool FnDoHomebaseProduction(C4AulContext *cthr, long iPlr, C4ID id, long iChange) +static bool FnDoHomebaseProduction(C4PropList * _this, long iPlr, C4ID id, long iChange) { // validity check if (!ValidPlr(iPlr)) return false; @@ -698,7 +754,7 @@ static bool FnDoHomebaseProduction(C4AulContext *cthr, long iPlr, C4ID id, long return ::Players.Get(iPlr)->HomeBaseProduction.SetIDCount(id,iLastcount+iChange,true); } -static bool FnSetPlrKnowledge(C4AulContext *cthr, long iPlr, C4ID id, bool fRemove) +static bool FnSetPlrKnowledge(C4PropList * _this, long iPlr, C4ID id, bool fRemove) { C4Player *pPlr=::Players.Get(iPlr); if (!pPlr) return false; @@ -715,12 +771,8 @@ static bool FnSetPlrKnowledge(C4AulContext *cthr, long iPlr, C4ID id, bool fRemo } } -static C4Value FnGetPlrKnowledge_C4V(C4AulContext *cthr, C4Value* iPlr_C4V, C4Value* id_C4V, C4Value* iIndex_C4V, C4Value* dwCategory_C4V) +static C4Value FnGetPlrKnowledge(C4PropList * _this, int iPlr, C4ID id, int iIndex, int dwCategory) { - long iPlr = iPlr_C4V->getInt(); - C4ID id = id_C4V->getC4ID(); - long iIndex = iIndex_C4V->getInt(); - DWORD dwCategory = dwCategory_C4V->getInt(); if (!ValidPlr(iPlr)) return C4VBool(false); // Search by id, check if available, return bool if (id) return C4VBool(::Players.Get(iPlr)->Knowledge.GetIDCount(id,1) != 0); @@ -728,18 +780,13 @@ static C4Value FnGetPlrKnowledge_C4V(C4AulContext *cthr, C4Value* iPlr_C4V, C4Va return C4VPropList(C4Id2Def(::Players.Get(iPlr)->Knowledge.GetID( ::Definitions, dwCategory, iIndex ))); } -static C4Def * FnGetDefinition(C4AulContext *cthr, long iIndex) +static C4Def * FnGetDefinition(C4PropList * _this, long iIndex) { return ::Definitions.GetDef(iIndex); } -static C4Value FnGetComponent_C4V(C4AulContext *cthr, C4Value* idComponent_C4V, C4Value* iIndex_C4V, C4Value* pObj_C4V, C4Value* idDef_C4V) +static C4Value FnGetComponent(C4PropList * _this, C4ID idComponent, int iIndex, C4Object * pObj, C4ID idDef) { - C4ID idComponent = idComponent_C4V->getC4ID(); - long iIndex = iIndex_C4V->getInt(); - C4Object *pObj = pObj_C4V->getObj(); - C4ID idDef = idDef_C4V->getC4ID(); - // Def component - as seen by scope object as builder if (idDef) { @@ -754,7 +801,7 @@ static C4Value FnGetComponent_C4V(C4AulContext *cthr, C4Value* idComponent_C4V, else { // Get object - if (!pObj) pObj=cthr->Obj; if (!pObj) return C4Value(); + if (!pObj) pObj=Object(_this); if (!pObj) return C4Value(); // Component count if (idComponent) return C4VInt(pObj->Component.GetIDCount(idComponent)); // Indexed component @@ -763,13 +810,8 @@ static C4Value FnGetComponent_C4V(C4AulContext *cthr, C4Value* idComponent_C4V, return C4Value(); } -static C4Value FnGetHomebaseMaterial_C4V(C4AulContext *cthr, C4Value* iPlr_C4V, C4Value* id_C4V, C4Value* iIndex_C4V, C4Value* dwCategory_C4V) +static C4Value FnGetHomebaseMaterial(C4PropList * _this, int iPlr, C4ID id, int iIndex, int dwCategory) { - long iPlr = iPlr_C4V->getInt(); - C4ID id = id_C4V->getC4ID(); - long iIndex = iIndex_C4V->getInt(); - DWORD dwCategory = dwCategory_C4V->getInt(); - if (!ValidPlr(iPlr)) return C4VBool(false); // Search by id, return available count if (id) return C4VInt(::Players.Get(iPlr)->HomeBaseMaterial.GetIDCount(id)); @@ -777,13 +819,8 @@ static C4Value FnGetHomebaseMaterial_C4V(C4AulContext *cthr, C4Value* iPlr_C4V, return C4VPropList(C4Id2Def(::Players.Get(iPlr)->HomeBaseMaterial.GetID( ::Definitions, dwCategory, iIndex ))); } -static C4Value FnGetHomebaseProduction_C4V(C4AulContext *cthr, C4Value* iPlr_C4V, C4Value* id_C4V, C4Value* iIndex_C4V, C4Value* dwCategory_C4V) +static C4Value FnGetHomebaseProduction(C4PropList * _this, int iPlr, C4ID id, int iIndex, int dwCategory) { - long iPlr = iPlr_C4V->getInt(); - C4ID id = id_C4V->getC4ID(); - long iIndex = iIndex_C4V->getInt(); - DWORD dwCategory = dwCategory_C4V->getInt(); - if (!ValidPlr(iPlr)) return C4VBool(false); // Search by id, return available count if (id) return C4VInt(::Players.Get(iPlr)->HomeBaseProduction.GetIDCount(id)); @@ -791,56 +828,56 @@ static C4Value FnGetHomebaseProduction_C4V(C4AulContext *cthr, C4Value* iPlr_C4V return C4VPropList(C4Id2Def(::Players.Get(iPlr)->HomeBaseProduction.GetID( ::Definitions, dwCategory, iIndex ))); } -static long FnGetWealth(C4AulContext *cthr, long iPlr) +static long FnGetWealth(C4PropList * _this, long iPlr) { if (!ValidPlr(iPlr)) return 0; return ::Players.Get(iPlr)->Wealth; } -static bool FnSetWealth(C4AulContext *cthr, long iPlr, long iValue) +static bool FnSetWealth(C4PropList * _this, long iPlr, long iValue) { if (!ValidPlr(iPlr)) return false; ::Players.Get(iPlr)->SetWealth(iValue); return true; } -static long FnDoPlayerScore(C4AulContext *cthr, long iPlr, long iChange) +static long FnDoPlayerScore(C4PropList * _this, long iPlr, long iChange) { if (!ValidPlr(iPlr)) return false; return ::Players.Get(iPlr)->DoScore(iChange); } -static long FnGetPlayerScore(C4AulContext *cthr, long iPlr) +static long FnGetPlayerScore(C4PropList * _this, long iPlr) { if (!ValidPlr(iPlr)) return 0; return ::Players.Get(iPlr)->CurrentScore; } -static long FnGetPlayerScoreGain(C4AulContext *cthr, long iPlr) +static long FnGetPlayerScoreGain(C4PropList * _this, long iPlr) { if (!ValidPlr(iPlr)) return 0; return ::Players.Get(iPlr)->CurrentScore - ::Players.Get(iPlr)->InitialScore; } -static C4Object *FnGetHiRank(C4AulContext *cthr, long iPlr) +static C4Object *FnGetHiRank(C4PropList * _this, long iPlr) { if (!ValidPlr(iPlr)) return NULL; return ::Players.Get(iPlr)->GetHiRankActiveCrew(); } -static C4Object *FnGetCrew(C4AulContext *cthr, long iPlr, long index) +static C4Object *FnGetCrew(C4PropList * _this, long iPlr, long index) { if (!ValidPlr(iPlr)) return NULL; return ::Players.Get(iPlr)->Crew.GetObject(index); } -static long FnGetCrewCount(C4AulContext *cthr, long iPlr) +static long FnGetCrewCount(C4PropList * _this, long iPlr) { if (!ValidPlr(iPlr)) return 0; return ::Players.Get(iPlr)->Crew.ObjectCount(); } -static long FnGetPlayerCount(C4AulContext *cthr, long iType) +static long FnGetPlayerCount(C4PropList * _this, long iType) { if (!iType) return ::Players.GetCount(); @@ -848,7 +885,7 @@ static long FnGetPlayerCount(C4AulContext *cthr, long iType) return ::Players.GetCount((C4PlayerType) iType); } -static long FnGetPlayerByIndex(C4AulContext *cthr, long iIndex, long iType) +static long FnGetPlayerByIndex(C4PropList * _this, long iIndex, long iType) { C4Player *pPlayer; if (iType) @@ -859,7 +896,7 @@ static long FnGetPlayerByIndex(C4AulContext *cthr, long iIndex, long iType) return pPlayer->Number; } -static long FnEliminatePlayer(C4AulContext *cthr, long iPlr, bool fRemoveDirect) +static long FnEliminatePlayer(C4PropList * _this, long iPlr, bool fRemoveDirect) { C4Player *pPlr=::Players.Get(iPlr); if (!pPlr) return false; @@ -879,7 +916,8 @@ static long FnEliminatePlayer(C4AulContext *cthr, long iPlr, bool fRemoveDirect) return true; } -static bool FnSurrenderPlayer(C4AulContext *cthr, long iPlr) +// undocumented! +static bool FnSurrenderPlayer(C4PropList * _this, long iPlr) { C4Player *pPlr=::Players.Get(iPlr); if (!pPlr) return false; @@ -888,7 +926,8 @@ static bool FnSurrenderPlayer(C4AulContext *cthr, long iPlr) return true; } -static bool FnSetLeaguePerformance(C4AulContext *cthr, long iScore) +// undocumented! +static bool FnSetLeaguePerformance(C4PropList * _this, long iScore) { Game.RoundResults.SetLeaguePerformance(iScore); return true; @@ -899,7 +938,7 @@ static const int32_t CSPF_FixedAttributes = 1<<0, CSPF_NoEliminationCheck = 1<<2, CSPF_Invisible = 1<<3; -static bool FnCreateScriptPlayer(C4AulContext *cthr, C4String *szName, long dwColor, long idTeam, long dwFlags, C4ID idExtra) +static bool FnCreateScriptPlayer(C4PropList * _this, C4String *szName, long dwColor, long idTeam, long dwFlags, C4ID idExtra) { // safety if (!szName || !szName->GetData().getLength()) return false; @@ -922,7 +961,7 @@ static bool FnCreateScriptPlayer(C4AulContext *cthr, C4String *szName, long dwCo return true; } -static C4Object *FnGetCursor(C4AulContext *cthr, long iPlr) +static C4Object *FnGetCursor(C4PropList * _this, long iPlr) { // get player C4Player *pPlr = ::Players.Get(iPlr); @@ -931,7 +970,8 @@ static C4Object *FnGetCursor(C4AulContext *cthr, long iPlr) return pPlr->Cursor; } -static C4Object *FnGetViewCursor(C4AulContext *cthr, long iPlr) +// undocumented! +static C4Object *FnGetViewCursor(C4PropList * _this, long iPlr) { // get player C4Player *pPlr = ::Players.Get(iPlr); @@ -939,7 +979,7 @@ static C4Object *FnGetViewCursor(C4AulContext *cthr, long iPlr) return pPlr ? pPlr->ViewCursor : NULL; } -static bool FnSetCursor(C4AulContext *cthr, long iPlr, C4Object *pObj, bool fNoSelectArrow) +static bool FnSetCursor(C4PropList * _this, long iPlr, C4Object *pObj, bool fNoSelectArrow) { C4Player *pPlr = ::Players.Get(iPlr); if (!pPlr || (pObj && !pObj->Status) || (pObj && pObj->CrewDisabled)) return false; @@ -947,7 +987,8 @@ static bool FnSetCursor(C4AulContext *cthr, long iPlr, C4Object *pObj, bool fNoS return true; } -static bool FnSetViewCursor(C4AulContext *cthr, long iPlr, C4Object *pObj) +// undocumented! +static bool FnSetViewCursor(C4PropList * _this, long iPlr, C4Object *pObj) { // get player C4Player *pPlr = ::Players.Get(iPlr); @@ -958,92 +999,93 @@ static bool FnSetViewCursor(C4AulContext *cthr, long iPlr, C4Object *pObj) return true; } -static long FnGetWind(C4AulContext *cthr, long x, long y, bool fGlobal) +static long FnGetWind(C4PropList * _this, long x, long y, bool fGlobal) { // global wind if (fGlobal) return ::Weather.Wind; // local wind - if (cthr->Obj) { x+=cthr->Obj->GetX(); y+=cthr->Obj->GetY(); } + if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); } return ::Weather.GetWind(x,y); } -static C4Void FnSetWind(C4AulContext *cthr, long iWind) +static C4Void FnSetWind(C4PropList * _this, long iWind) { ::Weather.SetWind(iWind); return C4Void(); } -static C4Void FnSetTemperature(C4AulContext *cthr, long iTemperature) +static C4Void FnSetTemperature(C4PropList * _this, long iTemperature) { ::Weather.SetTemperature(iTemperature); return C4Void(); } -static long FnGetTemperature(C4AulContext *cthr) +static long FnGetTemperature(C4PropList * _this) { return ::Weather.GetTemperature(); } -static C4Void FnSetSeason(C4AulContext *cthr, long iSeason) +static C4Void FnSetSeason(C4PropList * _this, long iSeason) { ::Weather.SetSeason(iSeason); return C4Void(); } -static long FnGetSeason(C4AulContext *cthr) +static long FnGetSeason(C4PropList * _this) { return ::Weather.GetSeason(); } -static C4Void FnSetClimate(C4AulContext *cthr, long iClimate) +static C4Void FnSetClimate(C4PropList * _this, long iClimate) { ::Weather.SetClimate(iClimate); return C4Void(); } -static long FnGetClimate(C4AulContext *cthr) +static long FnGetClimate(C4PropList * _this) { return ::Weather.GetClimate(); } -static long FnLandscapeWidth(C4AulContext *cthr) +static long FnLandscapeWidth(C4PropList * _this) { return GBackWdt; } -static long FnLandscapeHeight(C4AulContext *cthr) +static long FnLandscapeHeight(C4PropList * _this) { return GBackHgt; } -static C4Void FnShakeFree(C4AulContext *cthr, long x, long y, long rad) +static C4Void FnShakeFree(C4PropList * _this, long x, long y, long rad) { ::Landscape.ShakeFree(x,y,rad); return C4Void(); } -static long FnDigFree(C4AulContext *cthr, long x, long y, long rad, bool no_dig2objects) +static long FnDigFree(C4PropList * _this, long x, long y, long rad, bool no_dig2objects, bool no_instability_check) { - return ::Landscape.DigFree(x,y,rad,cthr->Obj,no_dig2objects); + return ::Landscape.DigFree(x,y,rad,Object(_this),no_dig2objects,no_instability_check); } -static long FnDigFreeRect(C4AulContext *cthr, long iX, long iY, long iWdt, long iHgt, bool no_dig2objects) +static long FnDigFreeRect(C4PropList * _this, long iX, long iY, long iWdt, long iHgt, bool no_dig2objects, bool no_instability_check) { - return ::Landscape.DigFreeRect(iX,iY,iWdt,iHgt,cthr->Obj,no_dig2objects); + return ::Landscape.DigFreeRect(iX,iY,iWdt,iHgt,Object(_this),no_dig2objects,no_instability_check); } -static C4Void FnClearFreeRect(C4AulContext *cthr, long iX, long iY, long iWdt, long iHgt) +static C4Void FnClearFreeRect(C4PropList * _this, long iX, long iY, long iWdt, long iHgt) { ::Landscape.ClearFreeRect(iX,iY,iWdt,iHgt); return C4Void(); } -static bool FnPathFree(C4AulContext *cthr, long X1, long Y1, long X2, long Y2) +static bool FnPathFree(C4PropList * _this, long X1, long Y1, long X2, long Y2) { return !!PathFree(X1, Y1, X2, Y2); } -static C4ValueArray* FnPathFree2(C4AulContext *cthr, int32_t x1, int32_t y1, int32_t x2, int32_t y2) +// undocumented! +static C4ValueArray* FnPathFree2(C4PropList * _this, int32_t x1, int32_t y1, int32_t x2, int32_t y2) { int32_t x = -1, y = -1; if (!PathFree(x1, y1, x2, y2, &x, &y)) @@ -1056,86 +1098,33 @@ static C4ValueArray* FnPathFree2(C4AulContext *cthr, int32_t x1, int32_t y1, int return 0; } -C4Object* FnObject(C4AulContext *cthr, long iNumber) +C4Object* FnObject(C4PropList * _this, long iNumber) { return ::Objects.SafeObjectPointer(iNumber); // See FnObjectNumber } -static C4Value FnCall_C4V(C4AulContext *cthr, C4Value* szFunction_C4V, - C4Value* par0, C4Value* par1, C4Value* par2, C4Value* par3, C4Value* par4, - C4Value* par5, C4Value* par6, C4Value* par7, C4Value* par8/*, C4Value* par9*/) +static C4Value FnGameCallEx(C4PropList * _this, C4Value * Pars) { - // safety - C4String *szFunction = szFunction_C4V->getStr(); - - if (!szFunction || !cthr->Obj) return C4Value(); - C4AulParSet Pars; - Copy2ParSet9(Pars, *par); - return cthr->Obj->Call(FnStringPar(szFunction),&Pars/*, true*/); -} - -static C4Value FnDefinitionCall_C4V(C4AulContext *cthr, - C4Value* idID_C4V, C4Value* szFunction_C4V, - C4Value* par0, C4Value* par1, C4Value* par2, C4Value* par3, C4Value* par4, - C4Value* par5, C4Value* par6, C4Value* par7/*, C4Value* par8, C4Value* par9*/) -{ - C4PropList * p = idID_C4V->getPropList(); - if (!p) return C4Value(); - C4Def * pDef = p->GetDef(); - C4String *szFunction = szFunction_C4V->getStr(); - if (!pDef || !szFunction) return C4Value(); + C4String * fn = Pars[0].getStr(); + if (!fn) return C4Value(); // copy parameters - C4AulParSet Pars; - Copy2ParSet8(Pars, *par); + C4AulParSet ParSet(&Pars[1], 9); // Call - return pDef->Call(szFunction, &Pars); + return ::GameScript.GRBroadcast(fn->GetCStr(), &ParSet, true); } -static C4Value FnGameCall_C4V(C4AulContext *cthr, - C4Value* szFunction_C4V, - C4Value* par0, C4Value* par1, C4Value* par2, C4Value* par3, C4Value* par4, - C4Value* par5, C4Value* par6, C4Value* par7, C4Value* par8/*, C4Value* par9*/) +static C4Object * FnEditCursor(C4PropList * _this) { - C4String *szFunction = szFunction_C4V->getStr(); - - if (!szFunction) return C4Value(); - // Make failsafe - char szFunc2[500+1]; sprintf(szFunc2,"~%s",FnStringPar(szFunction)); - // copy parameters - C4AulParSet Pars; - Copy2ParSet9(Pars, *par); - // Call - return ::GameScript.Call(szFunc2, &Pars, true); + if (::Control.SyncMode()) return NULL; + return Console.EditCursor.GetTarget(); } -static C4Value FnGameCallEx_C4V(C4AulContext *cthr, - C4Value* szFunction_C4V, - C4Value* par0, C4Value* par1, C4Value* par2, C4Value* par3, C4Value* par4, - C4Value* par5, C4Value* par6, C4Value* par7, C4Value* par8/*, C4Value* par9*/) -{ - C4String *szFunction = szFunction_C4V->getStr(); +static bool FnIsNetwork(C4PropList * _this) { return Game.Parameters.IsNetworkGame; } - if (!szFunction) return C4Value(); - // Make failsafe - char szFunc2[500+1]; sprintf(szFunc2,"~%s",FnStringPar(szFunction)); - // copy parameters - C4AulParSet Pars; - Copy2ParSet9(Pars, *par); - // Call - return ::GameScript.GRBroadcast(szFunc2,&Pars, true); -} - -static C4Value FnEditCursor(C4AulContext *cth, C4Value *pPars) -{ - if (::Control.SyncMode()) return C4VNull; - return C4VObj(Console.EditCursor.GetTarget()); -} - -static bool FnIsNetwork(C4AulContext *cthr) { return Game.Parameters.IsNetworkGame; } - -static C4String *FnGetLeague(C4AulContext *cthr, long idx) +// undocumented! +static C4String *FnGetLeague(C4PropList * _this, long idx) { // get indexed league StdStrBuf sIdxLeague; @@ -1143,7 +1132,8 @@ static C4String *FnGetLeague(C4AulContext *cthr, long idx) return String(sIdxLeague.getData()); } -static bool FnTestMessageBoard(C4AulContext *cthr, long iForPlr, bool fTestIfInUse) +// undocumented! +static bool FnTestMessageBoard(C4PropList * _this, long iForPlr, bool fTestIfInUse) { // multi-query-MessageBoard is always available if the player is valid =) // (but it won't do anything in developer mode...) @@ -1154,9 +1144,10 @@ static bool FnTestMessageBoard(C4AulContext *cthr, long iForPlr, bool fTestIfInU return pPlr->HasMessageBoardQuery(); } -static bool FnCallMessageBoard(C4AulContext *cthr, C4Object *pObj, bool fUpperCase, C4String *szQueryString, long iForPlr) +// undocumented! +static bool FnCallMessageBoard(C4PropList * _this, C4Object *pObj, bool fUpperCase, C4String *szQueryString, long iForPlr) { - if (!pObj) pObj=cthr->Obj; + if (!pObj) pObj=Object(_this); if (pObj && !pObj->Status) return false; // check player C4Player *pPlr = ::Players.Get(iForPlr); @@ -1166,9 +1157,10 @@ static bool FnCallMessageBoard(C4AulContext *cthr, C4Object *pObj, bool fUpperCa return true; } -static bool FnAbortMessageBoard(C4AulContext *cthr, C4Object *pObj, long iForPlr) +// undocumented! +static bool FnAbortMessageBoard(C4PropList * _this, C4Object *pObj, long iForPlr) { - if (!pObj) pObj=cthr->Obj; + if (!pObj) pObj=Object(_this); // check player C4Player *pPlr = ::Players.Get(iForPlr); if (!pPlr) return false; @@ -1178,25 +1170,7 @@ static bool FnAbortMessageBoard(C4AulContext *cthr, C4Object *pObj, long iForPlr return pPlr->RemoveMessageBoardQuery(pObj); } -static bool FnOnMessageBoardAnswer(C4AulContext *cthr, C4Object *pObj, long iForPlr, C4String *szAnswerString) -{ - // remove query - // fail if query doesn't exist to prevent any doubled answers - C4Player *pPlr = ::Players.Get(iForPlr); - if (!pPlr) return false; - if (!pPlr->RemoveMessageBoardQuery(pObj)) return false; - // if no answer string is provided, the user did not answer anything - // just remove the query - if (!szAnswerString || !szAnswerString->GetCStr()) return true; - C4AulParSet ps = C4AulParSet(C4VString(szAnswerString), C4VInt(iForPlr)); - // get script - if (pObj) - return pObj->Call(PSF_InputCallback, &ps); - else - return ::GameScript.Call(PSF_InputCallback, &ps); -} - -static C4Void FnSetFoW(C4AulContext *cthr, bool fEnabled, long iPlr) +static C4Void FnSetFoW(C4PropList * _this, bool fEnabled, long iPlr) { // safety if (!ValidPlr(iPlr)) return C4Void(); @@ -1206,7 +1180,7 @@ static C4Void FnSetFoW(C4AulContext *cthr, bool fEnabled, long iPlr) return C4Void(); } -static long FnSetMaxPlayer(C4AulContext *cthr, long iTo) +static long FnSetMaxPlayer(C4PropList * _this, long iTo) { // think positive! :) if (iTo < 0) return false; @@ -1216,7 +1190,7 @@ static long FnSetMaxPlayer(C4AulContext *cthr, long iTo) return true; } -static bool FnGetMissionAccess(C4AulContext *cthr, C4String *strMissionAccess) +static bool FnGetMissionAccess(C4PropList * _this, C4String *strMissionAccess) { // safety if (!strMissionAccess) return false; @@ -1375,46 +1349,30 @@ C4Value GetValByStdCompiler(const char *strEntry, const char *strSection, int iE } } -static C4Value FnGetDefCoreVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetDefCoreVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int iEntryNr) { - if (!cthr->Def || !cthr->Def->GetDef()) + if (!_this || !_this->GetDef()) throw new NeedNonGlobalContext("GetDefCoreVal"); - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - if (strSection && !*strSection) strSection = NULL; - long iEntryNr = iEntryNr_C4V->getInt(); - - return GetValByStdCompiler(strEntry, strSection, iEntryNr, mkNamingAdapt(*cthr->Def->GetDef(), "DefCore")); + return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, + iEntryNr, mkNamingAdapt(*_this->GetDef(), "DefCore")); } -static C4Value FnGetObjectVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetObjectVal(C4Object * _this, C4String * strEntry, C4String * strSection, int iEntryNr) { - if (!cthr->Obj) throw new NeedObjectContext("GetObjectVal"); - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - if (!*strSection) strSection = NULL; - - long iEntryNr = iEntryNr_C4V->getInt(); - // get value C4ValueNumbers numbers; - C4Value retval = GetValByStdCompiler(strEntry, strSection, iEntryNr, mkNamingAdapt(mkParAdapt(*cthr->Obj, &numbers), "Object")); + C4Value retval = GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, + iEntryNr, mkNamingAdapt(mkParAdapt(*Object(_this), &numbers), "Object")); numbers.Denumerate(); retval.Denumerate(&numbers); return retval; } -static C4Value FnGetObjectInfoCoreVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetObjectInfoCoreVal(C4Object * _this, C4String * strEntry, C4String * strSection, int iEntryNr) { - if (!cthr->Obj) throw new NeedObjectContext("GetObjectInfoCoreVal"); - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - if (strSection && !*strSection) strSection = NULL; - long iEntryNr = iEntryNr_C4V->getInt(); - // get obj info - C4ObjectInfo* pObjInfo = cthr->Obj->Info; + C4ObjectInfo* pObjInfo = Object(_this)->Info; if (!pObjInfo) return C4VNull; @@ -1422,69 +1380,47 @@ static C4Value FnGetObjectInfoCoreVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4ObjectInfoCore* pObjInfoCore = (C4ObjectInfoCore*) pObjInfo; // get value - return GetValByStdCompiler(strEntry, strSection, iEntryNr, mkNamingAdapt(*pObjInfoCore, "ObjectInfo")); + return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, + iEntryNr, mkNamingAdapt(*pObjInfoCore, "ObjectInfo")); } -static C4Value FnGetScenarioVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetScenarioVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int iEntryNr) { - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - long iEntryNr = iEntryNr_C4V->getInt(); - - if (strSection && !*strSection) strSection = NULL; - - return GetValByStdCompiler(strEntry, strSection, iEntryNr, mkParAdapt(Game.C4S, false)); + return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, + iEntryNr, mkParAdapt(Game.C4S, false)); } -static C4Value FnGetPlayerVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value* iPlayer_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetPlayerVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int iPlayer, int iEntryNr) { - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - if (strSection && !*strSection) strSection = NULL; - long iPlr = iPlayer_C4V->getInt(); - long iEntryNr = iEntryNr_C4V->getInt(); - - if (!ValidPlr(iPlr)) return C4Value(); - // get player - C4Player* pPlayer = ::Players.Get(iPlr); + C4Player* pPlayer = ::Players.Get(iPlayer); + if (!pPlayer) return C4Value(); // get value C4ValueNumbers numbers; - C4Value retval = GetValByStdCompiler(strEntry, strSection, iEntryNr, mkNamingAdapt(mkParAdapt(*pPlayer, &numbers), "Player")); + C4Value retval = GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, + iEntryNr, mkNamingAdapt(mkParAdapt(*pPlayer, &numbers), "Player")); numbers.Denumerate(); retval.Denumerate(&numbers); return retval; } -static C4Value FnGetPlayerInfoCoreVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value* iPlayer_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetPlayerInfoCoreVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int iPlayer, int iEntryNr) { - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - if (strSection && !*strSection) strSection = NULL; - long iPlr = iPlayer_C4V->getInt(); - long iEntryNr = iEntryNr_C4V->getInt(); - - if (!ValidPlr(iPlr)) return C4Value(); - // get player - C4Player* pPlayer = ::Players.Get(iPlr); + C4Player* pPlayer = ::Players.Get(iPlayer); + if (!pPlayer) return C4Value(); // get plr info core C4PlayerInfoCore* pPlayerInfoCore = (C4PlayerInfoCore*) pPlayer; // get value - return GetValByStdCompiler(strEntry, strSection, iEntryNr, *pPlayerInfoCore); + return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, + iEntryNr, *pPlayerInfoCore); } -static C4Value FnGetMaterialVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Value* strSection_C4V, C4Value* iMat_C4V, C4Value *iEntryNr_C4V) +static C4Value FnGetMaterialVal(C4PropList * _this, C4String * strEntry, C4String* strSection, int iMat, int iEntryNr) { - const char *strEntry = FnStringPar(strEntry_C4V->getStr()); - const char *strSection = FnStringPar(strSection_C4V->getStr()); - if (strSection && !*strSection) strSection = NULL; - long iMat = iMat_C4V->getInt(); - long iEntryNr = iEntryNr_C4V->getInt(); - if (iMat < 0 || iMat >= ::MaterialMap.Num) return C4Value(); // get material @@ -1493,14 +1429,11 @@ static C4Value FnGetMaterialVal(C4AulContext* cthr, C4Value* strEntry_C4V, C4Val // get plr info core C4MaterialCore* pMaterialCore = static_cast(pMaterial); - // material core implicates section "Material" - if (!SEqual(strSection, "Material")) return C4Value(); - // get value - return GetValByStdCompiler(strEntry, NULL, iEntryNr, *pMaterialCore); + return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : NULL, iEntryNr, *pMaterialCore); } -static C4String *FnMaterialName(C4AulContext* cthr, long iMat) +static C4String *FnMaterialName(C4PropList * _this, long iMat) { // mat valid? if (!MatValid(iMat)) return NULL; @@ -1508,14 +1441,7 @@ static C4String *FnMaterialName(C4AulContext* cthr, long iMat) return String(::MaterialMap.Map[iMat].Name); } -static C4String *FnGetNeededMatStr(C4AulContext* cthr) -{ - // local/safety - if (!cthr->Obj) throw new NeedObjectContext("GetNeededMatStr"); - return String(cthr->Obj->GetNeededMatStr().getData()); -} - -static bool FnSetSkyAdjust(C4AulContext* cthr, long dwAdjust, long dwBackClr) +static bool FnSetSkyAdjust(C4PropList * _this, long dwAdjust, long dwBackClr) { // set adjust ::Landscape.Sky.SetModulation(dwAdjust, dwBackClr); @@ -1523,7 +1449,7 @@ static bool FnSetSkyAdjust(C4AulContext* cthr, long dwAdjust, long dwBackClr) return true; } -static bool FnSetMatAdjust(C4AulContext* cthr, long dwAdjust) +static bool FnSetMatAdjust(C4PropList * _this, long dwAdjust) { // set adjust ::Landscape.SetModulation(dwAdjust); @@ -1531,38 +1457,35 @@ static bool FnSetMatAdjust(C4AulContext* cthr, long dwAdjust) return true; } -static long FnGetSkyAdjust(C4AulContext* cthr, bool fBackColor) +static long FnGetSkyAdjust(C4PropList * _this, bool fBackColor) { // get adjust return ::Landscape.Sky.GetModulation(!!fBackColor); } -static long FnGetMatAdjust(C4AulContext* cthr) +static long FnGetMatAdjust(C4PropList * _this) { // get adjust return ::Landscape.GetModulation(); } -static long FnGetTime(C4AulContext *) +static long FnGetTime(C4PropList * _this) { // check network, record, etc if (::Control.SyncMode()) return 0; - return GetTime(); + return C4TimeMilliseconds::Now().AsInt(); } -static C4Value FnSetPlrExtraData(C4AulContext *cthr, C4Value *iPlayer_C4V, C4Value *strDataName_C4V, C4Value *Data) +static C4Value FnSetPlrExtraData(C4PropList * _this, int iPlayer, C4String * DataName, const C4Value & Data) { - long iPlayer = iPlayer_C4V->getInt(); - const char *strDataName = FnStringPar(strDataName_C4V->getStr()); - // valid player? (for great nullpointer prevention) - if (!ValidPlr(iPlayer)) return C4Value(); + const char * strDataName = FnStringPar(DataName); // do not allow data type C4V_Array or C4V_C4Object - if (Data->GetType() != C4V_Nil && - Data->GetType() != C4V_Int && - Data->GetType() != C4V_Bool && - Data->GetType() != C4V_String) return C4VNull; - // get pointer on player... + if (Data.GetType() != C4V_Nil && + Data.GetType() != C4V_Int && + Data.GetType() != C4V_Bool && + Data.GetType() != C4V_String) return C4VNull; C4Player* pPlayer = ::Players.Get(iPlayer); + if (!pPlayer) return C4Value(); // no name list created yet? if (!pPlayer->ExtraData.pNames) // create name list @@ -1570,27 +1493,24 @@ static C4Value FnSetPlrExtraData(C4AulContext *cthr, C4Value *iPlayer_C4V, C4Val // data name already exists? long ival; if ((ival = pPlayer->ExtraData.pNames->GetItemNr(strDataName)) != -1) - pPlayer->ExtraData[ival] = *Data; + pPlayer->ExtraData[ival] = Data; else { // add name pPlayer->ExtraData.pNames->AddName(strDataName); // get val id & set if ((ival = pPlayer->ExtraData.pNames->GetItemNr(strDataName)) == -1) return C4Value(); - pPlayer->ExtraData[ival] = *Data; + pPlayer->ExtraData[ival] = Data; } // ok, return the value that has been set - return *Data; + return Data; } -static C4Value FnGetPlrExtraData(C4AulContext *cthr, C4Value *iPlayer_C4V, C4Value *strDataName_C4V) +static C4Value FnGetPlrExtraData(C4PropList * _this, int iPlayer, C4String * DataName) { - long iPlayer = iPlayer_C4V->getInt(); - const char *strDataName = FnStringPar(strDataName_C4V->getStr()); - // valid player? - if (!ValidPlr(iPlayer)) return C4Value(); - // get pointer on player... + const char *strDataName = FnStringPar(DataName); C4Player* pPlayer = ::Players.Get(iPlayer); + if (!pPlayer) return C4Value(); // no name list? if (!pPlayer->ExtraData.pNames) return C4Value(); long ival; @@ -1599,110 +1519,178 @@ static C4Value FnGetPlrExtraData(C4AulContext *cthr, C4Value *iPlayer_C4V, C4Val return pPlayer->ExtraData[ival]; } -static long FnDrawMatChunks(C4AulContext *cctx, long tx, long ty, long twdt, long thgt, long icntx, long icnty, C4String *strMaterial, C4String *strTexture, bool bIFT) +// undocumented! +static long FnDrawMatChunks(C4PropList * _this, long tx, long ty, long twdt, long thgt, long icntx, long icnty, C4String *strMaterial, C4String *strTexture, bool bIFT) { return ::Landscape.DrawChunks(tx, ty, twdt, thgt, icntx, icnty, FnStringPar(strMaterial), FnStringPar(strTexture), bIFT != 0); } -static long FnDrawMap(C4AulContext *cctx, long iX, long iY, long iWdt, long iHgt, C4String *szMapDef) +static long FnDrawMap(C4PropList * _this, long iX, long iY, long iWdt, long iHgt, C4String *szMapDef) { // draw it! // don't clear the old map before drawing return ::Landscape.DrawMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef), true); } -static long FnDrawDefMap(C4AulContext *cctx, long iX, long iY, long iWdt, long iHgt, C4String *szMapDef) +static long FnDrawDefMap(C4PropList * _this, long iX, long iY, long iWdt, long iHgt, C4String *szMapDef) { // draw it! // don't clear the old map before drawing return ::Landscape.DrawDefMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef), true); } -static bool FnCreateParticle(C4AulContext *cthr, C4String *szName, long iX, long iY, long iXDir, long iYDir, long a, long b, C4Object *pObj, bool fBack) +static bool FnCreateParticle(C4PropList * _this, C4String *name, C4Value x, C4Value y, C4Value speedX, C4Value speedY, C4Value lifetime, C4PropList *properties, int amount) { // safety - if (pObj && !pObj->Status) return false; - // local offset - if (cthr->Obj) - { - iX+=cthr->Obj->GetX(); - iY+=cthr->Obj->GetY(); - } + C4Object *obj = Object(_this); + if (obj && !_this->Status) return false; +#ifndef USE_CONSOLE + if (amount <= 0) amount = 1; + // get particle - C4ParticleDef *pDef=::Particles.GetDef(FnStringPar(szName)); + C4ParticleDef *pDef = ::Particles.definitions.GetDef(FnStringPar(name)); if (!pDef) return false; + // construct data + C4ParticleValueProvider valueX, valueY, valueSpeedX, valueSpeedY, valueLifetime; + valueX.Set(x); + valueY.Set(y); + valueSpeedX.Set(speedX); + valueSpeedY.Set(speedY); + valueLifetime.Set(lifetime); // create - ::Particles.Create(pDef, (float) iX, (float) iY, (float) iXDir/10.0f, (float) iYDir/10.0f, (float) a/10.0f, b, pObj ? (fBack ? &pObj->BackParticles : &pObj->FrontParticles) : NULL, pObj); + ::Particles.Create(pDef, valueX, valueY, valueSpeedX, valueSpeedY, valueLifetime, properties, amount, obj); +#endif // success, even if not created return true; } -static bool FnCastAParticles(C4AulContext *cthr, C4String *szName, long iAmount, long iLevel, long iX, long iY, long a0, long a1, long b0, long b1, C4Object *pObj, bool fBack) +static bool FnClearParticles(C4PropList * _this) { - // safety - if (pObj && !pObj->Status) return false; - // local offset - if (cthr->Obj) + C4Object *obj; + if (obj = Object(_this)) { - iX+=cthr->Obj->GetX(); - iY+=cthr->Obj->GetY(); - } - // get particle - C4ParticleDef *pDef=::Particles.GetDef(FnStringPar(szName)); - if (!pDef) return false; - // cast - ::Particles.Cast(pDef, iAmount, (float) iX, (float) iY, iLevel, (float) a0/10.0f, b0, (float) a1/10.0f, b1, pObj ? (fBack ? &pObj->BackParticles : &pObj->FrontParticles) : NULL, pObj); - // success, even if not created - return true; -} - -static bool FnCastParticles(C4AulContext *cthr, C4String *szName, long iAmount, long iLevel, long iX, long iY, long a0, long a1, long b0, long b1, C4Object *pObj) -{ - return FnCastAParticles(cthr, szName, iAmount, iLevel, iX, iY, a0, a1, b0, b1, pObj, false); -} - -static bool FnCastBackParticles(C4AulContext *cthr, C4String *szName, long iAmount, long iLevel, long iX, long iY, long a0, long a1, long b0, long b1, C4Object *pObj) -{ - return FnCastAParticles(cthr, szName, iAmount, iLevel, iX, iY, a0, a1, b0, b1, pObj, true); -} - -static bool FnPushParticles(C4AulContext *cthr, C4String *szName, long iAX, long iAY) -{ - // particle given? - C4ParticleDef *pDef=NULL; - if (szName) - { - pDef=::Particles.GetDef(FnStringPar(szName)); - if (!pDef) return false; - } - // push them - ::Particles.Push(pDef, (float) iAX/10.0f, (float)iAY/10.0f); - // success - return true; -} - -static bool FnClearParticles(C4AulContext *cthr, C4String *szName, C4Object *pObj) -{ - // particle given? - C4ParticleDef *pDef=NULL; - if (szName) - { - pDef=::Particles.GetDef(FnStringPar(szName)); - if (!pDef) return false; - } - // delete them - if (pObj) - { - pObj->FrontParticles.Remove(pDef); - pObj->BackParticles.Remove(pDef); + if (obj->BackParticles) + obj->BackParticles->Clear(); + if (obj->FrontParticles) + obj->FrontParticles->Clear(); } else - ::Particles.GlobalParticles.Remove(pDef); - // success + { + if (::Particles.GetGlobalParticles()) + ::Particles.GetGlobalParticles()->Clear(); + } + + // always return true return true; } -static bool FnSetSkyParallax(C4AulContext* ctx, Nillable iMode, Nillable iParX, Nillable iParY, Nillable iXDir, Nillable iYDir, Nillable iX, Nillable iY) +static C4ValueArray* FnPV_Linear(C4PropList * _this, C4Value startValue, C4Value endValue) +{ + C4ValueArray *pArray = new C4ValueArray(3); + pArray->SetItem(0, C4VInt(C4PV_Linear)); + pArray->SetItem(1, startValue); + pArray->SetItem(2, endValue); + return pArray; +} + +static C4ValueArray* FnPV_Random(C4PropList * _this, C4Value startValue, C4Value endValue, C4Value rerollInterval) +{ + C4ValueArray *pArray = new C4ValueArray(4); + pArray->SetItem(0, C4VInt(C4PV_Random)); + pArray->SetItem(1, startValue); + pArray->SetItem(2, endValue); + pArray->SetItem(3, rerollInterval); + return pArray; +} + +static C4ValueArray* FnPV_Direction(C4PropList * _this, C4Value factor) +{ + C4ValueArray *pArray = new C4ValueArray(2); + pArray->SetItem(0, C4VInt(C4PV_Direction)); + pArray->SetItem(1, factor.GetType() != C4V_Nil ? factor : C4VInt(1000)); + return pArray; +} + +static C4ValueArray* FnPV_Step(C4PropList * _this, C4Value step, C4Value startValue, C4Value delay) +{ + C4ValueArray *pArray = new C4ValueArray(4); + pArray->SetItem(0, C4VInt(C4PV_Step)); + pArray->SetItem(1, step); + pArray->SetItem(2, startValue); + pArray->SetItem(3, delay); + return pArray; +} + +static C4Value FnPV_KeyFrames(C4PropList * _this, C4Value *pars) +{ + C4ValueArray *pArray = new C4ValueArray(C4AUL_MAX_Par); + pArray->SetItem(0, C4VInt(C4PV_KeyFrames)); + const int offset = 1; + + // Read all parameters + int i = 0; + for (; i < C4AUL_MAX_Par; i++) + { + C4Value Data = *(pars++); + // No data given? + if (Data.GetType() == C4V_Nil) break; + + pArray->SetItem(offset + i, Data); + } + pArray->SetSize(i + offset); + return C4Value(pArray); +} + +static C4ValueArray* FnPV_Speed(C4PropList * _this, C4Value factor, C4Value startValue) +{ + C4ValueArray *pArray = new C4ValueArray(3); + pArray->SetItem(0, C4VInt(C4PV_Speed)); + pArray->SetItem(1, factor.GetType() == C4V_Nil ? C4VInt(1000) : factor); + pArray->SetItem(2, startValue); + return pArray; +} + +static C4ValueArray* FnPV_Wind(C4PropList * _this, C4Value factor, C4Value startValue) +{ + C4ValueArray *pArray = new C4ValueArray(3); + pArray->SetItem(0, C4VInt(C4PV_Wind)); + pArray->SetItem(1, factor.GetType() == C4V_Nil ? C4VInt(1000) : factor); + pArray->SetItem(2, startValue); + return pArray; +} + +static C4ValueArray* FnPV_Gravity(C4PropList * _this, C4Value factor, C4Value startValue) +{ + C4ValueArray *pArray = new C4ValueArray(3); + pArray->SetItem(0, C4VInt(C4PV_Gravity)); + pArray->SetItem(1, factor.GetType() == C4V_Nil ? C4VInt(1000) : factor); + pArray->SetItem(2, startValue); + return pArray; +} + +static C4ValueArray* FnPC_Die(C4PropList * _this) +{ + C4ValueArray *pArray = new C4ValueArray(1); + pArray->SetItem(0, C4VInt(C4PC_Die)); + return pArray; +} + +static C4ValueArray* FnPC_Bounce(C4PropList * _this, C4Value bouncyness) +{ + C4ValueArray *pArray = new C4ValueArray(2); + pArray->SetItem(0, C4VInt(C4PC_Bounce)); + pArray->SetItem(1, bouncyness.GetType() != C4V_Nil ? bouncyness : C4VInt(1000)); + return pArray; +} + +static C4ValueArray* FnPC_Stop(C4PropList * _this) +{ + C4ValueArray *pArray = new C4ValueArray(1); + pArray->SetItem(0, C4VInt(C4PC_Stop)); + return pArray; +} + +static bool FnSetSkyParallax(C4PropList * _this, Nillable iMode, Nillable iParX, Nillable iParY, Nillable iXDir, Nillable iYDir, Nillable iX, Nillable iY) { // set all parameters that aren't nil if (!iMode.IsNil()) @@ -1717,14 +1705,14 @@ static bool FnSetSkyParallax(C4AulContext* ctx, Nillable iMode, NillableObj) pDef=ctx->Obj->Def; + if (Object(_this)) pDef=Object(_this)->Def; } else // def by ID @@ -1737,25 +1725,26 @@ static long FnReloadDef(C4AulContext* ctx, C4ID idDef, long iReloadWhat) return Game.ReloadDef(pDef->id); } -static long FnReloadParticle(C4AulContext* ctx, C4String *szParticleName) +static long FnReloadParticle(C4PropList * _this, C4String *szParticleName) { // perform reload return Game.ReloadParticle(FnStringPar(szParticleName)); } -static bool FnSetGamma(C4AulContext* ctx, long dwClr1, long dwClr2, long dwClr3, long iRampIndex) +static bool FnSetGamma(C4PropList * _this, long dwClr1, long dwClr2, long dwClr3, long iRampIndex) { pDraw->SetGamma(dwClr1, dwClr2, dwClr3, iRampIndex); return true; } -static bool FnResetGamma(C4AulContext* ctx, long iRampIndex) +static bool FnResetGamma(C4PropList * _this, long iRampIndex) { pDraw->SetGamma(0x000000, 0x808080, 0xffffff, iRampIndex); return true; } -static long FnFrameCounter(C4AulContext*) { return Game.FrameCounter; } +// undocumented! +static long FnFrameCounter(C4PropList * _this) { return Game.FrameCounter; } struct PathInfo { @@ -1772,7 +1761,7 @@ static bool SumPathLength(int32_t iX, int32_t iY, intptr_t iTransferTarget, intp return true; } -static Nillable FnGetPathLength(C4AulContext* ctx, long iFromX, long iFromY, long iToX, long iToY) +static Nillable FnGetPathLength(C4PropList * _this, long iFromX, long iFromY, long iToX, long iToY) { PathInfo PathInfo; PathInfo.ilx = iFromX; @@ -1783,39 +1772,31 @@ static Nillable FnGetPathLength(C4AulContext* ctx, long iFromX, long iFrom return PathInfo.ilen + Distance(PathInfo.ilx, PathInfo.ily, iToX, iToY); } -static long FnSetTextureIndex(C4AulContext *ctx, C4String *psMatTex, long iNewIndex, bool fInsert) +// undocumented! +static long FnSetTextureIndex(C4PropList * _this, C4String *psMatTex, long iNewIndex, bool fInsert) { if (!Inside(iNewIndex, 0l, 255l)) return false; return ::Landscape.SetTextureIndex(FnStringPar(psMatTex), BYTE(iNewIndex), !!fInsert); } -static long FnRemoveUnusedTexMapEntries(C4AulContext *ctx) +// undocumented! +static long FnRemoveUnusedTexMapEntries(C4PropList * _this) { ::Landscape.RemoveUnusedTexMapEntries(); return true; } -static bool FnSetLandscapePixel(C4AulContext* ctx, long iX, long iY, long dwValue) -{ - // local call - if (ctx->Obj) { iX+=ctx->Obj->GetX(); iY+=ctx->Obj->GetY(); } - // set pixel in 32bit-sfc only - // TODO: ::Landscape.SetPixDw(iX, iY, dwValue); - // success - return true; -} - static const int32_t DMQ_Sky = 0, // draw w/ sky IFT - DMQ_Sub = 1, // draw w/ tunnel IFT - DMQ_Bridge = 2; // draw only over materials you can bridge over + DMQ_Sub = 1, // draw w/ tunnel IFT + DMQ_Bridge = 2; // draw only over materials you can bridge over -static bool FnDrawMaterialQuad(C4AulContext* ctx, C4String *szMaterial, long iX1, long iY1, long iX2, long iY2, long iX3, long iY3, long iX4, long iY4, int draw_mode) +static bool FnDrawMaterialQuad(C4PropList * _this, C4String *szMaterial, long iX1, long iY1, long iX2, long iY2, long iX3, long iY3, long iX4, long iY4, int draw_mode) { const char *szMat = FnStringPar(szMaterial); return !! ::Landscape.DrawQuad(iX1, iY1, iX2, iY2, iX3, iY3, iX4, iY4, szMat, draw_mode == DMQ_Sub, draw_mode==DMQ_Bridge); } -static bool FnSetFilmView(C4AulContext *ctx, long iToPlr) +static bool FnSetFilmView(C4PropList * _this, long iToPlr) { // check player if (!ValidPlr(iToPlr) && iToPlr != NO_OWNER) return false; @@ -1827,7 +1808,7 @@ static bool FnSetFilmView(C4AulContext *ctx, long iToPlr) return true; } -static bool FnAddMsgBoardCmd(C4AulContext *ctx, C4String *pstrCommand, C4String *pstrScript) +static bool FnAddMsgBoardCmd(C4PropList * _this, C4String *pstrCommand, C4String *pstrScript) { // safety if (!pstrCommand || !pstrScript) return false; @@ -1836,7 +1817,7 @@ static bool FnAddMsgBoardCmd(C4AulContext *ctx, C4String *pstrCommand, C4String return true; } -static bool FnSetGameSpeed(C4AulContext *ctx, long iSpeed) +static bool FnSetGameSpeed(C4PropList * _this, long iSpeed) { // safety if (iSpeed) if (!Inside(iSpeed, 0, 1000)) return false; @@ -1848,16 +1829,16 @@ static bool FnSetGameSpeed(C4AulContext *ctx, long iSpeed) bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensityMin, int32_t iDensityMax, int32_t &iIter); -static C4ValueArray* FnSimFlight(C4AulContext *ctx, int X, int Y, Nillable pvrXDir, Nillable pvrYDir, Nillable pviDensityMin, Nillable pviDensityMax, Nillable pviIter, int iPrec) +static C4ValueArray* FnSimFlight(C4PropList * _this, int X, int Y, Nillable pvrXDir, Nillable pvrYDir, Nillable pviDensityMin, Nillable pviDensityMax, Nillable pviIter, int iPrec) { // check and set parameters - if (ctx->Obj) + if (Object(_this)) { - X += ctx->Obj->GetX(); - Y += ctx->Obj->GetY(); + X += Object(_this)->GetX(); + Y += Object(_this)->GetY(); } - int XDir = pvrXDir.IsNil() && ctx->Obj ? fixtoi(ctx->Obj->xdir) : static_cast(pvrXDir); - int YDir = pvrXDir.IsNil() && ctx->Obj ? fixtoi(ctx->Obj->ydir) : static_cast(pvrYDir); + int XDir = pvrXDir.IsNil() && Object(_this) ? fixtoi(Object(_this)->xdir) : static_cast(pvrXDir); + int YDir = pvrXDir.IsNil() && Object(_this) ? fixtoi(Object(_this)->ydir) : static_cast(pvrYDir); int iDensityMin = pviDensityMin.IsNil() ? C4M_Solid : static_cast(pviDensityMin); int iDensityMax = pviDensityMax.IsNil() ? 100 : static_cast(pviDensityMax); @@ -1884,7 +1865,8 @@ static C4ValueArray* FnSimFlight(C4AulContext *ctx, int X, int Y, Nillable return pResults; } -static long FnLoadScenarioSection(C4AulContext *ctx, C4String *pstrSection, long dwFlags) +// undocumented! +static long FnLoadScenarioSection(C4PropList * _this, C4String *pstrSection, long dwFlags) { // safety const char *szSection; @@ -1893,25 +1875,21 @@ static long FnLoadScenarioSection(C4AulContext *ctx, C4String *pstrSection, long return Game.LoadScenarioSection(szSection, dwFlags); } -static C4Value FnAddEffect_C4V(C4AulContext *ctx, C4Value *pvsEffectName, C4Value *pvpTarget, C4Value *pviPrio, C4Value *pviTimerInterval, C4Value *pvpCmdTarget, C4Value *pvidCmdTarget, C4Value *pvVal1, C4Value *pvVal2, C4Value *pvVal3, C4Value *pvVal4) +static C4Value FnAddEffect(C4PropList * _this, C4String * szEffect, C4Object * pTarget, + int iPrio, int iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, + const C4Value & Val1, const C4Value & Val2, const C4Value & Val3, const C4Value & Val4) { - // evaluate parameters - C4String *szEffect = pvsEffectName->getStr(); - C4Object *pTarget = pvpTarget->getObj(); - long iPrio = pviPrio->getInt(), iTimerInterval = pviTimerInterval->getInt(); - C4Object *pCmdTarget = pvpCmdTarget->getObj(); - C4ID idCmdTarget = pvidCmdTarget->getC4ID(); // safety if (pTarget && !pTarget->Status) return C4Value(); if (!szEffect || !*szEffect->GetCStr() || !iPrio) return C4Value(); // create effect - C4Effect * pEffect = C4Effect::New(pTarget, szEffect, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, *pvVal1, *pvVal2, *pvVal3, *pvVal4); - // return effect - may be 0 if he effect has been denied by another effect + C4Effect * pEffect = C4Effect::New(pTarget, szEffect, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, Val1, Val2, Val3, Val4); + // return effect - may be 0 if the effect has been denied by another effect if (!pEffect) return C4Value(); return C4VPropList(pEffect); } -static C4Effect * FnGetEffect(C4AulContext *ctx, C4String *psEffectName, C4Object *pTarget, int index, int iMaxPriority) +static C4Effect * FnGetEffect(C4PropList * _this, C4String *psEffectName, C4Object *pTarget, int index, int iMaxPriority) { const char *szEffect = FnStringPar(psEffectName); // get effects @@ -1923,7 +1901,7 @@ static C4Effect * FnGetEffect(C4AulContext *ctx, C4String *psEffectName, C4Objec return NULL; } -static bool FnRemoveEffect(C4AulContext *ctx, C4String *psEffectName, C4Object *pTarget, C4Effect * pEffect2, bool fDoNoCalls) +static bool FnRemoveEffect(C4PropList * _this, C4String *psEffectName, C4Object *pTarget, C4Effect * pEffect2, bool fDoNoCalls) { // evaluate parameters const char *szEffect = FnStringPar(psEffectName); @@ -1946,12 +1924,10 @@ static bool FnRemoveEffect(C4AulContext *ctx, C4String *psEffectName, C4Object * return true; } -static C4Value FnCheckEffect_C4V(C4AulContext *ctx, C4Value *pvsEffectName, C4Value *pvpTarget, C4Value *pviPrio, C4Value *pviTimerInterval, C4Value *pvVal1, C4Value *pvVal2, C4Value *pvVal3, C4Value *pvVal4) +static C4Value FnCheckEffect(C4PropList * _this, C4String * psEffectName, C4Object * pTarget, + int iPrio, int iTimerInterval, + const C4Value & Val1, const C4Value & Val2, const C4Value & Val3, const C4Value & Val4) { - // evaluate parameters - C4String *psEffectName = pvsEffectName->getStr(); - C4Object *pTarget = pvpTarget->getObj(); - long iPrio = pviPrio->getInt(), iTimerInterval = pviTimerInterval->getInt(); const char *szEffect = FnStringPar(psEffectName); // safety if (pTarget && !pTarget->Status) return C4Value(); @@ -1960,13 +1936,13 @@ static C4Value FnCheckEffect_C4V(C4AulContext *ctx, C4Value *pvsEffectName, C4Va C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; if (!pEffect) return C4Value(); // let them check - C4Effect * r = pEffect->Check(pTarget, szEffect, iPrio, iTimerInterval, *pvVal1, *pvVal2, *pvVal3, *pvVal4); + C4Effect * r = pEffect->Check(pTarget, szEffect, iPrio, iTimerInterval, Val1, Val2, Val3, Val4); if (r == (C4Effect *)C4Fx_Effect_Deny) return C4VInt(C4Fx_Effect_Deny); if (r == (C4Effect *)C4Fx_Effect_Annul) return C4VInt(C4Fx_Effect_Annul); return C4VPropList(r); } -static long FnGetEffectCount(C4AulContext *ctx, C4String *psEffectName, C4Object *pTarget, long iMaxPriority) +static long FnGetEffectCount(C4PropList * _this, C4String *psEffectName, C4Object *pTarget, long iMaxPriority) { // evaluate parameters const char *szEffect = FnStringPar(psEffectName); @@ -1978,22 +1954,22 @@ static long FnGetEffectCount(C4AulContext *ctx, C4String *psEffectName, C4Object return pEffect->GetCount(szEffect, iMaxPriority); } -static C4Value FnEffectCall_C4V(C4AulContext *ctx, C4Value *pvpTarget, C4Value *pvEffect, C4Value *pvsCallFn, C4Value *pvVal1, C4Value *pvVal2, C4Value *pvVal3, C4Value *pvVal4, C4Value *pvVal5, C4Value *pvVal6, C4Value *pvVal7) +static C4Value FnEffectCall(C4PropList * _this, C4Value * Pars) { // evaluate parameters - C4String *psCallFn = pvsCallFn->getStr(); - C4Object *pTarget = pvpTarget->getObj(); - C4Effect * pEffect = pvEffect->getPropList() ? pvEffect->getPropList()->GetEffect() : 0; + C4Object *pTarget = Pars[0].getObj(); + C4Effect * pEffect = Pars[1].getPropList() ? Pars[1].getPropList()->GetEffect() : 0; + C4String *psCallFn = Pars[2].getStr(); const char *szCallFn = FnStringPar(psCallFn); // safety if (pTarget && !pTarget->Status) return C4Value(); if (!szCallFn || !*szCallFn) return C4Value(); if (!pEffect) return C4Value(); // do call - return pEffect->DoCall(pTarget, szCallFn, *pvVal1, *pvVal2, *pvVal3, *pvVal4, *pvVal5, *pvVal6, *pvVal7); + return pEffect->DoCall(pTarget, szCallFn, Pars[3], Pars[4], Pars[5], Pars[6], Pars[7], Pars[8], Pars[9]); } -static bool FnSetViewOffset(C4AulContext *ctx, long iPlayer, long iX, long iY) +static bool FnSetViewOffset(C4PropList * _this, long iPlayer, long iX, long iY) { if (!ValidPlr(iPlayer)) return 0; // get player viewport @@ -2006,7 +1982,8 @@ static bool FnSetViewOffset(C4AulContext *ctx, long iPlayer, long iX, long iY) return 1; } -static bool FnSetPreSend(C4AulContext *cthr, long iToVal, C4String *pNewName) +// undocumented! +static bool FnSetPreSend(C4PropList * _this, long iToVal, C4String *pNewName) { if (!::Control.isNetwork()) return true; // dbg: manual presend @@ -2019,13 +1996,13 @@ static bool FnSetPreSend(C4AulContext *cthr, long iToVal, C4String *pNewName) return true; } -static long FnGetPlayerID(C4AulContext *cthr, long iPlayer) +static long FnGetPlayerID(C4PropList * _this, long iPlayer) { C4Player *pPlr = ::Players.Get(iPlayer); return pPlr ? pPlr->ID : 0; } -static long FnGetPlayerTeam(C4AulContext *cthr, long iPlayer) +static long FnGetPlayerTeam(C4PropList * _this, long iPlayer) { // get player C4Player *pPlr = ::Players.Get(iPlayer); @@ -2039,7 +2016,7 @@ static long FnGetPlayerTeam(C4AulContext *cthr, long iPlayer) return 0; } -static bool FnSetPlayerTeam(C4AulContext *cthr, long iPlayer, long idNewTeam, bool fNoCalls) +static bool FnSetPlayerTeam(C4PropList * _this, long iPlayer, long idNewTeam, bool fNoCalls) { // no team changing in league games if (Game.Parameters.isLeague()) return false; @@ -2092,7 +2069,8 @@ static bool FnSetPlayerTeam(C4AulContext *cthr, long iPlayer, long idNewTeam, bo return true; } -static long FnGetTeamConfig(C4AulContext *cthr, long iConfigValue) +// undocumented! +static long FnGetTeamConfig(C4PropList * _this, long iConfigValue) { // query value switch (iConfigValue) @@ -2110,54 +2088,57 @@ static long FnGetTeamConfig(C4AulContext *cthr, long iConfigValue) return 0; } -static C4String *FnGetTeamName(C4AulContext *cthr, long iTeam) +static C4String *FnGetTeamName(C4PropList * _this, long iTeam) { C4Team *pTeam = Game.Teams.GetTeamByID(iTeam); if (!pTeam) return NULL; return String(pTeam->GetName()); } -static long FnGetTeamColor(C4AulContext *cthr, long iTeam) +static long FnGetTeamColor(C4PropList * _this, long iTeam) { C4Team *pTeam = Game.Teams.GetTeamByID(iTeam); return pTeam ? pTeam->GetColor() : 0u; } -static long FnGetTeamByIndex(C4AulContext *cthr, long iIndex) +static long FnGetTeamByIndex(C4PropList * _this, long iIndex) { C4Team *pTeam = Game.Teams.GetTeamByIndex(iIndex); return pTeam ? pTeam->GetID() : 0; } -static long FnGetTeamCount(C4AulContext *cthr) +static long FnGetTeamCount(C4PropList * _this) { return Game.Teams.GetTeamCount(); } -static bool FnInitScenarioPlayer(C4AulContext *cthr, long iPlayer, long idTeam) +// undocumented! +static bool FnInitScenarioPlayer(C4PropList * _this, long iPlayer, long idTeam) { C4Player *pPlr = ::Players.Get(iPlayer); if (!pPlr) return false; return pPlr->ScenarioAndTeamInit(idTeam); } -static bool FnSetScoreboardData(C4AulContext *cthr, long iRowID, long iColID, C4String *pText, long iData) +static bool FnSetScoreboardData(C4PropList * _this, long iRowID, long iColID, C4String *pText, long iData) { Game.Scoreboard.SetCell(iColID, iRowID, pText ? pText->GetCStr() : NULL, iData); return true; } -static C4String *FnGetScoreboardString(C4AulContext *cthr, long iRowID, long iColID) +// undocumented! +static C4String *FnGetScoreboardString(C4PropList * _this, long iRowID, long iColID) { return String(Game.Scoreboard.GetCellString(iColID, iRowID)); } -static int32_t FnGetScoreboardData(C4AulContext *cthr, long iRowID, long iColID) +// undocumented! +static int32_t FnGetScoreboardData(C4PropList * _this, long iRowID, long iColID) { return Game.Scoreboard.GetCellData(iColID, iRowID); } -static bool FnDoScoreboardShow(C4AulContext *cthr, long iChange, long iForPlr) +static bool FnDoScoreboardShow(C4PropList * _this, long iChange, long iForPlr) { C4Player *pPlr; if (iForPlr) @@ -2171,12 +2152,13 @@ static bool FnDoScoreboardShow(C4AulContext *cthr, long iChange, long iForPlr) return true; //Game.Scoreboard.ShouldBeShown(); } -static bool FnSortScoreboard(C4AulContext *cthr, long iByColID, bool fReverse) +static bool FnSortScoreboard(C4PropList * _this, long iByColID, bool fReverse) { return Game.Scoreboard.SortBy(iByColID, !!fReverse); } -static bool FnAddEvaluationData(C4AulContext *cthr, C4String *pText, long idPlayer) +// undocumented! +static bool FnAddEvaluationData(C4PropList * _this, C4String *pText, long idPlayer) { // safety if (!pText) return false; @@ -2187,30 +2169,14 @@ static bool FnAddEvaluationData(C4AulContext *cthr, C4String *pText, long idPlay return true; } -static C4Void FnHideSettlementScoreInEvaluation(C4AulContext *cthr, bool fHide) +// undocumented! +static C4Void FnHideSettlementScoreInEvaluation(C4PropList * _this, bool fHide) { Game.RoundResults.HideSettlementScore(fHide); return C4Void(); } -static long FnActivateGameGoalMenu(C4AulContext *ctx, long iPlayer) -{ - // get target player - C4Player *pPlr = ::Players.Get(iPlayer); - if (!pPlr) return false; - // open menu - return pPlr->Menu.ActivateGoals(pPlr->Number, pPlr->LocalControl && !::Control.isReplay()); -} - -static bool FnPlayVideo(C4AulContext *ctx, C4String *pFilename) -{ - // filename must be valid - if (!pFilename || !pFilename->GetCStr()) return false; - // play it! - return Game.VideoPlayer.PlayVideo(pFilename->GetCStr()); -} - -static bool FnCustomMessage(C4AulContext *ctx, C4String *pMsg, C4Object *pObj, Nillable iOwner, long iOffX, long iOffY, long dwClr, C4ID idDeco, C4PropList *pSrc, long dwFlags, long iHSize) +static bool FnCustomMessage(C4PropList * _this, C4String *pMsg, C4Object *pObj, Nillable iOwner, long iOffX, long iOffY, long dwClr, C4ID idDeco, C4PropList *pSrc, long dwFlags, long iHSize) { // safeties if (pSrc) @@ -2226,11 +2192,11 @@ static bool FnCustomMessage(C4AulContext *ctx, C4String *pMsg, C4Object *pObj, N uint32_t vpos = dwFlags & (C4GM_Top | C4GM_VCenter | C4GM_Bottom); if (((hpos | (hpos-1)) + 1)>>1 != hpos) { - throw new C4AulExecError(ctx->Obj, "CustomMessage: Only one horizontal positioning flag allowed"); + throw new C4AulExecError("CustomMessage: Only one horizontal positioning flag allowed"); } if (((vpos | (vpos-1)) + 1)>>1 != vpos) { - throw new C4AulExecError(ctx->Obj, "CustomMessage: Only one vertical positioning flag allowed"); + throw new C4AulExecError("CustomMessage: Only one vertical positioning flag allowed"); } // message color if (!dwClr) dwClr = 0xffffffff; @@ -2259,7 +2225,8 @@ static bool FnCustomMessage(C4AulContext *ctx, C4String *pMsg, C4Object *pObj, N return pDraw->SetSaturation(BoundBy(s,0l,255l)); }*/ -static bool FnPauseGame(C4AulContext *ctx, bool fToggle) +// undocumented! +static bool FnPauseGame(C4PropList * _this, bool fToggle) { // not in replay (film) if (::Control.isReplay()) return true; @@ -2271,7 +2238,7 @@ static bool FnPauseGame(C4AulContext *ctx, bool fToggle) return true; } -static bool FnSetNextMission(C4AulContext *ctx, C4String *szNextMission, C4String *szNextMissionText, C4String *szNextMissionDesc) +static bool FnSetNextMission(C4PropList * _this, C4String *szNextMission, C4String *szNextMissionText, C4String *szNextMissionDesc) { if (!szNextMission || !szNextMission->GetData().getLength()) { @@ -2303,7 +2270,8 @@ static bool FnSetNextMission(C4AulContext *ctx, C4String *szNextMission, C4Strin return true; } -static long FnGetPlayerControlState(C4AulContext *ctx, long iPlr, long iControl) +// undocumented! +static long FnGetPlayerControlState(C4PropList * _this, long iPlr, long iControl) { // get control set to check C4PlayerControl *pCheckCtrl = NULL; @@ -2329,7 +2297,8 @@ static long FnGetPlayerControlState(C4AulContext *ctx, long iPlr, long iControl) return pControlState->DownState.iStrength; } -static bool FnSetPlayerControlEnabled(C4AulContext *ctx, long iplr, long ctrl, bool is_enabled) +// undocumented! +static bool FnSetPlayerControlEnabled(C4PropList * _this, long iplr, long ctrl, bool is_enabled) { // get control set to check C4PlayerControl *plrctrl = NULL; @@ -2353,7 +2322,8 @@ static bool FnSetPlayerControlEnabled(C4AulContext *ctx, long iplr, long ctrl, b return plrctrl->SetControlDisabled(ctrl, !is_enabled); } -static bool FnGetPlayerControlEnabled(C4AulContext *ctx, long iplr, long ctrl) +// undocumented! +static bool FnGetPlayerControlEnabled(C4PropList * _this, long iplr, long ctrl) { // get control set to check C4PlayerControl *plrctrl = NULL; @@ -2374,6 +2344,27 @@ static bool FnGetPlayerControlEnabled(C4AulContext *ctx, long iplr, long ctrl) return !plrctrl->IsControlDisabled(ctrl); } +// undocumented! +static C4String *FnGetPlayerControlAssignment(C4PropList * _this, long player, long control, bool human_readable, bool short_name) +{ + // WARNING: As many functions returning strings, the result is not sync safe! + // "" is returned for invalid controls to make the obvious if(GetPlayerControlAssignmentName(...)) not cause a sync loss + // get desired assignment from parameters + C4Player *plr = ::Players.Get(player); + if (!plr) return NULL; // invalid player + if (!plr->ControlSet) return String(""); // player has no control (remote player) + C4PlayerControlAssignment *assignment = plr->ControlSet->GetAssignmentByControl(control); + if (!assignment) return String(""); + // get assignment as readable string + return String(assignment->GetKeysAsString(human_readable, short_name).getData()); +} + +static int32_t FnGetStartupPlayerCount(C4PropList * _this) +{ + // returns number of players when game was initially started + return ::Game.StartupPlayerCount; +} + extern C4ScriptConstDef C4ScriptGameConstMap[]; extern C4ScriptFnDef C4ScriptGameFnMap[]; @@ -2387,9 +2378,9 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) } // add all def script funcs for (C4ScriptFnDef *pDef = &C4ScriptGameFnMap[0]; pDef->Identifier; pDef++) - pEngine->AddFunc(pDef->Identifier, pDef); + new C4AulDefFunc(pEngine, pDef); +#define F(f) AddFunc(pEngine, #f, Fn##f) // AddFunc(pEngine, "SetSaturation", FnSetSaturation); //public: 0 - AddFunc(pEngine, "Smoke", FnSmoke); AddFunc(pEngine, "GetX", FnGetX); AddFunc(pEngine, "GetY", FnGetY); @@ -2403,6 +2394,7 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) AddFunc(pEngine, "FindConstructionSite", FnFindConstructionSite); AddFunc(pEngine, "CheckConstructionSite", FnCheckConstructionSite); AddFunc(pEngine, "Sound", FnSound); + AddFunc(pEngine, "SoundAt", FnSoundAt); AddFunc(pEngine, "Music", FnMusic); AddFunc(pEngine, "MusicLevel", FnMusicLevel); AddFunc(pEngine, "SetPlayList", FnSetPlayList); @@ -2453,6 +2445,7 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) AddFunc(pEngine, "Material", FnMaterial); AddFunc(pEngine, "BlastFree", FnBlastFree); AddFunc(pEngine, "InsertMaterial", FnInsertMaterial); + AddFunc(pEngine, "CanInsertMaterial", FnCanInsertMaterial); AddFunc(pEngine, "LandscapeWidth", FnLandscapeWidth); AddFunc(pEngine, "LandscapeHeight", FnLandscapeHeight); AddFunc(pEngine, "SetSeason", FnSetSeason); @@ -2469,21 +2462,15 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) AddFunc(pEngine, "TestMessageBoard", FnTestMessageBoard, false); AddFunc(pEngine, "CallMessageBoard", FnCallMessageBoard, false); AddFunc(pEngine, "AbortMessageBoard", FnAbortMessageBoard, false); - AddFunc(pEngine, "OnMessageBoardAnswer", FnOnMessageBoardAnswer, false); AddFunc(pEngine, "SetFoW", FnSetFoW); AddFunc(pEngine, "SetMaxPlayer", FnSetMaxPlayer); - AddFunc(pEngine, "ActivateGameGoalMenu", FnActivateGameGoalMenu); AddFunc(pEngine, "Object", FnObject); AddFunc(pEngine, "GetTime", FnGetTime); AddFunc(pEngine, "GetMissionAccess", FnGetMissionAccess); AddFunc(pEngine, "MaterialName", FnMaterialName); - AddFunc(pEngine, "GetNeededMatStr", FnGetNeededMatStr); AddFunc(pEngine, "DrawMap", FnDrawMap); AddFunc(pEngine, "DrawDefMap", FnDrawDefMap); AddFunc(pEngine, "CreateParticle", FnCreateParticle); - AddFunc(pEngine, "CastParticles", FnCastParticles); - AddFunc(pEngine, "CastBackParticles", FnCastBackParticles); - AddFunc(pEngine, "PushParticles", FnPushParticles); AddFunc(pEngine, "ClearParticles", FnClearParticles); AddFunc(pEngine, "SetSkyAdjust", FnSetSkyAdjust); AddFunc(pEngine, "SetMatAdjust", FnSetMatAdjust); @@ -2495,7 +2482,6 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) AddFunc(pEngine, "SetGamma", FnSetGamma); AddFunc(pEngine, "ResetGamma", FnResetGamma); AddFunc(pEngine, "FrameCounter", FnFrameCounter); - AddFunc(pEngine, "SetLandscapePixel", FnSetLandscapePixel); AddFunc(pEngine, "DrawMaterialQuad", FnDrawMaterialQuad); AddFunc(pEngine, "SetFilmView", FnSetFilmView); AddFunc(pEngine, "AddMsgBoardCmd", FnAddMsgBoardCmd); @@ -2528,7 +2514,6 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) AddFunc(pEngine, "HideSettlementScoreInEvaluation", FnHideSettlementScoreInEvaluation); AddFunc(pEngine, "ExtractMaterialAmount", FnExtractMaterialAmount); AddFunc(pEngine, "GetEffectCount", FnGetEffectCount); - AddFunc(pEngine, "PlayVideo", FnPlayVideo, false); AddFunc(pEngine, "CustomMessage", FnCustomMessage); AddFunc(pEngine, "PauseGame", FnPauseGame, false); AddFunc(pEngine, "PathFree", FnPathFree); @@ -2537,6 +2522,38 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine) AddFunc(pEngine, "GetPlayerControlState", FnGetPlayerControlState); AddFunc(pEngine, "SetPlayerControlEnabled", FnSetPlayerControlEnabled); AddFunc(pEngine, "GetPlayerControlEnabled", FnGetPlayerControlEnabled); + AddFunc(pEngine, "GetPlayerControlAssignment", FnGetPlayerControlAssignment); + AddFunc(pEngine, "GetStartupPlayerCount", FnGetStartupPlayerCount); + AddFunc(pEngine, "PlayerObjectCommand", FnPlayerObjectCommand); + AddFunc(pEngine, "EditCursor", FnEditCursor); + + F(GetPlrKnowledge); + F(GetComponent); + F(GetHomebaseMaterial); + F(GetHomebaseProduction); + F(GetDefCoreVal); + F(GetObjectVal); + F(GetObjectInfoCoreVal); + F(GetScenarioVal); + F(GetPlayerVal); + F(GetPlayerInfoCoreVal); + F(GetMaterialVal); + F(SetPlrExtraData); + F(GetPlrExtraData); + F(AddEffect); + F(CheckEffect); + + F(PV_Linear); + F(PV_Random); + F(PV_Direction); + F(PV_Step); + F(PV_Speed); + F(PV_Wind); + F(PV_Gravity); + // F(PV_KeyFrames); added below + F(PC_Die); + F(PC_Bounce); + F(PC_Stop); AddFunc(pEngine, "IncinerateLandscape", FnIncinerateLandscape); AddFunc(pEngine, "GetGravity", FnGetGravity); @@ -2664,46 +2681,24 @@ C4ScriptConstDef C4ScriptGameConstMap[]= { "PLRZOOM_LimitMin" ,C4V_Int, PLRZOOM_LimitMin }, { "PLRZOOM_LimitMax" ,C4V_Int, PLRZOOM_LimitMax }, + { "ATTACH_Front" ,C4V_Int, C4ATTACH_Front }, + { "ATTACH_Back" ,C4V_Int, C4ATTACH_Back }, + { "ATTACH_MoveRelative" ,C4V_Int, C4ATTACH_MoveRelative }, + { NULL, C4V_Nil, 0} }; -#define MkFnC4V (C4Value (*)(C4AulContext *cthr, C4Value*, C4Value*, C4Value*, C4Value*, C4Value*,\ - C4Value*, C4Value*, C4Value*, C4Value*, C4Value*)) - C4ScriptFnDef C4ScriptGameFnMap[]= { + { "FindObject", 1, C4V_Object, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObject }, + { "FindObjects", 1, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObjects }, + { "ObjectCount", 1, C4V_Int, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnObjectCount }, + { "GameCallEx", 1, C4V_Any, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnGameCallEx }, + { "PlayerMessage", 1, C4V_Int, { C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPlayerMessage }, + { "Message", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnMessage }, + { "AddMessage", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnAddMessage }, + { "EffectCall", 1, C4V_Any, { C4V_Object ,C4V_PropList,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnEffectCall }, + { "PV_KeyFrames", 1, C4V_Array, { C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPV_KeyFrames }, - { "PlayerObjectCommand", 1 ,C4V_Bool ,{ C4V_Int ,C4V_String ,C4V_Object ,C4V_Int ,C4V_Int ,C4V_Object ,C4V_Any ,C4V_Int ,C4V_Any ,C4V_Any} ,0 , FnPlayerObjectCommand }, - { "FindObject", 1 ,C4V_Object ,{ C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnFindObject }, - { "FindObjects", 1 ,C4V_Array ,{ C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnFindObjects }, - { "ObjectCount", 1 ,C4V_Int ,{ C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnObjectCount }, - { "GameCall", 1 ,C4V_Any ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGameCall_C4V , 0 }, - { "GameCallEx", 1 ,C4V_Any ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGameCallEx_C4V , 0 }, - { "DefinitionCall", 0 ,C4V_Any ,{ C4V_PropList,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnDefinitionCall_C4V , 0 }, - { "Call", 1 ,C4V_Any ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnCall_C4V , 0 }, - { "GetPlrKnowledge", 1 ,C4V_Int ,{ C4V_Int ,C4V_PropList,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetPlrKnowledge_C4V , 0 }, - { "GetComponent", 1 ,C4V_Int ,{ C4V_PropList,C4V_Int ,C4V_Object ,C4V_PropList,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetComponent_C4V , 0 }, - { "PlayerMessage", 1 ,C4V_Int ,{ C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V &FnPlayerMessage_C4V, 0 }, - { "Message", 1 ,C4V_Bool ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V &FnMessage_C4V, 0 }, - { "AddMessage", 1 ,C4V_Bool ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V &FnAddMessage_C4V, 0 }, - { "EditCursor", 1 ,C4V_Object ,{ C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnEditCursor }, - { "GetHomebaseMaterial", 1 ,C4V_Int ,{ C4V_Int ,C4V_PropList,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetHomebaseMaterial_C4V , 0 }, - { "GetHomebaseProduction",1 ,C4V_Int ,{ C4V_Int ,C4V_PropList,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetHomebaseProduction_C4V , 0 }, - - { "GetDefCoreVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetDefCoreVal, 0 }, - { "GetObjectVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetObjectVal, 0 }, - { "GetObjectInfoCoreVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetObjectInfoCoreVal, 0 }, - { "GetScenarioVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetScenarioVal, 0 }, - { "GetPlayerVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetPlayerVal, 0 }, - { "GetPlayerInfoCoreVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetPlayerInfoCoreVal, 0 }, - { "GetMaterialVal", 1 ,C4V_Any ,{ C4V_String ,C4V_String ,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetMaterialVal, 0 }, - - { "SetPlrExtraData", 1 ,C4V_Any ,{ C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnSetPlrExtraData, 0 }, - { "GetPlrExtraData", 1 ,C4V_Any ,{ C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetPlrExtraData, 0 }, - { "AddEffect", 1 ,C4V_PropList ,{ C4V_String ,C4V_Object ,C4V_Int ,C4V_Int ,C4V_Object, C4V_PropList,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnAddEffect_C4V, 0 }, - { "CheckEffect", 1 ,C4V_Int ,{ C4V_String ,C4V_Object ,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnCheckEffect_C4V, 0 }, - { "EffectCall", 1 ,C4V_Any ,{ C4V_Object ,C4V_PropList,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnEffectCall_C4V, 0 }, - - { NULL, 0 ,C4V_Nil ,{ C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil} ,0, 0 } - + { NULL, 0, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, 0 } }; diff --git a/src/game/script/C4Script.h b/src/gamescript/C4Script.h similarity index 85% rename from src/game/script/C4Script.h rename to src/gamescript/C4Script.h index ea77ce8a3..730b31d05 100644 --- a/src/game/script/C4Script.h +++ b/src/gamescript/C4Script.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Peter Wortmann - * Copyright (c) 2001, 2004, 2007 Sven Eberhardt - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Functions mapped by C4Script */ @@ -26,9 +22,6 @@ #include -class C4AulScriptEngine; -class StdMeshMatrix; - const int C4SCR_Access_Public = 0, C4SCR_Access_Protected = 1, C4SCR_Access_Private = 2; @@ -45,24 +38,6 @@ struct C4ScriptConstDef long Data; // raw data }; - - -// ** a definition of a script-function. -// includes two versions of the Function to be called: -// * the first (C4V) takes 10 parameters -// * the second (C4V2) takes an array of 10 parameters -// only one may be set. -struct C4ScriptFnDef -{ - const char* Identifier; // the name of the func in the script - bool Public; - C4V_Type RetType; // type returned. ignored when C4V - C4V_Type ParType[10];// type of the parameters. error when wrong parameter type. - C4Value (*FunctionC4V)(struct C4AulContext *cthr, C4Value*, C4Value*, C4Value*, C4Value*, C4Value*, - C4Value*, C4Value*, C4Value*, C4Value*, C4Value*); - C4Value (*FunctionC4V2)(struct C4AulContext *, C4Value *); -}; - // add functions to engine void InitGameFunctionMap(C4AulScriptEngine *pEngine); void InitObjectFunctionMap(C4AulScriptEngine *pEngine); @@ -81,6 +56,8 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix); #define PSF_InitializeScriptPlayer "~InitializeScriptPlayer" // iPlayer, idTeam #define PSF_PreInitializePlayer "~PreInitializePlayer" // iPlayer #define PSF_InitializePlayerControl "~InitializePlayerControl" // iPlayer, szControlSet, hasKeyboard, hasMouse, hasGamepad +#define PSF_InitializeMap "~InitializeMap" // map +#define PSF_InitializeObjects "~InitializeObjects" #define PSF_RemovePlayer "~RemovePlayer" // iPlayer #define PSF_RelaunchPlayer "~RelaunchPlayer" // iPlayer, iKilledBy #define PSF_Time1 "~Time1" @@ -114,7 +91,7 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix); #define PSF_LineBreak "~LineBreak" // iCause #define PSF_BuildNeedsMaterial "~BuildNeedsMaterial" // idMat1, iAmount1, idMat2, iAmount2... #define PSF_ControlTransfer "~ControlTransfer" // C4Object* pObj, int iTx, int iTy -#define PSF_UpdateTransferZone "~UpdateTransferZone" +#define PSF_OnSynchronized "~OnSynchronized" #define PSF_CalcValue "~CalcValue" // C4Object *pInBase, int iForPlayer #define PSF_CalcDefValue "~CalcDefValue" // C4Object *pInBase, int iForPlayer #define PSF_InputCallback "InputCallback" // const char *szText @@ -130,8 +107,11 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix); #define PSF_CalcSellValue "~CalcSellValue" // C4Object *pObj, int iObjValue #define PSF_OnJoinCrew "~Recruitment" // int Player #define PSF_OnRemoveCrew "~DeRecruitment" // int Player -#define PSF_OnBlastIncinerationDamage "OnBlastIncinerationDamage" // int Level, int Player #define PSF_OnInIncendiaryMaterial "OnInIncendiaryMaterial" +#define PSF_EditCursorSelection "~EditCursorSelection" +#define PSF_EditCursorDeselection "~EditCursorDeselection" +#define PSF_DigOutObject "~DigOutObject" // C4Object *obj +#define PSF_SaveScenarioObjects "~SaveScenarioObjects" // int file_handle // Effect callbacks diff --git a/src/game/script/C4TransferZone.cpp b/src/gamescript/C4TransferZone.cpp similarity index 87% rename from src/game/script/C4TransferZone.cpp rename to src/gamescript/C4TransferZone.cpp index 666eefa4d..668888d35 100644 --- a/src/game/script/C4TransferZone.cpp +++ b/src/gamescript/C4TransferZone.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Special regions to extend the pathfinder */ @@ -119,7 +115,7 @@ bool C4TransferZones::Add(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, C4 void C4TransferZones::Synchronize() { Clear(); - ::Objects.UpdateTransferZones(); + ::Objects.OnSynchronized(); } C4TransferZone* C4TransferZones::Find(int32_t iX, int32_t iY) diff --git a/src/game/script/C4TransferZone.h b/src/gamescript/C4TransferZone.h similarity index 65% rename from src/game/script/C4TransferZone.h rename to src/gamescript/C4TransferZone.h index c22677d52..129baa2a5 100644 --- a/src/game/script/C4TransferZone.h +++ b/src/gamescript/C4TransferZone.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Special regions to extend the pathfinder */ @@ -23,8 +20,6 @@ #ifndef INC_C4TransferZone #define INC_C4TransferZone -class C4Object; -class C4TargetFacet; class C4TransferZones; class C4TransferZone diff --git a/src/platform/Bitmap256.cpp b/src/graphics/Bitmap256.cpp similarity index 70% rename from src/platform/Bitmap256.cpp rename to src/graphics/Bitmap256.cpp index 05620448e..cdfeee866 100644 --- a/src/platform/Bitmap256.cpp +++ b/src/graphics/Bitmap256.cpp @@ -1,26 +1,25 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A structure for handling 256-color bitmap files */ #include "C4Include.h" #include +#include C4BMPInfo::C4BMPInfo() { @@ -73,7 +72,7 @@ int C4BMP256Info::FileBitsOffset() return Head.bfOffBits-sizeof(C4BMP256Info); } -void C4BMP256Info::Set(int iWdt, int iHgt, BYTE *bypPalette) +void C4BMP256Info::Set(int iWdt, int iHgt, CStdPalette *Palette) { Default(); // Set header @@ -92,9 +91,9 @@ void C4BMP256Info::Set(int iWdt, int iHgt, BYTE *bypPalette) // Set palette for (int cnt=0; cnt<256; cnt++) { - Colors[cnt].rgbRed = bypPalette[cnt*3+0]; - Colors[cnt].rgbGreen = bypPalette[cnt*3+1]; - Colors[cnt].rgbBlue = bypPalette[cnt*3+2]; + Colors[cnt].rgbRed = GetRedValue(Palette->Colors[cnt]); + Colors[cnt].rgbGreen = GetGreenValue(Palette->Colors[cnt]); + Colors[cnt].rgbBlue = GetBlueValue(Palette->Colors[cnt]); } } diff --git a/src/platform/Bitmap256.h b/src/graphics/Bitmap256.h similarity index 66% rename from src/platform/Bitmap256.h rename to src/graphics/Bitmap256.h index 02d6c4f94..c72b61958 100644 --- a/src/platform/Bitmap256.h +++ b/src/graphics/Bitmap256.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002 Sven Eberhardt - * Copyright (c) 2005, 2008 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A structure for handling 256-color bitmap files */ @@ -82,7 +78,7 @@ public: RGBQUAD Colors[256]; public: void Default(); - void Set(int iWdt, int iHgt, BYTE *bypPalette); + void Set(int iWdt, int iHgt, CStdPalette *); bool Valid(); int FileBitsOffset(); diff --git a/src/platform/StdDDraw2.cpp b/src/graphics/C4Draw.cpp similarity index 88% rename from src/platform/StdDDraw2.cpp rename to src/graphics/C4Draw.cpp index 2f5543fed..0cde4464d 100644 --- a/src/platform/StdDDraw2.cpp +++ b/src/graphics/C4Draw.cpp @@ -1,38 +1,30 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004, 2008 Matthes Bender - * Copyright (c) 2002-2007 Sven Eberhardt - * Copyright (c) 2002, 2005, 2010 Peter Wortmann - * Copyright (c) 2005-2011 Günther Brammer - * Copyright (c) 2009-2010 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* NewGfx interfaces */ #include "C4Include.h" -#include +#include #include "C4App.h" +#include #include -#include -#include -#include -#include +#include +#include #include -#include #include "C4Rect.h" #include #include "StdMesh.h" @@ -51,13 +43,13 @@ inline DWORD GetTextShadowClr(DWORD dwTxtClr) return RGBA(((dwTxtClr >> 0) % 256) / 3, ((dwTxtClr >> 8) % 256) / 3, ((dwTxtClr >> 16) % 256) / 3, (dwTxtClr >> 24) % 256); } -void C4BltTransform::SetRotate(int iAngle, float fOffX, float fOffY) // set by angle and rotation offset +void C4BltTransform::SetRotate(float iAngle, float fOffX, float fOffY) // set by angle and rotation offset { - // iAngle is in 1/100-degrees (cycling from 0 to 36000) + // iAngle is in degrees (cycling from 0 to 360) // determine sine and cos of reversed angle in radians - // fAngle = -iAngle/100 * pi/180 = iAngle * -pi/18000 - float fAngle=(float) iAngle*(-1.7453292519943295769236907684886e-4f); - float fsin=(float)sin(fAngle); float fcos=(float)cos(fAngle); + // fAngle = -iAngle * pi/180 = iAngle * -pi/180 + float fAngle = iAngle * -0.0174532925f; + float fsin = sinf(fAngle); float fcos = cosf(fAngle); // set matrix values mat[0] = +fcos; mat[1] = +fsin; mat[2] = (1-fcos)*fOffX - fsin*fOffY; mat[3] = -fsin; mat[4] = +fcos; mat[5] = (1-fcos)*fOffY + fsin*fOffX; @@ -404,6 +396,7 @@ void C4Draw::Default() void C4Draw::Clear() { + ResetGamma(); DisableGamma(); Active=BlitModulated=fUseClrModMap=false; dwBlitMode = 0; @@ -610,8 +603,8 @@ bool C4Draw::BlitUnscaled(C4Surface * sfcSource, float fx, float fy, float fwdt, int iTexX2=Min((int)(fx+fwdt-1)/iTexSizeX +1, sfcSource->iTexX); int iTexY2=Min((int)(fy+fhgt-1)/iTexSizeY +1, sfcSource->iTexY); // calc stretch regarding texture size and indent - float scaleX2 = scaleX * iTexSizeX; - float scaleY2 = scaleY * iTexSizeY; +/* float scaleX2 = scaleX * iTexSizeX; + float scaleY2 = scaleY * iTexSizeY;*/ // Enable textures SetTexture(); // blit from all these textures @@ -627,12 +620,12 @@ bool C4Draw::BlitUnscaled(C4Surface * sfcSource, float fx, float fy, float fwdt, if (iTexSizeX != pTex->iSizeX) { iTexSizeX = pTex->iSizeX; - scaleX2 = scaleX * iTexSizeX; + /*scaleX2 = scaleX * iTexSizeX;*/ } if (iTexSizeY != pTex->iSizeY) { iTexSizeY = pTex->iSizeY; - scaleY2 = scaleY * iTexSizeY; + /*scaleY2 = scaleY * iTexSizeY;*/ } // get new texture source bounds @@ -747,7 +740,7 @@ bool C4Draw::Blit8(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, C4Surface * sfcTarget, int tx, int ty, int twdt, int thgt, bool fSrcColKey, const C4BltTransform *pTransform) { - if (!pTransform) return BlitRotate(sfcSource, fx, fy, fwdt, fhgt, sfcTarget, tx, ty, twdt, thgt, 0, fSrcColKey!=false); + if (!pTransform) return BlitSimple(sfcSource, fx, fy, fwdt, fhgt, sfcTarget, tx, ty, twdt, thgt, fSrcColKey!=false); // safety if (!fwdt || !fhgt) return true; // Lock the surfaces @@ -788,21 +781,17 @@ bool C4Draw::Blit8(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, return true; } -bool C4Draw::BlitRotate(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, +bool C4Draw::BlitSimple(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, C4Surface * sfcTarget, int tx, int ty, int twdt, int thgt, - int iAngle, bool fTransparency) + bool fTransparency) { // rendertarget? if (sfcTarget->IsRenderTarget()) { - C4BltTransform rot; - rot.SetRotate(iAngle, (float) (tx+tx+twdt)/2, (float) (ty+ty+thgt)/2); - return Blit(sfcSource, float(fx), float(fy), float(fwdt), float(fhgt), sfcTarget, float(tx), float(ty), float(twdt), float(thgt), true, &rot); + return Blit(sfcSource, float(fx), float(fy), float(fwdt), float(fhgt), sfcTarget, float(tx), float(ty), float(twdt), float(thgt), true); } - // Object is first stretched to dest rect, then rotated at place. - int xcnt,ycnt,fcx,fcy,tcx,tcy,cpcx,cpcy; - int npcx,npcy; - double mtx[4],dang; + // Object is first stretched to dest rect + int xcnt,ycnt,tcx,tcy,cpcx,cpcy; if (!fwdt || !fhgt || !twdt || !thgt) return false; // Lock the surfaces if (!sfcSource->Lock()) @@ -810,71 +799,12 @@ bool C4Draw::BlitRotate(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhg if (!sfcTarget->Lock()) { sfcSource->Unlock(); return false; } // Rectangle centers - fcx=fwdt/2; fcy=fhgt/2; tcx=twdt/2; tcy=thgt/2; - // Adjust angle range - while (iAngle<0) iAngle+=36000; while (iAngle>35999) iAngle-=36000; - // Exact/free rotation - switch (iAngle) - { - case 0: - for (ycnt=0; ycntHgt-1)) - for (xcnt=0; xcntWdt-1)) - sfcTarget->BltPix(cpcx, cpcy, sfcSource, xcnt*fwdt/twdt+fx, ycnt*fhgt/thgt+fy, fTransparency); - break; - - case 9000: - for (ycnt=0; ycntWdt-1)) - for (xcnt=0; xcntHgt-1)) - sfcTarget->BltPix(cpcx, cpcy, sfcSource, xcnt*fwdt/twdt+fx, ycnt*fhgt/thgt+fy, fTransparency); - break; - - case 18000: - for (ycnt=0; ycntHgt-1)) - for (xcnt=0; xcntWdt-1)) - sfcTarget->BltPix(cpcx, cpcy, sfcSource, xcnt*fwdt/twdt+fx, ycnt*fhgt/thgt+fy, fTransparency); - break; - - case 27000: - for (ycnt=0; ycntWdt-1)) - for (xcnt=0; xcntHgt-1)) - sfcTarget->BltPix(cpcx, cpcy, sfcSource, xcnt*fwdt/twdt+fx, ycnt*fhgt/thgt+fy, fTransparency); - break; - - default: - // Calculate rotation matrix - dang=M_PI*iAngle/18000.0; - mtx[0]=cos(dang); mtx[1]=-sin(dang); - mtx[2]=sin(dang); mtx[3]= cos(dang); - // Blit source rect - for (ycnt=0; ycntBltPix(tx+tcx+npcx, ty+tcy+npcy, sfcSource, xcnt+fx, ycnt+fy, fTransparency); - sfcTarget->BltPix(tx+tcx+npcx+1, ty+tcy+npcy, sfcSource, xcnt+fx, ycnt+fy, fTransparency); - } - } - break; - } - + for (ycnt=0; ycntHgt-1)) + for (xcnt=0; xcntWdt-1)) + sfcTarget->BltPix(cpcx, cpcy, sfcSource, xcnt*fwdt/twdt+fx, ycnt*fhgt/thgt+fy, fTransparency); // Unlock the surfaces sfcSource->Unlock(); sfcTarget->Unlock(); @@ -977,7 +907,10 @@ bool C4Draw::BlitSurfaceTile2(C4Surface * sfcSurface, C4Surface * sfcTarget, int if (iX0) iBlitWdt-=iOver; // blit - if (!Blit(sfcSurface,float(iBlitX),float(iBlitY),float(iBlitWdt),float(iBlitHgt),sfcTarget,float(tx+iToX),float(ty+iToY),float(iBlitWdt),float(iBlitHgt),fSrcColKey)) return false; + if (!Blit(sfcSurface,float(iBlitX),float(iBlitY),float(iBlitWdt),float(iBlitHgt),sfcTarget,float(tx+iToX),float(ty+iToY),float(iBlitWdt),float(iBlitHgt),fSrcColKey)) + { + // Ignore blit errors. This is usually due to blit border lying outside surface and shouldn't cause remaining blits to fail. + } // next col tx+=iBlitWdt; } @@ -992,7 +925,7 @@ bool C4Draw::TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface { C4Markup Markup(true); static char szLinebuf[2500+1]; - for (int cnt=0; SCopySegmentEx(szText,cnt,szLinebuf,fDoMarkup ? '|' : '\n','\n',2500); cnt++,iTy+=int(fZoom*rFont.iLineHgt)) + for (int cnt=0; SCopySegmentEx(szText,cnt,szLinebuf,fDoMarkup ? '|' : '\n','\n',2500); cnt++,iTy+=int(fZoom*rFont.GetLineHeight())) if (!StringOut(szLinebuf,sfcDest,iTx,iTy,dwFCol,byForm,fDoMarkup,Markup,&rFont,fZoom)) return false; return true; } @@ -1046,7 +979,7 @@ void C4Draw::DrawPix(C4Surface * sfcDest, float tx, float ty, DWORD dwClr) PerformPix(sfcDest, tx, ty, dwClr); } -void C4Draw::DrawLineDw(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr) +void C4Draw::DrawLineDw(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width) { ApplyZoom(x1, y1); ApplyZoom(x2, y2); @@ -1090,7 +1023,7 @@ void C4Draw::DrawLineDw(C4Surface * sfcTarget, float x1, float y1, float x2, flo // apply color modulation ClrByCurrentBlitMod(dwClr); - PerformLine(sfcTarget, x1, y1, x2, y2, dwClr); + PerformLine(sfcTarget, x1, y1, x2, y2, dwClr, width); } void C4Draw::DrawFrameDw(C4Surface * sfcDest, int x1, int y1, int x2, int y2, DWORD dwClr) // make these parameters float...? @@ -1186,6 +1119,11 @@ void C4Draw::SetGamma(DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, int32_t iRampInd fSetGamma=true; } +void C4Draw::ResetGamma() +{ + pApp->ApplyGammaRamp(DefRamp.ramp, false); +} + void C4Draw::ApplyGamma() { // No gamma effects @@ -1250,21 +1188,14 @@ void C4Draw::RemoveZoom(float & X, float & Y) Y = (Y - ZoomY) / Zoom + ZoomY; } -bool DDrawInit(C4AbstractApp * pApp, bool Editor, bool fUsePageLock, unsigned int iXRes, unsigned int iYRes, int iBitDepth, int Engine, unsigned int iMonitor) +bool DDrawInit(C4AbstractApp * pApp, bool Editor, bool fUsePageLock, unsigned int iXRes, unsigned int iYRes, int iBitDepth, unsigned int iMonitor) { // create engine - switch (Engine) - { - default: // Use the first engine possible if none selected -#ifdef USE_DIRECTX - case GFXENGN_DIRECTX: pDraw = new CStdD3D(false); break; - case GFXENGN_DIRECTXS: pDraw = new CStdD3D(true); break; -#endif -#ifdef USE_GL - case GFXENGN_OPENGL: pDraw = new CStdGL(); break; -#endif - case GFXENGN_NOGFX: pDraw = new CStdNoGfx(); break; - } + #ifndef USE_CONSOLE + pDraw = new CStdGL(); + #else + pDraw = new CStdNoGfx(); + #endif if (!pDraw) return false; // init it if (!pDraw->Init(pApp, Editor, fUsePageLock, iXRes, iYRes, iBitDepth, iMonitor)) @@ -1353,16 +1284,5 @@ void C4Draw::DrawBoxFade(C4Surface * sfcDest, float iX, float iY, float iWdt, fl void C4Draw::DrawBoxDw(C4Surface * sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr) { - // manual clipping? - if (Config.Graphics.ClipManuallyE) - { - int iOver; - iOver=iX1-iClipX1; if (iOver<0) { iX1=iClipX1; } - iOver=iY1-iClipY1; if (iOver<0) { iY1=iClipY1; } - iOver=iClipX2-iX2; if (iOver<0) { iX2+=iOver; } - iOver=iClipY2-iY2; if (iOver<0) { iY2+=iOver; } - // inside screen? - if (iX2 -#include +#include #include #ifdef _WIN32 #include #endif -// engines -#define GFXENGN_DIRECTX 0 -#define GFXENGN_OPENGL 1 -#define GFXENGN_DIRECTXS 2 -#define GFXENGN_NOGFX 3 - // Global Draw access pointer extern C4Draw *pDraw; @@ -48,12 +38,12 @@ public: C4BltTransform() {} // default: don't init fields void Set(float fA, float fB, float fC, float fD, float fE, float fF, float fG, float fH, float fI) { mat[0]=fA; mat[1]=fB; mat[2]=fC; mat[3]=fD; mat[4]=fE; mat[5]=fF; mat[6]=fG; mat[7]=fH; mat[8]=fI; } - void SetRotate(int iAngle, float fOffX, float fOffY); // set by angle and rotation offset + void SetRotate(float iAngle, float fOffX, float fOffY); // set by angle and rotation offset bool SetAsInv(C4BltTransform &rOfTransform); - void Rotate(int iAngle, float fOffX, float fOffY) // rotate by angle around rotation offset + void Rotate(float Angle, float fOffX, float fOffY) // rotate by angle around rotation offset { // multiply matrix as seen in SetRotate by own matrix - C4BltTransform rot; rot.SetRotate(iAngle, fOffX, fOffY); + C4BltTransform rot; rot.SetRotate(Angle, fOffX, fOffY); (*this) *= rot; } void SetMoveScale(float dx, float dy, float sx, float sy) @@ -130,14 +120,12 @@ struct C4BltData // This structure is used by StdGL, too -#ifndef USE_DIRECTX -typedef struct _D3DGAMMARAMP +typedef struct _GAMMARAMP { WORD red [256]; WORD green[256]; WORD blue [256]; -} D3DGAMMARAMP; -#endif +} GAMMARAMP; // gamma ramp control class C4GammaControl @@ -146,7 +134,7 @@ private: void SetClrChannel(WORD *pBuf, BYTE c1, BYTE c2, int c3); // set color channel ramp protected: - D3DGAMMARAMP ramp; + GAMMARAMP ramp; public: C4GammaControl() { Default(); } // ctor @@ -157,7 +145,6 @@ public: DWORD ApplyTo(DWORD dwClr); // apply gamma to color value friend class C4Draw; - friend class CStdD3D; friend class CStdGL; }; @@ -212,9 +199,6 @@ public: #ifdef _WIN32 virtual CStdGLCtx *CreateContext(HWND, C4AbstractApp *) { return NULL; } #endif - virtual int GetEngine() = 0; // get indexed engine - virtual void TaskOut() = 0; // user taskswitched the app away - virtual void TaskIn() = 0; // user tasked back virtual bool OnResolutionChanged(unsigned int iXRes, unsigned int iYRes) = 0; // reinit clipper for new resolution virtual bool IsOpenGL() { return false; } virtual bool IsShaderific() { return false; } @@ -252,9 +236,9 @@ public: bool Blit8(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, // force 8bit-blit (inline) C4Surface * sfcTarget, int tx, int ty, int twdt, int thgt, bool fSrcColKey=false, const C4BltTransform *pTransform=NULL); - bool BlitRotate(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, + bool BlitSimple(C4Surface * sfcSource, int fx, int fy, int fwdt, int fhgt, C4Surface * sfcTarget, int tx, int ty, int twdt, int thgt, - int iAngle, bool fTransparency=true); + bool fTransparency=true); bool BlitSurface(C4Surface * sfcSurface, C4Surface * sfcTarget, int tx, int ty, bool fBlitBase); bool BlitSurfaceTile(C4Surface * sfcSurface, C4Surface * sfcTarget, int iToX, int iToY, int iToWdt, int iToHgt, int iOffsetX=0, int iOffsetY=0, bool fSrcColKey=false); bool BlitSurfaceTile2(C4Surface * sfcSurface, C4Surface * sfcTarget, int iToX, int iToY, int iToWdt, int iToHgt, int iOffsetX=0, int iOffsetY=0, bool fSrcColKey=false); @@ -269,13 +253,14 @@ public: void DrawBoxFade(C4Surface * sfcDest, float iX, float iY, float iWdt, float iHgt, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4, int iBoxOffX, int iBoxOffY); // calls DrawQuadDw void DrawPatternedCircle(C4Surface * sfcDest, int x, int y, int r, BYTE col, C4Pattern & Pattern, CStdPalette &rPal); void DrawFrameDw(C4Surface * sfcDest, int x1, int y1, int x2, int y2, DWORD dwClr); - virtual void DrawLineDw(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr); + virtual void DrawLineDw(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width = 1.0f); virtual void DrawQuadDw(C4Surface * sfcTarget, float *ipVtx, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4) = 0; // gamma void SetGamma(DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, int32_t iRampIndex); // set gamma ramp + void ResetGamma(); // reset all gamma ramps to default void ApplyGamma(); // apply gamma ramp to ddraw - void DisableGamma(); // reset gamma ramp to default - void EnableGamma(); // set current gamma ramp + void DisableGamma(); // temporarily reset app gamma to default + void EnableGamma(); // set current gamma ramp in app DWORD ApplyGammaTo(DWORD dwClr); // apply gamma to given color // blit states void ActivateBlitModulation(DWORD dwWithClr) { BlitModulated=true; BlitModulateClr=dwWithClr; } // modulate following blits with a given color @@ -313,7 +298,7 @@ public: protected: bool StringOut(const char *szText, C4Surface * sfcDest, float iTx, float iTy, DWORD dwFCol, BYTE byForm, bool fDoMarkup, C4Markup &Markup, CStdFont *pFont, float fZoom); virtual void PerformPix(C4Surface * sfcDest, float tx, float ty, DWORD dwCol) = 0; // without ClrModMap - virtual void PerformLine(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr) = 0; + virtual void PerformLine(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width) = 0; bool CreatePrimaryClipper(unsigned int iXRes, unsigned int iYRes); virtual bool CreatePrimarySurfaces(bool Editor, unsigned int iXRes, unsigned int iYRes, int iColorDepth, unsigned int iMonitor) = 0; virtual bool Error(const char *szMsg); @@ -327,7 +312,6 @@ protected: friend class C4Surface; friend class C4TexRef; friend class C4Pattern; - friend class CStdD3DShader; }; struct ZoomDataStackItem: public ZoomData @@ -342,5 +326,5 @@ bool UnLockSurfaceGlobal(C4Surface * sfcTarget); bool DLineSPix(int32_t x, int32_t y, int32_t col); bool DLineSPixDw(int32_t x, int32_t y, int32_t dwClr); -bool DDrawInit(C4AbstractApp * pApp, bool Editor, bool fUsePageLock, unsigned int iXRes, unsigned int iYRes, int iBitDepth, int Engine, unsigned int iMonitor); +bool DDrawInit(C4AbstractApp * pApp, bool Editor, bool fUsePageLock, unsigned int iXRes, unsigned int iYRes, int iBitDepth, unsigned int iMonitor); #endif // INC_STDDDRAW2 diff --git a/src/graphics/C4DrawGL.cpp b/src/graphics/C4DrawGL.cpp new file mode 100644 index 000000000..be55f6833 --- /dev/null +++ b/src/graphics/C4DrawGL.cpp @@ -0,0 +1,995 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ + +/* OpenGL implementation of NewGfx */ + +#include "C4Include.h" +#include + +#include +#include +#include "C4Rect.h" +#include "C4Config.h" +#include "C4Application.h" + +#ifndef USE_CONSOLE + +// MSVC doesn't define M_PI in math.h unless requested +#ifdef _MSC_VER +#define _USE_MATH_DEFINES +#endif /* _MSC_VER */ + +#include +#include +#include + +static void glColorDw(DWORD dwClr) +{ + glColor4ub(GLubyte(dwClr>>16), GLubyte(dwClr>>8), GLubyte(dwClr), GLubyte(dwClr>>24)); +} + +// GLubyte (&r)[4] is a reference to an array of four bytes named r. +static void DwTo4UB(DWORD dwClr, GLubyte (&r)[4]) +{ + //unsigned char r[4]; + r[0] = GLubyte(dwClr>>16); + r[1] = GLubyte(dwClr>>8); + r[2] = GLubyte(dwClr); + r[3] = GLubyte(dwClr>>24); +} + +CStdGL::CStdGL(): + pMainCtx(0) +{ + Default(); + byByteCnt=4; + // global ptr + pGL = this; + shaders[0] = 0; + vbo = 0; + lines_tex = 0; +} + +CStdGL::~CStdGL() +{ + Clear(); + pGL=NULL; +} + +void CStdGL::Clear() +{ + NoPrimaryClipper(); + //if (pTexMgr) pTexMgr->IntUnlock(); // cannot do this here or we can't preserve textures across GL reinitialization as required when changing multisampling + InvalidateDeviceObjects(); + NoPrimaryClipper(); + RenderTarget = NULL; + // clear context + if (pCurrCtx) pCurrCtx->Deselect(); + pMainCtx=0; + C4Draw::Clear(); +} + +void CStdGL::FillBG(DWORD dwClr) +{ + if (!pCurrCtx) return; + glClearColor((float)GetRedValue(dwClr)/255.0f, (float)GetGreenValue(dwClr)/255.0f, (float)GetBlueValue(dwClr)/255.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +bool CStdGL::UpdateClipper() +{ + // no render target? do nothing + if (!RenderTarget || !Active) return true; + // negative/zero? + int iWdt=Min(iClipX2, RenderTarget->Wdt-1)-iClipX1+1; + int iHgt=Min(iClipY2, RenderTarget->Hgt-1)-iClipY1+1; + int iX=iClipX1; if (iX<0) { iWdt+=iX; iX=0; } + int iY=iClipY1; if (iY<0) { iHgt+=iY; iY=0; } + + if (iWdt<=0 || iHgt<=0) + { + ClipAll=true; + return true; + } + ClipAll=false; + // set it + glViewport(iX, RenderTarget->Hgt-iY-iHgt, iWdt, iHgt); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Set clipping plane to -1000 and 1000 so that large meshes are not + // clipped away. + //glOrtho((GLdouble) iX, (GLdouble) (iX+iWdt), (GLdouble) (iY+iHgt), (GLdouble) iY, -1000.0f, 1000.0f); + gluOrtho2D((GLdouble) iX, (GLdouble) (iX+iWdt), (GLdouble) (iY+iHgt), (GLdouble) iY); + //gluOrtho2D((GLdouble) 0, (GLdouble) xRes, (GLdouble) yRes, (GLdouble) yRes-iHgt); + return true; +} + +bool CStdGL::PrepareRendering(C4Surface * sfcToSurface) +{ + // call from gfx thread only! + if (!pApp || !pApp->AssertMainThread()) return false; + // not ready? + if (!Active) + //if (!RestoreDeviceObjects()) + return false; + // target? + if (!sfcToSurface) return false; + // target locked? + if (sfcToSurface->Locked) return false; + // target is already set as render target? + if (sfcToSurface != RenderTarget) + { + // target is a render-target? + if (!sfcToSurface->IsRenderTarget()) return false; + // context + if (sfcToSurface->pCtx && sfcToSurface->pCtx != pCurrCtx) + if (!sfcToSurface->pCtx->Select()) return false; + // set target + RenderTarget=sfcToSurface; + // new target has different size; needs other clipping rect + UpdateClipper(); + } + // done + return true; +} + +void CStdGL::SetupTextureEnv(bool fMod2, bool landscape) +{ + if (shaders[0]) + { + GLuint s = landscape ? 2 : (fMod2 ? 1 : 0); + if (Saturation < 255) + { + s += 3; + } + if (fUseClrModMap) + { + s += 6; + } + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shaders[s]); + if (Saturation < 255) + { + GLfloat bla[4] = { Saturation / 255.0f, Saturation / 255.0f, Saturation / 255.0f, 1.0f }; + glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, bla); + } + } + // texture environment + else + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, fMod2 ? GL_ADD_SIGNED : GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, fMod2 ? 2.0f : 1.0f); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); + } + // set modes + glShadeModel((fUseClrModMap && !shaders[0]) ? GL_SMOOTH : GL_FLAT); +} + +void CStdGL::PerformBlt(C4BltData &rBltData, C4TexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact) +{ + // global modulation map + int i; + bool fAnyModNotBlack = (dwModClr != 0xff000000); + if (!shaders[0] && fUseClrModMap && dwModClr != 0xff000000) + { + fAnyModNotBlack = false; + for (i=0; iTransformPoint(x,y); + } + DWORD c = pClrModMap->GetModAt(int(x), int(y)); + ModulateClr(c, dwModClr); + if (c != 0xff000000) fAnyModNotBlack = true; + DwTo4UB(c, rBltData.vtVtx[i].color); + } + } + else + { + for (i=0; itexName); + if (!fExact) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + glMatrixMode(GL_TEXTURE); + /*float matrix[16]; + matrix[0]=rBltData.TexPos.mat[0]; matrix[1]=rBltData.TexPos.mat[3]; matrix[2]=0; matrix[3]=rBltData.TexPos.mat[6]; + matrix[4]=rBltData.TexPos.mat[1]; matrix[5]=rBltData.TexPos.mat[4]; matrix[6]=0; matrix[7]=rBltData.TexPos.mat[7]; + matrix[8]=0; matrix[9]=0; matrix[10]=1; matrix[11]=0; + matrix[12]=rBltData.TexPos.mat[2]; matrix[13]=rBltData.TexPos.mat[5]; matrix[14]=0; matrix[15]=rBltData.TexPos.mat[8]; + glLoadMatrixf(matrix);*/ + glLoadIdentity(); + + if (shaders[0] && fUseClrModMap) + { + glActiveTexture(GL_TEXTURE3); + glLoadIdentity(); + C4Surface * pSurface = pClrModMap->GetSurface(); + glScalef(1.0f/(pClrModMap->GetResolutionX()*(*pSurface->ppTex)->iSizeX), 1.0f/(pClrModMap->GetResolutionY()*(*pSurface->ppTex)->iSizeY), 1.0f); + glTranslatef(float(-pClrModMap->OffX), float(-pClrModMap->OffY), 0.0f); + } + if (rBltData.pTransform) + { + const float * mat = rBltData.pTransform->mat; + float matrix[16]; + matrix[0]=mat[0]; matrix[1]=mat[3]; matrix[2]=0; matrix[3]=mat[6]; + matrix[4]=mat[1]; matrix[5]=mat[4]; matrix[6]=0; matrix[7]=mat[7]; + matrix[8]=0; matrix[9]=0; matrix[10]=1; matrix[11]=0; + matrix[12]=mat[2]; matrix[13]=mat[5]; matrix[14]=0; matrix[15]=mat[8]; + if (shaders[0] && fUseClrModMap) + { + glMultMatrixf(matrix); + } + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(matrix); + } + else + { + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + + // draw polygon + for (i=0; iTransformPoint(rBltData.vtVtx[i].ftx, rBltData.vtVtx[i].fty); + rBltData.vtVtx[i].ftz = 0; + } + if (vbo) + { + glBufferDataARB(GL_ARRAY_BUFFER_ARB, rBltData.byNumVertices*sizeof(C4BltVertex), rBltData.vtVtx, GL_STREAM_DRAW_ARB); + glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(C4BltVertex), 0); + } + else + { + glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(C4BltVertex), rBltData.vtVtx); + } + if (shaders[0] && fUseClrModMap) + { + glClientActiveTexture(GL_TEXTURE3); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(C4BltVertex), &rBltData.vtVtx[0].ftx); + glClientActiveTexture(GL_TEXTURE0); + } + glDrawArrays(GL_POLYGON, 0, rBltData.byNumVertices); + if(shaders[0] && fUseClrModMap) + { + glClientActiveTexture(GL_TEXTURE3); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + } + glLoadIdentity(); + if (!fExact) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } +} + +void CStdGL::BlitLandscape(C4Surface * sfcSource, float fx, float fy, + C4Surface * sfcTarget, float tx, float ty, float wdt, float hgt, const C4Surface * mattextures[]) +{ + //Blit(sfcSource, fx, fy, wdt, hgt, sfcTarget, tx, ty, wdt, hgt);return; + // safety + if (!sfcSource || !sfcTarget || !wdt || !hgt) return; + assert(sfcTarget->IsRenderTarget()); + assert(!(dwBlitMode & C4GFXBLIT_MOD2)); + // Apply Zoom + float twdt = wdt; + float thgt = hgt; + tx = (tx - ZoomX) * Zoom + ZoomX; + ty = (ty - ZoomY) * Zoom + ZoomY; + twdt *= Zoom; + thgt *= Zoom; + // bound + if (ClipAll) return; + // manual clipping? (primary surface only) + if (Config.Graphics.ClipManuallyE) + { + int iOver; + // Left + iOver=int(tx)-iClipX1; + if (iOver<0) + { + wdt+=iOver; + twdt+=iOver*Zoom; + fx-=iOver; + tx=float(iClipX1); + } + // Top + iOver=int(ty)-iClipY1; + if (iOver<0) + { + hgt+=iOver; + thgt+=iOver*Zoom; + fy-=iOver; + ty=float(iClipY1); + } + // Right + iOver=iClipX2+1-int(tx+twdt); + if (iOver<0) + { + wdt+=iOver/Zoom; + twdt+=iOver; + } + // Bottom + iOver=iClipY2+1-int(ty+thgt); + if (iOver<0) + { + hgt+=iOver/Zoom; + thgt+=iOver; + } + } + // inside screen? + if (wdt<=0 || hgt<=0) return; + // prepare rendering to surface + if (!PrepareRendering(sfcTarget)) return; + // texture present? + if (!sfcSource->ppTex) + { + return; + } + // get involved texture offsets + int iTexSizeX=sfcSource->iTexSize; + int iTexSizeY=sfcSource->iTexSize; + int iTexX=Max(int(fx/iTexSizeX), 0); + int iTexY=Max(int(fy/iTexSizeY), 0); + int iTexX2=Min((int)(fx+wdt-1)/iTexSizeX +1, sfcSource->iTexX); + int iTexY2=Min((int)(fy+hgt-1)/iTexSizeY +1, sfcSource->iTexY); + // blit from all these textures + SetTexture(); + if (mattextures) + { + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + } + DWORD dwModMask = 0; + SetupTextureEnv(false, !!mattextures); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + for (int iY=iTexY; iYppTex + iY * sfcSource->iTexX + iX); + glBindTexture(GL_TEXTURE_2D, pTex->texName); + if (!mattextures && Zoom != 1.0) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + // get current blitting offset in texture + int iBlitX=sfcSource->iTexSize*iX; + int iBlitY=sfcSource->iTexSize*iY; + // size changed? recalc dependant, relevant (!) values + if (iTexSizeX != pTex->iSizeX) + iTexSizeX = pTex->iSizeX; + if (iTexSizeY != pTex->iSizeY) + iTexSizeY = pTex->iSizeY; + // get new texture source bounds + FLOAT_RECT fTexBlt; + // get new dest bounds + FLOAT_RECT tTexBlt; + // set up blit data as rect + fTexBlt.left = Max((float)(fx - iBlitX), 0.0f); + tTexBlt.left = (fTexBlt.left + iBlitX - fx) * Zoom + tx; + fTexBlt.top = Max((float)(fy - iBlitY), 0.0f); + tTexBlt.top = (fTexBlt.top + iBlitY - fy) * Zoom + ty; + fTexBlt.right = Min((float)(fx + wdt - iBlitX), (float)iTexSizeX); + tTexBlt.right = (fTexBlt.right + iBlitX - fx) * Zoom + tx; + fTexBlt.bottom= Min((float)(fy + hgt - iBlitY), (float)iTexSizeY); + tTexBlt.bottom= (fTexBlt.bottom+ iBlitY - fy) * Zoom + ty; + C4BltVertex Vtx[4]; + // blit positions + Vtx[0].ftx = tTexBlt.left; Vtx[0].fty = tTexBlt.top; + Vtx[1].ftx = tTexBlt.right; Vtx[1].fty = tTexBlt.top; + Vtx[2].ftx = tTexBlt.right; Vtx[2].fty = tTexBlt.bottom; + Vtx[3].ftx = tTexBlt.left; Vtx[3].fty = tTexBlt.bottom; + // blit positions + Vtx[0].tx = fTexBlt.left; Vtx[0].ty = fTexBlt.top; + Vtx[1].tx = fTexBlt.right; Vtx[1].ty = fTexBlt.top; + Vtx[2].tx = fTexBlt.right; Vtx[2].ty = fTexBlt.bottom; + Vtx[3].tx = fTexBlt.left; Vtx[3].ty = fTexBlt.bottom; + + // color modulation + // global modulation map + if (shaders[0] && fUseClrModMap) + { + glActiveTexture(GL_TEXTURE3); + glLoadIdentity(); + C4Surface * pSurface = pClrModMap->GetSurface(); + glScalef(1.0f/(pClrModMap->GetResolutionX()*(*pSurface->ppTex)->iSizeX), 1.0f/(pClrModMap->GetResolutionY()*(*pSurface->ppTex)->iSizeY), 1.0f); + glTranslatef(float(-pClrModMap->OffX), float(-pClrModMap->OffY), 0.0f); + + glClientActiveTexture(GL_TEXTURE3); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(C4BltVertex), &Vtx[0].ftx); + glClientActiveTexture(GL_TEXTURE0); + } + if (!shaders[0] && fUseClrModMap && dwModClr) + { + for (int i=0; i<4; ++i) + { + DWORD c = pClrModMap->GetModAt(int(Vtx[i].ftx), int(Vtx[i].fty)); + ModulateClr(c, dwModClr); + DwTo4UB(c | dwModMask, Vtx[i].color); + } + } + else + { + for (int i=0; i<4; ++i) + DwTo4UB(dwModClr | dwModMask, Vtx[i].color); + } + for (int i=0; i<4; ++i) + { + Vtx[i].tx /= iTexSizeX; + Vtx[i].ty /= iTexSizeY; + Vtx[i].ftz = 0; + } + if (mattextures) + { + GLfloat shaderparam[4]; + for (int cnt=1; cnt<127; cnt++) + { + if (mattextures[cnt]) + { + shaderparam[0]=static_cast(cnt)/255.0f; + glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 1, shaderparam); + //Bind Mat Texture + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, (*(mattextures[cnt]->ppTex))->texName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glActiveTexture(GL_TEXTURE0); + + glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(C4BltVertex), Vtx); + glDrawArrays(GL_QUADS, 0, 4); + } + } + } + else + { + glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(C4BltVertex), Vtx); + glDrawArrays(GL_QUADS, 0, 4); + } + + if(shaders[0] && fUseClrModMap) + { + glClientActiveTexture(GL_TEXTURE3); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + } + + } + } + if (mattextures) + { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + } + // reset texture + ResetTexture(); +} + +CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) +{ + DebugLog(" gl: Create Context..."); + // safety + if (!pWindow) return NULL; + // create it + CStdGLCtx *pCtx = new CStdGLCtx(); + if (!pMainCtx) pMainCtx = pCtx; + if (!pCtx->Init(pWindow, pApp)) + { + delete pCtx; Error(" gl: Error creating secondary context!"); return NULL; + } + // creation selected the new context - switch back to previous context + RenderTarget = NULL; + pCurrCtx = NULL; + // done + return pCtx; +} + +#ifdef USE_WIN32_WINDOWS +CStdGLCtx *CStdGL::CreateContext(HWND hWindow, C4AbstractApp *pApp) +{ + // safety + if (!hWindow) return NULL; + // create it + CStdGLCtx *pCtx = new CStdGLCtx(); + if (!pCtx->Init(NULL, pApp, hWindow)) + { + delete pCtx; Error(" gl: Error creating secondary context!"); return NULL; + } + if (!pMainCtx) + { + pMainCtx = pCtx; + } + else + { + // creation selected the new context - switch back to previous context + RenderTarget = NULL; + pCurrCtx = NULL; + } + // done + return pCtx; +} +#endif + +bool CStdGL::CreatePrimarySurfaces(bool, unsigned int, unsigned int, int iColorDepth, unsigned int) +{ + // store options + + return RestoreDeviceObjects(); +} + +void CStdGL::DrawQuadDw(C4Surface * sfcTarget, float *ipVtx, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4) +{ + // prepare rendering to target + if (!PrepareRendering(sfcTarget)) return; + // apply global modulation + ClrByCurrentBlitMod(dwClr1); + ClrByCurrentBlitMod(dwClr2); + ClrByCurrentBlitMod(dwClr3); + ClrByCurrentBlitMod(dwClr4); + // apply modulation map + if (fUseClrModMap) + { + ModulateClr(dwClr1, pClrModMap->GetModAt(int(ipVtx[0]), int(ipVtx[1]))); + ModulateClr(dwClr2, pClrModMap->GetModAt(int(ipVtx[2]), int(ipVtx[3]))); + ModulateClr(dwClr3, pClrModMap->GetModAt(int(ipVtx[4]), int(ipVtx[5]))); + ModulateClr(dwClr4, pClrModMap->GetModAt(int(ipVtx[6]), int(ipVtx[7]))); + } + glShadeModel((dwClr1 == dwClr2 && dwClr1 == dwClr3 && dwClr1 == dwClr4) ? GL_FLAT : GL_SMOOTH); + // set blitting state + int iAdditive = dwBlitMode & C4GFXBLIT_ADDITIVE; + glBlendFunc(GL_SRC_ALPHA, iAdditive ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA); + // draw two triangles + glInterleavedArrays(GL_V2F, sizeof(float)*2, ipVtx); + GLubyte colors[4][4]; + DwTo4UB(dwClr1,colors[0]); + DwTo4UB(dwClr2,colors[1]); + DwTo4UB(dwClr3,colors[2]); + DwTo4UB(dwClr4,colors[3]); + glColorPointer(4,GL_UNSIGNED_BYTE,0,colors); + glEnableClientState(GL_COLOR_ARRAY); + glDrawArrays(GL_POLYGON, 0, 4); + glDisableClientState(GL_COLOR_ARRAY); + glShadeModel(GL_FLAT); +} + +#ifdef _MSC_VER +#ifdef _M_X64 +# include +#endif +static inline long int lrintf(float f) +{ +#ifdef _M_X64 + return _mm_cvtt_ss2si(_mm_load_ps1(&f)); +#else + long int i; + __asm + { + fld f + fistp i + }; + return i; +#endif +} +#endif + +void CStdGL::PerformLine(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width) +{ + // render target? + if (sfcTarget->IsRenderTarget()) + { + // prepare rendering to target + if (!PrepareRendering(sfcTarget)) return; + SetTexture(); + SetupTextureEnv(false, false); + float offx = y1 - y2; + float offy = x2 - x1; + float l = sqrtf(offx * offx + offy * offy); + // avoid division by zero + l += 0.000000005f; + offx /= l; offx *= Zoom * width; + offy /= l; offy *= Zoom * width; + C4BltVertex vtx[4]; + vtx[0].ftx = x1 + offx; vtx[0].fty = y1 + offy; vtx[0].ftz = 0; + vtx[1].ftx = x1 - offx; vtx[1].fty = y1 - offy; vtx[1].ftz = 0; + vtx[2].ftx = x2 - offx; vtx[2].fty = y2 - offy; vtx[2].ftz = 0; + vtx[3].ftx = x2 + offx; vtx[3].fty = y2 + offy; vtx[3].ftz = 0; + // global clr modulation map + DWORD dwClr1 = dwClr; + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + if (fUseClrModMap) + { + if (shaders[0]) + { + glActiveTexture(GL_TEXTURE3); + glLoadIdentity(); + C4Surface * pSurface = pClrModMap->GetSurface(); + glScalef(1.0f/(pClrModMap->GetResolutionX()*(*pSurface->ppTex)->iSizeX), 1.0f/(pClrModMap->GetResolutionY()*(*pSurface->ppTex)->iSizeY), 1.0f); + glTranslatef(float(-pClrModMap->OffX), float(-pClrModMap->OffY), 0.0f); + + glClientActiveTexture(GL_TEXTURE3); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(C4BltVertex), &vtx[0].ftx); + glClientActiveTexture(GL_TEXTURE0); + } + else + { + ModulateClr(dwClr1, pClrModMap->GetModAt(lrintf(x1), lrintf(y1))); + ModulateClr(dwClr, pClrModMap->GetModAt(lrintf(x2), lrintf(y2))); + } + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + DwTo4UB(dwClr1,vtx[0].color); + DwTo4UB(dwClr1,vtx[1].color); + DwTo4UB(dwClr,vtx[2].color); + DwTo4UB(dwClr,vtx[3].color); + vtx[0].tx = 0; vtx[0].ty = 0; + vtx[1].tx = 0; vtx[1].ty = 2; + vtx[2].tx = 1; vtx[2].ty = 2; + vtx[3].tx = 1; vtx[3].ty = 0; + // draw two triangles + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, lines_tex); + glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(C4BltVertex), vtx); + glDrawArrays(GL_POLYGON, 0, 4); + glClientActiveTexture(GL_TEXTURE3); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + ResetTexture(); + } + else + { + // emulate + if (!LockSurfaceGlobal(sfcTarget)) return; + ForLine((int32_t)x1,(int32_t)y1,(int32_t)x2,(int32_t)y2,&DLineSPixDw,(int) dwClr); + UnLockSurfaceGlobal(sfcTarget); + } +} + +void CStdGL::PerformPix(C4Surface * sfcTarget, float tx, float ty, DWORD dwClr) +{ + // render target? + if (sfcTarget->IsRenderTarget()) + { + if (!PrepareRendering(sfcTarget)) return; + int iAdditive = dwBlitMode & C4GFXBLIT_ADDITIVE; + // use a different blendfunc here because of GL_POINT_SMOOTH + glBlendFunc(GL_SRC_ALPHA, iAdditive ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA); + // convert the alpha value for that blendfunc + glBegin(GL_POINTS); + glColorDw(dwClr); + glVertex2f(tx + 0.5f, ty + 0.5f); + glEnd(); + } + else + { + // emulate + sfcTarget->SetPixDw((int)tx, (int)ty, dwClr); + } +} + +static void DefineShaderARB(const char * p, GLuint & s) +{ + glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, s); + glProgramStringARB (GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(p), p); + if (GL_INVALID_OPERATION == glGetError()) + { + GLint errPos; glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errPos); + fprintf (stderr, "ARB program%d:%d: Error: %s\n", s, errPos, glGetString (GL_PROGRAM_ERROR_STRING_ARB)); + s = 0; + } +} + +bool CStdGL::RestoreDeviceObjects() +{ + assert(pMainCtx); + // delete any previous objects + InvalidateDeviceObjects(); + + // set states + Active = pMainCtx->Select(); + RenderTarget = pApp->pWindow->pSurface; + + // BGRA Pixel Formats, Multitexturing, Texture Combine Environment Modes + // Check for GL 1.2 and two functions from 1.3 we need. + if( !GLEW_VERSION_1_2 || + glActiveTexture == NULL || + glClientActiveTexture == NULL + ) { + return Error(" gl: OpenGL Version 1.3 or higher required. A better graphics driver will probably help."); + } + + // lines texture + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &lines_tex); + glBindTexture(GL_TEXTURE_2D, lines_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + const char * linedata = byByteCnt == 2 ? "\xff\xf0\xff\xff" : "\xff\xff\xff\x00\xff\xff\xff\xff"; + glTexImage2D(GL_TEXTURE_2D, 0, 4, 1, 2, 0, GL_BGRA, byByteCnt == 2 ? GL_UNSIGNED_SHORT_4_4_4_4_REV : GL_UNSIGNED_INT_8_8_8_8_REV, linedata); + + + MaxTexSize = 64; + GLint s = 0; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s); + if (s>0) MaxTexSize = s; + + // restore gamma if active + if (Active) + EnableGamma(); + // reset blit states + dwBlitMode = 0; + + // Vertex Buffer Objects crash some versions of the free radeon driver. TODO: provide an option for them + if (0 && GLEW_ARB_vertex_buffer_object) + { + glGenBuffersARB(1, &vbo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, 8 * sizeof(C4BltVertex), 0, GL_STREAM_DRAW_ARB); + } + + if (!Config.Graphics.EnableShaders) + { + } + else if (!shaders[0] && GLEW_ARB_fragment_program) + { + glGenProgramsARB (sizeof(shaders)/sizeof(*shaders), shaders); + const char * preface = + "!!ARBfp1.0\n" + "TEMP tmp;\n" + // sample the texture + "TXP tmp, fragment.texcoord[0], texture, 2D;\n"; + const char * alpha_mod = + // perform the modulation + "MUL tmp.rgba, tmp, fragment.color.primary;\n"; + const char * funny_add = + // perform the modulation + "ADD tmp.rgb, tmp, fragment.color.primary;\n" + "MUL tmp.a, tmp, fragment.color.primary;\n" + "MAD_SAT tmp, tmp, { 2.0, 2.0, 2.0, 1.0 }, { -1.0, -1.0, -1.0, 0.0 };\n"; + const char * grey = + "TEMP grey;\n" + "DP3 grey, tmp, { 0.299, 0.587, 0.114, 1.0 };\n" + "LRP tmp.rgb, program.local[0], tmp, grey;\n"; + const char * landscape = + "TEMP col;\n" + "MOV col.x, program.local[1].x;\n" //Load color to indentify + "ADD col.y, col.x, 0.001;\n" + "SUB col.z, col.x, 0.001;\n" //epsilon-range + "SGE tmp.r, tmp.b, 0.5015;\n" //Tunnel? + "MAD tmp.r, tmp.r, -0.5019, tmp.b;\n" + "SGE col.z, tmp.r, col.z;\n" //mat identified? + "SLT col.y, tmp.r, col.y;\n" + "TEMP coo;\n" + "MOV coo, fragment.texcoord;\n" + "MUL coo.xy, coo, 3.0;\n" + "TXP tmp, coo, texture[1], 2D;\n" + "MUL tmp.a, col.y, col.z;\n"; + const char * fow = + "TEMP fow;\n" + // sample the texture + "TXP fow, fragment.texcoord[3], texture[3], 2D;\n" + "LRP tmp.rgb, fow.aaaa, tmp, fow;\n"; + const char * end = + "MOV result.color, tmp;\n" + "END\n"; + DefineShaderARB(FormatString("%s%s%s", preface, alpha_mod, end).getData(), shaders[0]); + DefineShaderARB(FormatString("%s%s%s", preface, funny_add, end).getData(), shaders[1]); + DefineShaderARB(FormatString("%s%s%s%s", preface, landscape, alpha_mod, end).getData(), shaders[2]); + DefineShaderARB(FormatString("%s%s%s%s", preface, alpha_mod, grey, end).getData(), shaders[3]); + DefineShaderARB(FormatString("%s%s%s%s", preface, funny_add, grey, end).getData(), shaders[4]); + DefineShaderARB(FormatString("%s%s%s%s%s", preface, landscape, alpha_mod, grey, end).getData(), shaders[5]); + DefineShaderARB(FormatString("%s%s%s%s", preface, alpha_mod, fow, end).getData(), shaders[6]); + DefineShaderARB(FormatString("%s%s%s%s", preface, funny_add, fow, end).getData(), shaders[7]); + DefineShaderARB(FormatString("%s%s%s%s%s", preface, landscape, alpha_mod, fow, end).getData(), shaders[8]); + DefineShaderARB(FormatString("%s%s%s%s%s", preface, alpha_mod, grey, fow, end).getData(), shaders[9]); + DefineShaderARB(FormatString("%s%s%s%s%s", preface, funny_add, grey, fow, end).getData(), shaders[10]); + DefineShaderARB(FormatString("%s%s%s%s%s%s", preface, landscape, alpha_mod, grey, fow, end).getData(), shaders[11]); + } + // done + return Active; +} + +bool CStdGL::InvalidateDeviceObjects() +{ + bool fSuccess=true; + // clear gamma +#ifndef USE_SDL_MAINLOOP + DisableGamma(); +#endif + // deactivate + Active=false; + // invalidate font objects + // invalidate primary surfaces + if (lines_tex) + { + glDeleteTextures(1, &lines_tex); + lines_tex = 0; + } + if (shaders[0]) + { + glDeleteProgramsARB(sizeof(shaders)/sizeof(*shaders), shaders); + shaders[0] = 0; + } + if (vbo) + { + glDeleteBuffersARB(1, &vbo); + vbo = 0; + } + return fSuccess; +} + +void CStdGL::SetTexture() +{ + glBlendFunc(GL_SRC_ALPHA, (dwBlitMode & C4GFXBLIT_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA); + if (shaders[0]) + { + glEnable(GL_FRAGMENT_PROGRAM_ARB); + if (fUseClrModMap) + { + glActiveTexture(GL_TEXTURE3); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, (*pClrModMap->GetSurface()->ppTex)->texName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glActiveTexture(GL_TEXTURE0); + } + } + glEnable(GL_TEXTURE_2D); +} + +void CStdGL::ResetTexture() +{ + // disable texturing + if (shaders[0]) + { + glDisable(GL_FRAGMENT_PROGRAM_ARB); + glActiveTexture(GL_TEXTURE3); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + } + glDisable(GL_TEXTURE_2D); +} + +bool CStdGL::EnsureAnyContext() +{ + // Make sure some context is selected + if (pCurrCtx) return true; + if (!pMainCtx) return false; + return pMainCtx->Select(); +} + +bool CStdGL::Error(const char *szMsg) +{ +#ifdef USE_WIN32_WINDOWS + DWORD err = GetLastError(); +#endif + bool r = C4Draw::Error(szMsg); +#ifdef USE_WIN32_WINDOWS + wchar_t * lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + LogF(" gl: GetLastError() = %d - %s", err, StdStrBuf(lpMsgBuf).getData()); + LocalFree(lpMsgBuf); +#endif + LogF(" gl: %s", glGetString(GL_VENDOR)); + LogF(" gl: %s", glGetString(GL_RENDERER)); + LogF(" gl: %s", glGetString(GL_VERSION)); + LogF(" gl: %s", glGetString(GL_EXTENSIONS)); + return r; +} + +bool CStdGL::CheckGLError(const char *szAtOp) +{ + GLenum err = glGetError(); + if (!err) return true; + Log(szAtOp); + switch (err) + { + case GL_INVALID_ENUM: Log("GL_INVALID_ENUM"); break; + case GL_INVALID_VALUE: Log("GL_INVALID_VALUE"); break; + case GL_INVALID_OPERATION: Log("GL_INVALID_OPERATION"); break; + case GL_STACK_OVERFLOW: Log("GL_STACK_OVERFLOW"); break; + case GL_STACK_UNDERFLOW: Log("GL_STACK_UNDERFLOW"); break; + case GL_OUT_OF_MEMORY: Log("GL_OUT_OF_MEMORY"); break; + default: Log("unknown error"); break; + } + return false; +} + +CStdGL *pGL=NULL; + +#ifdef USE_WIN32_WINDOWS +void CStdGL::TaskOut() +{ + if (pCurrCtx) pCurrCtx->Deselect(); +} +#endif + +bool CStdGL::OnResolutionChanged(unsigned int iXRes, unsigned int iYRes) +{ + // Re-create primary clipper to adapt to new size. + CreatePrimaryClipper(iXRes, iYRes); + RestoreDeviceObjects(); + return true; +} + +void CStdGL::Default() +{ + C4Draw::Default(); + pCurrCtx = NULL; + iPixelFormat=0; + sfcFmt=0; + iClrDpt=0; +} + +#endif // USE_CONSOLE diff --git a/src/platform/StdGL.h b/src/graphics/C4DrawGL.h similarity index 80% rename from src/platform/StdGL.h rename to src/graphics/C4DrawGL.h index 2e30b5ab8..a4ac9f453 100644 --- a/src/platform/StdGL.h +++ b/src/graphics/C4DrawGL.h @@ -1,27 +1,23 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2006 Sven Eberhardt - * Copyright (c) 2004-2007 Günther Brammer - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* OpenGL implementation of NewGfx */ -#if !defined(INC_StdGL) && defined(USE_GL) + +#if !defined(INC_StdGL) && !defined(USE_CONSOLE) #define INC_StdGL #ifdef _WIN32 @@ -30,16 +26,22 @@ #include #if defined(__APPLE__) +#ifdef USE_COCOA +#import "ObjectiveCAssociated.h" +#endif #include #else #include #endif -#include +#include class C4Window; // one OpenGL context class CStdGLCtx +#ifdef USE_COCOA + : public ObjectiveCAssociated +#endif { public: CStdGLCtx(); // ctor @@ -54,10 +56,6 @@ public: bool Init(C4Window * pWindow, C4AbstractApp *pApp); #endif -#ifdef USE_COCOA - /*NSOpenGLContext*/void* GetNativeCtx(); -#endif - bool Select(bool verbose = false); // select this context void Deselect(); // select this context @@ -74,8 +72,6 @@ protected: static bool InitGlew(HINSTANCE hInst); #elif defined(USE_X11) /*GLXContext*/void * ctx; -#elif defined(USE_COCOA) - /*NSOpenGLContext*/void* ctx; #endif friend class CStdGL; @@ -106,9 +102,6 @@ public: // General void Clear(); void Default(); - virtual int GetEngine() { return 1; } // get indexed engine - void TaskOut(); // user taskswitched the app away - void TaskIn(); // user tasked back virtual bool IsOpenGL() { return true; } virtual bool IsShaderific() { return shaders[0] != 0; } virtual bool OnResolutionChanged(unsigned int iXRes, unsigned int iYRes); // reinit clipper for new resolution @@ -120,6 +113,7 @@ public: virtual CStdGLCtx *CreateContext(C4Window * pWindow, C4AbstractApp *pApp); #ifdef USE_WIN32_WINDOWS virtual CStdGLCtx *CreateContext(HWND hWindow, C4AbstractApp *pApp); + void TaskOut(); #endif // Blit void SetupTextureEnv(bool fMod2, bool landscape); @@ -130,7 +124,7 @@ public: void FillBG(DWORD dwClr=0); // Drawing void DrawQuadDw(C4Surface * sfcTarget, float *ipVtx, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4); - void PerformLine(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr); + void PerformLine(C4Surface * sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width); void PerformPix(C4Surface * sfcDest, float tx, float ty, DWORD dwCol); // device objects bool RestoreDeviceObjects(); // restore device dependent objects @@ -138,6 +132,7 @@ public: void SetTexture(); void ResetTexture(); bool DeviceReady() { return !!pMainCtx; } + bool EnsureAnyContext(); protected: bool CreatePrimarySurfaces(bool Editor, unsigned int iXRes, unsigned int iYRes, int iColorDepth, unsigned int iMonitor); diff --git a/src/platform/StdGLCtx.cpp b/src/graphics/C4DrawGLCtx.cpp similarity index 90% rename from src/platform/StdGLCtx.cpp rename to src/graphics/C4DrawGLCtx.cpp index 21f681215..1f37e50bc 100644 --- a/src/platform/StdGLCtx.cpp +++ b/src/graphics/C4DrawGLCtx.cpp @@ -1,36 +1,30 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2005-2006 Sven Eberhardt - * Copyright (c) 2005-2007, 2009-2010 Günther Brammer - * Copyright (c) 2006 Julian Raschke - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* OpenGL implementation of NewGfx, the context */ #include "C4Include.h" -#include +#include #include #include #include #include -#ifdef USE_GL +#ifndef USE_CONSOLE void CStdGLCtx::SelectCommon() { @@ -413,6 +407,8 @@ bool CStdGLCtx::PageFlip() #elif defined(USE_X11) #include +#include +#include CStdGLCtx::CStdGLCtx(): pWindow(0), ctx(0) { } @@ -421,7 +417,8 @@ void CStdGLCtx::Clear() Deselect(); if (ctx) { - glXDestroyContext(pWindow->dpy, (GLXContext)ctx); + Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); + glXDestroyContext(dpy, (GLXContext)ctx); ctx = 0; } pWindow = 0; @@ -433,12 +430,13 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) if (!pGL) return false; // store window this->pWindow = pWindow; + Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); // Create Context with sharing (if this is the main context, our ctx will be 0, so no sharing) // try direct rendering first - ctx = glXCreateContext(pWindow->dpy, (XVisualInfo*)pWindow->Info, (pGL->pMainCtx != this) ? (GLXContext)pGL->pMainCtx->ctx : 0, True); + ctx = glXCreateContext(dpy, (XVisualInfo*)pWindow->Info, (pGL->pMainCtx != this) ? (GLXContext)pGL->pMainCtx->ctx : 0, True); // without, rendering will be unacceptable slow, but that's better than nothing at all if (!ctx) - ctx = glXCreateContext(pWindow->dpy, (XVisualInfo*)pWindow->Info, pGL->pMainCtx ? (GLXContext)pGL->pMainCtx->ctx : 0, False); + ctx = glXCreateContext(dpy, (XVisualInfo*)pWindow->Info, pGL->pMainCtx ? (GLXContext)pGL->pMainCtx->ctx : 0, False); // No luck at all? if (!ctx) return pGL->Error(" gl: Unable to create context"); if (!Select(true)) return pGL->Error(" gl: Unable to select context"); @@ -460,8 +458,9 @@ bool CStdGLCtx::Select(bool verbose) if (verbose) pGL->Error(" gl: pGL is zero"); return false; } + Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); // make context current - if (!pWindow->renderwnd || !glXMakeCurrent(pWindow->dpy, pWindow->renderwnd, (GLXContext)ctx)) + if (!pWindow->renderwnd || !glXMakeCurrent(dpy, pWindow->renderwnd, (GLXContext)ctx)) { if (verbose) pGL->Error(" gl: glXMakeCurrent failed"); return false; @@ -482,7 +481,8 @@ void CStdGLCtx::Deselect() { if (pGL && pGL->pCurrCtx == this) { - glXMakeCurrent(pWindow->dpy, None, NULL); + Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); + glXMakeCurrent(dpy, None, NULL); pGL->pCurrCtx = 0; pGL->RenderTarget = 0; } @@ -493,7 +493,8 @@ bool CStdGLCtx::PageFlip() // flush GL buffer glFlush(); if (!pWindow || !pWindow->renderwnd) return false; - glXSwapBuffers(pWindow->dpy, pWindow->renderwnd); + Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); + glXSwapBuffers(dpy, pWindow->renderwnd); return true; } @@ -558,4 +559,4 @@ bool CStdGLCtx::PageFlip() #endif //USE_X11/USE_SDL_MAINLOOP -#endif // USE_GL +#endif // USE_CONSOLE diff --git a/src/platform/ClonkOpenGLView.h b/src/graphics/C4DrawGLMac.h similarity index 50% rename from src/platform/ClonkOpenGLView.h rename to src/graphics/C4DrawGLMac.h index 0c89b7276..09d7fa3d8 100644 --- a/src/platform/ClonkOpenGLView.h +++ b/src/graphics/C4DrawGLMac.h @@ -1,17 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Martin Plicht - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * "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. */ #import @@ -19,32 +18,32 @@ #ifdef USE_COCOA -@class ClonkWindowController; +@class C4WindowController; -@interface ClonkOpenGLView : NSView +extern int ActualFullscreenX, ActualFullscreenY; + +@interface C4OpenGLView : NSView { @private NSOpenGLContext* context; - CGPoint savedMouse; } -- (ClonkWindowController*) controller; +- (C4WindowController*) controller; - (void)update; - (void) enableEvents; - (void) showCursor; - (void) hideCursor; - (BOOL) shouldHideMouseCursor; - (void) setContextSurfaceBackingSizeToOwnDimensions; -- (void) centerMouse; + (CGDirectDisplayID) displayID; + (NSOpenGLContext*) mainContext; + (void) setSurfaceBackingSizeOf:(NSOpenGLContext*) context width:(int)wdt height:(int)hgt; + (NSOpenGLContext*) createContext:(CStdGLCtx*) pMainCtx; -@property(readwrite, retain) NSOpenGLContext* context; +@property(readwrite, strong) NSOpenGLContext* context; @end -@interface ClonkEditorOpenGLView: ClonkOpenGLView +@interface C4EditorOpenGLView: C4OpenGLView { } - (IBAction) grabContents:(id) sender; diff --git a/src/platform/ClonkOpenGLView.mm b/src/graphics/C4DrawGLMac.mm similarity index 69% rename from src/platform/ClonkOpenGLView.mm rename to src/graphics/C4DrawGLMac.mm index 224410176..cae0b1e82 100644 --- a/src/platform/ClonkOpenGLView.mm +++ b/src/graphics/C4DrawGLMac.mm @@ -26,25 +26,20 @@ #include #include -#include +#include -#import "ClonkOpenGLView.h" -#import "ClonkWindowController.h" -#import "ClonkMainMenuActions.h" +#import "C4DrawGLMac.h" +#import "C4WindowController.h" +#import "C4AppDelegate+MainMenuActions.h" #ifdef USE_COCOA -@implementation ClonkOpenGLView +@implementation C4OpenGLView @synthesize context; - (BOOL) isOpaque {return YES;} -- (void) dealloc -{ - [context release]; - [super dealloc]; -} - (id) initWithFrame:(NSRect)frameRect { @@ -120,12 +115,22 @@ // better not to draw anything when the game has already finished if (Application.fQuitMsgReceived) return; + // don't draw if tab-switched away from fullscreen - if ([self.controller isFullScreenConsideringLionFullScreen] && ![NSApp isActive]) - return; - if ([self.window isMiniaturized] || ![self.window isVisible]) - return; - //[self.context update]; + if ([NSApp respondsToSelector:@selector(occlusionState)]) + { + // Mavericks - query app occlusion state + if (([NSApp occlusionState] & NSApplicationOcclusionStateVisible) == 0) + return; + } + else + { + if ([self.controller isFullScreenConsideringLionFullScreen] && ![NSApp isActive]) + return; + if ([self.window isMiniaturized] || ![self.window isVisible]) + return; + } + C4Window* stdWindow = self.controller.stdWindow; if (stdWindow) @@ -134,7 +139,7 @@ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); } -- (ClonkWindowController*) controller {return (ClonkWindowController*)[self.window delegate];} +- (C4WindowController*) controller {return (C4WindowController*)[self.window delegate];} int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags) { @@ -183,75 +188,51 @@ int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags) [NSCursor hide]; } -- (void) centerMouse -{ - savedMouse = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); - // emulate MouseEvent assuming this method is called in game mode - ::C4GUI::MouseMove(C4MC_Button_None, - savedMouse.x*Config.Graphics.ResX/self.frame.size.width, - savedMouse.y*Config.Graphics.ResY/self.frame.size.height, - 0, NULL - ); -} - - (void) mouseEvent:(NSEvent*)event { DWORD flags = 0; int32_t button = mouseButtonFromEvent(event, &flags); - int actualSizeX = Application.isEditor ? self.frame.size.width : Config.Graphics.ResX; - int actualSizeY = Application.isEditor ? self.frame.size.height : Config.Graphics.ResY; - if (!Application.isEditor && lionAndBeyond() && (self.window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask) + int actualSizeX = Application.isEditor ? self.frame.size.width : ActualFullscreenX; + int actualSizeY = Application.isEditor ? self.frame.size.height : ActualFullscreenY; + CGPoint mouse = [self convertPoint:[self.window mouseLocationOutsideOfEventStream] fromView:nil]; + if (!Application.isEditor) { - //CGWarpMouseCursorPosition(CGPointMake(actualSizeX/2, actualSizeY/2)); - if (button != C4MC_Button_Wheel) - { - savedMouse.x += event.deltaX * (Config.Graphics.ResX/self.frame.size.width); - savedMouse.y -= event.deltaY * (Config.Graphics.ResY/self.frame.size.height); - } - } else - { - savedMouse = [self convertPoint:[self.window mouseLocationOutsideOfEventStream] fromView:nil]; - if (!Application.isEditor) - { - savedMouse.x *= Config.Graphics.ResX/self.frame.size.width; - savedMouse.y *= Config.Graphics.ResY/self.frame.size.height; - } + mouse.x *= ActualFullscreenX/self.frame.size.width; + mouse.y *= ActualFullscreenY/self.frame.size.height; } - savedMouse.x = fmin(fmax(savedMouse.x, 0), actualSizeX); - savedMouse.y = fmin(fmax(savedMouse.y, 0), actualSizeY); - int x = savedMouse.x; - int y = actualSizeY - savedMouse.y; + mouse.x = fmin(fmax(mouse.x, 0), actualSizeX); + mouse.y = fmin(fmax(mouse.y, 0), actualSizeY); + int x = mouse.x; + int y = actualSizeY - mouse.y; + C4Viewport* viewport = self.controller.viewport; + if (::MouseControl.IsViewport(viewport) && Console.EditCursor.GetMode() == C4CNS_ModePlay) + { + DWORD keyMask = flags; + if ([event type] == NSScrollWheel) + keyMask |= (int)[event deltaY] << 16; + ::C4GUI::MouseMove(button, x, y, keyMask, Application.isEditor ? viewport : NULL); + } + else if (viewport) { - C4Viewport* viewport = self.controller.viewport; - if (::MouseControl.IsViewport(viewport) && Console.EditCursor.GetMode() == C4CNS_ModePlay) - { - DWORD keyMask = flags; - if ([event type] == NSScrollWheel) - keyMask |= (int)[event deltaY] << 16; - ::C4GUI::MouseMove(button, x, y, keyMask, Application.isEditor ? viewport : NULL); - } - else if (viewport) + switch (button) { - switch (button) - { - case C4MC_Button_LeftDown: - Console.EditCursor.Move(viewport->ViewX+x/viewport->GetZoom(), viewport->ViewY+y/viewport->GetZoom(), 0); - Console.EditCursor.LeftButtonDown(!!(flags & MK_CONTROL)); - break; - case C4MC_Button_LeftUp: - Console.EditCursor.LeftButtonUp(); - break; - case C4MC_Button_RightDown: - Console.EditCursor.RightButtonDown(!!(flags & MK_CONTROL)); - break; - case C4MC_Button_RightUp: - Console.EditCursor.RightButtonUp(); - break; - case C4MC_Button_None: - Console.EditCursor.Move(viewport->ViewX+x/viewport->GetZoom(),viewport->ViewY+y/viewport->GetZoom(), 0); - break; - } + case C4MC_Button_LeftDown: + Console.EditCursor.Move(viewport->ViewX+x/viewport->GetZoom(), viewport->ViewY+y/viewport->GetZoom(), flags); + Console.EditCursor.LeftButtonDown(flags); + break; + case C4MC_Button_LeftUp: + Console.EditCursor.LeftButtonUp(flags); + break; + case C4MC_Button_RightDown: + Console.EditCursor.RightButtonDown(flags); + break; + case C4MC_Button_RightUp: + Console.EditCursor.RightButtonUp(flags); + break; + case C4MC_Button_None: + Console.EditCursor.Move(viewport->ViewX+x/viewport->GetZoom(),viewport->ViewY+y/viewport->GetZoom(), flags); + break; } } @@ -281,9 +262,9 @@ int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags) { // swiping left triggers going back in startup dialogs if (event.deltaX > 0) - [ClonkAppDelegate.instance simulateKeyPressed:K_LEFT]; + [C4AppDelegate.instance simulateKeyPressed:K_LEFT]; else - [ClonkAppDelegate.instance simulateKeyPressed:K_RIGHT]; + [C4AppDelegate.instance simulateKeyPressed:K_RIGHT]; } - (void)insertText:(id)insertString @@ -350,7 +331,8 @@ int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags) { for (NSString* fileName in files) { - viewport->DropFile([fileName cStringUsingEncoding:NSUTF8StringEncoding], [sender draggingLocation].x, [sender draggingLocation].y); + auto loc = NSMakePoint([sender draggingLocation].x, self.bounds.size.height - [sender draggingLocation].y); + viewport->DropFile([fileName cStringUsingEncoding:NSUTF8StringEncoding], loc.x, loc.y); } } } @@ -437,7 +419,7 @@ int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags) - (void) setContextSurfaceBackingSizeToOwnDimensions { - [ClonkOpenGLView setSurfaceBackingSizeOf:self.context width:self.frame.size.width height:self.frame.size.height]; + [C4OpenGLView setSurfaceBackingSizeOf:self.context width:self.frame.size.width height:self.frame.size.height]; } static NSOpenGLContext* MainContext; @@ -469,20 +451,17 @@ static NSOpenGLContext* MainContext; //attribs.push_back(NSOpenGLPFADoubleBuffer); attribs.push_back(NSOpenGLPFAWindow); attribs.push_back(0); - NSOpenGLPixelFormat* format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]] autorelease]; + NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; - NSOpenGLContext* result = [[NSOpenGLContext alloc] initWithFormat:format shareContext:pMainCtx ? (NSOpenGLContext*)pMainCtx->GetNativeCtx() : nil]; - [self setSurfaceBackingSizeOf:result width:Config.Graphics.ResX height:Config.Graphics.ResY]; + NSOpenGLContext* result = [[NSOpenGLContext alloc] initWithFormat:format shareContext:pMainCtx ? pMainCtx->objectiveCObject() : nil]; if (!MainContext) - { MainContext = result; - } return result; } @end -@implementation ClonkEditorOpenGLView +@implementation C4EditorOpenGLView - (void) copy:(id) sender { @@ -520,43 +499,18 @@ static NSOpenGLContext* MainContext; #pragma mark CStdGLCtx: Initialization -void* CStdGLCtx::GetNativeCtx() -{ - return ctx; -} - -CStdGLCtx::CStdGLCtx(): pWindow(0), ctx(nil) {} +CStdGLCtx::CStdGLCtx(): pWindow(0) {} void CStdGLCtx::Clear() { Deselect(); - if (ctx) - { - [(NSOpenGLContext*)ctx release]; - ctx = nil; - } + setObjectiveCObject(nil); pWindow = 0; } void C4Window::EnumerateMultiSamples(std::vector& samples) const { - [ClonkOpenGLView enumerateMultiSamples:samples]; -} - -bool C4AbstractApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen) -{ - fFullScreen &= !lionAndBeyond(); // Always false for Lion since then Lion's true(tm) Fullscreen is used - ClonkWindowController* controller = (ClonkWindowController*)pWindow->GetController(); - NSWindow* window = controller.window; - - pWindow->SetSize(iXRes, iYRes); - [controller setFullscreen:fFullScreen]; - [window setAspectRatio:[[window contentView] frame].size]; - [window center]; - if (!fFullScreen) - [window makeKeyAndOrderFront:nil]; - OnResolutionChanged(iXRes, iYRes); - return true; + [C4OpenGLView enumerateMultiSamples:samples]; } bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) @@ -567,8 +521,8 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) this->pWindow = pWindow; // Create Context with sharing (if this is the main context, our ctx will be 0, so no sharing) // try direct rendering first - NSOpenGLContext* ctx = [ClonkOpenGLView createContext:pGL->pMainCtx]; - this->ctx = (void*)ctx; + NSOpenGLContext* ctx = [C4OpenGLView createContext:pGL->pMainCtx]; + setObjectiveCObject(ctx); // No luck at all? if (!Select(true)) return pGL->Error(" gl: Unable to select context"); // init extensions @@ -579,7 +533,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) return pGL->Error(reinterpret_cast(glewGetErrorString(err))); } // set the openglview's context - ClonkWindowController* controller = (ClonkWindowController*)pWindow->GetController(); + auto controller = pWindow->objectiveCObject(); if (controller && controller.openGLView) { [controller.openGLView setContext:ctx]; @@ -591,8 +545,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) bool CStdGLCtx::Select(bool verbose) { - if (ctx) - [(NSOpenGLContext*)ctx makeCurrentContext]; + [objectiveCObject() makeCurrentContext]; SelectCommon(); // update clipper - might have been done by UpdateSize // however, the wrong size might have been assumed @@ -622,38 +575,6 @@ bool CStdGLCtx::PageFlip() return true; } -#pragma mark CStdGLCtx: Gamma +int ActualFullscreenX = 0, ActualFullscreenY = 0; -bool C4AbstractApp::ApplyGammaRamp(struct _D3DGAMMARAMP &ramp, bool fForce) -{ - CGGammaValue r[256]; - CGGammaValue g[256]; - CGGammaValue b[256]; - for (int i = 0; i < 256; i++) - { - r[i] = static_cast(ramp.red[i])/65535.0; - g[i] = static_cast(ramp.green[i])/65535.0; - b[i] = static_cast(ramp.blue[i])/65535.0; - } - CGSetDisplayTransferByTable(ClonkOpenGLView.displayID, 256, r, g, b); - return true; -} - -bool C4AbstractApp::SaveDefaultGammaRamp(_D3DGAMMARAMP &ramp) -{ - CGGammaValue r[256]; - CGGammaValue g[256]; - CGGammaValue b[256]; - uint32_t count; - CGGetDisplayTransferByTable(ClonkOpenGLView.displayID, 256, r, g, b, &count); - for (int i = 0; i < 256; i++) - { - ramp.red[i] = r[i]*65535; - ramp.green[i] = g[i]*65535; - ramp.blue[i] = b[i]*65535; - } - return true; - -} - -#endif \ No newline at end of file +#endif diff --git a/src/graphics/C4DrawMeshGL.cpp b/src/graphics/C4DrawMeshGL.cpp new file mode 100644 index 000000000..91418427c --- /dev/null +++ b/src/graphics/C4DrawMeshGL.cpp @@ -0,0 +1,1039 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, 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. + */ + +/* OpenGL implementation of Mesh Rendering */ + +#include "C4Include.h" +#include + +#include "StdMesh.h" + +#ifndef USE_CONSOLE + +namespace +{ + //////////////////////////////////////////// + // Shader code generation + // This translates the fixed function instructions in a material script + // to an equivalent fragment shader. The generated code can certainly + // be optimized more. + //////////////////////////////////////////// + StdStrBuf TextureUnitSourceToCode(int index, StdMeshMaterialTextureUnit::BlendOpSourceType source, const float manualColor[3], float manualAlpha) + { + switch(source) + { + case StdMeshMaterialTextureUnit::BOS_Current: return StdStrBuf("currentColor"); + case StdMeshMaterialTextureUnit::BOS_Texture: return FormatString("texture2D(oc_Textures[%d], texcoord)", index); + case StdMeshMaterialTextureUnit::BOS_Diffuse: return StdStrBuf("diffuse"); + case StdMeshMaterialTextureUnit::BOS_Specular: return StdStrBuf("diffuse"); // TODO: Should be specular + case StdMeshMaterialTextureUnit::BOS_PlayerColor: return StdStrBuf("vec4(oc_PlayerColor, 1.0)"); + case StdMeshMaterialTextureUnit::BOS_Manual: return FormatString("vec4(%f, %f, %f, %f)", manualColor[0], manualColor[1], manualColor[2], manualAlpha); + default: assert(false); return StdStrBuf("vec4(0.0, 0.0, 0.0, 0.0)"); + } + } + + StdStrBuf TextureUnitBlendToCode(int index, StdMeshMaterialTextureUnit::BlendOpExType blend_type, const char* source1, const char* source2, float manualFactor) + { + switch(blend_type) + { + case StdMeshMaterialTextureUnit::BOX_Source1: return StdStrBuf(source1); + case StdMeshMaterialTextureUnit::BOX_Source2: return StdStrBuf(source2); + case StdMeshMaterialTextureUnit::BOX_Modulate: return FormatString("%s * %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_ModulateX2: return FormatString("2.0 * %s * %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_ModulateX4: return FormatString("4.0 * %s * %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_Add: return FormatString("%s + %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_AddSigned: return FormatString("%s + %s - 0.5", source1, source2); + case StdMeshMaterialTextureUnit::BOX_AddSmooth: return FormatString("%s + %s - %s*%s", source1, source2, source1, source2); + case StdMeshMaterialTextureUnit::BOX_Subtract: return FormatString("%s - %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_BlendDiffuseAlpha: return FormatString("diffuse.a * %s + (1.0 - diffuse.a) * %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_BlendTextureAlpha: return FormatString("texture2D(oc_Textures[%d], texcoord).a * %s + (1.0 - texture2D(oc_Textures[%d], texcoord).a) * %s", index, source1, index, source2); + case StdMeshMaterialTextureUnit::BOX_BlendCurrentAlpha: return FormatString("currentColor.a * %s + (1.0 - currentColor.a) * %s", source1, source2); + case StdMeshMaterialTextureUnit::BOX_BlendManual: return FormatString("%f * %s + (1.0 - %f) * %s", manualFactor, source1, manualFactor, source2); + case StdMeshMaterialTextureUnit::BOX_Dotproduct: return FormatString("vec3(4.0 * dot(%s - 0.5, %s - 0.5), 4.0 * dot(%s - 0.5, %s - 0.5), 4.0 * dot(%s - 0.5, %s - 0.5));", source1, source2, source1, source2, source1, source2); // TODO: Needs special handling for the case of alpha + case StdMeshMaterialTextureUnit::BOX_BlendDiffuseColor: return FormatString("diffuse.rgb * %s + (1.0 - diffuse.rgb) * %s", source1, source2); + default: assert(false); return StdStrBuf(source1); + } + } + + StdStrBuf TextureUnitToCode(int index, const StdMeshMaterialTextureUnit& texunit) + { + StdStrBuf color_source1 = FormatString("%s.rgb", TextureUnitSourceToCode(index, texunit.ColorOpSources[0], texunit.ColorOpManualColor1, texunit.AlphaOpManualAlpha1).getData()); + StdStrBuf color_source2 = FormatString("%s.rgb", TextureUnitSourceToCode(index, texunit.ColorOpSources[1], texunit.ColorOpManualColor2, texunit.AlphaOpManualAlpha2).getData()); + StdStrBuf alpha_source1 = FormatString("%s.a", TextureUnitSourceToCode(index, texunit.AlphaOpSources[0], texunit.ColorOpManualColor1, texunit.AlphaOpManualAlpha1).getData()); + StdStrBuf alpha_source2 = FormatString("%s.a", TextureUnitSourceToCode(index, texunit.AlphaOpSources[1], texunit.ColorOpManualColor2, texunit.AlphaOpManualAlpha2).getData()); + + return FormatString("currentColor = clamp(vec4(%s, %s), 0.0, 1.0);", TextureUnitBlendToCode(index, texunit.ColorOpEx, color_source1.getData(), color_source2.getData(), texunit.ColorOpManualFactor).getData(), TextureUnitBlendToCode(index, texunit.AlphaOpEx, alpha_source1.getData(), alpha_source2.getData(), texunit.AlphaOpManualFactor).getData()); + } + + // Simple helper function + inline GLenum OgreBlendTypeToGL(StdMeshMaterialPass::SceneBlendType blend) + { + switch(blend) + { + case StdMeshMaterialPass::SB_One: return GL_ONE; + case StdMeshMaterialPass::SB_Zero: return GL_ZERO; + case StdMeshMaterialPass::SB_DestColor: return GL_DST_COLOR; + case StdMeshMaterialPass::SB_SrcColor: return GL_SRC_COLOR; + case StdMeshMaterialPass::SB_OneMinusDestColor: return GL_ONE_MINUS_DST_COLOR; + case StdMeshMaterialPass::SB_OneMinusSrcColor: return GL_ONE_MINUS_SRC_COLOR; + case StdMeshMaterialPass::SB_DestAlpha: return GL_DST_ALPHA; + case StdMeshMaterialPass::SB_SrcAlpha: return GL_SRC_ALPHA; + case StdMeshMaterialPass::SB_OneMinusDestAlpha: return GL_ONE_MINUS_DST_ALPHA; + case StdMeshMaterialPass::SB_OneMinusSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA; + default: assert(false); return GL_ZERO; + } + } +} // anonymous namespace + +class C4DrawMeshGLShader: public StdMeshMaterialPass::Shader +{ +public: + C4DrawMeshGLShader(const StdMeshMaterialPass& pass); + virtual ~C4DrawMeshGLShader(); + + class Error + { + public: + Error(const StdStrBuf& buf): Message(buf) {} + StdCopyStrBuf Message; + }; + + class ShaderObject + { + friend class C4DrawMeshGLShader; + public: + ShaderObject(GLint shader_type); + ~ShaderObject(); + + void Load(const char* code); + private: + GLuint Shader; + }; + + GLuint Program; + + GLint TexturesLocation; + GLint PlayerColorLocation; + GLint ColorModulationLocation; + GLint Mod2Location; +}; + +C4DrawMeshGLShader::ShaderObject::ShaderObject(GLint shader_type) +{ + Shader = glCreateShaderObjectARB(shader_type); + if(!Shader) throw Error(StdStrBuf("Failed to create shader")); +} + +C4DrawMeshGLShader::ShaderObject::~ShaderObject() +{ + glDeleteObjectARB(Shader); +} + +void C4DrawMeshGLShader::ShaderObject::Load(const char* code) +{ + glShaderSourceARB(Shader, 1, &code, NULL); + glCompileShaderARB(Shader); + + GLint compile_status; + glGetObjectParameterivARB(Shader, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status); + if(compile_status != GL_TRUE) + { + GLint shader_type; + glGetObjectParameterivARB(Shader, GL_OBJECT_SUBTYPE_ARB, &shader_type); + const char* shader_type_str; + switch(shader_type) + { + case GL_VERTEX_SHADER_ARB: shader_type_str = "vertex"; break; + case GL_FRAGMENT_SHADER_ARB: shader_type_str = "fragment"; break; + //case GL_GEOMETRY_SHADER_ARB: shader_type_str = "geometry"; break; + default: assert(false); break; + } + + GLint length; + glGetObjectParameterivARB(Shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); + if(length > 0) + { + std::vector error_message(length); + glGetInfoLogARB(Shader, length, NULL, &error_message[0]); + throw Error(FormatString("Failed to compile %s shader: %s", shader_type_str, &error_message[0])); + } + else + { + throw Error(FormatString("Failed to compile %s shader", shader_type_str)); + } + } +} + +C4DrawMeshGLShader::C4DrawMeshGLShader(const StdMeshMaterialPass& pass) +{ + ShaderObject FragmentShader(GL_FRAGMENT_SHADER_ARB); + ShaderObject VertexShader(GL_VERTEX_SHADER_ARB); + + VertexShader.Load( + "varying vec4 diffuse;" + "varying vec2 texcoord;" + "void main()" + "{" + " vec3 normal = normalize(gl_NormalMatrix * gl_Normal);" // TODO: Do we need to normalize? I think we enable GL_NORMALIZE in cases we have to... + " vec3 lightDir = normalize(gl_LightSource[0].position.xyz);" // TODO: Do we need to normalize? + " diffuse = clamp(gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal, lightDir)), 0.0, 1.0);" + " texcoord = gl_MultiTexCoord0.xy;" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;" + "}" + ); + + // Produce the fragment shader... first we create one code fragment for each + // texture unit, and we count the number of active textures, i.e. texture + // units that actually use a texture. + unsigned int texIndex = 0; + StdStrBuf textureUnitCode(""); + for(unsigned int i = 0; i < pass.TextureUnits.size(); ++i) + { + const StdMeshMaterialTextureUnit& texunit = pass.TextureUnits[i]; + textureUnitCode.Append(TextureUnitToCode(texIndex, texunit)); + + if(texunit.HasTexture()) + ++texIndex; + } + + FragmentShader.Load( + FormatString( + "varying vec4 diffuse;" + "varying vec2 texcoord;" + "%s" // Texture units with active textures, only if >0 texture units + "uniform vec3 oc_PlayerColor;" + "uniform vec4 oc_ColorModulation;" + "uniform int oc_Mod2;" + "void main()" + "{" + " vec4 currentColor = diffuse;" + " %s" + " if(oc_Mod2 != 0)" + " gl_FragColor = clamp(2.0 * currentColor * oc_ColorModulation - 0.5, 0.0, 1.0);" + " else" + " gl_FragColor = currentColor * oc_ColorModulation;" + "}", + ((texIndex > 0) ? FormatString("uniform sampler2D oc_Textures[%d];", texIndex).getData() : ""), + textureUnitCode.getData() + ).getData() + ); + + Program = glCreateProgramObjectARB(); + glAttachObjectARB(Program, VertexShader.Shader); + glAttachObjectARB(Program, FragmentShader.Shader); + glLinkProgramARB(Program); + + GLint link_status; + glGetObjectParameterivARB(Program, GL_OBJECT_LINK_STATUS_ARB, &link_status); + if(link_status != GL_TRUE) + { + GLint length; + glGetObjectParameterivARB(Program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); + if(length > 0) + { + std::vector error_message(length); + glGetInfoLogARB(Program, length, NULL, &error_message[0]); + glDeleteObjectARB(Program); + throw Error(FormatString("Failed to link program: %s", &error_message[0])); + } + else + { + glDeleteObjectARB(Program); + throw Error(StdStrBuf("Failed to link program")); + } + } + + TexturesLocation = glGetUniformLocationARB(Program, "oc_Textures"); + PlayerColorLocation = glGetUniformLocationARB(Program, "oc_PlayerColor"); + ColorModulationLocation = glGetUniformLocationARB(Program, "oc_ColorModulation"); + Mod2Location = glGetUniformLocationARB(Program, "oc_Mod2"); +} + +C4DrawMeshGLShader::~C4DrawMeshGLShader() +{ + glDeleteObjectARB(Program); +} + +bool CStdGL::PrepareMaterial(StdMeshMaterial& mat) +{ + // TODO: If a technique is not available, show an error message what the problem is + + // select context, if not already done + if (!pCurrCtx) return false; + + for (unsigned int i = 0; i < mat.Techniques.size(); ++i) + { + StdMeshMaterialTechnique& technique = mat.Techniques[i]; + technique.Available = true; + for (unsigned int j = 0; j < technique.Passes.size(); ++j) + { + StdMeshMaterialPass& pass = technique.Passes[j]; + + GLint max_texture_units; + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_units); + assert(max_texture_units >= 1); + + unsigned int active_texture_units = 0; + for(unsigned int k = 0; k < pass.TextureUnits.size(); ++k) + if(pass.TextureUnits[k].HasTexture()) + ++active_texture_units; + + if (active_texture_units > static_cast(max_texture_units)) + technique.Available = false; + + for (unsigned int k = 0; k < pass.TextureUnits.size(); ++k) + { + StdMeshMaterialTextureUnit& texunit = pass.TextureUnits[k]; + for (unsigned int l = 0; l < texunit.GetNumTextures(); ++l) + { + const C4TexRef& texture = texunit.GetTexture(l); + glBindTexture(GL_TEXTURE_2D, texture.texName); + switch (texunit.TexAddressMode) + { + case StdMeshMaterialTextureUnit::AM_Wrap: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case StdMeshMaterialTextureUnit::AM_Border: + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, texunit.TexBorderColor); + // fallthrough + case StdMeshMaterialTextureUnit::AM_Clamp: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + case StdMeshMaterialTextureUnit::AM_Mirror: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + break; + } + + if (texunit.Filtering[2] == StdMeshMaterialTextureUnit::F_Point || + texunit.Filtering[2] == StdMeshMaterialTextureUnit::F_Linear) + { + // If mipmapping is enabled, then autogenerate mipmap data. + // In OGRE this is deactivated for several OS/graphics card + // combinations because of known bugs... + + // This does work for me, but requires re-upload of texture data... + // so the proper way would be to set this prior to the initial + // upload, which would be the same place where we could also use + // gluBuild2DMipmaps. GL_GENERATE_MIPMAP is probably still more + // efficient though. + + // Disabled for now, until we find a better place for this (C4TexRef?) +#if 0 + if (GLEW_VERSION_1_4) + { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); const_cast(&texunit.GetTexture())->Lock(); const_cast(&texunit.GetTexture())->Unlock(); } + else + technique.Available = false; +#else + // Disable mipmap for now as a workaround. + texunit.Filtering[2] = StdMeshMaterialTextureUnit::F_None; +#endif + } + + switch (texunit.Filtering[0]) // min + { + case StdMeshMaterialTextureUnit::F_None: + technique.Available = false; + break; + case StdMeshMaterialTextureUnit::F_Point: + switch (texunit.Filtering[2]) // mip + { + case StdMeshMaterialTextureUnit::F_None: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + break; + case StdMeshMaterialTextureUnit::F_Point: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + break; + case StdMeshMaterialTextureUnit::F_Linear: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + break; + case StdMeshMaterialTextureUnit::F_Anisotropic: + technique.Available = false; // invalid + break; + } + break; + case StdMeshMaterialTextureUnit::F_Linear: + switch (texunit.Filtering[2]) // mip + { + case StdMeshMaterialTextureUnit::F_None: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + break; + case StdMeshMaterialTextureUnit::F_Point: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + break; + case StdMeshMaterialTextureUnit::F_Linear: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + break; + case StdMeshMaterialTextureUnit::F_Anisotropic: + technique.Available = false; // invalid + break; + } + break; + case StdMeshMaterialTextureUnit::F_Anisotropic: + // unsupported + technique.Available = false; + break; + } + + switch (texunit.Filtering[1]) // max + { + case StdMeshMaterialTextureUnit::F_None: + technique.Available = false; // invalid + break; + case StdMeshMaterialTextureUnit::F_Point: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case StdMeshMaterialTextureUnit::F_Linear: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + case StdMeshMaterialTextureUnit::F_Anisotropic: + // unsupported + technique.Available = false; + break; + } + + for (unsigned int m = 0; m < texunit.Transformations.size(); ++m) + { + StdMeshMaterialTextureUnit::Transformation& trans = texunit.Transformations[m]; + if (trans.TransformType == StdMeshMaterialTextureUnit::Transformation::T_TRANSFORM) + { + // transpose so we can directly pass it to glMultMatrixf + std::swap(trans.Transform.M[ 1], trans.Transform.M[ 4]); + std::swap(trans.Transform.M[ 2], trans.Transform.M[ 8]); + std::swap(trans.Transform.M[ 3], trans.Transform.M[12]); + std::swap(trans.Transform.M[ 6], trans.Transform.M[ 9]); + std::swap(trans.Transform.M[ 7], trans.Transform.M[13]); + std::swap(trans.Transform.M[11], trans.Transform.M[14]); + } + } + } // loop over textures + } // loop over texture units + + try + { + assert(pass.Program == NULL); + pass.Program = new C4DrawMeshGLShader(pass); + } + catch(const C4DrawMeshGLShader::Error& error) + { + technique.Available = false; + LogF("Failed to compile shader: %s\n", error.Message.getData()); + } + } + + if (technique.Available && mat.BestTechniqueIndex == -1) + mat.BestTechniqueIndex = i; + } + + return mat.BestTechniqueIndex != -1; +} + +namespace +{ + void RenderSubMeshImpl(const StdMeshInstance& mesh_instance, const StdSubMeshInstance& instance, DWORD dwModClr, DWORD dwBlitMode, DWORD dwPlayerColor, bool parity) + { + const StdMeshMaterial& material = instance.GetMaterial(); + assert(material.BestTechniqueIndex != -1); + const StdMeshMaterialTechnique& technique = material.Techniques[material.BestTechniqueIndex]; + const StdMeshVertex* vertices = instance.GetVertices().empty() ? &mesh_instance.GetSharedVertices()[0] : &instance.GetVertices()[0]; + + // Render each pass + for (unsigned int i = 0; i < technique.Passes.size(); ++i) + { + const StdMeshMaterialPass& pass = technique.Passes[i]; + + if(!pass.DepthCheck) + glDisable(GL_DEPTH_TEST); + + glDepthMask(pass.DepthWrite ? GL_TRUE : GL_FALSE); + + if(pass.AlphaToCoverage) + glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + + // Set material properties + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pass.Ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pass.Diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pass.Specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pass.Emissive); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pass.Shininess); + + // Use two-sided light model so that vertex normals are inverted for lighting calculation on back-facing polygons + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); + glFrontFace(parity ? GL_CW : GL_CCW); + + if(mesh_instance.GetCompletion() < 1.0f) + { + // Backfaces might be visible when completion is < 1.0f since front + // faces might be omitted. + glDisable(GL_CULL_FACE); + } + else + { + switch (pass.CullHardware) + { + case StdMeshMaterialPass::CH_Clockwise: + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + break; + case StdMeshMaterialPass::CH_CounterClockwise: + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + break; + case StdMeshMaterialPass::CH_None: + glDisable(GL_CULL_FACE); + break; + } + } + + // Overwrite blend mode with default alpha blending when alpha in clrmod + // is <255. This makes sure that normal non-blended meshes can have + // blending disabled in their material script (which disables expensive + // face ordering) but when they are made translucent via clrmod + if(!(dwBlitMode & C4GFXBLIT_ADDITIVE)) + { + if( ((dwModClr >> 24) & 0xff) < 0xff) // && (!(dwBlitMode & C4GFXBLIT_MOD2)) ) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else + glBlendFunc(OgreBlendTypeToGL(pass.SceneBlendFactors[0]), + OgreBlendTypeToGL(pass.SceneBlendFactors[1])); + } + else + { + if( ((dwModClr >> 24) & 0xff) < 0xff) // && (!(dwBlitMode & C4GFXBLIT_MOD2)) ) + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else + glBlendFunc(OgreBlendTypeToGL(pass.SceneBlendFactors[0]), GL_ONE); + } + + // TODO: Use vbo if available. + + glVertexPointer(3, GL_FLOAT, sizeof(StdMeshVertex), &vertices->x); + glNormalPointer(GL_FLOAT, sizeof(StdMeshVertex), &vertices->nx); + + glMatrixMode(GL_TEXTURE); + + std::vector textures; + textures.reserve(pass.TextureUnits.size()); + for (unsigned int j = 0; j < pass.TextureUnits.size(); ++j) + { + const StdMeshMaterialTextureUnit& texunit = pass.TextureUnits[j]; + const unsigned int texIndex = textures.size(); + + if (texunit.HasTexture()) + { + // Array with texture indices set for passing the textures to the + // shader -- shader cannot use fixed texture image units before OGL 4.2. + textures.push_back(texIndex); + + // Note that it is guaranteed that the GL_TEXTUREn + // constants are contiguous. + glActiveTexture(GL_TEXTURE0+texIndex); + glClientActiveTexture(GL_TEXTURE0+texIndex); + glEnable(GL_TEXTURE_2D); + + const unsigned int Phase = instance.GetTexturePhase(i, j); + glBindTexture(GL_TEXTURE_2D, texunit.GetTexture(Phase).texName); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(StdMeshVertex), &vertices->u); + + // Setup texture coordinate transform + glLoadIdentity(); + const double Position = instance.GetTexturePosition(i, j); + for (unsigned int k = 0; k < texunit.Transformations.size(); ++k) + { + const StdMeshMaterialTextureUnit::Transformation& trans = texunit.Transformations[k]; + switch (trans.TransformType) + { + case StdMeshMaterialTextureUnit::Transformation::T_SCROLL: + glTranslatef(trans.Scroll.X, trans.Scroll.Y, 0.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::T_SCROLL_ANIM: + glTranslatef(trans.GetScrollX(Position), trans.GetScrollY(Position), 0.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::T_ROTATE: + glRotatef(trans.Rotate.Angle, 0.0f, 0.0f, 1.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::T_ROTATE_ANIM: + glRotatef(trans.GetRotate(Position), 0.0f, 0.0f, 1.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::T_SCALE: + glScalef(trans.Scale.X, trans.Scale.Y, 1.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::T_TRANSFORM: + glMultMatrixf(trans.Transform.M); + break; + case StdMeshMaterialTextureUnit::Transformation::T_WAVE_XFORM: + switch (trans.WaveXForm.XForm) + { + case StdMeshMaterialTextureUnit::Transformation::XF_SCROLL_X: + glTranslatef(trans.GetWaveXForm(Position), 0.0f, 0.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::XF_SCROLL_Y: + glTranslatef(0.0f, trans.GetWaveXForm(Position), 0.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::XF_ROTATE: + glRotatef(trans.GetWaveXForm(Position), 0.0f, 0.0f, 1.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::XF_SCALE_X: + glScalef(trans.GetWaveXForm(Position), 1.0f, 1.0f); + break; + case StdMeshMaterialTextureUnit::Transformation::XF_SCALE_Y: + glScalef(1.0f, trans.GetWaveXForm(Position), 1.0f); + break; + } + break; + } + } + } + } + + glMatrixMode(GL_MODELVIEW); + + const float dwMod[4] = { + ((dwModClr >> 16) & 0xff) / 255.0f, + ((dwModClr >> 8) & 0xff) / 255.0f, + ((dwModClr ) & 0xff) / 255.0f, + ((dwModClr >> 24) & 0xff) / 255.0f + }; + + const float dwPlrClr[3] = { + ((dwPlayerColor >> 16) & 0xff) / 255.0f, + ((dwPlayerColor >> 8) & 0xff) / 255.0f, + ((dwPlayerColor ) & 0xff) / 255.0f + }; + + const int fMod2 = (dwBlitMode & C4GFXBLIT_MOD2) != 0; + + const C4DrawMeshGLShader& shader = static_cast(*pass.Program); + + glUseProgramObjectARB(shader.Program); + if(shader.TexturesLocation != -1 && !textures.empty()) glUniform1ivARB(shader.TexturesLocation, textures.size(), &textures[0]); + if(shader.PlayerColorLocation != -1) glUniform3fvARB(shader.PlayerColorLocation, 1, dwPlrClr); + if(shader.ColorModulationLocation != -1) glUniform4fvARB(shader.ColorModulationLocation, 1, dwMod); + if(shader.Mod2Location != -1) glUniform1iARB(shader.Mod2Location, fMod2); + glDrawElements(GL_TRIANGLES, instance.GetNumFaces()*3, GL_UNSIGNED_INT, instance.GetFaces()); + + // Clean-up, re-set default state + for (unsigned int j = 0; j < textures.size(); ++j) + { + glActiveTexture(GL_TEXTURE0+textures[j]); + glClientActiveTexture(GL_TEXTURE0+textures[j]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + } + + if(!pass.DepthCheck) + glEnable(GL_DEPTH_TEST); + } + } + + void RenderMeshImpl(StdMeshInstance& instance, DWORD dwModClr, DWORD dwBlitMode, DWORD dwPlayerColor, bool parity); // Needed by RenderAttachedMesh + + void RenderAttachedMesh(StdMeshInstance::AttachedMesh* attach, DWORD dwModClr, DWORD dwBlitMode, DWORD dwPlayerColor, bool parity) + { + const StdMeshMatrix& FinalTrans = attach->GetFinalTransformation(); + + // Convert matrix to column-major order, add fourth row + const float attach_trans_gl[16] = + { + FinalTrans(0,0), FinalTrans(1,0), FinalTrans(2,0), 0, + FinalTrans(0,1), FinalTrans(1,1), FinalTrans(2,1), 0, + FinalTrans(0,2), FinalTrans(1,2), FinalTrans(2,2), 0, + FinalTrans(0,3), FinalTrans(1,3), FinalTrans(2,3), 1 + }; + + // TODO: Take attach transform's parity into account + glPushMatrix(); + glMultMatrixf(attach_trans_gl); + RenderMeshImpl(*attach->Child, dwModClr, dwBlitMode, dwPlayerColor, parity); + glPopMatrix(); + +#if 0 + const StdMeshMatrix& own_trans = attach->Parent->GetBoneTransform(attach->ParentBone) + * StdMeshMatrix::Transform(attach->Parent->GetMesh().GetBone(attach->ParentBone).Transformation); + + // Draw attached bone + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor4f(1.0f, 0.0f, 0.0f, 1.0f); + GLUquadric* quad = gluNewQuadric(); + glPushMatrix(); + glTranslatef(own_trans(0,3), own_trans(1,3), own_trans(2,3)); + gluSphere(quad, 1.0f, 4, 4); + glPopMatrix(); + gluDeleteQuadric(quad); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); +#endif + } + + void RenderMeshImpl(StdMeshInstance& instance, DWORD dwModClr, DWORD dwBlitMode, DWORD dwPlayerColor, bool parity) + { + const StdMesh& mesh = instance.GetMesh(); + + // Render AM_DrawBefore attached meshes + StdMeshInstance::AttachedMeshIter attach_iter = instance.AttachedMeshesBegin(); + + for (; attach_iter != instance.AttachedMeshesEnd() && ((*attach_iter)->GetFlags() & StdMeshInstance::AM_DrawBefore); ++attach_iter) + RenderAttachedMesh(*attach_iter, dwModClr, dwBlitMode, dwPlayerColor, parity); + + GLint modes[2]; + // Check if we should draw in wireframe or normal mode + if(dwBlitMode & C4GFXBLIT_WIREFRAME) + { + // save old mode + glGetIntegerv(GL_POLYGON_MODE, modes); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + + // Render each submesh + for (unsigned int i = 0; i < mesh.GetNumSubMeshes(); ++i) + RenderSubMeshImpl(instance, instance.GetSubMesh(i), dwModClr, dwBlitMode, dwPlayerColor, parity); + + // reset old mode to prevent rendering errors + if(dwBlitMode & C4GFXBLIT_WIREFRAME) + { + glPolygonMode(GL_FRONT, modes[0]); + glPolygonMode(GL_BACK, modes[1]); + } + +#if 0 + // Draw attached bone + if (instance.GetAttachParent()) + { + const StdMeshInstance::AttachedMesh* attached = instance.GetAttachParent(); + const StdMeshMatrix& own_trans = instance.GetBoneTransform(attached->ChildBone) * StdMeshMatrix::Transform(instance.GetMesh().GetBone(attached->ChildBone).Transformation); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor4f(1.0f, 1.0f, 0.0f, 1.0f); + GLUquadric* quad = gluNewQuadric(); + glPushMatrix(); + glTranslatef(own_trans(0,3), own_trans(1,3), own_trans(2,3)); + gluSphere(quad, 1.0f, 4, 4); + glPopMatrix(); + gluDeleteQuadric(quad); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } +#endif + + // Render non-AM_DrawBefore attached meshes + for (; attach_iter != instance.AttachedMeshesEnd(); ++attach_iter) + RenderAttachedMesh(*attach_iter, dwModClr, dwBlitMode, dwPlayerColor, parity); + } + + // Apply Zoom and Transformation to the current matrix stack. Return + // parity of the transformation. + bool ApplyZoomAndTransform(float ZoomX, float ZoomY, float Zoom, C4BltTransform* pTransform) + { + // Apply zoom + glTranslatef(ZoomX, ZoomY, 0.0f); + glScalef(Zoom, Zoom, 1.0f); + glTranslatef(-ZoomX, -ZoomY, 0.0f); + + // Apply transformation + if (pTransform) + { + const GLfloat transform[16] = { pTransform->mat[0], pTransform->mat[3], 0, pTransform->mat[6], pTransform->mat[1], pTransform->mat[4], 0, pTransform->mat[7], 0, 0, 1, 0, pTransform->mat[2], pTransform->mat[5], 0, pTransform->mat[8] }; + glMultMatrixf(transform); + + // Compute parity of the transformation matrix - if parity is swapped then + // we need to cull front faces instead of back faces. + const float det = transform[0]*transform[5]*transform[15] + + transform[4]*transform[13]*transform[3] + + transform[12]*transform[1]*transform[7] + - transform[0]*transform[13]*transform[7] + - transform[4]*transform[1]*transform[15] + - transform[12]*transform[5]*transform[3]; + return det > 0; + } + + return true; + } +} + +void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, C4BltTransform* pTransform) +{ + // Field of View for perspective projection, in degrees + static const float FOV = 60.0f; + static const float TAN_FOV = tan(FOV / 2.0f / 180.0f * M_PI); + + // Convert OgreToClonk matrix to column-major order + // TODO: This must be executed after C4Draw::OgreToClonk was + // initialized - is this guaranteed at this position? + static const float OgreToClonkGL[16] = + { + C4Draw::OgreToClonk(0,0), C4Draw::OgreToClonk(1,0), C4Draw::OgreToClonk(2,0), 0, + C4Draw::OgreToClonk(0,1), C4Draw::OgreToClonk(1,1), C4Draw::OgreToClonk(2,1), 0, + C4Draw::OgreToClonk(0,2), C4Draw::OgreToClonk(1,2), C4Draw::OgreToClonk(2,2), 0, + C4Draw::OgreToClonk(0,3), C4Draw::OgreToClonk(1,3), C4Draw::OgreToClonk(2,3), 1 + }; + + static const bool OgreToClonkParity = C4Draw::OgreToClonk.Determinant() > 0.0f; + + const StdMesh& mesh = instance.GetMesh(); + + bool parity = OgreToClonkParity; + + // Convert bounding box to clonk coordinate system + // (TODO: We should cache this, not sure where though) + // TODO: Note that this does not generally work with an arbitrary transformation this way + const StdMeshBox& box = mesh.GetBoundingBox(); + StdMeshVector v1, v2; + v1.x = box.x1; v1.y = box.y1; v1.z = box.z1; + v2.x = box.x2; v2.y = box.y2; v2.z = box.z2; + v1 = OgreToClonk * v1; // TODO: Include translation + v2 = OgreToClonk * v2; // TODO: Include translation + + // Vector from origin of mesh to center of mesh + const StdMeshVector MeshCenter = (v1 + v2)/2.0f; + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_BLEND); // TODO: Shouldn't this always be enabled? - blending does not work for meshes without this though. + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); // might still be active from a previous (non-mesh-rendering) GL operation + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); // same -- we enable this individually for every texture unit in RenderSubMeshImpl + + // TODO: We ignore the additive drawing flag for meshes but instead + // set the blending mode of the corresponding material. I'm not sure + // how the two could be combined. + // TODO: Maybe they can be combined using a pixel shader which does + // ftransform() and then applies colormod, additive and mod2 + // on the result (with alpha blending). + //int iAdditive = dwBlitMode & C4GFXBLIT_ADDITIVE; + //glBlendFunc(GL_SRC_ALPHA, iAdditive ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA); + + // Set up projection matrix first. We do transform and Zoom with the + // projection matrix, so that lighting is applied to the untransformed/unzoomed + // mesh. + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + // Mesh extents + const float b = fabs(v2.x - v1.x)/2.0f; + const float h = fabs(v2.y - v1.y)/2.0f; + const float l = fabs(v2.z - v1.z)/2.0f; + + if (!fUsePerspective) + { + // Orthographic projection. The orthographic projection matrix + // is already loaded in the GL matrix stack. + + if (!ApplyZoomAndTransform(ZoomX, ZoomY, Zoom, pTransform)) + parity = !parity; + + // Scale so that the mesh fits in (tx,ty,twdt,thgt) + const float rx = -std::min(v1.x,v2.x) / fabs(v2.x - v1.x); + const float ry = -std::min(v1.y,v2.y) / fabs(v2.y - v1.y); + const float dx = tx + rx*twdt; + const float dy = ty + ry*thgt; + + // Scale so that Z coordinate is between -1 and 1, otherwise parts of + // the mesh could be clipped away by the near or far clipping plane. + // Note that this only works for the projection matrix, otherwise + // lighting is screwed up. + + // This technique might also enable us not to clear the depth buffer + // after every mesh rendering - we could simply scale the first mesh + // of the scene so that it's Z coordinate is between 0 and 1, scale + // the second mesh that it is between 1 and 2, and so on. + // This of course requires an orthogonal projection so that the + // meshes don't look distorted - if we should ever decide to use + // a perspective projection we need to think of something different. + // Take also into account that the depth is not linear but linear + // in the logarithm (if I am not mistaken), so goes as 1/z + + // Don't scale by Z extents since mesh might be transformed + // by MeshTransformation, so use GetBoundingRadius to be safe. + // Note this still fails if mesh is scaled in Z direction or + // there are attached meshes. + const float scz = 1.0/(mesh.GetBoundingRadius()); + + glTranslatef(dx, dy, 0.0f); + glScalef(1.0f, 1.0f, scz); + } + else + { + // Perspective projection. We need current viewport size. + const int iWdt=Min(iClipX2, RenderTarget->Wdt-1)-iClipX1+1; + const int iHgt=Min(iClipY2, RenderTarget->Hgt-1)-iClipY1+1; + + // Get away with orthographic projection matrix currently loaded + glLoadIdentity(); + + // Back to GL device coordinates + glTranslatef(-1.0f, 1.0f, 0.0f); + glScalef(2.0f/iWdt, -2.0f/iHgt, 1.0f); + + glTranslatef(-iClipX1, -iClipY1, 0.0f); + if (!ApplyZoomAndTransform(ZoomX, ZoomY, Zoom, pTransform)) + parity = !parity; + + // Move to target location and compensate for 1.0f aspect + float ttx = tx, tty = ty, ttwdt = twdt, tthgt = thgt; + if(twdt > thgt) + { + tty += (thgt-twdt)/2.0; + tthgt = twdt; + } + else + { + ttx += (twdt-thgt)/2.0; + ttwdt = thgt; + } + + glTranslatef(ttx, tty, 0.0f); + glScalef(((float)ttwdt)/iWdt, ((float)tthgt)/iHgt, 1.0f); + + // Return to Clonk coordinate frame + glScalef(iWdt/2.0, -iHgt/2.0, 1.0f); + glTranslatef(1.0f, -1.0f, 0.0f); + + // Fix for the case when we have a non-square target + const float ta = twdt / thgt; + const float ma = b / h; + if(ta <= 1 && ta/ma <= 1) + glScalef(std::max(ta, ta/ma), std::max(ta, ta/ma), 1.0f); + else if(ta >= 1 && ta/ma >= 1) + glScalef(std::max(1.0f/ta, ma/ta), std::max(1.0f/ta, ma/ta), 1.0f); + + // Apply perspective projection. After this, x and y range from + // -1 to 1, and this is mapped into tx/ty/twdt/thgt by the above code. + // Aspect is 1.0f which is accounted for above. + gluPerspective(FOV, 1.0f, 0.1f, 100.0f); + } + + // Now set up modelview matrix + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + if (!fUsePerspective) + { + // Put a light source in front of the object + const GLfloat light_position[] = { 0.0f, 0.0f, 1.0f, 0.0f }; + glLightfv(GL_LIGHT0, GL_POSITION, light_position); + glEnable(GL_LIGHT0); + } + else + { + // Setup camera position so that the mesh with uniform transformation + // fits well into a square target (without distortion). + const float EyeR = l + std::max(b/TAN_FOV, h/TAN_FOV); + const float EyeX = MeshCenter.x; + const float EyeY = MeshCenter.y; + const float EyeZ = MeshCenter.z + EyeR; + + // Up vector is unit vector in theta direction + const float UpX = 0;//-sinEyePhi * sinEyeTheta; + const float UpY = -1;//-cosEyeTheta; + const float UpZ = 0;//-cosEyePhi * sinEyeTheta; + + // Apply lighting (light source at camera position) + const GLfloat light_position[] = { EyeX, EyeY, EyeZ, 1.0f }; + glLightfv(GL_LIGHT0, GL_POSITION, light_position); + glEnable(GL_LIGHT0); + + // Fix X axis (???) + glScalef(-1.0f, 1.0f, 1.0f); + // center on mesh's bounding box, so that the mesh is really in the center of the viewport + gluLookAt(EyeX, EyeY, EyeZ, MeshCenter.x, MeshCenter.y, MeshCenter.z, UpX, UpY, UpZ); + } + + // Apply mesh transformation matrix + if (MeshTransform) + { + // Convert to column-major order + const float Matrix[16] = + { + (*MeshTransform)(0,0), (*MeshTransform)(1,0), (*MeshTransform)(2,0), 0, + (*MeshTransform)(0,1), (*MeshTransform)(1,1), (*MeshTransform)(2,1), 0, + (*MeshTransform)(0,2), (*MeshTransform)(1,2), (*MeshTransform)(2,2), 0, + (*MeshTransform)(0,3), (*MeshTransform)(1,3), (*MeshTransform)(2,3), 1 + }; + + const float det = MeshTransform->Determinant(); + if (det < 0) parity = !parity; + + // Renormalize if transformation resizes the mesh + // for lighting to be correct. + // TODO: Also needs to check for orthonormality to be correct + if (det != 1 && det != -1) + glEnable(GL_NORMALIZE); + + // Apply MeshTransformation (in the Mesh's coordinate system) + glMultMatrixf(Matrix); + } + + // Convert from Ogre to Clonk coordinate system + glMultMatrixf(OgreToClonkGL); + + DWORD dwModClr = BlitModulated ? BlitModulateClr : 0xffffffff; + + if(fUseClrModMap) + { + float x = tx + twdt/2.0f; + float y = ty + thgt/2.0f; + + if(pTransform) + pTransform->TransformPoint(x,y); + + ApplyZoom(x, y); + DWORD c = pClrModMap->GetModAt(int(x), int(y)); + ModulateClr(dwModClr, c); + } + + RenderMeshImpl(instance, dwModClr, dwBlitMode, dwPlayerColor, parity); + + glUseProgramObjectARB(0); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glActiveTexture(GL_TEXTURE0); // switch back to default + glClientActiveTexture(GL_TEXTURE0); // switch back to default + glDepthMask(GL_TRUE); + + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_NORMALIZE); + glDisable(GL_LIGHT0); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + //glDisable(GL_BLEND); + glShadeModel(GL_FLAT); + + // TODO: glScissor, so that we only clear the area the mesh covered. + glClear(GL_DEPTH_BUFFER_BIT); +} + +#endif // USE_CONSOLE diff --git a/src/graphics/C4DrawT.cpp b/src/graphics/C4DrawT.cpp new file mode 100644 index 000000000..9278ffcc9 --- /dev/null +++ b/src/graphics/C4DrawT.cpp @@ -0,0 +1,33 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, 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. + */ +#include "C4Include.h" +#include +#include + +bool CStdNoGfx::CreatePrimarySurfaces(bool Fullscreen, unsigned int iXRes, unsigned int iYRes, int iColorDepth, unsigned int iMonitor) +{ + Log("Graphics disabled."); + // Save back color depth + byByteCnt = iColorDepth / 8; + MaxTexSize = 2147483647; + return true; +} + +bool CStdNoGfx::PrepareMaterial(StdMeshMaterial& mesh) +{ + mesh.BestTechniqueIndex=0; return true; +} + diff --git a/src/platform/StdNoGfx.h b/src/graphics/C4DrawT.h similarity index 69% rename from src/platform/StdNoGfx.h rename to src/graphics/C4DrawT.h index a623c156a..67686d33a 100644 --- a/src/platform/StdNoGfx.h +++ b/src/graphics/C4DrawT.h @@ -1,37 +1,30 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2007 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Implemention of NewGfx - without gfx */ #ifndef INC_StdNoGfx #define INC_StdNoGfx -#include +#include class CStdNoGfx : public C4Draw { -public: - CStdNoGfx(); - virtual ~CStdNoGfx(); public: virtual bool BeginScene() { return true; } virtual void EndScene() { } - virtual int GetEngine() { return GFXENGN_NOGFX; } virtual void TaskOut() { } virtual void TaskIn() { } virtual bool UpdateClipper() { return true; } @@ -41,7 +34,7 @@ public: virtual void FillBG(DWORD dwClr=0) { } virtual void PerformBlt(C4BltData &, C4TexRef *, DWORD, bool, bool) { } virtual void PerformMesh(StdMeshInstance &, float, float, float, float, DWORD, C4BltTransform* pTransform) { } - virtual void PerformLine(C4Surface *, float, float, float, float, DWORD) { } + virtual void PerformLine(C4Surface *, float, float, float, float, DWORD, float) { } virtual void DrawQuadDw(C4Surface *, float *, DWORD, DWORD, DWORD, DWORD) { } virtual void PerformPix(C4Surface *, float, float, DWORD) { } virtual void SetTexture() { } diff --git a/src/lib/texture/C4Facet.cpp b/src/graphics/C4Facet.cpp similarity index 90% rename from src/lib/texture/C4Facet.cpp rename to src/graphics/C4Facet.cpp index fa12e9a98..f6bebf1e9 100644 --- a/src/lib/texture/C4Facet.cpp +++ b/src/graphics/C4Facet.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2006 Matthes Bender - * Copyright (c) 2002-2003, 2005-2006, 2008 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005-2009 Günther Brammer - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A piece of a DirectDraw surface */ @@ -26,7 +21,6 @@ #include #include -#include #include #ifdef WITH_GLIB @@ -38,7 +32,7 @@ void C4Facet::Default() Set(NULL,0,0,0,0); } -void C4Facet::Set(C4Surface * nsfc, int32_t nx, int32_t ny, int32_t nwdt, int32_t nhgt) +void C4Facet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt) { Surface=nsfc; X=nx; Y=ny; Wdt=nwdt; Hgt=nhgt; } @@ -162,20 +156,20 @@ void C4Facet::Draw(C4Facet &cgo, bool fAspect, int32_t iPhaseX, int32_t iPhaseY, if (!pDraw || !Surface || !cgo.Surface || !Wdt || !Hgt) return; // Drawing area C4Facet ccgo = cgo; - // Adjust for fixed aspect ratio + // Adjust for fixed aspect ratio (letterbox) if (fAspect) { // By height - if (100*cgo.Wdt/Wdt<100*cgo.Hgt/Hgt) + if (cgo.Wdt / Wdt < cgo.Hgt / Hgt) { - ccgo.Hgt=Hgt*cgo.Wdt/Wdt; - ccgo.Y+=(cgo.Hgt-ccgo.Hgt)/2; + ccgo.Hgt = Hgt * cgo.Wdt / Wdt; + ccgo.Y += (cgo.Hgt - ccgo.Hgt) / 2; } // By width - else if (100*cgo.Hgt/Hgt<100*cgo.Wdt/Wdt) + else if (cgo.Hgt / Hgt < cgo.Wdt / Wdt) { - ccgo.Wdt=Wdt*cgo.Hgt/Hgt; - ccgo.X+=(cgo.Wdt-ccgo.Wdt)/2; + ccgo.Wdt = Wdt * cgo.Hgt / Hgt; + ccgo.X += (cgo.Wdt - ccgo.Wdt) / 2; } } // Blit @@ -188,14 +182,31 @@ void C4Facet::Draw(C4Facet &cgo, bool fAspect, int32_t iPhaseX, int32_t iPhaseY, void C4Facet::DrawFullScreen(C4Facet &cgo) { + // Valid parameter check + if (!pDraw || !Surface || !cgo.Surface || !Wdt || !Hgt) return; + // Drawing area + C4Facet ccgo = cgo; // stretched fullscreen blit: make sure right and lower side are cleared, because this may be missed due to stretching if (cgo.Wdt > Wdt+2 || cgo.Hgt > Wdt+2) { - pDraw->DrawBoxDw(cgo.Surface, cgo.X, cgo.Y+cgo.Hgt-1, cgo.X+cgo.Wdt+2, cgo.Y+cgo.Hgt+2, 0xff000000); - pDraw->DrawBoxDw(cgo.Surface, cgo.X+cgo.Wdt-1, cgo.Y, cgo.X+cgo.Wdt+2, cgo.Y+cgo.Hgt+2, 0xff000000); + ccgo.X -= 1; ccgo.Y -= 1; + ccgo.Wdt += 2; ccgo.Hgt += 2; } - // normal blit OK - Draw(cgo, false); + // Adjust for fixed aspect ratio (crop) + // By height + if (cgo.Wdt / Wdt < cgo.Hgt / Hgt) + { + ccgo.Wdt = Wdt * cgo.Hgt / Hgt; + ccgo.X += (cgo.Wdt - ccgo.Wdt) / 2; + } + // By width + else if (cgo.Hgt / Hgt < cgo.Wdt / Wdt) + { + ccgo.Hgt = Hgt * cgo.Wdt / Wdt; + ccgo.Y += (cgo.Hgt - ccgo.Hgt) / 2; + } + // Blit + pDraw->Blit(Surface, X, Y, Wdt, Hgt, ccgo.Surface, ccgo.X, ccgo.Y, ccgo.Wdt, ccgo.Hgt); } void C4Facet::DrawClr(C4Facet &cgo, bool fAspect, DWORD dwClr) @@ -227,7 +238,7 @@ void C4Facet::DrawXR(C4Surface * sfcTarget, int32_t iX, int32_t iY, int32_t iWdt { if (!pDraw || !Surface || !sfcTarget || !Wdt || !Hgt) return; C4BltTransform rot; - rot.SetRotate(r, (float) (iX+iX+iWdt)/2, (float) (iY+iY+iHgt)/2); + rot.SetRotate(r / 100.0f, (float) (iX+iX+iWdt)/2, (float) (iY+iY+iHgt)/2); pDraw->Blit(Surface, float(X+Wdt*iSectionX),float(Y+Hgt*iSectionY),float(Wdt),float(Hgt), sfcTarget, @@ -553,7 +564,7 @@ C4Facet C4Facet::GetFraction(int32_t percentWdt, int32_t percentHgt, int32_t ali // Simple spec for square fractions if (percentHgt == 0) percentHgt = percentWdt; // Alignment - int iX = X, iY = Y, iWdt = Max(Wdt*percentWdt/100, 1), iHgt = Max(Hgt*percentHgt/100, 1); + int iX = X, iY = Y, iWdt = Max(Wdt*percentWdt/100, 1.0f), iHgt = Max(Hgt*percentHgt/100, 1.0f); if (alignX & C4FCT_Right) iX += Wdt - iWdt; if (alignX & C4FCT_Center) iX += Wdt/2 - iWdt/2; if (alignY & C4FCT_Bottom) iY += Hgt - iHgt; diff --git a/src/lib/texture/C4Facet.h b/src/graphics/C4Facet.h similarity index 87% rename from src/lib/texture/C4Facet.h rename to src/graphics/C4Facet.h index fc45f08af..ee21a7ebf 100644 --- a/src/lib/texture/C4Facet.h +++ b/src/graphics/C4Facet.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2003, 2005-2006 Sven Eberhardt - * Copyright (c) 2006 Peter Wortmann - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A piece of a DirectDraw surface */ @@ -24,7 +20,7 @@ #ifndef INC_C4Facet #define INC_C4Facet -#include +#include const int32_t C4FCT_None = 0, @@ -121,15 +117,15 @@ class C4Facet { public: C4Surface * Surface; - int32_t X,Y,Wdt,Hgt; + float X,Y,Wdt,Hgt; public: C4Facet(); - C4Facet(C4Surface * pSfc, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt) + C4Facet(C4Surface * pSfc, float iX, float iY, float iWdt, float iHgt) : Surface(pSfc), X(iX), Y(iY), Wdt(iWdt), Hgt(iHgt) { } public: void Default(); void Set(C4Surface &rSfc); - void Set(C4Surface * nsfc, int32_t nx, int32_t ny, int32_t nwdt, int32_t nhgt); + void Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt); void Set(const C4Facet &cpy) { *this=cpy; } void Expand(int32_t iLeft=0, int32_t iRight=0, int32_t iTop=0, int32_t iBottom=0); void DrawTile(C4Surface * sfcTarget, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt); diff --git a/src/lib/texture/C4FacetEx.cpp b/src/graphics/C4FacetEx.cpp similarity index 87% rename from src/lib/texture/C4FacetEx.cpp rename to src/graphics/C4FacetEx.cpp index 97ac69bc6..17a087a89 100644 --- a/src/lib/texture/C4FacetEx.cpp +++ b/src/graphics/C4FacetEx.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004, 2008 Matthes Bender - * Copyright (c) 2002, 2006, 2008 Sven Eberhardt - * Copyright (c) 2006-2009 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A facet that can hold its own surface and also target coordinates */ @@ -29,7 +25,7 @@ #include -void C4TargetFacet::Set(C4Surface * nsfc, int nx, int ny, int nwdt, int nhgt, float ntx, float nty, float Zoom) +void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom) { C4Facet::Set(nsfc, nx, ny, nwdt, nhgt); TargetX = ntx; TargetY = nty; this->Zoom = Zoom; diff --git a/src/lib/texture/C4FacetEx.h b/src/graphics/C4FacetEx.h similarity index 79% rename from src/lib/texture/C4FacetEx.h rename to src/graphics/C4FacetEx.h index fd871f07f..a471711a3 100644 --- a/src/lib/texture/C4FacetEx.h +++ b/src/graphics/C4FacetEx.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2004, 2008-2009 Sven Eberhardt - * Copyright (c) 2008-2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A facet that can hold its own surface and also target coordinates */ @@ -30,10 +27,6 @@ const int C4FCT_Full = -1, C4FCT_Height = -2, C4FCT_Width = -3; -class C4TargetRect; -class C4Surface; -class C4Rect; - class C4TargetFacet: public C4Facet { public: @@ -47,7 +40,7 @@ public: void Set(const C4Facet &cpy) { TargetX=TargetY=0; Zoom=1; C4Facet::Set(cpy); } void Set(const C4TargetFacet &cpy) { *this = cpy; } - void Set(class C4Surface *nsfc, int nx, int ny, int nwdt, int nhgt, float ntx=0, float nty=0, float Zoom=1); + void Set(class C4Surface *nsfc, float nx, float ny, float nwdt, float nhgt, float ntx=0, float nty=0, float Zoom=1); void Set(class C4Surface *nsfc, const C4Rect & r, float ntx=0, float nty=0, float Zoom=1); void DrawLineDw(int iX1, int iY1, int iX2, int iY2, uint32_t col1, uint32_t col2); // uses Target and position diff --git a/src/platform/StdFont.cpp b/src/graphics/C4FontLoader.cpp similarity index 84% rename from src/platform/StdFont.cpp rename to src/graphics/C4FontLoader.cpp index 64da6e9bd..79f36951b 100644 --- a/src/platform/StdFont.cpp +++ b/src/graphics/C4FontLoader.cpp @@ -1,36 +1,33 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2007 Sven Eberhardt - * Copyright (c) 2005-2007, 2009-2010 Günther Brammer - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2009-2010 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // text drawing facility for C4Draw -#include "C4Include.h" -#include +#include +#include "C4FontLoader.h" -#include "Standard.h" -#include -#include -#include +#ifndef USE_CONSOLE +#include +#include +#include +#include +#include #include +#include + #include #include @@ -38,14 +35,154 @@ #include #endif -#ifdef HAVE_FREETYPE #include #include FT_FREETYPE_H -#endif // HAVE_FREETYPE +#endif /* Initialization */ -#ifdef HAVE_FREETYPE +bool C4FontLoader::InitFont(CStdFont * rFont, const char *szFontName, FontType eType, int32_t iSize, C4GroupSet *pGfxGroups, bool fDoShadow) +{ +#ifdef USE_CONSOLE + return true; +#else + // safety + assert(szFontName); + if (!szFontName || !*szFontName) + { + LogFatal(FormatString("%s (\"%s\")", LoadResStr("IDS_ERR_INITFONTS"), szFontName ? szFontName : "(null)").getData()); + return false; + } + // if def has not been found, use the def as font name + // determine font def string + const char *szFontString = szFontName; + // font not assigned? + assert(*szFontString); + if (!*szFontString) + { + // invalid call or spec + LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; + } + // get font name + char FontFaceName[C4MaxName+1], FontParam[C4MaxName+1]; + SCopyUntil(szFontString, FontFaceName, ',', C4MaxName); + // is it an image file? + int32_t iDefFontSize; DWORD dwDefWeight=FW_NORMAL; + switch (eType) + { + case C4FT_Log: iDefFontSize = iSize*12/14; break; + case C4FT_MainSmall:iDefFontSize = iSize*13/14; break; + case C4FT_Main: iDefFontSize = iSize; break; + case C4FT_Caption: iDefFontSize = iSize*16/14; /*dwDefWeight = FW_MEDIUM;*/ break; + case C4FT_Title: iDefFontSize = iSize*22/14; /*dwDefWeight = FW_MEDIUM;*/ break; + default: assert(false); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call + } + // regular font name: let WinGDI or Freetype draw a font with the given parameters + // font size given? + if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) + sscanf(FontParam, "%i", &iDefFontSize); + // font weight given? + if (SCopySegment(szFontString, 2, FontParam, ',', C4MaxName)) + { + int iDefWeight; + sscanf(FontParam, "%i", &iDefWeight); + dwDefWeight = iDefWeight; + } + // check if it's already loaded from that group with that parameters + if (rFont->IsSameAs(FontFaceName, iDefFontSize, dwDefWeight)) + return true; + // it's not; so (re-)load it now! + if (rFont->IsInitialized()) + { + // reloading + rFont->Clear(); + LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iDefFontSize, dwDefWeight); + } + // check if one of the internally listed fonts should be used + const char * const extensions[] = { "ttf", "otf", "ttc", "fon", "fnt", "fot", NULL }; + char FileName[_MAX_PATH+1]; + int32_t ID; + C4Group * pGrp = pGfxGroups->FindSuitableFile(FontFaceName, extensions, FileName, &ID); + if (pGrp) + { + if (LastUsedGrpID != ID || LastUsedName != FontFaceName) + { + DestroyFont(pLastUsedFont); + pLastUsedFont = NULL; + } + if (!pLastUsedFont) + { + StdBuf Data; + if (pGrp->LoadEntry(FileName, &Data)) + { + try + { + pLastUsedFont = CreateFont(Data); + LastUsedGrpID = ID; + LastUsedName = FontFaceName; + } + catch (std::runtime_error & e) + { + LogFatal(e.what()); + pGrp = NULL; + } + } + } + } + // no internal font match? Then create one using the given face/filename (using a system font) + if (!pGrp) + { + if (LastUsedGrpID != -1 || LastUsedName != FontFaceName) + { + DestroyFont(pLastUsedFont); + pLastUsedFont = NULL; + } + if (!pLastUsedFont) + { + try + { + pLastUsedFont = CreateFont(FontFaceName); + if (!pLastUsedFont) + // no match for font face found + throw std::runtime_error(FormatString("Font face %s undefined", FontFaceName).getData()); + LastUsedGrpID = -1; + LastUsedName = FontFaceName; + } + catch (std::runtime_error & e) + { + LogFatal(e.what()); + } + } + } + if (!pLastUsedFont) + { + LogFatal(LoadResStr("IDS_ERR_INITFONTS")); + return false; + } + try + { + rFont->Init(*pLastUsedFont, FontFaceName, iDefFontSize, dwDefWeight, fDoShadow); // throws exception on error + return true; + } + catch (std::runtime_error & e) + { + LogFatal(e.what()); + LogFatal(LoadResStr("IDS_ERR_INITFONTS")); + return false; + } +#endif +} + +void C4FontLoader::Clear() +{ +#ifndef USE_CONSOLE + // delete vector font cache + DestroyFont(pLastUsedFont); + pLastUsedFont = NULL; +#endif +} + +#ifndef USE_CONSOLE class CStdVectorFont { FT_Library library; @@ -54,7 +191,7 @@ class CStdVectorFont public: CStdVectorFont(const char * FontFaceName): RefCnt(1) { -#if defined(_WIN32) && defined(HAVE_FREETYPE) +#if defined(_WIN32) // Win32 using freetype: Load TrueType-data from WinGDI into Data-buffer to be used by FreeType bool fSuccess = false; HDC hDC = ::CreateCompatibleDC(NULL); @@ -123,37 +260,28 @@ public: int RefCnt; }; -CStdVectorFont * CStdFont::CreateFont(const char *szFaceName) +CStdVectorFont * C4FontLoader::CreateFont(const char *szFaceName) { return new CStdVectorFont(szFaceName); } -CStdVectorFont * CStdFont::CreateFont(StdBuf & Data) +CStdVectorFont * C4FontLoader::CreateFont(StdBuf & Data) { return new CStdVectorFont(Data); } -void CStdFont::DestroyFont(CStdVectorFont * pFont) +void C4FontLoader::DestroyFont(CStdVectorFont * pFont) { if (!pFont) return; --(pFont->RefCnt); if (!pFont->RefCnt) delete pFont; } -#else -CStdVectorFont * CStdFont::CreateFont(StdBuf & Data) -{ - return 0; -} -CStdVectorFont * CStdFont::CreateFont(const char *szFaceName) -{ - return 0; -} -void CStdFont::DestroyFont(CStdVectorFont * pFont) -{ -} #endif +C4FontLoader FontLoader; + CStdFont::CStdFont() { +#ifndef USE_CONSOLE // set default values psfcFontData = NULL; sfcCurrent = NULL; @@ -169,11 +297,11 @@ CStdFont::CStdFont() *szFontName=0; id=0; pCustomImages=NULL; -#if defined HAVE_FREETYPE pVectorFont = NULL; #endif } +#ifndef USE_CONSOLE bool CStdFont::AddSurface() { // add new surface as render target; copy old ones @@ -214,7 +342,6 @@ bool CStdFont::CheckRenderedCharSpace(uint32_t iCharWdt, uint32_t iCharHgt) bool CStdFont::AddRenderedChar(uint32_t dwChar, C4Facet *pfctTarget) { -#if defined HAVE_FREETYPE if (!pVectorFont) return false; // Freetype character rendering FT_Set_Pixel_Sizes(*pVectorFont, dwDefFontHeight, dwDefFontHeight); @@ -291,7 +418,6 @@ bool CStdFont::AddRenderedChar(uint32_t dwChar, C4Facet *pfctTarget) sfcCurrent->Unlock(); // Save the position of the glyph for the rendering code pfctTarget->Set(sfcCurrent, iCurrentSfcX, iCurrentSfcY, width, iGfxLineHgt); -#endif // end of freetype rendering - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // advance texture position iCurrentSfcX += pfctTarget->Wdt; @@ -307,9 +433,11 @@ C4Facet &CStdFont::GetUnicodeCharacterFacet(uint32_t c) // rendering might have failed, in which case rFacet remains empty. Should be OK; char won't be printed then return rFacet; } +#endif void CStdFont::Init(CStdVectorFont & VectorFont, const char *font_face_name, DWORD dwHeight, DWORD dwFontWeight, bool fDoShadow) { +#ifndef USE_CONSOLE // clear previous Clear(); // set values @@ -332,8 +460,6 @@ void CStdFont::Init(CStdVectorFont & VectorFont, const char *font_face_name, DWO throw std::runtime_error(std::string("Cannot create surface (") + szFontName + ")"); } -#if defined HAVE_FREETYPE - // Store vector font pVectorFont = &VectorFont; ++(pVectorFont->RefCnt); @@ -341,9 +467,6 @@ void CStdFont::Init(CStdVectorFont & VectorFont, const char *font_face_name, DWO // FIXME: use bbox or dynamically determined line heights here iLineHgt = (VectorFont->ascender - VectorFont->descender) * dwHeight / VectorFont->units_per_EM; iGfxLineHgt = iLineHgt + fDoShadow; // vertical shadow -#else - throw std::runtime_error("You have a engine without Truetype support."); -#endif // HAVE_FREETYPE // loop through all ASCII printable characters and prepare them // Non-ASCII Unicode characters will be created on the fly @@ -370,14 +493,15 @@ void CStdFont::Init(CStdVectorFont & VectorFont, const char *font_face_name, DWO StdStrBuf pngfilename = FormatString("%s%u%s_%d.png",szFontName,static_cast(dwHeight),fDoShadow ? "_shadow" : "",i); psfcFontData[i]->SavePNG(pngfilename.getData(), true, false, false); } +#endif } void CStdFont::Clear() { -#if defined HAVE_FREETYPE - DestroyFont(pVectorFont); +#ifndef USE_CONSOLE + FontLoader.DestroyFont(pVectorFont); pVectorFont = NULL; -#endif + // clear font sfcs if (psfcFontData) { @@ -399,6 +523,7 @@ void CStdFont::Clear() // font not yet initialized *szFontName=0; id=0; +#endif } /* Text size measurement */ @@ -407,6 +532,9 @@ bool CStdFont::GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, boo // safety if (!szText) return false; assert(IsValidUtf8(szText)); +#ifdef USE_CONSOLE + rsx = rsy = 0; +#else // keep track of each row's size int iRowWdt=0,iWdt=0,iHgt=iLineHgt; // ignore any markup @@ -453,11 +581,15 @@ bool CStdFont::GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, boo // store output rsx=iWdt; rsy=iHgt; // done, success +#endif return true; } int CStdFont::BreakMessage(const char *szMsg, int iWdt, char *szOut, int iMaxOutLen, bool fCheckMarkup, float fZoom) { +#ifdef USE_CONSOLE + return 0; +#else // 2do: Implement this in terms of StdStrBuf-version // note iMaxOutLen does not include terminating null character // safety @@ -606,10 +738,14 @@ int CStdFont::BreakMessage(const char *szMsg, int iWdt, char *szOut, int iMaxOut } // return text height return iHgt; +#endif } int CStdFont::BreakMessage(const char *szMsg, int iWdt, StdStrBuf *pOut, bool fCheckMarkup, float fZoom) { +#ifdef USE_CONSOLE + return 0; +#else // safety if (!szMsg || !pOut) return 0; pOut->Clear(); @@ -732,12 +868,16 @@ int CStdFont::BreakMessage(const char *szMsg, int iWdt, StdStrBuf *pOut, bool fC pOut->Append(szLastPos, szPos - szLastPos); // return text height return iHgt; +#endif } // get message break and pos after message break // 2do: Function not ready for UTF-8, markup or inline images. Remove its usage using standardized BreakMessage int CStdFont::GetMessageBreak(const char *szMsg, const char **ppNewPos, int iBreakWidth, float fZoom) { +#ifdef USE_CONSOLE + *ppNewPos = szMsg; return 0; +#else // safety if (!szMsg || !*szMsg) { *ppNewPos = szMsg; return 0; } const char *szPos = szMsg; unsigned char c; @@ -780,6 +920,7 @@ int CStdFont::GetMessageBreak(const char *szMsg, const char **ppNewPos, int iBre if (*szPos2 == ' ') ++*ppNewPos; // return output string length return szPos2 - szMsg; +#endif } @@ -790,6 +931,7 @@ int CStdFont::GetMessageBreak(const char *szMsg, const char **ppNewPos, int iBre void CStdFont::DrawText(C4Surface * sfcDest, float iX, float iY, DWORD dwColor, const char *szText, DWORD dwFlags, C4Markup &Markup, float fZoom) { +#ifndef USE_CONSOLE assert(IsValidUtf8(szText)); C4DrawTransform bt, *pbt=NULL; // set blit color @@ -906,10 +1048,14 @@ void CStdFont::DrawText(C4Surface * sfcDest, float iX, float iY, DWORD dwColor, pDraw->ActivateBlitModulation(dwOldModClr); else pDraw->DeactivateBlitModulation(); +#endif } bool CStdFont::GetFontImageSize(const char* szTag, int& width, int& height) const { +#ifdef USE_CONSOLE + width = height = 0; +#else const float aspect = pCustomImages ? pCustomImages->GetFontImageAspect(szTag) : -1.0f; // aspect < 0 means there is no such image @@ -927,6 +1073,7 @@ bool CStdFont::GetFontImageSize(const char* szTag, int& width, int& height) cons width = height;//static_cast(width*scale + 0.5f); height = static_cast(height*scale + 0.5f); } +#endif return true; } diff --git a/src/platform/StdFont.h b/src/graphics/C4FontLoader.h similarity index 68% rename from src/platform/StdFont.h rename to src/graphics/C4FontLoader.h index 8d0af57db..0bb919b8e 100644 --- a/src/platform/StdFont.h +++ b/src/graphics/C4FontLoader.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2004, 2007 Sven Eberhardt - * Copyright (c) 2005, 2007 Günther Brammer - * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // text drawing facility for C4Draw @@ -45,6 +42,40 @@ class C4Markup; class CStdVectorFont; +// font loader +class C4FontLoader +{ +public: + // enum of different fonts used in the clonk engine + enum FontType { C4FT_Log, C4FT_MainSmall, C4FT_Main, C4FT_Caption, C4FT_Title }; + + C4FontLoader() +#ifndef USE_CONSOLE + : pLastUsedFont(NULL), LastUsedGrpID(0) +#endif + { } // ctor + ~C4FontLoader() { Clear(); } // dtor + + void Clear(); // clear loaded fonts + // init a font class of the given type + // iSize is always the size of the normal font, which is adjusted for larger (title) and smaller (log) font types + bool InitFont(CStdFont * Font, const char *szFontName, FontType eType, int32_t iSize, C4GroupSet *pGfxGroups, bool fDoShadow=true); + +protected: +#ifndef USE_CONSOLE + CStdVectorFont * pLastUsedFont; // cache + StdCopyStrBuf LastUsedName; + int32_t LastUsedGrpID; + + CStdVectorFont * CreateFont(StdBuf & Data); + CStdVectorFont * CreateFont(const char *szFaceName); + void DestroyFont(CStdVectorFont * pFont); + friend class CStdFont; +#endif +}; + +extern C4FontLoader FontLoader; + class CStdFont { public: @@ -60,13 +91,10 @@ public: virtual ~CustomImages() { } }; - static CStdVectorFont * CreateFont(StdBuf & Data); - static CStdVectorFont * CreateFont(const char *szFaceName); - static void DestroyFont(CStdVectorFont * pFont); -public: int id; // used by the engine to keep track of where the font came from protected: +#ifndef USE_CONSOLE DWORD dwDefFontHeight; // configured font size (in points) char szFontName[80+1]; // used font name (or surface file name) @@ -88,14 +116,7 @@ protected: CustomImages *pCustomImages; // callback class for custom images -#if defined _WIN32 && !(defined HAVE_FREETYPE) - HDC hDC; - HBITMAP hbmBitmap; - DWORD *pBitmapBits; int iBitmapSize; - HFONT hFont; -#elif (defined HAVE_FREETYPE) CStdVectorFont *pVectorFont; // class assumed to be held externally! -#endif bool AddSurface(); bool CheckRenderedCharSpace(uint32_t iCharWdt, uint32_t iCharHgt); @@ -107,16 +128,24 @@ protected: } C4Facet &GetUnicodeCharacterFacet(uint32_t c); -public: int iLineHgt; // height of one line of font (in pixels) +#endif + +public: // draw ine line of text void DrawText(C4Surface * sfcDest, float iX, float iY, DWORD dwColor, const char *szText, DWORD dwFlags, C4Markup &Markup, float fZoom); // get text size bool GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, bool fCheckMarkup = true); // get height of a line - inline int GetLineHeight() { return iLineHgt; } - // Sometimes, only the width of a text is needed + inline int GetLineHeight() const + { +#ifdef USE_CONSOLE + return 0; +#else + return iLineHgt; +#endif + } // Sometimes, only the width of a text is needed int32_t GetTextWidth(const char *szText, bool fCheckMarkup = true) { int32_t x, y; GetTextExtent(szText, x, y, fCheckMarkup); return x; } // insert line breaks into a message and return overall height - uses and regards '|' as line breaks int BreakMessage(const char *szMsg, int iWdt, char *szOut, int iMaxOutLen, bool fCheckMarkup, float fZoom=1.0f); @@ -135,17 +164,39 @@ public: void Clear(); // clear font // query whether font is initialized - bool IsInitialized() { return !!*szFontName; } + bool IsInitialized() const { +#ifdef USE_CONSOLE + return true; +#else + return !!*szFontName; +#endif + } // query whether font is already initialized with certain data - bool IsSameAsID(const char *szCFontName, int iCID, int iCIndent) - { return SEqual(szCFontName, szFontName) && iCID==id && iCIndent==-iHSpace; } - bool IsSameAs(const char *szCFontName, DWORD iCHeight, DWORD dwCWeight) - { return SEqual(szCFontName, szFontName) && !id && iCHeight==dwDefFontHeight && dwCWeight==dwWeight; } + bool IsSameAsID(const char *szCFontName, int iCID, int iCIndent) const + { +#ifdef USE_CONSOLE + return true; +#else + return SEqual(szCFontName, szFontName) && iCID==id && iCIndent==-iHSpace; +#endif + } + bool IsSameAs(const char *szCFontName, DWORD iCHeight, DWORD dwCWeight) const + { +#ifdef USE_CONSOLE + return true; +#else + return SEqual(szCFontName, szFontName) && !id && iCHeight==dwDefFontHeight && dwCWeight==dwWeight; +#endif + } // set custom image request handler void SetCustomImages(CustomImages *pHandler) - { pCustomImages = pHandler; } + { +#ifndef USE_CONSOLE + pCustomImages = pHandler; +#endif + } bool GetFontImageSize(const char* szTag, int& width, int& height) const; }; diff --git a/src/lib/texture/C4GraphicsResource.cpp b/src/graphics/C4GraphicsResource.cpp similarity index 90% rename from src/lib/texture/C4GraphicsResource.cpp rename to src/graphics/C4GraphicsResource.cpp index 8b78c6dc9..9e2514030 100644 --- a/src/lib/texture/C4GraphicsResource.cpp +++ b/src/graphics/C4GraphicsResource.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2001, 2003, 2006 Matthes Bender - * Copyright (c) 2002, 2004-2010 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005-2007, 2009-2010 Günther Brammer - * Copyright (c) 2008 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Loads all standard graphics from Graphics.ocg */ @@ -26,13 +21,13 @@ #include #include +#include #include #include #include #include -#include -#include +#include C4GraphicsResource::C4GraphicsResource(): idSfcCaption(0), idSfcButton(0), idSfcButtonD(0), idSfcScroll(0), idSfcContext(0), @@ -154,15 +149,15 @@ bool C4GraphicsResource::InitFonts() // this regards scenario-specific fonts or overloads in Extra.ocg const char *szFont; if (*Game.C4S.Head.Font) szFont = Game.C4S.Head.Font; else szFont = Config.General.RXFontName; - if (!::FontLoader.InitFont(FontRegular, szFont, C4FontLoader::C4FT_Main, Config.General.RXFontSize, &Files)) return false; + if (!::FontLoader.InitFont(&FontRegular, szFont, C4FontLoader::C4FT_Main, Config.General.RXFontSize, &Files)) return false; Game.SetInitProgress(ProgressStart); ProgressStart += ProgressIncrement; - if (!::FontLoader.InitFont(FontTiny, szFont, C4FontLoader::C4FT_Log, Config.General.RXFontSize, &Files)) return false; + if (!::FontLoader.InitFont(&FontTiny, szFont, C4FontLoader::C4FT_Log, Config.General.RXFontSize, &Files)) return false; Game.SetInitProgress(ProgressStart); ProgressStart += ProgressIncrement; - if (!::FontLoader.InitFont(FontTitle, szFont, C4FontLoader::C4FT_Title, Config.General.RXFontSize, &Files)) return false; + if (!::FontLoader.InitFont(&FontTitle, szFont, C4FontLoader::C4FT_Title, Config.General.RXFontSize, &Files)) return false; Game.SetInitProgress(ProgressStart); ProgressStart += ProgressIncrement; - if (!::FontLoader.InitFont(FontCaption, szFont, C4FontLoader::C4FT_Caption, Config.General.RXFontSize, &Files)) return false; + if (!::FontLoader.InitFont(&FontCaption, szFont, C4FontLoader::C4FT_Caption, Config.General.RXFontSize, &Files)) return false; Game.SetInitProgress(ProgressStart); ProgressStart += ProgressIncrement; - if (!::FontLoader.InitFont(FontTooltip, szFont, C4FontLoader::C4FT_Main, Config.General.RXFontSize, &Files, false)) return false; + if (!::FontLoader.InitFont(&FontTooltip, szFont, C4FontLoader::C4FT_Main, Config.General.RXFontSize, &Files, false)) return false; Game.SetInitProgress(ProgressStart); ProgressStart += ProgressIncrement; // assign def list as custom image source FontRegular.SetCustomImages(&::Definitions); @@ -471,8 +466,25 @@ bool C4GraphicsResource::ReloadResolutionDependantFiles() if(!fInitialized) return false; // reload any files that depend on the current resolution // reloads the cursor + + // Re-open the graphics files if they are not open anymore -- this + // happens when the game is running. + // Note also that at the moment there are no resolution dependent + // graphics files... + const bool hadGroupsRegistered = (idRegisteredMainGroupSetFiles != -1); + if(!hadGroupsRegistered) + { + RegisterGlobalGraphics(); + RegisterMainGroups(); + } + fctMouseCursor.idSourceGroup = 0; - return LoadCursorGfx(); + const bool result = true; + + if(!hadGroupsRegistered) + CloseFiles(); + + return result; } C4GraphicsResource GraphicsResource; diff --git a/src/lib/texture/C4GraphicsResource.h b/src/graphics/C4GraphicsResource.h similarity index 86% rename from src/lib/texture/C4GraphicsResource.h rename to src/graphics/C4GraphicsResource.h index 847e97b86..00af3cd84 100644 --- a/src/lib/texture/C4GraphicsResource.h +++ b/src/graphics/C4GraphicsResource.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2004-2005, 2007 Sven Eberhardt - * Copyright (c) 2008, 2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Loads all standard graphics from Graphics.ocg */ diff --git a/src/platform/C4Surface.cpp b/src/graphics/C4Surface.cpp similarity index 76% rename from src/platform/C4Surface.cpp rename to src/graphics/C4Surface.cpp index 63c3980bb..b67298aa6 100644 --- a/src/platform/C4Surface.cpp +++ b/src/graphics/C4Surface.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003, 2008 Matthes Bender - * Copyright (c) 2002, 2004-2008 Sven Eberhardt - * Copyright (c) 2005, 2007-2011 Günther Brammer - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2009-2010 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a wrapper class to DirectDraw surfaces @@ -28,12 +22,10 @@ #include #include #include "C4App.h" -#include +#include #include #include -#include -#include -#include +#include #include #include #include @@ -69,9 +61,8 @@ C4Surface::C4Surface(C4AbstractApp * pApp, C4Window * pWindow): fPrimary=true; this->pWindow=pWindow; // create rendering context -#ifdef USE_GL - if (pGL) - pCtx = pGL->CreateContext(pWindow, pApp); +#ifndef USE_CONSOLE + pCtx = pGL->CreateContext(pWindow, pApp); #endif // reset clipping NoClip(); @@ -94,12 +85,9 @@ void C4Surface::Default() Locked=0; Attached=false; fPrimary=false; -#ifdef USE_DIRECTX - pSfc=NULL; -#endif ppTex=NULL; pMainSfc=NULL; -#ifdef USE_GL +#ifndef USE_CONSOLE pCtx=NULL; #endif pWindow=NULL; @@ -137,11 +125,7 @@ void C4Surface::MoveFrom(C4Surface *psfcFrom) iTexSize=psfcFrom->iTexSize; iTexX=psfcFrom->iTexX; iTexY=psfcFrom->iTexY; byBytesPP=psfcFrom->byBytesPP; -#ifdef USE_DIRECTX - dwClrFormat=psfcFrom->dwClrFormat; - pSfc=psfcFrom->pSfc; -#endif -#ifdef USE_GL +#ifndef USE_CONSOLE Format=psfcFrom->Format; #endif fIsBackground = psfcFrom->fIsBackground; @@ -154,14 +138,7 @@ void C4Surface::Clear() // Undo all locks while (Locked) Unlock(); // release surface -#ifdef USE_DIRECTX - if (pD3D) - { - if (pSfc) pSfc->Release(); - } - pSfc=NULL; -#endif -#ifdef USE_GL +#ifndef USE_CONSOLE if (pCtx) { delete pCtx; @@ -179,14 +156,7 @@ void C4Surface::Clear() bool C4Surface::IsRenderTarget() { // primary is always OK... - return fPrimary - // other surfaces may be used as render targets, if offscreen rendertargets are not disabled by config, - // or the surface is split (large sfcs) or locked (landscape) - // (only D3D for now) -#ifdef USE_DIRECTX - || (!Locked && !Config.Graphics.NoOffscreenBlits && pD3D && fIsRenderTarget) -#endif - ; + return fPrimary; } void C4Surface::NoClip() @@ -211,17 +181,9 @@ bool C4Surface::Create(int iWdt, int iHgt, bool, bool fIsRenderTarget, int MaxTe if (!pDraw->DeviceReady()) return false; // store color format that will be used -#ifdef USE_DIRECTX - if (pD3D) - dwClrFormat=pD3D->dwSurfaceType; - else +#ifndef USE_CONSOLE + Format=pGL->sfcFmt; #endif -#ifdef USE_GL - if (pGL) - Format=pGL->sfcFmt; - else -#endif - {/* nothing to do */} byBytesPP=pDraw->byByteCnt; this->fIsRenderTarget = fIsRenderTarget; // create textures @@ -253,7 +215,7 @@ namespace { int iNeedSize = Size; - #ifdef USE_GL + #ifndef USE_CONSOLE if (!pGL || !GLEW_ARB_texture_non_power_of_two) #endif { @@ -296,14 +258,6 @@ bool C4Surface::CreateTextures(int MaxTextureSize) if (fIsBackground && ppCTex) (*ppCTex)->FillBlack(); -#ifdef USE_DIRECTX - if (!(*ppCTex)->pTex && pD3D) - { - // error creating texture - return false; - } -#endif - ++ppCTex; } } @@ -317,7 +271,7 @@ bool C4Surface::CreateTextures(int MaxTextureSize) { // last texture might be smaller iNeedSize=Max(Wdt%iTexSize, Hgt%iTexSize); -#ifdef USE_GL +#ifndef USE_CONSOLE if (!pGL || !GLEW_ARB_texture_non_power_of_two) #endif { @@ -328,13 +282,6 @@ bool C4Surface::CreateTextures(int MaxTextureSize) *ppCTex = new C4TexRef(iNeedSize, fIsRenderTarget); } if (fIsBackground && ppCTex) (*ppCTex)->FillBlack(); -#ifdef USE_DIRECTX - if (!(*ppCTex)->pTex && pD3D) - { - // error creating texture - return false; - } -#endif } #endif @@ -481,32 +428,6 @@ bool C4Surface::SetAsClrByOwnerOf(C4Surface *pOfSurface) return true; } -#ifdef USE_GL -/*bool C4Surface::CreatePrimaryGLTextures() - { - if (!pGL) return false; - // primary OpenGL-surface: ensure context is selected - if (!pGL->pCurrCtx) if (!pGL->MainCtx.Select()) return false; - // create texture array - CreateTextures(); - // get from framebuffer - C4TexRef **ppTexRef = ppTex; - for (int iY=0; iYtexName); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, iX, iY, txWdt, txHgt, 0); - // next texture reference - ++ppTexRef; - } - // done, success - return true; - }*/ -#endif - bool C4Surface::UpdateSize(int wdt, int hgt) { assert(fPrimary); @@ -523,39 +444,12 @@ bool C4Surface::PageFlip(C4Rect *pSrcRt, C4Rect *pDstRt) return false; // call from gfx thread only! if (!pDraw->pApp || !pDraw->pApp->AssertMainThread()) return false; -#ifdef USE_GL - if (pGL) - return pCtx->PageFlip(); -#endif -#ifdef USE_DIRECTX - if (pD3D) - return pD3D->PageFlip(pSrcRt, pDstRt); +#ifndef USE_CONSOLE + return pCtx->PageFlip(); #endif return true; } -#ifdef USE_DIRECTX -IDirect3DSurface9 *C4Surface::GetSurface() -{ - // direct surface? - if (pSfc) - { - pSfc->AddRef(); - return pSfc; - } - // surface by texture? - if (fIsRenderTarget && ppTex) - { - IDirect3DTexture9 *pTex = (*ppTex)->pTex; - IDirect3DSurface9 *pSfcResult=NULL; - if (pTex) pTex->GetSurfaceLevel(0, &pSfcResult); - return pSfcResult; - } - // split surfaces: Won't work; we're no render target anyway - return NULL; -} -#endif //USE_DIRECTX - bool C4Surface::ReadBMP(CStdStream &hGroup) { int lcnt; @@ -694,8 +588,8 @@ bool C4Surface::SavePNG(const char *szFilename, bool fSaveAlpha, bool fApplyGamm C4Surface *pMainSfcBackup = NULL; if (fSaveOverlayOnly) { pMainSfcBackup=pMainSfc; pMainSfc=NULL; } -#ifdef USE_GL - if (fPrimary && pGL) +#ifndef USE_CONSOLE + if (fPrimary) { // Take shortcut. FIXME: Check Endian for (int y = 0; y < Hgt; ++y) @@ -751,37 +645,9 @@ bool C4Surface::Lock() { // lock main sfc if (pMainSfc) if (!pMainSfc->Lock()) return false; - // not yet locked? - if (!Locked) - { - if (fPrimary) - { -#ifdef USE_DIRECTX - if (pD3D) - { - D3DLOCKED_RECT lock; - // locking primary - if (!pSfc) return false; - // lock it - if (pSfc->LockRect(&lock, NULL, 0) != D3D_OK) - return false; - pDraw->LockingPrimary(); - // store pitch and pointer - PrimarySurfaceLockPitch=lock.Pitch; - PrimarySurfaceLockBits=(BYTE*) lock.pBits; - } -#endif //USE_DIRECTX - - // OpenGL: - // cannot really lock primary surface, but Get/SetPix will emulate it - } - else - { - if (!ppTex) return false; - // lock texture - // textures will be locked when needed - } - } + // lock texture + if (!Locked && !fPrimary && !ppTex) + return false; // count lock Locked++; return true; } @@ -792,32 +658,18 @@ bool C4Surface::Unlock() if (pMainSfc) pMainSfc->Unlock(); // locked? if (!Locked) return false; - // decrease lock counter; check if zeroed + // decrease lock counter; check if zeroed and unlock then Locked--; if (!Locked) { - // zeroed: unlock if (fPrimary) { -#ifdef USE_DIRECTX - if (pD3D) - { - if (!pSfc) return false; - // unlocking primary? - if (pSfc->UnlockRect() != D3D_OK) - return false; - pDraw->PrimaryUnlocked(); - } - else -#endif - { - // if tex refs exist, free them - /*FreeTextures();*/ - // otherwise, emulated primary locks in OpenGL - delete[] PrimarySurfaceLockBits; - PrimarySurfaceLockBits = 0; - return true; - } + // if tex refs exist, free them + /*FreeTextures();*/ + // otherwise, emulated primary locks in OpenGL + delete[] PrimarySurfaceLockBits; + PrimarySurfaceLockBits = 0; + return true; } else { @@ -876,17 +728,14 @@ DWORD C4Surface::GetPixDw(int iX, int iY, bool fApplyModulation) // primary? if (fPrimary) { -#ifdef USE_GL - // OpenGL? - if (pGL) +#ifndef USE_CONSOLE + if (!PrimarySurfaceLockBits) { - if (!PrimarySurfaceLockBits) - { - PrimarySurfaceLockBits = new unsigned char[Wdt*Hgt*3 + 1]; - glReadPixels( 0, 0, Wdt, Hgt, GL_BGR, GL_UNSIGNED_BYTE, PrimarySurfaceLockBits); - PrimarySurfaceLockPitch = Wdt*3; - } - return * (DWORD *) (PrimarySurfaceLockBits+(Hgt-iY-1)*PrimarySurfaceLockPitch+iX*3); + PrimarySurfaceLockBits = new unsigned char[Wdt*Hgt*3 + 1]; + glReadPixels( 0, 0, Wdt, Hgt, GL_BGR, GL_UNSIGNED_BYTE, PrimarySurfaceLockBits); + PrimarySurfaceLockPitch = Wdt*3; + } + return * (DWORD *) (PrimarySurfaceLockBits+(Hgt-iY-1)*PrimarySurfaceLockPitch+iX*3); // copy content into textures /*if (!ppTex) if (!CreatePrimaryGLTextures()) return 0; @@ -898,42 +747,6 @@ DWORD C4Surface::GetPixDw(int iX, int iY, bool fApplyModulation) iPitch=pTexRef->texLock.Pitch; // get pixel return *(DWORD *)(pBuf+iY*iPitch+iX*4);*/ - } -#endif -#ifdef USE_DIRECTX - if (!PrimarySurfaceLockBits) - { - return 0; - } - else - { - // clip - if (iX<0 || iY<0 || iX>=Wdt || iY>=Hgt) return 0; - // get pixel from primary surface - WORD pix16; - switch (dwClrFormat) - { - case D3DFMT_X1R5G5B5: - // 16 bit 5-5-5 - pix16= * (WORD *) (((BYTE *) PrimarySurfaceLockBits)+iY*PrimarySurfaceLockPitch+iX*2); - return ((pix16 & 0x001f) << 3) - | ((pix16 & 0x03e0) << 6) - | ((pix16 & 0x7c00) << 9); - - case D3DFMT_R5G6B5: - // 16 bit 5-6-5 - pix16= * (WORD *) (((BYTE *) PrimarySurfaceLockBits)+iY*PrimarySurfaceLockPitch+iX*2); - return ((pix16 & 0x001f) << 3) - | ((pix16 & 0x07e0) << 5) - | ((pix16 & 0xf800) << 8); - break; - - case D3DFMT_X8R8G8B8: - // 32 bit - return * (DWORD *) (((BYTE *) PrimarySurfaceLockBits)+iY*PrimarySurfaceLockPitch+iX*4); - default: assert(false); return 0; // should not happen - } - } #endif } else @@ -1019,46 +832,11 @@ bool C4Surface::IsPixTransparent(int iX, int iY) if ((iXClipX2) || (iYClipY2)) return true; // primary? if (fPrimary) - { -#ifdef USE_GL - // OpenGL: Use OpenGL API - if (pGL) - { +#ifndef USE_CONSOLE pGL->DrawPixInt(this, iX, iY, dwClr); - } else #endif { -#ifdef USE_DIRECTX - // must be locked! - if (!Bits) return false; - // set according to pixel format - DWORD *pPix32; WORD *pPix16; - switch (dwClrFormat) - { - case D3DFMT_X1R5G5B5: - // 16 bit 5-5-5 - pPix16=(WORD *) (((BYTE *) Bits)+iY*Pitch+iX*2); - *pPix16=WORD((dwClr & 0x000000f8) >> 3) - | WORD((dwClr & 0x0000f800) >> 6) - | WORD((dwClr & 0x00f80000) >> 9); - break; - - case D3DFMT_R5G6B5: - // 16 bit 5-6-5 - pPix16=(WORD *) (((BYTE *) Bits)+iY*Pitch+iX*2); - *pPix16=WORD((dwClr & 0x000000f8) >> 3) - | WORD((dwClr & 0x0000fc00) >> 5) - | WORD((dwClr & 0x00f80000) >> 8); - break; - - case D3DFMT_X8R8G8B8: - // 32 bit - pPix32=(DWORD *) (((BYTE *) Bits)+iY*Pitch+iX*4); - *pPix32=dwClr; - break; - } -#endif } return true; } @@ -1078,11 +856,11 @@ bool C4Surface::SetPixDw(int iX, int iY, DWORD dwClr) // if color is fully transparent, ensure it's black if (dwClr>>24 == 0x00) dwClr=0x00000000; C4TexRef *pTexRef; -#ifdef USE_GL +#ifndef USE_CONSOLE // openGL: use glTexSubImage2D // This optimization was moved to LockForUpdate, as it only slows down mass updates here // Keep this code in case there is a need for fast single pixel updates again - if (0 && pGL && pGL->pCurrCtx) + if (0 && pGL->pCurrCtx) { if (!GetTexAt(&pTexRef, iX, iY)) return false; @@ -1285,10 +1063,7 @@ bool C4Surface::CopyBytes(BYTE *pImageData) C4TexRef::C4TexRef(int iSizeX, int iSizeY, bool fSingle) { // zero fields -#ifdef USE_DIRECTX - pTex=NULL; -#endif -#ifdef USE_GL +#ifndef USE_CONSOLE texName=0; #endif texLock.pBits=NULL; fIntLock=false; @@ -1302,63 +1077,32 @@ C4TexRef::C4TexRef(int iSizeX, int iSizeY, bool fSingle) if (!pDraw) return; if (!pDraw->DeviceReady()) return; // create it! -#ifdef USE_DIRECTX - if (pD3D) +#ifndef USE_CONSOLE + // OpenGL + // create mem array for texture creation + texLock.pBits = new unsigned char[iSizeX*iSizeY*pGL->byByteCnt]; + texLock.Pitch = iSizeX*pGL->byByteCnt; + memset(texLock.pBits, 0x00, texLock.Pitch*iSizeY); + // turn mem array into texture + Unlock(); +#endif + if (pDraw) { - // Direct3D - bool fRenderTarget = fSingle && !Config.Graphics.NoOffscreenBlits; - if (pD3D->lpDevice->CreateTexture(iSizeX, iSizeY, 1, fRenderTarget ? D3DUSAGE_RENDERTARGET : 0, pD3D->dwSurfaceType, fRenderTarget ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &pTex, NULL) != D3D_OK) - { - pDraw->Error("Error creating surface"); - return; - } - // empty texture - if (!Lock()) return; - FillMemory(texLock.pBits, texLock.Pitch*iSizeY, 0x00); - Unlock(); + texLock.pBits = new unsigned char[iSizeX*iSizeY*pDraw->byByteCnt]; + texLock.Pitch = iSizeX*pDraw->byByteCnt; + memset(texLock.pBits, 0x00, texLock.Pitch*iSizeY); + // Always locked + LockSize.x = LockSize.y = 0; + LockSize.Wdt = iSizeX; LockSize.Hgt = iSizeY; } - else -#endif -#ifdef USE_GL - if (pGL) - { - // OpenGL - // create mem array for texture creation - texLock.pBits = new unsigned char[iSizeX*iSizeY*pGL->byByteCnt]; - texLock.Pitch = iSizeX*pGL->byByteCnt; - memset(texLock.pBits, 0x00, texLock.Pitch*iSizeY); - // turn mem array into texture - Unlock(); - } - else -#endif - if (pDraw) - { - texLock.pBits = new unsigned char[iSizeX*iSizeY*pDraw->byByteCnt]; - texLock.Pitch = iSizeX*pDraw->byByteCnt; - memset(texLock.pBits, 0x00, texLock.Pitch*iSizeY); - // Always locked - LockSize.x = LockSize.y = 0; - LockSize.Wdt = iSizeX; LockSize.Hgt = iSizeY; - } } C4TexRef::~C4TexRef() { fIntLock=false; // free texture -#ifdef USE_DIRECTX - if (pD3D) - { - if (texLock.pBits) Unlock(); - if (pTex) pTex->Release(); - } -#endif -#ifdef USE_GL - if (pGL) - { - if (texName && pGL->pCurrCtx) glDeleteTextures(1, &texName); - } +#ifndef USE_CONSOLE + if (texName && pGL && pGL->pCurrCtx) glDeleteTextures(1, &texName); #endif if (pDraw) delete [] static_cast(texLock.pBits); texLock.pBits = 0; // remove from texture manager @@ -1382,36 +1126,15 @@ bool C4TexRef::LockForUpdate(C4Rect & rtUpdate) } } // lock -#ifdef USE_DIRECTX - if (pD3D) - { - RECT r; - r.left = rtUpdate.x; - r.top = rtUpdate.y; - r.right = rtUpdate.x + rtUpdate.Wdt; - r.bottom = rtUpdate.y + rtUpdate.Hgt; - if (pTex) - if (pTex->LockRect(0, &texLock, &r, D3DLOCK_DISCARD) == D3D_OK) - { - LockSize = rtUpdate; - return true; - } - } - else -#endif -#ifdef USE_GL - if (pGL) +#ifndef USE_CONSOLE + if (texName) { - if (texName) - { - // prepare texture data - texLock.pBits = new unsigned char[rtUpdate.Wdt * rtUpdate.Hgt * pGL->byByteCnt]; - texLock.Pitch = rtUpdate.Wdt * pGL->byByteCnt; - LockSize = rtUpdate; - return true; - } + // prepare texture data + texLock.pBits = new unsigned char[rtUpdate.Wdt * rtUpdate.Hgt * pGL->byByteCnt]; + texLock.Pitch = rtUpdate.Wdt * pGL->byByteCnt; + LockSize = rtUpdate; + return true; } - else #endif { // nothing to do @@ -1427,17 +1150,7 @@ bool C4TexRef::Lock() LockSize.Wdt = iSizeX; LockSize.Hgt = iSizeY; LockSize.x = LockSize.y = 0; // lock -#ifdef USE_DIRECTX - if (pD3D) - { - if (pTex) - if (pTex->LockRect(0, &texLock, NULL, 0) == D3D_OK) return true; - } - else -#endif -#ifdef USE_GL - if (pGL) - { +#ifndef USE_CONSOLE if (texName) { if (!pGL->pCurrCtx) return false; @@ -1448,8 +1161,6 @@ bool C4TexRef::Lock() glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, pDraw->byByteCnt == 2 ? GL_UNSIGNED_SHORT_4_4_4_4_REV : GL_UNSIGNED_INT_8_8_8_8_REV, texLock.pBits); return true; } - } - else #endif { // nothing to do @@ -1462,18 +1173,7 @@ void C4TexRef::Unlock() { // locked? if (!texLock.pBits || fIntLock) return; -#ifdef USE_DIRECTX - if (pD3D) - { - // unlock - if (pTex) pTex->UnlockRect(0); - texLock.pBits=NULL; - } - else -#endif -#ifdef USE_GL - if (pGL) - { +#ifndef USE_CONSOLE if (!pGL->pCurrCtx) { // BREAKPOINT_HERE; @@ -1503,12 +1203,7 @@ void C4TexRef::Unlock() } delete[] static_cast(texLock.pBits); texLock.pBits=NULL; // switch back to original context - } - else #endif - { - // nothing to do - } } bool C4TexRef::ClearRect(C4Rect &rtClear) @@ -1603,7 +1298,7 @@ void C4TexMgr::IntLock() if (pRef->Lock() && pRef->texLock.pBits) { pRef->fIntLock = true; -#ifdef USE_GL +#ifndef USE_CONSOLE // Release the underlying texture with GL and recreate // it on unlock, so that the texture survives // context recreation. diff --git a/src/platform/C4Surface.h b/src/graphics/C4Surface.h similarity index 78% rename from src/platform/C4Surface.h rename to src/graphics/C4Surface.h index ca75f509c..37123e35a 100644 --- a/src/platform/C4Surface.h +++ b/src/graphics/C4Surface.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2004-2005, 2008 Sven Eberhardt - * Copyright (c) 2004-2005, 2007-2011 Günther Brammer - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a wrapper class to DirectDraw surfaces @@ -29,14 +24,8 @@ #ifdef _WIN32 #include #endif -#ifdef USE_DIRECTX -#include -#undef DrawText -#else -typedef void* IDirect3DSurface9; -#endif -#ifdef USE_GL +#ifndef USE_CONSOLE #include #endif @@ -48,9 +37,10 @@ typedef void* IDirect3DSurface9; #define C4GFXBLIT_MOD2 2 // additive color modulation #define C4GFXBLIT_CLRSFC_OWNCLR 4 // do not apply global modulation to ColorByOwner-surface #define C4GFXBLIT_CLRSFC_MOD2 8 // additive color modulation for ClrByOwner-surface +#define C4GFXBLIT_WIREFRAME 16 // draws a mesh as wireframe -#define C4GFXBLIT_ALL 15 // bist mask covering all blit modes -#define C4GFXBLIT_NOADD 14 // bit mask covering all blit modes except additive +#define C4GFXBLIT_ALL 31 // bist mask covering all blit modes +#define C4GFXBLIT_NOADD 30 // bit mask covering all blit modes except additive #define C4GFXBLIT_CUSTOM 128 // custom blitting mode - ignored by gfx system #define C4GFXBLIT_PARENT 256 // blitting mode inherited by parent - ignored by gfx system @@ -60,12 +50,7 @@ typedef void* IDirect3DSurface9; const int ALeft=0,ACenter=1,ARight=2; -#ifdef USE_DIRECTX -class CStdD3D; -extern CStdD3D *pD3D; -#endif - -#ifdef USE_GL +#ifndef USE_CONSOLE class CStdGL; class CStdGLCtx; extern CStdGL *pGL; @@ -94,29 +79,9 @@ public: #ifdef _DEBUG int *dbg_idx; #endif -#if defined(USE_DIRECTX) && defined(USE_GL) - union - { - struct // D3D values - { -#endif -#ifdef USE_DIRECTX - IDirect3DSurface9 *pSfc; // surface (primary sfc) - D3DFORMAT dwClrFormat; // used color format in textures -#endif -#if defined(USE_DIRECTX) && defined(USE_GL) - - }; - struct // OpenGL values - { -#endif -#ifdef USE_GL +#ifndef USE_CONSOLE GLenum Format; // used color format in textures CStdGLCtx * pCtx; -#endif -#if defined(USE_DIRECTX) && defined(USE_GL) - }; - }; #endif C4TexRef **ppTex; // textures BYTE byBytesPP; // bytes per pixel (2 or 4) @@ -151,7 +116,7 @@ public: bool Copy(C4Surface &fromSfc); bool CreateColorByOwner(C4Surface *pBySurface); // create ColorByOwner-surface bool SetAsClrByOwnerOf(C4Surface *pOfSurface); // assume that ColorByOwner-surface has been created, and just assign it; fails if the size doesn't match -#ifdef USE_GL +#ifndef USE_CONSOLE bool CreatePrimaryGLTextures(); // create primary textures from back buffer #endif // Only for surfaces which map to a window @@ -176,9 +141,6 @@ public: bool ReadBMP(CStdStream &hGroup); bool AttachPalette(); -#ifdef USE_DIRECTX - IDirect3DSurface9 *GetSurface(); // get internal surface -#endif bool GetSurfaceSize(int &irX, int &irY); // get surface size void SetClr(DWORD toClr) { ClrByOwnerClr=toClr; } DWORD GetClr() { return ClrByOwnerClr; } @@ -192,43 +154,22 @@ protected: friend class C4Draw; friend class C4Pattern; - friend class CStdD3D; friend class CStdGL; }; -#ifndef USE_DIRECTX -typedef struct _D3DLOCKED_RECT +typedef struct _LOCKED_RECT { int Pitch; unsigned char * pBits; -} D3DLOCKED_RECT; -#endif +} LOCKED_RECT; // one texture encapsulation class C4TexRef { public: - D3DLOCKED_RECT texLock; // current lock-data -#if defined(USE_DIRECTX) && defined(USE_GL) - union - { - struct // D3D - { -#endif -#ifdef USE_DIRECTX - IDirect3DTexture9 *pTex; // texture -#endif -#if defined(USE_DIRECTX) && defined(USE_GL) - }; - struct // OpenGL - { -#endif -#ifdef USE_GL - GLuint texName; -#endif -#if defined(USE_DIRECTX) && defined(USE_GL) - }; - }; + LOCKED_RECT texLock; // current lock-data +#ifndef USE_CONSOLE + GLuint texName; #endif int iSizeX; int iSizeY; diff --git a/src/lib/texture/C4SurfaceLoaders.cpp b/src/graphics/C4SurfaceLoaders.cpp similarity index 93% rename from src/lib/texture/C4SurfaceLoaders.cpp rename to src/graphics/C4SurfaceLoaders.cpp index 3e3a00345..115463b7c 100644 --- a/src/lib/texture/C4SurfaceLoaders.cpp +++ b/src/graphics/C4SurfaceLoaders.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003, 2008 Matthes Bender - * Copyright (c) 2002, 2007-2008, 2010-2011 Sven Eberhardt - * Copyright (c) 2004-2009 Günther Brammer - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Extension to C4Surface that handles bitmaps in C4Group files */ @@ -31,7 +26,7 @@ #include #include -#include +#include bool C4Surface::LoadAny(C4Group &hGroup, const char *szName, bool fOwnPal, bool fNoErrIfNotFound) { @@ -265,6 +260,8 @@ bool C4Surface::SavePNG(C4Group &hGroup, const char *szFilename, bool fSaveAlpha /* JPEG loading */ +#ifndef USE_CONSOLE + // Some distributions ship jpeglib.h with extern "C", others don't - gah. extern "C" { @@ -394,3 +391,13 @@ bool C4Surface::ReadJPEG(CStdStream &hGroup) // return if successful return true; } + +#else // ifndef USE_CONSOLE + +bool C4Surface::ReadJPEG(CStdStream &hGroup) { + // Dummy surface + if (!Create(1, 1)) return false; + return true; +} + +#endif // USE_CONSOLE diff --git a/src/platform/StdSurface8.cpp b/src/graphics/CSurface8.cpp similarity index 82% rename from src/platform/StdSurface8.cpp rename to src/graphics/CSurface8.cpp index 8d39f4cd6..ffa259b7d 100644 --- a/src/platform/StdSurface8.cpp +++ b/src/graphics/CSurface8.cpp @@ -1,29 +1,26 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002, 2007 Sven Eberhardt - * Copyright (c) 2007, 2009-2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a wrapper class to DirectDraw surfaces #include "C4Include.h" -#include +#include #include #include -#include +#include #include #include @@ -131,10 +128,9 @@ bool CSurface8::Read(CStdStream &hGroup) // Copy palette for (cnt=0; cnt<256; cnt++) { - pPal->Colors[cnt*3+0]=BitmapInfo.Colors[cnt].rgbRed; - pPal->Colors[cnt*3+1]=BitmapInfo.Colors[cnt].rgbGreen; - pPal->Colors[cnt*3+2]=BitmapInfo.Colors[cnt].rgbBlue; - pPal->Alpha[cnt]=0xff; + pPal->Colors[cnt] = C4RGB(BitmapInfo.Colors[cnt].rgbRed, + BitmapInfo.Colors[cnt].rgbGreen, + BitmapInfo.Colors[cnt].rgbBlue); } } @@ -164,10 +160,10 @@ bool CSurface8::Read(CStdStream &hGroup) return true; } -bool CSurface8::Save(const char *szFilename, BYTE *bpPalette) +bool CSurface8::Save(const char *szFilename, CStdPalette *bpPalette) { C4BMP256Info BitmapInfo; - BitmapInfo.Set(Wdt,Hgt,bpPalette ? bpPalette : pPal->Colors); + BitmapInfo.Set(Wdt,Hgt, bpPalette ? bpPalette : pPal); // Create file & write info CStdFile hFile; diff --git a/src/platform/StdSurface8.h b/src/graphics/CSurface8.h similarity index 75% rename from src/platform/StdSurface8.h rename to src/graphics/CSurface8.h index 4d66a2fdc..a2c678765 100644 --- a/src/platform/StdSurface8.h +++ b/src/graphics/CSurface8.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a class holding a 8 bpp memory surface @@ -45,6 +43,11 @@ public: // set pix in local copy... if (Bits) Bits[iY*Pitch+iX]=byCol; } + void _SetPix(int iX, int iY, BYTE byCol) + { + // set pix in local copy without bounds or surface checks + Bits[iY*Pitch+iX]=byCol; + } BYTE GetPix(int iX, int iY) // get pixel { if (iX<0 || iY<0 || iX>=Wdt || iY>=Hgt) return 0; @@ -60,7 +63,7 @@ public: void Clip(int iX, int iY, int iX2, int iY2); void NoClip(); bool Read(class CStdStream &hGroup); - bool Save(const char *szFilename, BYTE *bpPalette = NULL); + bool Save(const char *szFilename, CStdPalette * = NULL); void GetSurfaceSize(int &irX, int &irY); // get surface size void AllowColor(BYTE iRngLo, BYTE iRngHi, bool fAllowZero=false); void SetBuffer(BYTE *pbyToBuf, int Wdt, int Hgt, int Pitch); diff --git a/src/lib/texture/StdPNG.cpp b/src/graphics/StdPNG.cpp similarity index 89% rename from src/lib/texture/StdPNG.cpp rename to src/graphics/StdPNG.cpp index 61d3504e8..f2afc730c 100644 --- a/src/lib/texture/StdPNG.cpp +++ b/src/graphics/StdPNG.cpp @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002 Sven Eberhardt - * Copyright (c) 2005, 2011 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // png file reading functionality @@ -23,14 +20,10 @@ #include -CPNGFile *pCurrPng=NULL; // global crap for file-reading callback - // png reading proc -void PNGAPI CPNGReadFn(png_structp png_ptr, png_bytep data, size_t length) +void PNGAPI CPNGFile::CPNGReadFn(png_structp png_ptr, png_bytep data, size_t length) { - // read from current pnt - if (!pCurrPng) return; - pCurrPng->Read(data, length); + static_cast(png_get_io_ptr(png_ptr))->Read(data, length); } void CPNGFile::Read(unsigned char *pData, int iLength) @@ -44,8 +37,6 @@ void CPNGFile::Read(unsigned char *pData, int iLength) bool CPNGFile::DoLoad() { - // set current png ptr - pCurrPng=this; // reset file ptr pFilePtr=pFile; // check file @@ -61,7 +52,7 @@ bool CPNGFile::DoLoad() // error handling if (setjmp(png_jmpbuf(png_ptr))) return false; // set file-reading proc - png_set_read_fn(png_ptr, png_get_io_ptr(png_ptr), &CPNGReadFn); + png_set_read_fn(png_ptr, this, &CPNGFile::CPNGReadFn); // read info png_read_info(png_ptr, info_ptr); // assign local vars diff --git a/src/lib/texture/StdPNG.h b/src/graphics/StdPNG.h similarity index 75% rename from src/lib/texture/StdPNG.h rename to src/graphics/StdPNG.h index 67cb4dd38..bcb941737 100644 --- a/src/lib/texture/StdPNG.h +++ b/src/graphics/StdPNG.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002 Sven Eberhardt - * Copyright (c) 2005 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // png file reading functionality @@ -23,8 +20,6 @@ #include -void PNGAPI CPNGReadFn(png_structp png_ptr, png_bytep data, size_t length); // reading proc (callback) - class CPNGFile { private: @@ -69,6 +64,7 @@ public: BYTE *GetImageData() { return pImageData; } // return raw image data int GetBitsPerPixel(); // return number of bits per pixel in raw image data - friend void PNGAPI CPNGReadFn(png_structp png_ptr, png_bytep data, size_t length); +private: + static void PNGAPI CPNGReadFn(png_structp png_ptr, png_bytep data, size_t length); // reading proc (callback) }; #endif //INC_STDPNG diff --git a/src/gui/C4ChatDlg.cpp b/src/gui/C4ChatDlg.cpp index 1037d7116..f41130277 100644 --- a/src/gui/C4ChatDlg.cpp +++ b/src/gui/C4ChatDlg.cpp @@ -1,25 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007-2008 Matthes Bender - * Copyright (c) 2007, 2009-2010 Günther Brammer - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // IRC client dialog @@ -1000,7 +992,7 @@ void C4ChatDlg::StopChat() bool C4ChatDlg::ToggleChat() { if (pInstance && pInstance->IsShown()) - StopChat(); + pInstance->Close(false); else ShowChat(); return true; diff --git a/src/gui/C4ChatDlg.h b/src/gui/C4ChatDlg.h index bf34309fb..f9213002e 100644 --- a/src/gui/C4ChatDlg.h +++ b/src/gui/C4ChatDlg.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // IRC client dialog diff --git a/src/gui/C4DownloadDlg.cpp b/src/gui/C4DownloadDlg.cpp index 30fb97d1d..2ba68b664 100644 --- a/src/gui/C4DownloadDlg.cpp +++ b/src/gui/C4DownloadDlg.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2007 Armin Burgmeier - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // HTTP download dialog; downloads a file diff --git a/src/gui/C4DownloadDlg.h b/src/gui/C4DownloadDlg.h index aae05d801..e2e76c34f 100644 --- a/src/gui/C4DownloadDlg.h +++ b/src/gui/C4DownloadDlg.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // HTTP download dialog; downloads a file // (like, e.g., a .ocu update group) diff --git a/src/gui/C4FileSelDlg.cpp b/src/gui/C4FileSelDlg.cpp index 25fa32ad1..7a16523a5 100644 --- a/src/gui/C4FileSelDlg.cpp +++ b/src/gui/C4FileSelDlg.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2008 Sven Eberhardt - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // file selection dialogs @@ -25,12 +20,13 @@ #include // only for single use of ::GraphicsResource.fctOKCancel below... #include -#include +#include #ifdef _WIN32 #ifndef _WIN32_IE #define _WIN32_IE 0x0400 #endif +#undef MK_ALT #include #ifndef CSIDL_MYPICTURES #define CSIDL_MYPICTURES 0x0027 diff --git a/src/gui/C4FileSelDlg.h b/src/gui/C4FileSelDlg.h index 3e12df6e0..b0165d0de 100644 --- a/src/gui/C4FileSelDlg.h +++ b/src/gui/C4FileSelDlg.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2008 Sven Eberhardt - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // file selection dialogs diff --git a/src/gui/C4Folder.cpp b/src/gui/C4Folder.cpp index d2c2480e0..b540d955f 100644 --- a/src/gui/C4Folder.cpp +++ b/src/gui/C4Folder.cpp @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Core component of a folder */ diff --git a/src/gui/C4Folder.h b/src/gui/C4Folder.h index 528b8d448..ed24b3c6e 100644 --- a/src/gui/C4Folder.h +++ b/src/gui/C4Folder.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Core component of a folder */ @@ -21,9 +19,6 @@ #ifndef INC_C4Folder #define INC_C4Folder -class StdCompiler; -class C4Group; - const int C4MaxFolderSort = 4096; class C4FolderHead diff --git a/src/gui/C4GameDialogs.cpp b/src/gui/C4GameDialogs.cpp index e60b38fa0..cc41da2f1 100644 --- a/src/gui/C4GameDialogs.cpp +++ b/src/gui/C4GameDialogs.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2007-2008 Matthes Bender - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // main game dialogs (abort game dlg, observer dlg) diff --git a/src/gui/C4GameDialogs.h b/src/gui/C4GameDialogs.h index f0812715f..56e2d5dd4 100644 --- a/src/gui/C4GameDialogs.h +++ b/src/gui/C4GameDialogs.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // main game dialogs (abort game dlg, observer dlg) diff --git a/src/gui/C4GameLobby.cpp b/src/gui/C4GameLobby.cpp index 6b0fe31ee..fc9af857b 100644 --- a/src/gui/C4GameLobby.cpp +++ b/src/gui/C4GameLobby.cpp @@ -1,25 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2008 Sven Eberhardt - * Copyright (c) 2005-2006, 2009-2010 Günther Brammer - * Copyright (c) 2005, 2009 Peter Wortmann - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2007-2008 Matthes Bender - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Carl-Philip Hänsch - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // the ingame-lobby @@ -94,7 +86,7 @@ namespace C4GameLobby StdStrBuf sDesc; // load desc C4ComponentHost DefDesc; - if (DefDesc.LoadEx(ScenarioFile, C4CFN_ScenarioDesc, Config.General.LanguageEx)) + if (C4Language::LoadComponentHost(&DefDesc, ScenarioFile, C4CFN_ScenarioDesc, Config.General.LanguageEx)) { C4RTFFile rtf; rtf.Load(StdBuf(DefDesc.GetData(), SLen(DefDesc.GetData()))); @@ -205,7 +197,7 @@ namespace C4GameLobby //C4GUI::CallbackButton *btnTest = new C4GUI::CallbackButton("test", caBottom.GetFromRight(90), &MainDlg::OnTestBtn); pGameOptionButtons = new C4GameOptionButtons(caBottom.GetCentered(caBottom.GetInnerWidth(), Min(C4GUI_IconExHgt, caBottom.GetHeight())), true, fHost, true); - // players / ressources sidebar + // players / resources sidebar C4GUI::ComponentAligner caRight(caMain.GetFromRight(iClientListWdt), iIndentX3,iIndentY4); pRightTabLbl = new C4GUI::WoodenLabel("", caRight.GetFromTop(C4GUI::WoodenLabel::GetDefaultHeight(&(::GraphicsResource.TextFont))), C4GUI_CaptionFontClr, &::GraphicsResource.TextFont, ALeft); caRight.ExpandTop(iIndentY4*2 + 1); // undo margin, so client list is located directly under label @@ -258,7 +250,7 @@ namespace C4GameLobby AddElement(pLbl); AddElement(pEdt); // chat AddElement(pRightTabLbl); - //(new C4GUI::ContextButton(pRightTabLbl, true))->SetToolTip("[.!] Switches between player and ressource view"); // right tab label+ctx menu + //(new C4GUI::ContextButton(pRightTabLbl, true))->SetToolTip("[.!] Switches between player and resource view"); // right tab label+ctx menu if (btnTeams) AddElement(btnTeams); AddElement(btnPlayers); AddElement(btnResources); @@ -446,164 +438,7 @@ namespace C4GameLobby // store input in backbuffer before processing commands // because those might kill the edit field ::MessageInput.StoreBackBuffer(szInputText); - bool fProcessed = false; - // CAUTION when implementing special commands (like /quit) here: - // those must not be executed when text is pasted, because that could crash the GUI system - // when there are additional lines to paste, but the edit field is destructed by the command - if (!fProcessed && *szInputText == '/') - { - // must be 1 char longer than the longest command only. If given commands are longer, they will be truncated, and such a command won't exist anyway - const int32_t MaxCommandLen = 20; - char Command[MaxCommandLen+1]; - const char *szPar = szInputText; - // parse command until first space - int32_t iParPos = SCharPos(' ', szInputText); - if (iParPos<0) - { - // command w/o par - SCopy(szInputText, Command, MaxCommandLen); - szPar += SLen(szPar); - } - else - { - // command with following par - SCopy(szInputText, Command, Min(MaxCommandLen, iParPos)); - szPar += iParPos+1; - } - fProcessed = true; - // evaluate lobby-only commands - // ------------------------------------------------------ - if (SEqualNoCase(Command, "/joinplr")) - { - // compose path from given filename - StdStrBuf plrPath; - plrPath.Format("%s%s", Config.General.UserDataPath, szPar); - // player join - check filename - if (!ItemExists(plrPath.getData())) - { - LobbyError(FormatString(LoadResStr("IDS_MSG_CMD_JOINPLR_NOFILE"), plrPath.getData()).getData()); - } - else - ::Network.Players.JoinLocalPlayer(plrPath.getData(), true); - } - // ------------------------------------------------------ - else if (SEqualNoCase(Command, "/plrclr")) - { - // get player name from input text - int iSepPos = SCharPos(' ', szPar, 0); - C4PlayerInfo *pNfo=NULL; - int32_t idLocalClient = -1; - if (::Network.Clients.GetLocal()) idLocalClient = ::Network.Clients.GetLocal()->getID(); - if (iSepPos>0) - { - // a player name is given: Parse it - StdStrBuf sPlrName; - sPlrName.Copy(szPar, iSepPos); - szPar += iSepPos+1; int32_t id=0; - while ((pNfo = Game.PlayerInfos.GetNextPlayerInfoByID(id))) - { - id = pNfo->GetID(); - if (WildcardMatch(sPlrName.getData(), pNfo->GetName())) break; - } - } - else - // no player name: Set local player - pNfo = Game.PlayerInfos.GetPrimaryInfoByClientID(idLocalClient); - C4ClientPlayerInfos *pCltNfo=NULL; - if (pNfo) pCltNfo = Game.PlayerInfos.GetClientInfoByPlayerID(pNfo->GetID()); - if (!pCltNfo) - { - LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOPLAYER")); - } - else - { - // may color of this client be set? - if (pCltNfo->GetClientID() != idLocalClient && !::Network.isHost()) - { - LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOACCESS")); - } - else - { - // get color to set - uint32_t dwNewClr; - if (sscanf(szPar, "%x", &dwNewClr) != 1) - { - LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_USAGE")); - } - else - { - // color validation - dwNewClr |= 0xff000000; - if (!dwNewClr) ++dwNewClr; - // request a color change to this color - C4ClientPlayerInfos LocalInfoRequest = *pCltNfo; - C4PlayerInfo *pPlrInfo = LocalInfoRequest.GetPlayerInfoByID(pNfo->GetID()); - assert(pPlrInfo); - if (pPlrInfo) - { - pPlrInfo->SetOriginalColor(dwNewClr); // set this as a new color wish - ::Network.Players.RequestPlayerInfoUpdate(LocalInfoRequest); - } - } - } - } - } - // ------------------------------------------------------ - else if (SEqualNoCase(Command, "/start")) - { - // timeout given? - int32_t iTimeout = Config.Lobby.CountdownTime; - if (!::Network.isHost()) - LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY")); - else if (szPar && *szPar && (!sscanf(szPar, "%d", &iTimeout) || iTimeout<0)) - LobbyError(LoadResStr("IDS_MSG_CMD_START_USAGE")); - else - { - // abort previous countdown - if (eCountdownState) ::Network.AbortLobbyCountdown(); - // start new countdown (aborts previous if necessary) - Start(iTimeout); - } - } - // ------------------------------------------------------ - else if (SEqualNoCase(Command, "/abort")) - { - if (!::Network.isHost()) - LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY")); - else if (eCountdownState) - ::Network.AbortLobbyCountdown(); - else - LobbyError(LoadResStr("IDS_MSG_CMD_ABORT_NOCOUNTDOWN")); - } - // ------------------------------------------------------ - else if (SEqualNoCase(Command, "/help")) - { - Log(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGLO")); - LogF("/start [time] - %s", LoadResStr("IDS_TEXT_STARTTHEROUNDWITHSPECIFIE")); - LogF("/abort - %s", LoadResStr("IDS_TEXT_ABORTSTARTCOUNTDOWN")); - LogF("/alert - %s", LoadResStr("IDS_TEXT_ALERTTHEHOSTIFTHEHOSTISAW")); - LogF("/joinplr [filename] - %s", LoadResStr("IDS_TEXT_JOINALOCALPLAYERFROMTHESP")); - LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT")); - LogF("/observer [client] - %s", LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB")); - LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME")); - LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO")); - LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR")); - LogF("/plrclr [player] [RGB] - %s", LoadResStr("IDS_TEXT_CHANGETHECOLOROFTHESPECIF")); - LogF("/plrclr [RGB] - %s", LoadResStr("IDS_TEXT_CHANGEYOUROWNPLAYERCOLOR")); - LogF("/set comment [comment] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT")); - LogF("/set password [password] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD")); - LogF("/set maxplayer [number] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA")); - LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD")); - } - // ------------------------------------------------------ - else - { - // command not known or not a specific lobby command - forward to messageinput - fProcessed = false; - } - } - // not processed? Then forward to messageinput, which parses additional commands and sends regular messages - if (!fProcessed) ::MessageInput.ProcessInput(szInputText); + ::MessageInput.ProcessInput(szInputText); } // clear edit field after text has been processed pEdt->SelectAll(); pEdt->DeleteSelection(); @@ -711,7 +546,7 @@ namespace C4GameLobby { // create context menu C4GUI::ContextMenu *pMenu = new C4GUI::ContextMenu(); - // players/ressources + // players/resources C4GUI::Tabular::Sheet *pPlayerSheet = pRightTab->GetSheet(0); C4GUI::Tabular::Sheet *pResSheet = pRightTab->GetSheet(1); C4GUI::Tabular::Sheet *pOptionsSheet = pRightTab->GetSheet(2); @@ -862,6 +697,7 @@ namespace C4GameLobby // get lobby MainDlg *pLobby = ::Network.GetLobby(); if (pLobby) pLobby->OnError(szErrorMsg); + else Log(szErrorMsg); } diff --git a/src/gui/C4GameLobby.h b/src/gui/C4GameLobby.h index 0bbf9458a..7c35fa60a 100644 --- a/src/gui/C4GameLobby.h +++ b/src/gui/C4GameLobby.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2007 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // the ingame-lobby @@ -28,13 +25,6 @@ #include "C4Client.h" #include "C4PlayerInfo.h" -class C4PlayerInfo; -class C4PlayerInfoListBox; -class C4ClientPlayerInfos; -class C4Network2ResDlg; -class C4GameOptionsList; -class C4GameOptionButtons; - namespace C4GameLobby { class MainDlg; @@ -132,7 +122,6 @@ namespace C4GameLobby private: void SetCountdownState(CountdownState eToState, int32_t iTimer); - void Start(int32_t iCountdownTime); // host only: Do game start with specified countdown time (forwards to network system) int32_t ValidatedCountdownTime(int32_t iTimeout); // correct invalid timeout settings void UpdatePlayerList(); @@ -156,6 +145,7 @@ namespace C4GameLobby void OnCountdownPacket(const C4PacketCountdown &Pkt); // called when a countdown packet is received: Update countdown state bool IsCountdown(); + void Start(int32_t iCountdownTime); // host only: Do game start with specified countdown time (forwards to network system) void UpdatePassword(); void ClearLog(); }; diff --git a/src/gui/C4GameMessage.cpp b/src/gui/C4GameMessage.cpp index 51a902d44..b613c2827 100644 --- a/src/gui/C4GameMessage.cpp +++ b/src/gui/C4GameMessage.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2004 Matthes Bender - * Copyright (c) 2002, 2005-2008 Sven Eberhardt - * Copyright (c) 2004, 2006, 2009-2010 Günther Brammer - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Text messages drawn inside the viewport */ diff --git a/src/gui/C4GameMessage.h b/src/gui/C4GameMessage.h index 5632ff53f..26f74888b 100644 --- a/src/gui/C4GameMessage.h +++ b/src/gui/C4GameMessage.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2001, 2005, 2008 Sven Eberhardt - * Copyright (c) 2004, 2009-2010 Günther Brammer - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Text messages drawn inside the viewport */ diff --git a/src/gui/C4GameOptions.cpp b/src/gui/C4GameOptions.cpp index e9668f9c5..280e207df 100644 --- a/src/gui/C4GameOptions.cpp +++ b/src/gui/C4GameOptions.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006, 2008 Sven Eberhardt - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2009 Peter Wortmann - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Custom game options and configuration dialog diff --git a/src/gui/C4GameOptions.h b/src/gui/C4GameOptions.h index a244edf3e..6e0fca387 100644 --- a/src/gui/C4GameOptions.h +++ b/src/gui/C4GameOptions.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2008 Sven Eberhardt - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Custom game options and configuration dialog diff --git a/src/gui/C4GameOverDlg.cpp b/src/gui/C4GameOverDlg.cpp index deddd7533..009bac87b 100644 --- a/src/gui/C4GameOverDlg.cpp +++ b/src/gui/C4GameOverDlg.cpp @@ -1,25 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2008 Sven Eberhardt - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2008 Armin Burgmeier - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -"Clonk" is a registered trademark of Matthes Bender. */ + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ // game over dialog showing winners and losers #include @@ -47,28 +40,20 @@ C4GoalDisplay::GoalPicture::GoalPicture(const C4Rect &rcBounds, C4ID idGoal, boo // bounds SetBounds(rcBounds); // can't get specialized desc from object at the moment because of potential script callbacks! - StdStrBuf strGoalName, strGoalDesc; - /*C4Object *pGoalObj = ::Objects.FindInternal(idGoal); - if (pGoalObj) - { - pGoalObj->GetInfoString().getData(); - } - else*/ + StdStrBuf strGoalName; + // just get desc from def + C4Def *pGoalDef = ::Definitions.ID2Def(idGoal); + if (pGoalDef) { - // just get desc from def - C4Def *pGoalDef = ::Definitions.ID2Def(idGoal); - if (pGoalDef) - { - strGoalName.Copy(pGoalDef->GetName()); - // strGoalDesc.Copy(pGoalDef->GetDesc()); - } + strGoalName.Copy(pGoalDef->GetName()); + // strGoalDesc.Copy(pGoalDef->GetDesc()); } // get tooltip StdStrBuf sToolTip; if (fFulfilled) - sToolTip.Format(LoadResStr("IDS_DESC_GOALFULFILLED"), strGoalName.getData(), strGoalDesc.getData()); + sToolTip.Format(LoadResStr("IDS_DESC_GOALFULFILLED"), strGoalName.getData()); else - sToolTip.Format(LoadResStr("IDS_DESC_GOALNOTFULFILLED"), strGoalName.getData(), strGoalDesc.getData()); + sToolTip.Format(LoadResStr("IDS_DESC_GOALNOTFULFILLED"), strGoalName.getData()); SetToolTip(sToolTip.getData()); // create buffered picture of goal definition C4Def *pDrawDef = ::Definitions.ID2Def(idGoal); diff --git a/src/gui/C4GameOverDlg.h b/src/gui/C4GameOverDlg.h index f85c4ede8..c8e9d472d 100644 --- a/src/gui/C4GameOverDlg.h +++ b/src/gui/C4GameOverDlg.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2008 Sven Eberhardt - * Copyright (c) 2009 Peter Wortmann - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // game over dialog showing winners and losers diff --git a/src/gui/C4GfxErrorDlg.cpp b/src/gui/C4GfxErrorDlg.cpp index f3e250d68..4446ff244 100644 --- a/src/gui/C4GfxErrorDlg.cpp +++ b/src/gui/C4GfxErrorDlg.cpp @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2012, Julius Michaelis + * Copyright (c) 2012-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Functions for displaying a settings dialogue to users when the graphics system failed */ diff --git a/src/gui/C4Gui.cpp b/src/gui/C4Gui.cpp index d3dcee4be..8f7a50b8c 100644 --- a/src/gui/C4Gui.cpp +++ b/src/gui/C4Gui.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2008 Sven Eberhardt - * Copyright (c) 2006-2010 Günther Brammer - * Copyright (c) 2007-2008 Matthes Bender - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // all generic classes that do not fit into other C4Gui*-files @@ -337,33 +332,42 @@ namespace C4GUI void Element::DrawVBar(C4TargetFacet &cgo, DynBarFacet &rFacets) { - int32_t y0=cgo.TargetY+rcBounds.y, x0=cgo.TargetX+rcBounds.x; - int32_t iY = rFacets.fctBegin.Hgt, h=rFacets.fctMiddle.Hgt; - rFacets.fctBegin.Draw(cgo.Surface, x0,y0); - while (iY < rcBounds.Hgt-5) - { - int32_t h2=Min(h, rcBounds.Hgt-5-iY); rFacets.fctMiddle.Hgt=h2; - rFacets.fctMiddle.Draw(cgo.Surface, x0, y0+iY); - iY += h; - } - rFacets.fctMiddle.Hgt=h; - rFacets.fctEnd.Draw(cgo.Surface, x0, y0+rcBounds.Hgt-rFacets.fctEnd.Hgt); + C4DrawTransform trf(1); + DrawHVBar(cgo, rFacets, trf, rcBounds.Hgt); } void Element::DrawHBarByVGfx(C4TargetFacet &cgo, DynBarFacet &rFacets) { - int32_t y0=cgo.TargetY+rcBounds.y, x0=cgo.TargetX+rcBounds.x; - int32_t iY = rFacets.fctBegin.Hgt, h=rFacets.fctMiddle.Hgt; - C4DrawTransform trf; trf.SetRotate(-90*100, (float)(cgo.TargetX+rcBounds.x+rcBounds.Hgt/2), (float)(cgo.TargetY+rcBounds.y+rcBounds.Hgt/2)); - rFacets.fctBegin.DrawT(cgo.Surface, x0,y0, 0, 0, &trf); - while (iY < rcBounds.Wdt-5) + C4DrawTransform trf; + float fOffX = cgo.TargetX + rcBounds.x + rcBounds.Hgt/2; + float fOffY = cgo.TargetY + rcBounds.y + rcBounds.Hgt/2; + trf.SetRotate(-90.0f, fOffX, fOffY); + + DrawHVBar(cgo, rFacets, trf, rcBounds.Wdt); + } + + void Element::DrawHVBar(C4TargetFacet &cgo, DynBarFacet &rFacets, C4DrawTransform &trf, int32_t iMiddleLength) + { + int32_t y0 = cgo.TargetY + rcBounds.y; + int32_t x0 = cgo.TargetX + rcBounds.x; + + // draw up arrow + rFacets.fctBegin.DrawT(cgo.Surface, x0, y0, 0, 0, &trf); + + // draw middle part + int32_t h = rFacets.fctMiddle.Hgt; + int32_t barHeight = iMiddleLength - (rFacets.fctBegin.Hgt + rFacets.fctEnd.Hgt); + + for (int32_t iY = 0; iY <= barHeight; iY += h) { - int32_t h2=Min(h, rcBounds.Wdt-5-iY); rFacets.fctMiddle.Hgt=h2; - rFacets.fctMiddle.DrawT(cgo.Surface, x0, y0+iY, 0, 0, &trf); - iY += h; + int32_t h2 = Min(h, barHeight - iY); + rFacets.fctMiddle.Hgt = h2; + rFacets.fctMiddle.DrawT(cgo.Surface, x0, y0 + rFacets.fctBegin.Hgt + iY, 0, 0, &trf); } - rFacets.fctMiddle.Hgt=h; - rFacets.fctEnd.DrawT(cgo.Surface, x0, y0+rcBounds.Wdt-rFacets.fctEnd.Hgt, 0, 0, &trf); + rFacets.fctMiddle.Hgt = h; + + // draw lower arrow + rFacets.fctEnd.DrawT(cgo.Surface, x0, y0 + iMiddleLength - rFacets.fctEnd.Hgt, 0, 0, &trf); } C4Rect Element::GetToprightCornerRect(int32_t iWidth, int32_t iHeight, int32_t iHIndent, int32_t iVIndent, int32_t iIndexX) @@ -462,8 +466,6 @@ namespace C4GUI int32_t iOffsetX = -GfxR->fctMouseCursor.Wdt/2; int32_t iOffsetY = -GfxR->fctMouseCursor.Hgt/2; GfxR->fctMouseCursor.Draw(cgo.Surface,x+iOffsetX,y+iOffsetY,0); - if (::MouseControl.IsHelp()) - GfxR->fctMouseCursor.Draw(cgo.Surface,x+iOffsetX+5,y+iOffsetY-5,29); // ToolTip if (fDrawToolTip && pMouseOverElement) { @@ -541,10 +543,7 @@ namespace C4GUI { Mouse.x = tx+twdt/2; Mouse.y = ty+thgt/2; - // calculate zoom - float fZoomX = float(Config.Graphics.ResX) / twdt; - float fZoomY = float(Config.Graphics.ResY) / thgt; - fZoom = Min(fZoomX, fZoomY); + fZoom = 1.0f; // set size - calcs client area as well SetBounds(C4Rect(tx,ty,twdt,thgt)); SetPreferredDlgRect(C4Rect(0,0,twdt,thgt)); @@ -709,7 +708,7 @@ namespace C4GUI void Screen::RenderMouse(C4TargetFacet &cgo) { // draw mouse cursor - Mouse.Draw(cgo, (Mouse.IsMouseStill() && Mouse.IsActiveInput()) || ::MouseControl.IsHelp()); + Mouse.Draw(cgo, Mouse.IsMouseStill() && Mouse.IsActiveInput()); } void Screen::Draw(C4TargetFacet &cgo, bool fDoBG) @@ -809,27 +808,6 @@ namespace C4GUI float fZoom = pForDlg ? 1.0f : GetZoom(); // Developer mode dialogs are currently drawn unzoomed float fX = float(iPxX) / fZoom; float fY = float(iPxY) / fZoom; - // help mode and button pressed: Abort help and discard button - if (::MouseControl.IsHelp()) - { - switch (iButton) - { - case C4MC_Button_None: - // just movement - break; - case C4MC_Button_LeftDown: - case C4MC_Button_RightDown: - // special for left/right down: Just ignore them, but don't stop help yet - // help should be stopped on button-up, so these won't be processed - iButton = C4MC_Button_None; - break; - default: - // buttons stop help - ::MouseControl.AbortHelp(); - iButton = C4MC_Button_None; - break; - } - } // forward to mouse Mouse.Input(iButton, fX, fY, dwKeyParam); // dragging diff --git a/src/gui/C4Gui.h b/src/gui/C4Gui.h index 2159daad4..efadaec8d 100644 --- a/src/gui/C4Gui.h +++ b/src/gui/C4Gui.h @@ -1,26 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2008, 2011 Sven Eberhardt - * Copyright (c) 2005, 2009 Peter Wortmann - * Copyright (c) 2005-2010 Günther Brammer - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2010 Carl-Philip Hänsch - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // defines user controls @@ -32,9 +23,7 @@ #ifndef INC_C4Gui #define INC_C4Gui -#define ConsoleDlgClassName L"C4GUIdlg" -#define ConsoleDlgWindowStyle (WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX) - +#include #include "C4Rect.h" #include "C4Shape.h" #include "C4FacetEx.h" @@ -46,10 +35,8 @@ #include -#include #include - // consts (load those from a def file some time) // font colors - alpha is font alpha, which is inversed opaque #define C4GUI_CaptionFontClr 0xffffffff @@ -413,6 +400,7 @@ namespace C4GUI void DrawBar(C4TargetFacet &cgo, DynBarFacet &rFacets); // draw gfx bar within element bounds void DrawVBar(C4TargetFacet &cgo, DynBarFacet &rFacets); // draw gfx bar within element bounds void DrawHBarByVGfx(C4TargetFacet &cgo, DynBarFacet &rFacets); // draw horizontal gfx bar within element bounds, using gfx of vertical one + void DrawHVBar(C4TargetFacet &cgo, DynBarFacet &rFacets, C4DrawTransform &trf, int32_t iMiddleLength); virtual bool IsOwnPtrElement() { return false; } // if true is returned, item will not be deleted when container is cleared virtual bool IsExternalDrawDialog() { return false; } @@ -527,8 +515,10 @@ namespace C4GUI class WoodenLabel : public Label { private: - time_t tAutoScrollDelay; // if set and text is longer than would fit, the label will automatically start moving if not changed and displayed for a while - time_t tLastChangeTime; // time when the label text was changed last. 0 if not initialized; set upon first drawing + uint32_t iAutoScrollDelay; // if set and text is longer than would fit, the label will automatically start moving if not changed and displayed for a while + + // Time when the label text was changed last. NULL if not initialized; set upon first drawing + C4TimeMilliseconds tLastChangeTime; int32_t iScrollPos, iScrollDir; int32_t iRightIndent; protected: @@ -541,14 +531,15 @@ namespace C4GUI public: WoodenLabel(const char *szLblText, const C4Rect &rcBounds, DWORD dwFClr=0xffffffff, CStdFont *pFont=NULL, int32_t iAlign=ACenter, bool fMarkup=true) // ctor - : Label(szLblText, rcBounds, iAlign, dwFClr, pFont, true, true, fMarkup), tAutoScrollDelay(0), tLastChangeTime(0), iScrollPos(0), iScrollDir(0), iRightIndent(0) + : Label(szLblText, rcBounds, iAlign, dwFClr, pFont, true, true, fMarkup), iAutoScrollDelay(0), tLastChangeTime(C4TimeMilliseconds::Now()), iScrollPos(0), iScrollDir(0), iRightIndent(0) { SetAutosize(false); this->rcBounds=rcBounds; }// ctor - re-sets bounds after SetText static int32_t GetDefaultHeight(CStdFont *pUseFont=NULL); void SetIcon(const C4Facet &rfctIcon); - void SetAutoScrollTime(time_t tDelay) { tAutoScrollDelay=tDelay; ResetAutoScroll(); } - void ResetAutoScroll() { tLastChangeTime=0; iScrollPos=iScrollDir=0; } + void SetAutoScrollTime(uint32_t tDelay) { iAutoScrollDelay=tDelay; ResetAutoScroll(); } + void ResetAutoScroll(); + void SetRightIndent(int32_t iNewIndent) { iRightIndent = iNewIndent; } }; @@ -1237,7 +1228,7 @@ namespace C4GUI int32_t iCursorPos; // cursor position: char, before which the cursor is located int32_t iSelectionStart, iSelectionEnd; // selection range (start may be larger than end) int32_t iMaxTextLength; // maximum number of characters to be input here - DWORD dwLastInputTime; // time of last input (for cursor flashing) + C4TimeMilliseconds tLastInputTime; // time of last input (for cursor flashing) int32_t iXScroll; // horizontal scrolling char cPasswordMask; // character to be used for masking the contents. 0 for none. @@ -1571,7 +1562,7 @@ namespace C4GUI int32_t iSheetSpacing, iSheetOff; // distances of sheet captions int32_t iCaptionLengthTotal, iCaptionScrollPos; // scrolling in captions (top only) bool fScrollingLeft, fScrollingRight, fScrollingLeftDown, fScrollingRightDown; // scrolling in captions (top only) - time_t tLastScrollTime; // set when fScrollingLeftDown or fScrollingRightDown are true: Time for next scrolling if mouse is held down + C4TimeMilliseconds tLastScrollTime; // set when fScrollingLeftDown or fScrollingRightDown are true: Time for next scrolling if mouse is held down int iSheetMargin; bool fDrawSelf; // if border and bg shall be drawn @@ -1953,11 +1944,8 @@ namespace C4GUI Dialog* pDialog; DialogWindow(): C4Window(), pDialog(NULL) {} using C4Window::Init; - C4Window * Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent, const C4Rect &rcBounds, const char *szID); + C4Window * Init(C4AbstractApp * pApp, const char * Title, const C4Rect &rcBounds, const char *szID); virtual void Close(); -#ifdef USE_X11 - virtual void HandleMessage (XEvent &); -#endif virtual void PerformUpdate(); }; @@ -2143,7 +2131,6 @@ namespace C4GUI protected: Label *pFullscreenTitle, *pSubTitle; // subtitle to be put in upper-right corner int32_t iDlgMarginX, iDlgMarginY; // dialog margin set by screen size - IconButton *pBtnHelp; virtual const char *GetID() { return 0; } // no ID needed, because it's never created as a window @@ -2152,9 +2139,6 @@ namespace C4GUI void SetTitle(const char *szToTitle); // change title text; creates or removes title bar if necessary - private: - void UpdateHelpButtonPos(); - protected: virtual void DrawElement(C4TargetFacet &cgo); // draw dlg bg @@ -2176,8 +2160,6 @@ namespace C4GUI // helper func: draw facet to screen background void DrawBackground(C4TargetFacet &cgo, C4Facet &rFromFct); - - void OnHelpBtn(C4GUI::Control *pBtn); }; // a button closing the Dlg @@ -2248,7 +2230,7 @@ namespace C4GUI class ResetButton : public CloseButton { public: ResetButton(const C4Rect &rtBounds) // ctor - : CloseButton(LoadResStr("[!]Reset"), rtBounds, true) {} }; + : CloseButton(LoadResStr("IDS_BTN_RESET"), rtBounds, true) {} }; // a simple message dialog class MessageDialog : public Dialog @@ -2256,17 +2238,21 @@ namespace C4GUI private: bool fHasOK; int32_t *piConfigDontShowAgainSetting; + class C4KeyBinding *pKeyCopy; + StdCopyStrBuf sCopyText; // text that goes into clipboard if user presses Ctrl+C on this window public: enum Buttons { btnOK=1, btnAbort=2, btnYes=4, btnNo=8, btnRetry=16, btnReset=32, btnOKAbort=btnOK|btnAbort, btnYesNo=btnYes|btnNo, btnRetryAbort=btnRetry|btnAbort }; enum DlgSize { dsRegular=C4GUI_MessageDlgWdt, dsMedium=C4GUI_MessageDlgWdtMedium, dsSmall=C4GUI_MessageDlgWdtSmall }; MessageDialog(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, DlgSize eSize=dsRegular, int32_t *piConfigDontShowAgainSetting=NULL, bool fDefaultNo=false); + ~MessageDialog(); protected: virtual bool OnEnter() { if (!fHasOK) return false; Close(true); return true; } void OnDontShowAgainCheck(C4GUI::Element *pCheckBox) { if (piConfigDontShowAgainSetting) *piConfigDontShowAgainSetting = static_cast(pCheckBox)->GetChecked(); } + bool KeyCopy(); virtual const char *GetID() { return "MessageDialog"; } virtual int32_t GetZOrdering() { return C4GUI_Z_INPUT; } @@ -2457,7 +2443,7 @@ namespace C4GUI int32_t LDownX, LDownY; // position where left button was pressed last DWORD dwKeys; // shift, ctrl, etc. bool fActive; - time_t tLastMovementTime; // GetTime() when the mouse pos changed last + C4TimeMilliseconds tLastMovementTime; // C4TimeMilliseconds::Now() when the mouse pos changed last // whether last input was done by mouse // set to true whenever mouse pos changes or buttons are pressed @@ -2488,8 +2474,8 @@ namespace C4GUI void SetOwnedMouse(bool fToVal) { fActive=fToVal; } - void ResetToolTipTime() { tLastMovementTime = GetTime(); } - bool IsMouseStill() { return GetTime()-tLastMovementTime >= C4GUI_ToolTipShowTime; } + void ResetToolTipTime() { tLastMovementTime = C4TimeMilliseconds::Now(); } + bool IsMouseStill() { return C4TimeMilliseconds::Now()-tLastMovementTime >= C4GUI_ToolTipShowTime; } void ResetActiveInput() { fActiveInput = false; } bool IsActiveInput() { return fActiveInput; } diff --git a/src/gui/C4GuiButton.cpp b/src/gui/C4GuiButton.cpp index 714223ee8..80f1d5134 100644 --- a/src/gui/C4GuiButton.cpp +++ b/src/gui/C4GuiButton.cpp @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2008 Sven Eberhardt - * Copyright (c) 2007-2008, 2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // that which can be pressed @@ -27,7 +24,7 @@ #include #include #include -#include +#include namespace C4GUI { @@ -239,7 +236,7 @@ namespace C4GUI if (sText.getLength()) { CStdFont &rUseFont = pCustomFont ? *pCustomFont : ::GraphicsResource.TextFont; - pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, x0+rcBounds.Wdt/2, y0+rcBounds.Hgt-rUseFont.GetLineHeight()*4/5, pCustomFont ? dwCustomFontClr : C4GUI_CaptionFontClr, ACenter); + pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, x0+rcBounds.Wdt/2, y0+rcBounds.Hgt, pCustomFont ? dwCustomFontClr : C4GUI_CaptionFontClr, ACenter); } } diff --git a/src/gui/C4GuiCheckBox.cpp b/src/gui/C4GuiCheckBox.cpp index ac0b9d889..d315c7493 100644 --- a/src/gui/C4GuiCheckBox.cpp +++ b/src/gui/C4GuiCheckBox.cpp @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006 Sven Eberhardt - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // checkbox diff --git a/src/gui/C4GuiComboBox.cpp b/src/gui/C4GuiComboBox.cpp index ecac715ba..2cda7c3d0 100644 --- a/src/gui/C4GuiComboBox.cpp +++ b/src/gui/C4GuiComboBox.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2008 Sven Eberhardt - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // dropdown box diff --git a/src/gui/C4GuiContainers.cpp b/src/gui/C4GuiContainers.cpp index bc84150f9..e362785b3 100644 --- a/src/gui/C4GuiContainers.cpp +++ b/src/gui/C4GuiContainers.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2008 Sven Eberhardt - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2008, 2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // grouping elements and control base classes diff --git a/src/gui/C4GuiDialogs.cpp b/src/gui/C4GuiDialogs.cpp index adbcdfefb..91bab45d3 100644 --- a/src/gui/C4GuiDialogs.cpp +++ b/src/gui/C4GuiDialogs.cpp @@ -1,25 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2003-2008, 2010-2011 Sven Eberhardt - * Copyright (c) 2005, 2007, 2009 Peter Wortmann - * Copyright (c) 2005-2006, 2008-2010 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // dialog base classes and some user dialogs @@ -38,19 +31,9 @@ #include #include -#include +#include #include -#ifdef _WIN32 -#include "resource.h" -#endif - -#ifdef USE_X11 -#define None Die_XLib_Die -#include -#undef None -#endif - namespace C4GUI { @@ -194,245 +177,35 @@ namespace C4GUI // DialogWindow #ifdef USE_WIN32_WINDOWS - C4Window * DialogWindow::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent, const C4Rect &rcBounds, const char *szID) + + C4Window * DialogWindow::Init(C4AbstractApp * pApp, const char * Title, const C4Rect &rcBounds, const char *szID) { - Active = true; - // calculate required size - RECT rtSize; - rtSize.left = 0; - rtSize.top = 0; - rtSize.right = rcBounds.Wdt; - rtSize.bottom = rcBounds.Hgt; - if (!::AdjustWindowRectEx(&rtSize, ConsoleDlgWindowStyle, false, 0)) return false; - // create it! - if (!Title || !*Title) Title = "???"; - hWindow = ::CreateWindowExW ( - 0, - ConsoleDlgClassName, GetWideChar(Title), - ConsoleDlgWindowStyle, - CW_USEDEFAULT,CW_USEDEFAULT,rtSize.right-rtSize.left,rtSize.bottom-rtSize.top, - pParent->hWindow,NULL,pApp->GetInstance(),NULL); - if (hWindow) + C4Window * result = C4Window::Init(C4Window::W_GuiWindow, pApp, Title, &rcBounds); + if (result) { - hRenderWindow = hWindow; // update pos if (szID && *szID) RestoreWindowPosition(hWindow, FormatString("ConsoleGUI_%s", szID).getData(), Config.GetSubkeyPath("Console"), false); // and show ::ShowWindow(hWindow, SW_SHOW); } - return hWindow ? this : 0; + return result; } -// -------------------------------------------------- -// Dialog - LRESULT APIENTRY DialogWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - // Determine dialog - Dialog *pDlg = ::pGUI->GetDialog(hwnd); - if (!pDlg) return DefWindowProc(hwnd, uMsg, wParam, lParam); - - // Process message - switch (uMsg) - { - //--------------------------------------------------------------------------------------------------------------------------- - case WM_KEYDOWN: - if (Game.DoKeyboardInput(wParam, KEYEV_Down, !!(lParam & 0x20000000), Application.IsControlDown(), Application.IsShiftDown(), !!(lParam & 0x40000000), pDlg)) return 0; - break; - //--------------------------------------------------------------------------------------------------------------------------- - case WM_KEYUP: - if (Game.DoKeyboardInput(wParam, KEYEV_Up, !!(lParam & 0x20000000), Application.IsControlDown(), Application.IsShiftDown(), false, pDlg)) return 0; - break; - //------------------------------------------------------------------------------------------------------------ - case WM_SYSKEYDOWN: - if (wParam == 18) break; - if (Game.DoKeyboardInput(wParam, KEYEV_Down, !!(lParam & 0x20000000), Application.IsControlDown(), Application.IsShiftDown(), !!(lParam & 0x40000000), pDlg)) return 0; - break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_DESTROY: - { - const char *szID = pDlg->GetID(); - if (szID && *szID) - StoreWindowPosition(hwnd, FormatString("ConsoleGUI_%s", szID).getData(), Config.GetSubkeyPath("Console"), false); - } - break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_CLOSE: - pDlg->Close(false); - break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_SIZE: - // UpdateOutputSize - break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_PAINT: - // 2do: only draw specific dlg? - //::GraphicsSystem.Execute(); - break; - return 0; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_LBUTTONDOWN: ::pGUI->MouseInput(C4MC_Button_LeftDown,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_LBUTTONUP: ::pGUI->MouseInput(C4MC_Button_LeftUp,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_RBUTTONDOWN: ::pGUI->MouseInput(C4MC_Button_RightDown,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_RBUTTONUP: ::pGUI->MouseInput(C4MC_Button_RightUp,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_LBUTTONDBLCLK: ::pGUI->MouseInput(C4MC_Button_LeftDouble,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_RBUTTONDBLCLK: ::pGUI->MouseInput(C4MC_Button_RightDouble,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_MOUSEMOVE: - //SetCursor(NULL); - ::pGUI->MouseInput(C4MC_Button_None,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); - break; - //---------------------------------------------------------------------------------------------------------------------------------- - case WM_MOUSEWHEEL: - ::pGUI->MouseInput(C4MC_Button_Wheel,LOWORD(lParam),HIWORD(lParam),wParam, pDlg, NULL); - break; - //---------------------------------------------------------------------------------------------------------------------------------- - } - - return DefWindowProc(hwnd, uMsg, wParam, lParam); - } - - bool Dialog::RegisterWindowClass(HINSTANCE hInst) - { - // register landscape viewport class - WNDCLASSEXW WndClass; - WndClass.cbSize=sizeof(WNDCLASSEX); - WndClass.style = CS_DBLCLKS | CS_BYTEALIGNCLIENT; - WndClass.lpfnWndProc = DialogWinProc; - WndClass.cbClsExtra = 0; - WndClass.cbWndExtra = 0; - WndClass.hInstance = hInst; - WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); // - always use normal hw cursor - WndClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND; - WndClass.lpszMenuName = NULL; - WndClass.lpszClassName = ConsoleDlgClassName; - WndClass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_00_C4X) ); - WndClass.hIconSm = LoadIcon (hInst, MAKEINTRESOURCE (IDI_00_C4X) ); - return !!RegisterClassExW(&WndClass); - } #else - C4Window * DialogWindow::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, const char * Title, C4Window * pParent, const C4Rect &rcBounds, const char *szID) + C4Window * DialogWindow::Init(C4AbstractApp * pApp, const char * Title, const C4Rect &rcBounds, const char *szID) { - C4Window *result; - if (C4Window::Init(windowKind, pApp, Title, pParent, false)) + C4Window * result = C4Window::Init(C4Window::W_GuiWindow, pApp, Title, &rcBounds); + if (result) { // update pos if (szID && *szID) RestorePosition(FormatString("ConsoleGUI_%s", szID).getData(), Config.GetSubkeyPath("Console"), false); else SetSize(rcBounds.Wdt, rcBounds.Hgt); - result = this; } - else - result = NULL; return result; } -#ifdef USE_X11 - void DialogWindow::HandleMessage (XEvent &e) - { - // Parent handling - C4Window::HandleMessage(e); - - // Determine dialog - Dialog *pDlg = ::pGUI->GetDialog(this); - if (!pDlg) return; - - switch (e.type) - { - case KeyPress: - { - // Do not take into account the state of the various modifiers and locks - // we don't need that for keyboard control - DWORD key = XKeycodeToKeysym(e.xany.display, e.xkey.keycode, 0); - Game.DoKeyboardInput(key, KEYEV_Down, Application.IsAltDown(), Application.IsControlDown(), Application.IsShiftDown(), false, pDlg); - break; - } - case KeyRelease: - { - DWORD key = XKeycodeToKeysym(e.xany.display, e.xkey.keycode, 0); - Game.DoKeyboardInput(key, KEYEV_Up, e.xkey.state & Mod1Mask, e.xkey.state & ControlMask, e.xkey.state & ShiftMask, false, pDlg); - break; - } - case ButtonPress: - { - static int last_left_click, last_right_click; - switch (e.xbutton.button) - { - case Button1: - if (GetTime() - last_left_click < 400) - { - ::pGUI->MouseInput(C4MC_Button_LeftDouble, - e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - last_left_click = 0; - } - else - { - ::pGUI->MouseInput(C4MC_Button_LeftDown, - e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - last_left_click = GetTime(); - } - break; - case Button2: - ::pGUI->MouseInput(C4MC_Button_MiddleDown, - e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - break; - case Button3: - if (GetTime() - last_right_click < 400) - { - ::pGUI->MouseInput(C4MC_Button_RightDouble, - e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - last_right_click = 0; - } - else - { - ::pGUI->MouseInput(C4MC_Button_RightDown, - e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - last_right_click = GetTime(); - } - break; - case Button4: - ::pGUI->MouseInput(C4MC_Button_Wheel, - e.xbutton.x, e.xbutton.y, e.xbutton.state + (short(32) << 16), pDlg, NULL); - break; - case Button5: - ::pGUI->MouseInput(C4MC_Button_Wheel, - e.xbutton.x, e.xbutton.y, e.xbutton.state + (short(-32) << 16), pDlg, NULL); - break; - default: - break; - } - } - break; - case ButtonRelease: - switch (e.xbutton.button) - { - case Button1: - ::pGUI->MouseInput(C4MC_Button_LeftUp, e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - break; - case Button2: - ::pGUI->MouseInput(C4MC_Button_MiddleUp, e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - break; - case Button3: - ::pGUI->MouseInput(C4MC_Button_RightUp, e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - break; - default: - break; - } - break; - case MotionNotify: - ::pGUI->MouseInput(C4MC_Button_None, e.xbutton.x, e.xbutton.y, e.xbutton.state, pDlg, NULL); - break; - case ConfigureNotify: - pSurface->UpdateSize(e.xconfigure.width, e.xconfigure.height); - break; - } - } -#endif #endif // _WIN32 void DialogWindow::PerformUpdate() @@ -445,7 +218,7 @@ namespace C4GUI { pSurface->Wdt = r.Wdt; pSurface->Hgt = r.Hgt; -#ifdef USE_GL +#ifndef USE_CONSOLE pGL->PrepareRendering(pSurface); glClear(GL_COLOR_BUFFER_BIT); #endif @@ -468,7 +241,7 @@ namespace C4GUI if (pWindow) return true; // create it! pWindow = new DialogWindow(); - if (!pWindow->Init(C4Window::W_GuiWindow, &Application, TitleString.getData(), &Console, rcBounds, GetID())) + if (!pWindow->Init(&Application, TitleString.getData(), rcBounds, GetID())) { delete pWindow; pWindow = NULL; @@ -630,17 +403,7 @@ namespace C4GUI // update assigned window if (pWindow) { -#ifdef _WIN32 - RECT rtSize; - rtSize.left = 0; - rtSize.top = 0; - rtSize.right = rcBounds.Wdt; - rtSize.bottom = rcBounds.Hgt; - if (::AdjustWindowRectEx(&rtSize, ConsoleDlgWindowStyle, false, 0)) - pWindow->SetSize(rtSize.right-rtSize.left,rtSize.bottom-rtSize.top); -#else pWindow->SetSize(rcBounds.Wdt,rcBounds.Hgt); -#endif // _WIN32 } } @@ -756,8 +519,10 @@ namespace C4GUI bool Dialog::KeyHotkey(const C4KeyCodeEx &key) { - WORD wKey = WORD(key.Key); + StdStrBuf sKey = C4KeyCodeEx::KeyCode2String(key.Key, true, true); // do hotkey procs for standard alphanumerics only + if (sKey.getLength() != 1) return false; + WORD wKey = WORD(*sKey.getData()); if (Inside(TOUPPERIFX11(wKey), 'A', 'Z')) if (OnHotkey(char(TOUPPERIFX11(wKey)))) return true; if (Inside(TOUPPERIFX11(wKey), '0', '9')) if (OnHotkey(char(TOUPPERIFX11(wKey)))) return true; return false; @@ -995,7 +760,7 @@ namespace C4GUI // FullscreenDialog FullscreenDialog::FullscreenDialog(const char *szTitle, const char *szSubtitle) - : Dialog(Screen::GetScreenS()->GetClientRect().Wdt, Screen::GetScreenS()->GetClientRect().Hgt, NULL /* create own title */, false), pFullscreenTitle(NULL), pBtnHelp(NULL) + : Dialog(Screen::GetScreenS()->GetClientRect().Wdt, Screen::GetScreenS()->GetClientRect().Hgt, NULL /* create own title */, false), pFullscreenTitle(NULL) { // set margins int32_t iScreenX = Screen::GetScreenS()->GetClientRect().Wdt; @@ -1013,18 +778,6 @@ namespace C4GUI pSubTitle->SetToolTip(szTitle); } else pSubTitle = NULL; - // titled dialogs always have a help button in the top right corner - if (szTitle && *szTitle) - { - // help button disabled; use meaningful captions instead - //pBtnHelp = new CallbackButton(Ico_UnknownClient /* 2do: Help icon */, C4Rect(0,0,32,32), 'H' /* 2do */, &FullscreenDialog::OnHelpBtn, this); - //C4Facet fctHelp = ::GraphicsResource.fctOKCancel; - //fctHelp.Y += fctHelp.Hgt; - //pBtnHelp->SetFacet(fctHelp); - //pBtnHelp->SetToolTip("[.!]Help button: Press this button and hover the element you want help for!"); - //UpdateHelpButtonPos(); - //AddElement(pBtnHelp); - } } void FullscreenDialog::SetTitle(const char *szTitle) @@ -1055,38 +808,21 @@ namespace C4GUI { // inherited to update client rect Dialog::UpdateOwnPos(); - // reposition help button - UpdateHelpButtonPos(); - } - - void FullscreenDialog::UpdateHelpButtonPos() - { - // reposition help button - if (pBtnHelp) pBtnHelp->SetBounds(C4Rect(GetBounds().Wdt-4-32-GetMarginLeft(), 4-GetMarginTop(), 32,32)); } void FullscreenDialog::DrawBackground(C4TargetFacet &cgo, C4Facet &rFromFct) { // draw across fullscreen bounds - zoom 1px border to prevent flashing borders by blit offsets Screen *pScr = GetScreen(); - C4Facet cgoScreen = cgo; C4Rect &rcScreenBounds = pScr ? pScr->GetBounds() : GetBounds(); - cgoScreen.X = rcScreenBounds.x-1; cgoScreen.Y = rcScreenBounds.y-1; - cgoScreen.Wdt = rcScreenBounds.Wdt+2; cgoScreen.Hgt = rcScreenBounds.Hgt+2; - rFromFct.DrawFullScreen(cgoScreen); + rFromFct.DrawFullScreen(cgo); } - void FullscreenDialog::OnHelpBtn(C4GUI::Control *pBtn) - { - ::MouseControl.SetHelp(); - } - - // -------------------------------------------------- // MessageDialog MessageDialog::MessageDialog(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, DlgSize eSize, int32_t *piConfigDontShowAgainSetting, bool fDefaultNo) - : Dialog(eSize, 100 /* will be resized */, szCaption, false), piConfigDontShowAgainSetting(piConfigDontShowAgainSetting) + : Dialog(eSize, 100 /* will be resized */, szCaption, false), piConfigDontShowAgainSetting(piConfigDontShowAgainSetting), pKeyCopy(NULL), sCopyText() { CStdFont &rUseFont = ::GraphicsResource.TextFont; // get positions @@ -1188,8 +924,24 @@ namespace C4GUI if (btnFocus) SetFocus(btnFocus, false); // resize to actually needed size SetClientSize(GetClientRect().Wdt, GetClientRect().Hgt - caMain.GetHeight()); + // Control+C copies text to clipboard + sCopyText.Format("[%s] %s", szCaption ? szCaption : "", szMessage ? szMessage : ""); + pKeyCopy = new C4KeyBinding(C4KeyCodeEx(K_C, KEYS_Control), "GUIEditCopy", KEYSCOPE_Gui, + new DlgKeyCB(*this, &MessageDialog::KeyCopy), C4CustomKey::PRIO_CtrlOverride); } +MessageDialog::~MessageDialog() +{ + delete pKeyCopy; +} + +bool MessageDialog::KeyCopy() +{ + // Copy text to clipboard + ::Application.Copy(sCopyText); + return true; +} + // -------------------------------------------------- // ConfirmationDialog diff --git a/src/gui/C4GuiEdit.cpp b/src/gui/C4GuiEdit.cpp index b51cb7d21..a601093c9 100644 --- a/src/gui/C4GuiEdit.cpp +++ b/src/gui/C4GuiEdit.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2007 Sven Eberhardt - * Copyright (c) 2005, 2007, 2009-2011 Günther Brammer - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // room for textual deconvolution @@ -80,13 +74,13 @@ namespace C4GUI pKeyCursorEnd = RegisterCursorOp(COP_END , K_END , "GUIEditCursorEnd", eKeyPrio); pKeyEnter = new C4KeyBinding(C4KeyCodeEx(K_RETURN), "GUIEditConfirm", KEYSCOPE_Gui, new ControlKeyCB(*this, &Edit::KeyEnter), eKeyPrio); - pKeyCopy = new C4KeyBinding(C4KeyCodeEx(KEY_C, KEYS_Control), "GUIEditCopy", KEYSCOPE_Gui, + pKeyCopy = new C4KeyBinding(C4KeyCodeEx(K_C, KEYS_Control), "GUIEditCopy", KEYSCOPE_Gui, new ControlKeyCB(*this, &Edit::KeyCopy), eKeyPrio); - pKeyPaste = new C4KeyBinding(C4KeyCodeEx(KEY_V, KEYS_Control), "GUIEditPaste", KEYSCOPE_Gui, + pKeyPaste = new C4KeyBinding(C4KeyCodeEx(K_V, KEYS_Control), "GUIEditPaste", KEYSCOPE_Gui, new ControlKeyCB(*this, &Edit::KeyPaste), eKeyPrio); - pKeyCut = new C4KeyBinding(C4KeyCodeEx(KEY_X, KEYS_Control), "GUIEditCut", KEYSCOPE_Gui, + pKeyCut = new C4KeyBinding(C4KeyCodeEx(K_X, KEYS_Control), "GUIEditCut", KEYSCOPE_Gui, new ControlKeyCB(*this, &Edit::KeyCut), eKeyPrio); - pKeySelAll = new C4KeyBinding(C4KeyCodeEx(KEY_A, KEYS_Control), "GUIEditSelAll", KEYSCOPE_Gui, + pKeySelAll = new C4KeyBinding(C4KeyCodeEx(K_A, KEYS_Control), "GUIEditSelAll", KEYSCOPE_Gui, new ControlKeyCB(*this, &Edit::KeySelectAll), eKeyPrio); } @@ -150,7 +144,7 @@ namespace C4GUI // reset selection iSelectionStart = iSelectionEnd = 0; // cursor might have moved: ensure it is shown - dwLastInputTime=GetTime(); + tLastInputTime = C4TimeMilliseconds::Now(); } void Edit::DeleteSelection() @@ -162,7 +156,7 @@ namespace C4GUI // adjust cursor pos if (iCursorPos > iSelBegin) iCursorPos = Max(iSelBegin, iCursorPos - iSelEnd + iSelBegin); // cursor might have moved: ensure it is shown - dwLastInputTime=GetTime(); + tLastInputTime = C4TimeMilliseconds::Now(); // nothing selected iSelectionStart = iSelectionEnd = iSelBegin; } @@ -189,7 +183,7 @@ namespace C4GUI // advance cursor iCursorPos += iTextLen; // cursor moved: ensure it is shown - dwLastInputTime=GetTime(); + tLastInputTime = C4TimeMilliseconds::Now(); ScrollCursorInView(); } // done; return whether everything was inserted @@ -452,7 +446,7 @@ namespace C4GUI iCursorPos += iMoveLength; } // show cursor - dwLastInputTime=GetTime(); + tLastInputTime = C4TimeMilliseconds::Now(); ScrollCursorInView(); // operation recognized return true; @@ -556,7 +550,7 @@ namespace C4GUI // select all iSelectionStart=0; iSelectionEnd=iCursorPos=SLen(Text); // begin with a flashing cursor - dwLastInputTime=GetTime(); + tLastInputTime = C4TimeMilliseconds::Now(); } void Edit::OnLooseFocus() @@ -629,7 +623,8 @@ namespace C4GUI // draw edit text pDraw->TextOut(pDrawText, *pFont, 1.0f, cgo.Surface, rcClientRect.x + cgo.TargetX - iXScroll, iY0 + cgo.TargetY - 1, dwFontClr, ALeft, false); // draw cursor - if (HasDrawFocus() && !(((dwLastInputTime-GetTime())/500)%2)) + bool fBlink = ((tLastInputTime - C4TimeMilliseconds::Now())/500)%2 == 0; + if (HasDrawFocus() && fBlink) { char cAtCursor = pDrawText[iCursorPos]; pDrawText[iCursorPos]=0; int32_t w,h,wc; pFont->GetTextExtent(pDrawText, w, h, false); diff --git a/src/gui/C4GuiLabels.cpp b/src/gui/C4GuiLabels.cpp index 4b46642e7..cbdad8150 100644 --- a/src/gui/C4GuiLabels.cpp +++ b/src/gui/C4GuiLabels.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2007 Sven Eberhardt - * Copyright (c) 2008, 2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // eye candy @@ -151,12 +147,10 @@ namespace C4GUI // calculations for automatic scrolling int32_t iXOff = 0; if (iAlign == ALeft) iXOff += 5; - if (tAutoScrollDelay) + if (iAutoScrollDelay) { - time_t tNow = GetTime(); - if (!tLastChangeTime) - tLastChangeTime = tNow; - else if (tNow - tLastChangeTime >= tAutoScrollDelay) + C4TimeMilliseconds tNow = C4TimeMilliseconds::Now(); + if (tNow >= tLastChangeTime + iAutoScrollDelay) { if (!iScrollDir) iScrollDir=1; int32_t iMaxScroll = Max(pFont->GetTextWidth(sText.getData(), true) + (x0 - rcBounds.x) + iXOff + GetRightIndent() - rcBounds.Wdt, 0); @@ -198,6 +192,10 @@ namespace C4GUI UpdateOwnPos(); } + void WoodenLabel::ResetAutoScroll() + { + iScrollPos = iScrollDir = 0; + } // -------------------------------------------------- // MultilineLabel diff --git a/src/gui/C4GuiListBox.cpp b/src/gui/C4GuiListBox.cpp index da629ec84..5bc8d873a 100644 --- a/src/gui/C4GuiListBox.cpp +++ b/src/gui/C4GuiListBox.cpp @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2006, 2008 Sven Eberhardt - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // container for a dynamic number of vertically stacked controls diff --git a/src/gui/C4GuiMenu.cpp b/src/gui/C4GuiMenu.cpp index c01b70c07..b254d881b 100644 --- a/src/gui/C4GuiMenu.cpp +++ b/src/gui/C4GuiMenu.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2007 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2006, 2008, 2010 Günther Brammer - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // context menu diff --git a/src/gui/C4GuiTabular.cpp b/src/gui/C4GuiTabular.cpp index 1af1c30e8..34c718564 100644 --- a/src/gui/C4GuiTabular.cpp +++ b/src/gui/C4GuiTabular.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2007 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // generic user interface // tab control @@ -364,7 +358,7 @@ namespace C4GUI void Tabular::DoCaptionScroll(int32_t iDir) { // store time of scrolling change - tLastScrollTime = GetTime(); + tLastScrollTime = C4TimeMilliseconds::Now(); // change scrolling within max range int32_t iAvailableTabSpace = rcBounds.Wdt; int32_t iScrollPinSize = GetTopSize(); @@ -377,19 +371,25 @@ namespace C4GUI if (!fDrawSelf) return; bool fGfx = HasGfx(); // execute scrolling - if ((fScrollingLeftDown || fScrollingRightDown) && GetTime()-tLastScrollTime >= C4GUI_TabCaptionScrollTime) + bool fCaptionScrollDelayOver = C4TimeMilliseconds::Now() - tLastScrollTime >= C4GUI_TabCaptionScrollTime; + if ((fScrollingLeftDown || fScrollingRightDown) && fCaptionScrollDelayOver) DoCaptionScroll(fScrollingRightDown - fScrollingLeftDown); // border if (!fGfx) Draw3DFrame(cgo, false, 1, 0xaf, eTabPos!=tbTop, GetTopSize(), eTabPos!=tbLeft, GetLeftSize()); // calc positions int32_t x0 = cgo.TargetX + rcBounds.x + GetLeftSize(), - y0 = cgo.TargetY + rcBounds.y + GetTopSize(), - x1 = cgo.TargetX + rcBounds.x + rcBounds.Wdt - 1, - y1 = cgo.TargetY + rcBounds.y + rcBounds.Hgt - 1; + y0 = cgo.TargetY + rcBounds.y + GetTopSize(), + x1 = cgo.TargetX + rcBounds.x + rcBounds.Wdt - 1, + y1 = cgo.TargetY + rcBounds.y + rcBounds.Hgt - 1; // main area BG if (!fGfx) pDraw->DrawBoxDw(cgo.Surface, x0,y0,x1,y1, C4GUI_StandardBGColor); // no tabs? - if (!eTabPos) return; + if (!eTabPos) + { + if (fGfx) + pfctBack->DrawX(cgo.Surface, x0, y0, x1-x0+1, y1-y0+1); + return; + } bool fLeft = (eTabPos == tbLeft); // top or left bar int32_t d=(fLeft ? y0 : x0)+iSheetOff; // current tab position (leave some space to the left/top) diff --git a/src/gui/C4KeyboardInput.cpp b/src/gui/C4KeyboardInput.cpp index 66d3d5e9c..1ad973e4b 100644 --- a/src/gui/C4KeyboardInput.cpp +++ b/src/gui/C4KeyboardInput.cpp @@ -1,27 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006, 2008-2010 Sven Eberhardt - * Copyright (c) 2005-2006 Günther Brammer - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005-2006, 2008-2010 Asmageddon - * Copyright (c) 2008 Julian Raschke - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2009-2010 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Martin Plicht - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Keyboard input mapping to engine functions @@ -33,8 +23,9 @@ #include #ifdef USE_X11 -#include -#include // XConvertCase +#include +#include +#include #endif #include @@ -109,230 +100,127 @@ struct C4KeyCodeMapEntry const char *szShortName; }; -#ifdef _WIN32 -const C4KeyCodeMapEntry KeyCodeMap [] = -{ - { VK_CANCEL , "Cancel" , NULL }, - - { VK_BACK , "Backspace" , NULL }, - { VK_TAB , "Tab" , NULL }, - { VK_CLEAR , "Clear" , NULL }, - { VK_RETURN , "Return" , NULL }, - - { VK_SHIFT , "KeyShift" , "Shift" }, - { VK_CONTROL , "KeyControl" , "Control" }, - { VK_MENU , "Menu" , NULL }, - { VK_PAUSE , "Pause" , NULL }, - - { VK_CAPITAL , "Capital" , NULL }, - { VK_KANA , "Kana" , NULL }, - { VK_HANGEUL , "Hangeul" , NULL }, - { VK_HANGUL , "Hangul" , NULL }, - { VK_JUNJA , "Junja" , NULL }, - { VK_FINAL , "Final" , NULL }, - { VK_HANJA , "Hanja" , NULL }, - { VK_KANJI , "Kanji" , NULL }, - { VK_ESCAPE , "Escape" , "Esc" }, - { VK_ESCAPE , "Esc" ,NULL }, - { VK_CONVERT , "Convert" , NULL }, - { VK_NONCONVERT , "Noconvert" , NULL }, - { VK_ACCEPT , "Accept" , NULL }, - { VK_MODECHANGE , "Modechange" , NULL }, - - { VK_SPACE , "Space" , "Sp" }, - - { VK_PRIOR , "Prior" , NULL }, - { VK_NEXT , "Next" , NULL }, - { VK_END , "End" , NULL }, - { VK_HOME , "Home" , NULL }, - { VK_LEFT , "Left" , NULL }, - { VK_UP , "Up" , NULL }, - { VK_RIGHT , "Right" , NULL }, - { VK_DOWN , "Down" , NULL }, - { VK_SELECT , "Select" , NULL }, - { VK_PRINT , "Print" , NULL }, - { VK_EXECUTE , "Execute" , NULL }, - { VK_SNAPSHOT , "Snapshot" , NULL }, - { VK_INSERT , "Insert" , "Ins" }, - { VK_DELETE , "Delete" , "Del" }, - { VK_HELP , "Help" , NULL }, - - { '0' , "0" , NULL }, - { '1' , "1" , NULL }, - { '2' , "2" , NULL }, - { '3' , "3" , NULL }, - { '4' , "4" , NULL }, - { '5' , "5" , NULL }, - { '6' , "6" , NULL }, - { '7' , "7" , NULL }, - { '8' , "8" , NULL }, - { '9' , "9" , NULL }, - - { 'A' , "A" , NULL }, - { 'B' , "B" , NULL }, - { 'C' , "C" , NULL }, - { 'D' , "D" , NULL }, - { 'E' , "E" , NULL }, - { 'F' , "F" , NULL }, - { 'G' , "G" , NULL }, - { 'H' , "H" , NULL }, - { 'I' , "I" , NULL }, - { 'J' , "J" , NULL }, - { 'K' , "K" , NULL }, - { 'L' , "L" , NULL }, - { 'M' , "M" , NULL }, - { 'N' , "N" , NULL }, - { 'O' , "O" , NULL }, - { 'P' , "P" , NULL }, - { 'Q' , "Q" , NULL }, - { 'R' , "R" , NULL }, - { 'S' , "S" , NULL }, - { 'T' , "T" , NULL }, - { 'U' , "U" , NULL }, - { 'V' , "V" , NULL }, - { 'W' , "W" , NULL }, - { 'X' , "X" , NULL }, - { 'Y' , "Y" , NULL }, - { 'Z' , "Z" , NULL }, - { VK_OEM_COMMA , "Comma" , NULL }, - { VK_OEM_PERIOD , "Period" , NULL }, - { VK_OEM_7 , "Apostrophe", NULL }, - - { VK_LWIN , "WinLeft" , NULL }, - { VK_RWIN , "WinRight" , NULL }, - { VK_APPS , "Apps" , NULL }, - - { VK_NUMPAD0 , "Num0" , "N0" }, - { VK_NUMPAD1 , "Num1" , "N1" }, - { VK_NUMPAD2 , "Num2" , "N2" }, - { VK_NUMPAD3 , "Num3" , "N3" }, - { VK_NUMPAD4 , "Num4" , "N4" }, - { VK_NUMPAD5 , "Num5" , "N5" }, - { VK_NUMPAD6 , "Num6" , "N6" }, - { VK_NUMPAD7 , "Num7" , "N7" }, - { VK_NUMPAD8 , "Num8" , "N8" }, - { VK_NUMPAD9 , "Num9" , "N9" }, - { VK_MULTIPLY , "Multiply" , "N*" }, - { VK_ADD , "Add" , "N+" }, - { VK_SEPARATOR , "Separator" , "NSep" }, - { VK_SUBTRACT , "Subtract" , "N-" }, - { VK_DECIMAL , "Decimal" , "N," }, - { VK_DIVIDE , "Divide" , "N/" }, - { VK_F1 , "F1" , NULL }, - { VK_F2 , "F2" , NULL }, - { VK_F3 , "F3" , NULL }, - { VK_F4 , "F4" , NULL }, - { VK_F5 , "F5" , NULL }, - { VK_F6 , "F6" , NULL }, - { VK_F7 , "F7" , NULL }, - { VK_F8 , "F8" , NULL }, - { VK_F9 , "F9" , NULL }, - { VK_F10 , "F10" , NULL }, - { VK_F11 , "F11" , NULL }, - { VK_F12 , "F12" , NULL }, - { VK_F13 , "F13" , NULL }, - { VK_F14 , "F14" , NULL }, - { VK_F15 , "F15" , NULL }, - { VK_F16 , "F16" , NULL }, - { VK_F17 , "F17" , NULL }, - { VK_F18 , "F18" , NULL }, - { VK_F19 , "F19" , NULL }, - { VK_F20 , "F20" , NULL }, - { VK_F21 , "F21" , NULL }, - { VK_F22 , "F22" , NULL }, - { VK_F23 , "F23" , NULL }, - { VK_F24 , "F24" , NULL }, - { VK_NUMLOCK , "NumLock" , "NLock" }, - { VK_SCROLL , "Scroll" , NULL }, - - { VK_PROCESSKEY , "PROCESSKEY" , NULL }, - -#if defined VK_SLEEP && defined VK_OEM_NEC_EQUAL - { VK_SLEEP , "Sleep" , NULL }, - - { VK_OEM_NEC_EQUAL , "OEM_NEC_EQUAL" , NULL }, - - { VK_OEM_FJ_JISHO , "OEM_FJ_JISHO" , NULL }, - { VK_OEM_FJ_MASSHOU , "OEM_FJ_MASSHOU" , NULL }, - { VK_OEM_FJ_TOUROKU , "OEM_FJ_TOUROKU" , NULL }, - { VK_OEM_FJ_LOYA , "OEM_FJ_LOYA" , NULL }, - { VK_OEM_FJ_ROYA , "OEM_FJ_ROYA" , NULL }, - - { VK_BROWSER_BACK , "BROWSER_BACK" , NULL }, - { VK_BROWSER_FORWARD , "BROWSER_FORWARD" , NULL }, - { VK_BROWSER_REFRESH , "BROWSER_REFRESH" , NULL }, - { VK_BROWSER_STOP , "BROWSER_STOP" , NULL }, - { VK_BROWSER_SEARCH , "BROWSER_SEARCH" , NULL }, - { VK_BROWSER_FAVORITES , "BROWSER_FAVORITES" , NULL }, - { VK_BROWSER_HOME , "BROWSER_HOME" , NULL }, - - { VK_VOLUME_MUTE , "VOLUME_MUTE" , NULL }, - { VK_VOLUME_DOWN , "VOLUME_DOWN" , NULL }, - { VK_VOLUME_UP , "VOLUME_UP" , NULL }, - { VK_MEDIA_NEXT_TRACK , "MEDIA_NEXT_TRACK" , NULL }, - { VK_MEDIA_PREV_TRACK , "MEDIA_PREV_TRACK" , NULL }, - { VK_MEDIA_STOP , "MEDIA_STOP" , NULL }, - { VK_MEDIA_PLAY_PAUSE , "MEDIA_PLAY_PAUSE" , NULL }, - { VK_LAUNCH_MAIL , "LAUNCH_MAIL" , NULL }, - { VK_LAUNCH_MEDIA_SELECT , "LAUNCH_MEDIA_SELECT" , NULL }, - { VK_LAUNCH_APP1 , "LAUNCH_APP1" , NULL }, - { VK_LAUNCH_APP2 , "LAUNCH_APP2" , NULL }, - - { VK_OEM_1 , "Comma_US" , "Ü" }, // German hax - { VK_OEM_PLUS , "OEM +" , "+" }, - { VK_OEM_COMMA , "OEM ," , "," }, - { VK_OEM_MINUS , "OEM -" , "-" }, - { VK_OEM_PERIOD , "OEM ." , "." }, - { VK_OEM_2 , "OEM 2" , "2" }, - { VK_OEM_3 , "OEM Ö" , "Ö" }, // German hax - { VK_OEM_4 , "OEM 4" , "4" }, - { VK_OEM_5 , "OEM 5" , "5" }, - { VK_OEM_6 , "OEM 6" , "6" }, - { VK_OEM_7 , "OEM Ä" , "Ä" }, // German hax - { VK_OEM_8 , "OEM 8" , "8" }, - { VK_OEM_AX , "AX" , "AX" }, - { VK_OEM_102 , "Less" , "<" }, // German hax - { VK_OEM_102 , "Backslash", NULL }, // German hax - { VK_ICO_HELP , "Help" , "Help" }, - { VK_ICO_00 , "ICO_00" , "00" }, - - { VK_ICO_CLEAR , "ICO_CLEAR" , NULL }, - - { VK_PACKET , "PACKET" , NULL }, - - { VK_OEM_RESET , "OEM_RESET" , NULL }, - { VK_OEM_JUMP , "OEM_JUMP" , NULL }, - { VK_OEM_PA1 , "OEM_PA1" , NULL }, - { VK_OEM_PA2 , "OEM_PA2" , NULL }, - { VK_OEM_PA3 , "OEM_PA3" , NULL }, - { VK_OEM_WSCTRL , "OEM_WSCTRL" , NULL }, - { VK_OEM_CUSEL , "OEM_CUSEL" , NULL }, - { VK_OEM_ATTN , "OEM_ATTN" , NULL }, - { VK_OEM_FINISH , "OEM_FINISH" , NULL }, - { VK_OEM_COPY , "OEM_COPY" , NULL }, - { VK_OEM_AUTO , "OEM_AUTO" , NULL }, - { VK_OEM_ENLW , "OEM_ENLW" , NULL }, - { VK_OEM_BACKTAB , "OEM_BACKTAB" , NULL }, -#endif - - { VK_ATTN , "ATTN" , NULL }, - { VK_CRSEL , "CRSEL" , NULL }, - { VK_EXSEL , "EXSEL" , NULL }, - { VK_EREOF , "EREOF" , NULL }, - { VK_PLAY , "PLAY" , NULL }, - { VK_ZOOM , "ZOOM" , NULL }, - { VK_NONAME , "NONAME" , NULL }, - { VK_PA1 , "PA1" , NULL }, - { VK_OEM_CLEAR , "OEM_CLEAR" , NULL }, - - { KEY_Any, "Any" , NULL}, - { KEY_Default, "None", NULL}, - { KEY_Undefined, NULL, NULL } +#if defined(USE_WIN32_WINDOWS) || defined(USE_X11) +const C4KeyCodeMapEntry KeyCodeMap[] = { + {K_ESCAPE, "Escape", "Esc"}, + {K_1, "1", NULL}, + {K_2, "2", NULL}, + {K_3, "3", NULL}, + {K_4, "4", NULL}, + {K_5, "5", NULL}, + {K_6, "6", NULL}, + {K_7, "7", NULL}, + {K_8, "8", NULL}, + {K_9, "9", NULL}, + {K_0, "0", NULL}, + {K_MINUS, "Minus", "-"}, + {K_EQUAL, "Equal", "="}, + {K_BACK, "BackSpace", NULL}, + {K_TAB, "Tab", NULL}, + {K_Q, "Q", NULL}, + {K_W, "W", NULL}, + {K_E, "E", NULL}, + {K_R, "R", NULL}, + {K_T, "T", NULL}, + {K_Y, "Y", NULL}, + {K_U, "U", NULL}, + {K_I, "I", NULL}, + {K_O, "O", NULL}, + {K_P, "P", NULL}, + {K_LEFT_BRACKET,"LeftBracket", "["}, + {K_RIGHT_BRACKET,"RightBracket","]"}, + {K_RETURN, "Return", "Ret"}, + {K_CONTROL_L, "LeftControl", "LCtrl"}, + {K_A, "A", NULL}, + {K_S, "S", NULL}, + {K_D, "D", NULL}, + {K_F, "F", NULL}, + {K_G, "G", NULL}, + {K_H, "H", NULL}, + {K_J, "J", NULL}, + {K_K, "K", NULL}, + {K_L, "L", NULL}, + {K_SEMICOLON, "Semicolon", ";"}, + {K_APOSTROPHE, "Apostrophe", "'"}, + {K_GRAVE_ACCENT,"GraveAccent", "`"}, + {K_SHIFT_L, "LeftShift", "LShift"}, + {K_BACKSLASH, "Backslash", "\\"}, + {K_Z, "Z", NULL}, + {K_X, "X", NULL}, + {K_C, "C", NULL}, + {K_V, "V", NULL}, + {K_B, "B", NULL}, + {K_N, "N", NULL}, + {K_M, "M", NULL}, + {K_COMMA, "Comma", ","}, + {K_PERIOD, "Period", "."}, + {K_SLASH, "Slash", "/"}, + {K_SHIFT_R, "RightShift", "RShift"}, + {K_MULTIPLY, "Multiply", "N*"}, + {K_ALT_L, "LeftAlt", "LAlt"}, + {K_SPACE, "Space", "Sp"}, + {K_CAPS, "Capslock", NULL}, + {K_F1, "F1", NULL}, + {K_F2, "F2", NULL}, + {K_F3, "F3", NULL}, + {K_F4, "F4", NULL}, + {K_F5, "F5", NULL}, + {K_F6, "F6", NULL}, + {K_F7, "F7", NULL}, + {K_F8, "F8", NULL}, + {K_F9, "F9", NULL}, + {K_F10, "F10", NULL}, + {K_NUM, "NumLock", "NLock"}, + {K_SCROLL, "ScrollLock", "SLock"}, + {K_NUM7, "Num7", "N7"}, + {K_NUM8, "Num8", "N8"}, + {K_NUM9, "Num9", "N9"}, + {K_SUBTRACT, "Subtract", "N-"}, + {K_NUM4, "Num4", "N4"}, + {K_NUM5, "Num5", "N5"}, + {K_NUM6, "Num6", "N6"}, + {K_ADD, "Add", "N+"}, + {K_NUM1, "Num1", "N1"}, + {K_NUM2, "Num2", "N2"}, + {K_NUM3, "Num3", "N3"}, + {K_NUM0, "Num0", "N0"}, + {K_DECIMAL, "Decimal", "N,"}, + {K_86, "|<>", NULL}, + {K_F11, "F11", NULL}, + {K_F12, "F12", NULL}, + {K_NUM_RETURN, "NumReturn", "NRet"}, + {K_CONTROL_R, "RightControl", "RCtrl"}, + {K_DIVIDE, "Divide", "N/"}, + {K_ALT_R, "RightAlt", "RAlt"}, + {K_HOME, "Home", NULL}, + {K_UP, "Up", NULL}, + {K_PAGEUP, "PageUp", NULL}, + {K_LEFT, "Left", NULL}, + {K_RIGHT, "Right", NULL}, + {K_END, "End", NULL}, + {K_DOWN, "Down", NULL}, + {K_PAGEDOWN, "PageDown", NULL}, + {K_INSERT, "Insert", "Ins"}, + {K_DELETE, "Delete", "Del"}, + {K_PAUSE, "Pause", NULL}, + {K_WIN_L, "LeftWin", "LWin"}, + {K_WIN_R, "RightWin", "RWin"}, + {K_MENU, "Menu", NULL}, + {K_PRINT, "Print", NULL}, + {0x00, NULL, NULL} }; #elif defined(USE_COCOA) #include "CocoaKeycodeMap.h" #endif +C4KeyCode C4KeyCodeEx::GetKeyByScanCode(const char *scan_code) +{ + // scan code is in hex format + unsigned int scan_code_int; + if (sscanf(scan_code, "$%x", &scan_code_int) != 1) return KEY_Undefined; + return scan_code_int; +} + C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName) { // direct key code? @@ -340,6 +228,8 @@ C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName) { unsigned int dwRVal; if (sscanf(sName.getData(), "\\x%x", &dwRVal) == 1) return dwRVal; + // scan code + if (*sName.getData() == '$') return GetKeyByScanCode(sName.getData()); // direct gamepad code #ifdef _WIN32 if (!strnicmp(sName.getData(), "Joy", 3)) @@ -432,29 +322,16 @@ C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName) } } -#if defined(_WIN32) || defined(USE_COCOA) +#if defined(USE_WIN32_WINDOWS) || defined(USE_COCOA) || defined(USE_X11) // query map const C4KeyCodeMapEntry *pCheck = KeyCodeMap; - while (pCheck->szName) - if (SEqualNoCase(sName.getData(), pCheck->szName)) break; else ++pCheck; - return pCheck->wCode; -#elif defined(USE_X11) - KeySym result = XStringToKeysym(sName.getData()); - // Some keysysm strings start with a lowercase letter, so also check that. - if (!result) - { - StdCopyStrBuf sName2(sName); - sName2.ToLowerCase(); - result = XStringToKeysym(sName2.getData()); - if(!result) - return KEY_Undefined; + while (pCheck->szName) { + if (SEqualNoCase(sName.getData(), pCheck->szName)) { + return(pCheck->wCode); + } + ++pCheck; } - - // Use the lowercase keysym in case there is a difference because this - // is what's reported for actual key presses. - KeySym lower, upper; - XConvertCase(result, &lower, &upper); - return lower; + return KEY_Undefined; #elif defined(USE_SDL_MAINLOOP) for (C4KeyCode k = 0; k < SDLK_LAST; ++k) { @@ -529,7 +406,12 @@ StdStrBuf C4KeyCodeEx::KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool } } -#if defined(_WIN32) || defined(USE_COCOA) + // it's a keyboard key + if (!fHumanReadable) { + // for config files and such: dump scancode + return FormatString("$%x", static_cast(wCode)); + } +#if defined(_WIN32) // TODO: Works? // StdStrBuf Name; Name.SetLength(1000); @@ -541,6 +423,13 @@ StdStrBuf C4KeyCodeEx::KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool // Name.SetLength(res); // return Name; + wchar_t buf[100]; + int len = GetKeyNameText(wCode<<16, buf, 100); + if (len > 0) { + // buf is nullterminated name + return StdStrBuf(buf); + } +#elif defined (USE_COCOA) // query map const C4KeyCodeMapEntry *pCheck = KeyCodeMap; while (pCheck->szName) @@ -548,15 +437,29 @@ StdStrBuf C4KeyCodeEx::KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool // not found: Compose as direct code return FormatString("\\x%x", static_cast(wCode)); #elif defined(USE_X11) - return StdStrBuf(XKeysymToString(wCode)); + Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); + KeySym keysym = (KeySym)XkbKeycodeToKeysym(dpy,wCode+8,0,0); + char* name = NULL; + if (keysym != NoSymbol) { // is the keycode without shift modifiers mapped to a symbol? + #if defined(USE_GTK3) + name = gtk_accelerator_get_label_with_keycode(dpy, keysym, wCode+8, (GdkModifierType)0); + #else + name = gtk_accelerator_get_label(keysym, (GdkModifierType)0); + #endif + } + if (name) { // is there a string representation of the keysym? + // prevent memleak + StdStrBuf buf; + buf.Take(name); + return buf; + } #elif defined(USE_SDL_MAINLOOP) return StdStrBuf(getKeyName(wCode).c_str()); -#else - return StdStrBuf("unknown"); #endif + return FormatString("$%x", static_cast(wCode)); } -StdStrBuf C4KeyCodeEx::ToString(bool fHumanReadable, bool fShort) +StdStrBuf C4KeyCodeEx::ToString(bool fHumanReadable, bool fShort) const { static StdStrBuf sResult; sResult.Clear(); @@ -583,16 +486,25 @@ StdStrBuf C4KeyCodeEx::ToString(bool fHumanReadable, bool fShort) /* ----------------- C4KeyCodeEx ------------------ */ -void C4KeyCodeEx::CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBufIfUndefined) +void C4KeyCodeEx::CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBuf) { if (pComp->isCompiler()) { // reading from file StdStrBuf sCode; + bool is_scan_code; + // read shifts DWORD dwSetShift = 0; for (;;) { + is_scan_code = pComp->Separator(StdCompiler::SEP_DOLLAR); + if (!is_scan_code) pComp->NoSeparator(); pComp->Value(mkParAdapt(sCode, StdCompiler::RCT_Idtf)); + if (is_scan_code) // scan codes start with $. Reassamble the two tokens that were split by StdCompiler + { + sCode.Take(FormatString("$%s", sCode.getData())); + break; + } if (!pComp->Separator(StdCompiler::SEP_PLUS)) break; // no more separator: Parse this as keyboard code // try to convert to shift state C4KeyShiftState eAddState = String2KeyShift(sCode); @@ -607,10 +519,9 @@ void C4KeyCodeEx::CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBufIfUndefined) C4KeyCode eCode = String2KeyCode(sCode); if (eCode == KEY_Undefined) { - if (pOutBufIfUndefined) + if (pOutBuf) { - // unknown key, but an output buffer for unknown keys was provided. Use it. - pOutBufIfUndefined->Take(std::move(sCode)); + // unknown key, but an output buffer for unknown keys was provided. No failure; caller might resolve key. eCode = KEY_Default; } else @@ -620,6 +531,7 @@ void C4KeyCodeEx::CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBufIfUndefined) } dwShift = dwSetShift; Key = eCode; + if (pOutBuf) pOutBuf->Take(std::move(sCode)); } } else diff --git a/src/gui/C4KeyboardInput.h b/src/gui/C4KeyboardInput.h index c18a04af1..6543927a8 100644 --- a/src/gui/C4KeyboardInput.h +++ b/src/gui/C4KeyboardInput.h @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006, 2009 Sven Eberhardt - * Copyright (c) 2005 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Keyboard input mapping to engine functions @@ -200,7 +196,7 @@ struct C4KeyCodeEx static C4KeyShiftState String2KeyShift(const StdStrBuf &sName); static C4KeyCode String2KeyCode(const StdStrBuf &sName); static StdStrBuf KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool fShort); - StdStrBuf ToString(bool fHumanReadable, bool fShort); + StdStrBuf ToString(bool fHumanReadable, bool fShort) const; static StdStrBuf KeyShift2String(C4KeyShiftState eShift); // comparison operator for map access @@ -214,12 +210,14 @@ struct C4KeyCodeEx return Key == v2.Key && dwShift == v2.dwShift; } - void CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBufIfUndefined=NULL); + void CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBuf=NULL); C4KeyCodeEx(C4KeyCode Key = KEY_Default, C4KeyShiftState Shift = KEYS_None, bool fIsRepeated = false) : Key(Key), dwShift(Shift), fRepeated(fIsRepeated) {} bool IsRepeated() const { return fRepeated; } +private: + static C4KeyCode GetKeyByScanCode(const char *scan_code); }; // extra data associated with a key event diff --git a/src/gui/C4LoaderScreen.cpp b/src/gui/C4LoaderScreen.cpp index 687726398..d69712432 100644 --- a/src/gui/C4LoaderScreen.cpp +++ b/src/gui/C4LoaderScreen.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002-2003, 2005-2007 Sven Eberhardt - * Copyright (c) 2003 Matthes Bender - * Copyright (c) 2005-2006, 2009-2010 Günther Brammer - * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // startup screen @@ -159,7 +155,7 @@ void C4LoaderScreen::Draw(C4Facet &cgo, int iProgress, C4LogBuffer *pLog, int Pr // Background (loader) fctBackground.DrawFullScreen(cgo); // draw scenario title - pDraw->StringOut(Game.ScenarioTitle.getData(), TitleFont, 1.0f, cgo.Surface, cgo.Wdt-iHIndent, cgo.Hgt-iVIndent-iLogBoxHgt-iVMargin-iProgressBarHgt-iVMargin-TitleFont.iLineHgt, 0xdddddddd, ARight, false); + pDraw->StringOut(Game.ScenarioTitle.getData(), TitleFont, 1.0f, cgo.Surface, cgo.Wdt-iHIndent, cgo.Hgt-iVIndent-iLogBoxHgt-iVMargin-iProgressBarHgt-iVMargin-TitleFont.GetLineHeight(), 0xdddddddd, ARight, false); // draw info /*if (szInfo) pDraw->TextOutDw(szInfo, cgo.Surface, cgo.Wdt/2, cgo.Hgt/2+20);*/ @@ -176,13 +172,13 @@ void C4LoaderScreen::Draw(C4Facet &cgo, int iProgress, C4LogBuffer *pLog, int Pr pDraw->DrawBoxDw(cgo.Surface, iHIndent+1, cgo.Hgt-iVIndent-iLogBoxHgt-iVMargin-iProgressBarHgt+1, iHIndent+1+iProgressBarWdt*iProgress/100, cgo.Hgt-iVIndent-iLogBoxHgt-iVMargin-1, 0xb0ff0000); } pDraw->StringOut(FormatString("%i%%", iProgress).getData(), rProgressBarFont, 1.0f, cgo.Surface, - cgo.Wdt/2, cgo.Hgt-iVIndent-iLogBoxHgt-iVMargin-rProgressBarFont.iLineHgt/2-iProgressBarHgt/2, 0xffffffff, + cgo.Wdt/2, cgo.Hgt-iVIndent-iLogBoxHgt-iVMargin-rProgressBarFont.GetLineHeight()/2-iProgressBarHgt/2, 0xffffffff, ACenter, true); // draw log box if (pLog) { pDraw->DrawBoxDw(cgo.Surface, iHIndent, cgo.Hgt-iVIndent-iLogBoxHgt, cgo.Wdt-iHIndent, cgo.Hgt-iVIndent, 0x7f000000); - int iLineHgt=int(fLogBoxFontZoom*LogFont.iLineHgt); if (!iLineHgt) iLineHgt=5; + int iLineHgt=int(fLogBoxFontZoom*LogFont.GetLineHeight()); if (!iLineHgt) iLineHgt=5; int iLinesVisible = (iLogBoxHgt-2*iLogBoxMargin)/iLineHgt; int iX = iHIndent+iLogBoxMargin; int iY = cgo.Hgt-iVIndent-iLogBoxHgt+iLogBoxMargin; diff --git a/src/gui/C4LoaderScreen.h b/src/gui/C4LoaderScreen.h index abfb7f2f6..58e889c77 100644 --- a/src/gui/C4LoaderScreen.h +++ b/src/gui/C4LoaderScreen.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003 Sven Eberhardt - * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // startup screen diff --git a/src/gui/C4MainMenu.cpp b/src/gui/C4MainMenu.cpp index 8ee923c14..ec7eff478 100644 --- a/src/gui/C4MainMenu.cpp +++ b/src/gui/C4MainMenu.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003, 2007-2008 Matthes Bender - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2003, 2007-2008 Sven Eberhardt - * Copyright (c) 2004, 2008-2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Engine internal C4Menus: Main menu, Options, Player join, Hostility, etc. @@ -670,7 +664,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) if (SEqual(szCommand+13,"NewPlayer")) return ActivateNewPlayer(Player); if (SEqual(szCommand+13,"Goals")) { - ::Control.DoInput(CID_Script, new C4ControlScript(FormatString("ActivateGameGoalMenu(%d)", Player).getData()), CDT_Queue); + ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::ActivateGoalMenu(::Players.Get(Player)), CDT_Queue); return true; } if (SEqual(szCommand+13,"Rules")) return ActivateRules(Player); @@ -701,8 +695,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) int32_t iOpponent; sscanf(szCommand+13,"%i",&iOpponent); C4Player *pOpponent = ::Players.Get(iOpponent); if (!pOpponent || pOpponent->GetType() != C4PT_User) return false; - // TODO: doesn't really work - Game.Input.Add(CID_Script, new C4ControlScript(FormatString("SetHostility(%d, %d, !Hostile(%d, %d, true))", Player, iOpponent, Player, iOpponent).getData(), C4ControlScript::SCOPE_Global, true)); + ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::SetHostility(::Players.Get(Player), pOpponent, !::Players.HostilityDeclared(Player, pOpponent->Number)), CDT_Queue); return true; } // Abort @@ -714,7 +707,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) // Surrender if (SEqual2(szCommand,"Surrender")) { - ::Control.DoInput(CID_Script, new C4ControlScript(FormatString("SurrenderPlayer(%d)", Player).getData()), CDT_Queue); + ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::Surrender(::Players.Get(Player)), CDT_Queue); return true; } // Save game @@ -813,7 +806,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) Close(true); C4Object *pObj; C4ID idItem(szCommand+12); if ((pObj = ::Objects.Find(idItem))) - ::Control.DoInput(CID_Script, new C4ControlScript(FormatString("Activate(%d)", Player).getData(), pObj->Number), CDT_Queue); + ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::ActivateGoal(::Players.Get(Player), pObj), CDT_Queue); else return false; return true; @@ -837,7 +830,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) // check if it's still allowed if (!Game.Teams.IsTeamSwitchAllowed()) return false; // OK, join this team - ::Control.DoInput(CID_Script, new C4ControlScript(FormatString("SetPlayerTeam(%d,%d)", (int)Player, (int)idTeam).getData()), CDT_Queue); + ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::SetTeam(::Players.Get(Player), idTeam), CDT_Queue); return true; } // Observe diff --git a/src/gui/C4MainMenu.h b/src/gui/C4MainMenu.h index 74fb7a2e0..05bf72d22 100644 --- a/src/gui/C4MainMenu.h +++ b/src/gui/C4MainMenu.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2008 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Engine internal C4Menus: Main menu, Options, Player join, Hostility, etc. diff --git a/src/gui/C4Menu.cpp b/src/gui/C4Menu.cpp index 090e19d20..dccc182bc 100644 --- a/src/gui/C4Menu.cpp +++ b/src/gui/C4Menu.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007-2008 Matthes Bender - * Copyright (c) 2001-2008 Sven Eberhardt - * Copyright (c) 2004-2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* In-game menu as used by objects, players, and fullscreen options */ @@ -123,7 +119,7 @@ int32_t C4MenuItem::GetSymbolWidth(int32_t iForHeight) { // Context or dialog menus if (iStyle==C4MN_Style_Context || (iStyle==C4MN_Style_Dialog && Symbol.Surface)) - return Max(Symbol.Wdt * iForHeight / Max(Symbol.Hgt, 1), iForHeight); + return Max(Symbol.Wdt * iForHeight / Max(Symbol.Hgt, 1.0f), static_cast(iForHeight)); // Info menus if (iStyle==C4MN_Style_Info && Symbol.Surface && Symbol.Wdt) return Symbol.Wdt; @@ -157,7 +153,7 @@ void C4MenuItem::DrawElement(C4TargetFacet &cgo) // Draw if there is no text progression at all (TextDisplayProgress==-1, or if it's progressed far enough already (TextDisplayProgress>0) if(pSymbolObj && TextDisplayProgress) { - pSymbolObj->DrawPicture(cgoSymbolOut, false, NULL, NULL); + pSymbolObj->DrawPicture(cgoSymbolOut, false, NULL); } else if (pSymbolGraphics && TextDisplayProgress) { @@ -205,7 +201,7 @@ void C4MenuItem::DrawElement(C4TargetFacet &cgo) { char szCount[10+1]; sprintf(szCount,"%ix",Count); - pDraw->TextOut(szCount,::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X+cgoItemText.Wdt-1,cgoItemText.Y+cgoItemText.Hgt-1-::GraphicsResource.FontRegular.iLineHgt,C4Draw::DEFAULT_MESSAGE_COLOR,ARight); + pDraw->TextOut(szCount, ::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface, cgoItemText.X+cgoItemText.Wdt-1, cgoItemText.Y+cgoItemText.Hgt-1-::GraphicsResource.FontRegular.GetLineHeight(), C4Draw::DEFAULT_MESSAGE_COLOR, ARight); } } @@ -243,30 +239,6 @@ void C4MenuItem::MouseEnter(C4GUI::CMouse &rMouse) ParentClass::MouseEnter(rMouse); } -void C4MenuItem::DoDragging(C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam) -{ - // is this a drag element? - if (!IsDragElement()) { rMouse.pDragElement = NULL; } - // check if outside drag range - if (Max(Abs(iX - iDragX), Abs(iY - iDragY)) >= C4MC_DragSensitivity) - { - // then do a drag! - ::MouseControl.StartConstructionDrag(id); - // this disables the window: Release mouse - rMouse.ReleaseButtons(); - rMouse.pDragElement = NULL; - rMouse.pMouseOverElement = NULL; - } -} - -void C4MenuItem::StopDragging(C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam) -{ - // drag stop: Nothing to do, really - // Mouse up will be processed by regular procedure - rMouse.pDragElement = NULL; -} - - // ----------------------------------------------------------- // C4Menu @@ -427,13 +399,14 @@ bool C4Menu::AddItem(C4MenuItem *pNew, const char *szCaption, const char *szComm C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable) { #ifdef DEBUGREC_MENU - if (pObject) - { - C4RCMenuAdd rc = { pObject ? pObject->Number : -1, iCount, idID, fOwnValue, iValue, fIsSelectable }; - AddDbgRec(RCT_MenuAdd, &rc, sizeof(C4RCMenuAdd)); - if (szCommand) AddDbgRec(RCT_MenuAddC, szCommand, strlen(szCommand)+1); - if (szCommand2) AddDbgRec(RCT_MenuAddC, szCommand2, strlen(szCommand2)+1); - } + if (Config.General.DebugRec) + if (pObject) + { + C4RCMenuAdd rc = { pObject ? pObject->Number : -1, iCount, idID, fOwnValue, iValue, fIsSelectable }; + AddDbgRec(RCT_MenuAdd, &rc, sizeof(C4RCMenuAdd)); + if (szCommand) AddDbgRec(RCT_MenuAddC, szCommand, strlen(szCommand)+1); + if (szCommand2) AddDbgRec(RCT_MenuAddC, szCommand2, strlen(szCommand2)+1); + } #endif // Add it to the list pClientWindow->AddElement(pNew); diff --git a/src/gui/C4Menu.h b/src/gui/C4Menu.h index 1a2a15c11..57cd69397 100644 --- a/src/gui/C4Menu.h +++ b/src/gui/C4Menu.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005, 2007-2008 Sven Eberhardt - * Copyright (c) 2006-2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* In-game menu as used by objects, players, and fullscreen options */ @@ -29,9 +25,6 @@ #include "C4Shape.h" #include "C4Gui.h" #include "C4IDList.h" -#include "C4Region.h" - -class C4Viewport; enum { @@ -119,8 +112,6 @@ protected: // GUI calls virtual void MouseInput(class C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam); // input: mouse movement or buttons virtual void MouseEnter(class C4GUI::CMouse &rMouse); // called when mouse cursor enters element region: Select this item (deselects any other) - virtual void DoDragging(class C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam); // called by mouse: dragging process - virtual void StopDragging(class C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam); // called by mouse: mouse released after dragging process public: C4ID GetC4ID() const { return id; } @@ -224,7 +215,7 @@ private: protected: bool DoInitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal); bool DoInit(C4FacetSurface &fctSymbol, const char *szEmpty, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal); - void DrawBuffer(C4Facet &cgo, C4RegionList *pRegions); + void DrawBuffer(C4Facet &cgo); void AdjustSelection(); void AdjustPosition(); bool CheckBuffer(); diff --git a/src/gui/C4MessageBoard.cpp b/src/gui/C4MessageBoard.cpp index b82068056..a08f0db98 100644 --- a/src/gui/C4MessageBoard.cpp +++ b/src/gui/C4MessageBoard.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2008 Matthes Bender - * Copyright (c) 2002-2004 Peter Wortmann - * Copyright (c) 2002-2005 Sven Eberhardt - * Copyright (c) 2009-2010 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Fullscreen startup log and chat type-in */ @@ -129,7 +124,7 @@ void C4MessageBoard::Init(C4Facet &cgo, bool fStartup) Active=true; Output=cgo; Startup=fStartup; - iLineHgt=::GraphicsResource.FontRegular.iLineHgt; + iLineHgt=::GraphicsResource.FontRegular.GetLineHeight(); LogBuffer.SetLBWidth(Output.Wdt); if (!Startup) diff --git a/src/gui/C4MessageBoard.h b/src/gui/C4MessageBoard.h index 172560a05..d7d5317d4 100644 --- a/src/gui/C4MessageBoard.h +++ b/src/gui/C4MessageBoard.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2002 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Fullscreen startup log and chat type-in */ @@ -28,8 +25,6 @@ const int C4MSGB_MaxMsgFading = 6; #include #include -class C4Player; - class C4MessageBoard { public: diff --git a/src/gui/C4MessageInput.cpp b/src/gui/C4MessageInput.cpp index 6a3628d08..6e8d02a48 100644 --- a/src/gui/C4MessageInput.cpp +++ b/src/gui/C4MessageInput.cpp @@ -1,25 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2006 Peter Wortmann - * Copyright (c) 2005-2008 Sven Eberhardt - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // handles input dialogs, last-message-buffer, MessageBoard-commands @@ -106,8 +98,7 @@ void C4ChatInputDialog::OnChatCancel() if (pPlr->MarkMessageBoardQueryAnswered(pTarget)) { // there was an associated query - it must be removed on all clients synchronized via queue - // do this by calling OnMessageBoardAnswer without an answer - ::Control.DoInput(CID_Script, new C4ControlScript(FormatString("OnMessageBoardAnswer(Object(%d), %d, 0)", pTarget ? pTarget->Number : 0, iPlr).getData()), CDT_Decide); + ::Control.DoInput(CID_MsgBoardReply, new C4ControlMsgBoardReply(nullptr, pTarget ? pTarget->Number : 0, iPlr), CDT_Decide); } } } @@ -147,10 +138,7 @@ C4GUI::Edit::InputResult C4ChatInputDialog::OnChatInput(C4GUI::Edit *edt, bool f } // then do a script callback, incorporating the input into the answer if (fUppercase) SCapitalize(szInputText); - StdStrBuf sInput; - sInput.Copy(szInputText); - sInput.EscapeString(); - ::Control.DoInput(CID_Script, new C4ControlScript(FormatString("OnMessageBoardAnswer(Object(%d), %d, \"%s\")", pTarget ? pTarget->Number : 0, iPlr, sInput.getData()).getData()), CDT_Decide); + ::Control.DoInput(CID_MsgBoardReply, new C4ControlMsgBoardReply(szInputText, pTarget ? pTarget->Number : 0, iPlr), CDT_Decide); return C4GUI::Edit::IR_CloseDlg; } else @@ -377,6 +365,7 @@ bool C4MessageInput::ProcessInput(const char *szText) eMsgType = C4CMT_Sound; szMsg = szText+7; } + // Disabled due to spamming // Starts with "/alert": Taskbar flash (message optional) else if (SEqual2NoCase(szText, "/alert ") || SEqualNoCase(szText, "/alert")) { @@ -444,30 +433,160 @@ bool C4MessageInput::ProcessCommand(const char *szCommand) { C4GameLobby::MainDlg *pLobby = ::Network.GetLobby(); // command - char szCmdName[C4MaxName + 1]; - SCopyUntil(szCommand + 1, szCmdName, ' ', C4MaxName); + // must be 1 char longer than the longest command only. If given commands are longer, they will be truncated, and such a command won't exist anyway + const int32_t MaxCommandLen = 20; + char szCmdName[MaxCommandLen + 1]; + SCopyUntil(szCommand + 1, szCmdName, ' ', MaxCommandLen); // parameter const char *pCmdPar = SSearch(szCommand, " "); if (!pCmdPar) pCmdPar = ""; - // dev-scripts + // CAUTION when implementing special commands (like /quit) here: + // those must not be executed when text is pasted, because that could crash the GUI system + // when there are additional lines to paste, but the edit field is destructed by the command + + // lobby-only commands + if (!Game.IsRunning && SEqualNoCase(szCmdName, "joinplr")) + { + // compose path from given filename + StdStrBuf plrPath; + plrPath.Format("%s%s", Config.General.UserDataPath, pCmdPar); + // player join - check filename + if (!ItemExists(plrPath.getData())) + { + C4GameLobby::LobbyError(FormatString(LoadResStr("IDS_MSG_CMD_JOINPLR_NOFILE"), plrPath.getData()).getData()); + } + else + ::Network.Players.JoinLocalPlayer(plrPath.getData(), true); + return true; + } + if (!Game.IsRunning && SEqualNoCase(szCmdName, "plrclr")) + { + // get player name from input text + int iSepPos = SCharPos(' ', pCmdPar, 0); + C4PlayerInfo *pNfo=NULL; + int32_t idLocalClient = -1; + if (::Network.Clients.GetLocal()) idLocalClient = ::Network.Clients.GetLocal()->getID(); + if (iSepPos>0) + { + // a player name is given: Parse it + StdStrBuf sPlrName; + sPlrName.Copy(pCmdPar, iSepPos); + pCmdPar += iSepPos+1; int32_t id=0; + while ((pNfo = Game.PlayerInfos.GetNextPlayerInfoByID(id))) + { + id = pNfo->GetID(); + if (WildcardMatch(sPlrName.getData(), pNfo->GetName())) break; + } + } + else + // no player name: Set local player + pNfo = Game.PlayerInfos.GetPrimaryInfoByClientID(idLocalClient); + C4ClientPlayerInfos *pCltNfo=NULL; + if (pNfo) pCltNfo = Game.PlayerInfos.GetClientInfoByPlayerID(pNfo->GetID()); + if (!pCltNfo) + { + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOPLAYER")); + } + else + { + // may color of this client be set? + if (pCltNfo->GetClientID() != idLocalClient && !::Network.isHost()) + { + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOACCESS")); + } + else + { + // get color to set + uint32_t dwNewClr; + if (sscanf(pCmdPar, "%x", &dwNewClr) != 1) + { + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_USAGE")); + } + else + { + // color validation + dwNewClr |= 0xff000000; + if (!dwNewClr) ++dwNewClr; + // request a color change to this color + C4ClientPlayerInfos LocalInfoRequest = *pCltNfo; + C4PlayerInfo *pPlrInfo = LocalInfoRequest.GetPlayerInfoByID(pNfo->GetID()); + assert(pPlrInfo); + if (pPlrInfo) + { + pPlrInfo->SetOriginalColor(dwNewClr); // set this as a new color wish + ::Network.Players.RequestPlayerInfoUpdate(LocalInfoRequest); + } + } + } + } + return true; + } + if (!Game.IsRunning && SEqualNoCase(szCmdName, "start")) + { + // timeout given? + int32_t iTimeout = Config.Lobby.CountdownTime; + if (!::Network.isHost()) + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY")); + else if (pCmdPar && *pCmdPar && (!sscanf(pCmdPar, "%d", &iTimeout) || iTimeout<0)) + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_START_USAGE")); + else if (pLobby) + { + // abort previous countdown + if (::Network.isLobbyCountDown()) ::Network.AbortLobbyCountdown(); + // start new countdown (aborts previous if necessary) + pLobby->Start(iTimeout); + } + else + { + if (iTimeout) + ::Network.StartLobbyCountdown(iTimeout); + else + ::Network.Start(); + } + return true; + } + if (!Game.IsRunning && SEqualNoCase(szCmdName, "abort")) + { + if (!::Network.isHost()) + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY")); + else if (::Network.isLobbyCountDown()) + ::Network.AbortLobbyCountdown(); + else + C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_ABORT_NOCOUNTDOWN")); + return true; + } + if (SEqual(szCmdName, "help")) { - Log(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGGA")); - LogF("/private [player] [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES")); - LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR")); - LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME")); - LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO")); + Log(LoadResStr(pLobby ? "IDS_TEXT_COMMANDSAVAILABLEDURINGLO" : "IDS_TEXT_COMMANDSAVAILABLEDURINGGA")); + if (!Game.IsRunning) + { + LogF("/start [time] - %s", LoadResStr("IDS_TEXT_STARTTHEROUNDWITHSPECIFIE")); + LogF("/abort - %s", LoadResStr("IDS_TEXT_ABORTSTARTCOUNTDOWN")); + LogF("/alert - %s", LoadResStr("IDS_TEXT_ALERTTHEHOSTIFTHEHOSTISAW")); + LogF("/joinplr [filename] - %s", LoadResStr("IDS_TEXT_JOINALOCALPLAYERFROMTHESP")); + LogF("/plrclr [player] [RGB] - %s", LoadResStr("IDS_TEXT_CHANGETHECOLOROFTHESPECIF")); + LogF("/plrclr [RGB] - %s", LoadResStr("IDS_TEXT_CHANGEYOUROWNPLAYERCOLOR")); + } + else + { + LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA")); + LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE")); + LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS")); + LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU")); + LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND")); + LogF("/screenshot [zoom] - %s", LoadResStr("IDS_TEXT_SAFEZOOMEDFULLSCREENSHOT")); + } LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT")); LogF("/observer [client] - %s", LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB")); - LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA")); - LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE")); - LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS")); - LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU")); + LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME")); + LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO")); + if (Game.IsRunning) LogF("/private [player] [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES")); + LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR")); LogF("/set comment [comment] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT")); LogF("/set password [password] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD")); - LogF("/set maxplayer [4] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA")); - LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND")); + LogF("/set maxplayer [number] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA")); LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD")); return true; } @@ -479,10 +598,10 @@ bool C4MessageInput::ProcessCommand(const char *szCommand) if (!::Network.isEnabled() && Game.ScenarioFile.IsPacked()) return false; if (::Network.isEnabled() && !::Network.isHost()) return false; - ::Control.DoInput(CID_Script, new C4ControlScript(pCmdPar, C4ControlScript::SCOPE_Console, false), CDT_Decide); + ::Control.DoInput(CID_Script, new C4ControlScript(pCmdPar, C4ControlScript::SCOPE_Console), CDT_Decide); return true; } - // set runtimte properties + // set runtime properties if (SEqual(szCmdName, "set")) { if (SEqual2(pCmdPar, "maxplayer ")) @@ -602,7 +721,7 @@ bool C4MessageInput::ProcessCommand(const char *szCommand) if (SEqual(szCmdName, "nodebug")) { if (!Game.IsRunning) return false; - ::Control.DoInput(CID_Set, new C4ControlSet(C4CVT_AllowDebug, false), CDT_Decide); + ::Control.DoInput(CID_Set, new C4ControlSet(C4CVT_DisableDebug, 0), CDT_Decide); return true; } @@ -644,47 +763,33 @@ bool C4MessageInput::ProcessCommand(const char *szCommand) } // show chart - if (Game.IsRunning) if (SEqual(szCmdName, "chart")) + if (Game.IsRunning) + if (SEqual(szCmdName, "chart")) return Game.ToggleChart(); + // whole map screenshot + if (SEqual(szCmdName, "screenshot")) + { + double zoom = atof(pCmdPar); + if (zoom<=0) return false; + ::GraphicsSystem.SaveScreenshot(true, zoom); + return true; + } + // custom command C4MessageBoardCommand *pCmd; - if (Game.IsRunning) if ((pCmd = GetCommand(szCmdName))) + if (Game.IsRunning) + if ((pCmd = GetCommand(szCmdName))) { - StdStrBuf Script, CmdScript; - // replace %player% by calling player number - if (SSearch(pCmd->Script, "%player%")) - { - int32_t iLocalPlr = NO_OWNER; - C4Player *pLocalPlr = ::Players.GetLocalByIndex(0); - if (pLocalPlr) iLocalPlr = pLocalPlr->Number; - StdStrBuf sLocalPlr; sLocalPlr.Format("%d", iLocalPlr); - CmdScript.Copy(pCmd->Script); - CmdScript.Replace("%player%", sLocalPlr.getData()); - } - else - { - CmdScript.Ref(pCmd->Script); - } - // insert parameters - if (SSearch(CmdScript.getData(), "%d")) - { - // make sure it's a number by converting - Script.Format(CmdScript.getData(), (int) atoi(pCmdPar)); - } - else if (SSearch(CmdScript.getData(), "%s")) - { - // escape strings - StdStrBuf Par; - Par.Copy(pCmdPar); - Par.EscapeString(); - // compose script - Script.Format(CmdScript.getData(), Par.getData()); - } - else - Script = CmdScript.getData(); - // add script - ::Control.DoInput(CID_Script, new C4ControlScript(Script.getData()), CDT_Decide); + // get player number of first local player; if multiple players + // share one computer, we can't distinguish between them anyway + int32_t player_num = NO_OWNER; + C4Player *player = ::Players.GetLocalByIndex(0); + if (player) player_num = player->Number; + + // send command to network + ::Control.DoInput(CID_MsgBoardCmd, new C4ControlMsgBoardCmd(szCmdName, pCmdPar, player_num), CDT_Decide); + // ok return true; } diff --git a/src/gui/C4MessageInput.h b/src/gui/C4MessageInput.h index cdbdcbbe3..f1a44cb11 100644 --- a/src/gui/C4MessageInput.h +++ b/src/gui/C4MessageInput.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006 Sven Eberhardt - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // handles input dialogs, last-message-buffer, MessageBoard-commands diff --git a/src/gui/C4MouseControl.cpp b/src/gui/C4MouseControl.cpp index 99f800b67..0e39d7706 100644 --- a/src/gui/C4MouseControl.cpp +++ b/src/gui/C4MouseControl.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003-2004 Matthes Bender - * Copyright (c) 2001-2003, 2005-2007, 2009-2010 Sven Eberhardt - * Copyright (c) 2002, 2004 Peter Wortmann - * Copyright (c) 2005-2006, 2008-2009 Günther Brammer - * Copyright (c) 2006, 2010 Armin Burgmeier - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Mouse input */ @@ -44,52 +38,21 @@ #include const int32_t C4MC_Drag_None = 0, - C4MC_Drag_Selecting = 1, - C4MC_Drag_Moving = 2, - //C4MC_Drag_Menu = 3, - //C4MC_Drag_MenuScroll = 4, - C4MC_Drag_Construct = 5, C4MC_Drag_Script = 6, - C4MC_Drag_Unhandled = 7, + C4MC_Drag_Unhandled = 7; - C4MC_Selecting_Unknown = 0; - -const int32_t C4MC_Cursor_Region = 0, - C4MC_Cursor_Crosshair = 1, - C4MC_Cursor_Enter = 2, - C4MC_Cursor_Grab = 3, - C4MC_Cursor_Chop = 4, - C4MC_Cursor_Dig = 5, - C4MC_Cursor_Build = 6, - C4MC_Cursor_Select = 7, - C4MC_Cursor_Object = 8, - C4MC_Cursor_Ungrab = 9, - C4MC_Cursor_Up = 10, - C4MC_Cursor_Down = 11, - C4MC_Cursor_Left = 12, - C4MC_Cursor_Right = 13, - C4MC_Cursor_UpLeft = 14, - C4MC_Cursor_UpRight = 15, - C4MC_Cursor_DownLeft = 16, - C4MC_Cursor_DownRight = 17, - C4MC_Cursor_JumpLeft = 18, - C4MC_Cursor_JumpRight = 19, - C4MC_Cursor_Drop = 20, - C4MC_Cursor_ThrowRight = 21, - C4MC_Cursor_Put = 22, - //C4MC_Cursor_DragMenu = 23, - C4MC_Cursor_Vehicle = 24, - C4MC_Cursor_VehiclePut = 25, - C4MC_Cursor_ThrowLeft = 26, - C4MC_Cursor_DragDrop = 26, - C4MC_Cursor_Point = 27, - C4MC_Cursor_DigObject = 28, - C4MC_Cursor_Help = 29, - C4MC_Cursor_DigMaterial = 30, - C4MC_Cursor_Add = 31, - C4MC_Cursor_Construct = 32, - C4MC_Cursor_Attack = 33, - C4MC_Cursor_Nothing = 34; +const int32_t C4MC_Cursor_Select = 0, // click cursor to select/click stuff in the GUI + C4MC_Cursor_Crosshair = 1, // standard ingame cursor + C4MC_Cursor_DragDrop = 3, // cursor when drag&dropping + C4MC_Cursor_Up = 4, // cursors for scrolling the viewport ... + C4MC_Cursor_Down = 5, // ... + C4MC_Cursor_Left = 6, + C4MC_Cursor_Right = 7, + C4MC_Cursor_UpLeft = 8, + C4MC_Cursor_UpRight = 9, + C4MC_Cursor_DownLeft = 10, + C4MC_Cursor_DownRight = 11, + C4MC_Cursor_Passive = 12; // passive cursor in records and an fog of war const int32_t C4MC_Time_on_Target = 10; @@ -109,35 +72,31 @@ void C4MouseControl::Default() Player=NO_OWNER; pPlayer=NULL; Viewport=NULL; - Cursor=DownCursor=0; + Cursor=0; Caption.Clear(); - IsHelpCaption=false; CaptionBottomY=0; VpX=VpY=0; - DownX=DownY=DownOffsetX=DownOffsetY=0; + DownX=DownY=0; ViewX=ViewY=0; GuiX=GuiY=GameX=GameY=0; - ShowPointX=ShowPointY=-1; LeftButtonDown=RightButtonDown=false; LeftDoubleIgnoreUp=false; ButtonDownOnSelection=false; Visible=true; InitCentered=false; - Help=false; FogOfWar=false; DragID=C4ID::None; DragObject=NULL; KeepCaption=0; - Drag=C4MC_Drag_None; DragSelecting=C4MC_Selecting_Unknown; + Drag=C4MC_Drag_None; Selection.Default(); TargetObject=DownTarget=NULL; TimeOnTargetObject=0; ControlDown=false; ShiftDown=false; + AltDown=false; Scrolling=false; ScrollSpeed=10; - TargetRegion=NULL; - DownRegion.Default(); DragImageDef=NULL; DragImageObject=NULL; fMouseOwned = true; // default mouse owned @@ -160,9 +119,9 @@ void C4MouseControl::Execute() if (Scrolling || !::Game.iTick5) { WORD wKeyState=0; - if (Application.IsControlDown()) wKeyState|=MK_CONTROL; - if (Application.IsShiftDown()) wKeyState|=MK_SHIFT; - Move(C4MC_Button_None,VpX,VpY,wKeyState); + if (ControlDown) wKeyState|=MK_CONTROL; + if (ShiftDown) wKeyState|=MK_SHIFT; + Move(C4MC_Button_None, VpX, VpY, wKeyState); } } @@ -229,10 +188,14 @@ void C4MouseControl::UpdateClip() void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFlags, bool fCenter) { + // Control state + ControlDown=false; if (dwKeyFlags & MK_CONTROL) ControlDown=true; + ShiftDown=false; if (dwKeyFlags & MK_SHIFT) ShiftDown=true; + AltDown=false; if(dwKeyFlags & MK_ALT) AltDown=true; // Active if (!Active || !fMouseOwned) return; // Execute caption - if (KeepCaption) KeepCaption--; else { Caption.Clear(); IsHelpCaption=false; CaptionBottomY=0; } + if (KeepCaption) KeepCaption--; else { Caption.Clear(); CaptionBottomY=0; } // Check player if (Player>NO_OWNER) { @@ -291,7 +254,6 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl GameX=ViewX+VpX/Viewport->Zoom; GameY=ViewY+VpY/Viewport->Zoom; GuiX=float(VpX)/Viewport->GetGUIZoom(); GuiY=float(VpY)/Viewport->GetGUIZoom(); } - UpdateTargetRegion(); UpdateScrolling(); if (iButton == C4MC_Button_LeftDown) LeftDown(); else if (iButton == C4MC_Button_LeftUp) LeftUp(); @@ -305,18 +267,13 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl VpX=iX; VpY=iY; GameX=ViewX+VpX/Viewport->Zoom; GameY=ViewY+VpY/Viewport->Zoom; GuiX=float(VpX)/Viewport->GetGUIZoom(); GuiY=float(VpY)/Viewport->GetGUIZoom(); - // Control state - ControlDown=false; if (dwKeyFlags & MK_CONTROL) ControlDown=true; - ShiftDown=false; if (dwKeyFlags & MK_SHIFT) ShiftDown=true; - // Target region - UpdateTargetRegion(); // Scrolling UpdateScrolling(); // Fog of war UpdateFogOfWar(); // Blocked by fog of war: evaluate button up, dragging and region controls only - if (FogOfWar && Drag == C4MC_Drag_None && !TargetRegion) + if (FogOfWar && Drag == C4MC_Drag_None) { // Left button up if (iButton==C4MC_Button_LeftUp) @@ -342,9 +299,6 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl { case C4MC_Drag_Unhandled: break; // nothing to do case C4MC_Drag_None: DragNone(); break; - case C4MC_Drag_Selecting: DragSelect(); break; - case C4MC_Drag_Moving: DragMoving(); break; - case C4MC_Drag_Construct: DragConstruct(); break; case C4MC_Drag_Script: DragScript(); break; } break; @@ -365,7 +319,7 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl // script handling of mouse control for everything but regular movement (which is sent at control frame intervals only) if (iButton != C4MC_Button_None) // not if blocked by selection object - if (!TargetRegion && !TargetObject) + if (!TargetObject) // safety (can't really happen in !IsPassive, but w/e if (pPlayer && pPlayer->ControlSet) { @@ -373,7 +327,7 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl { int wheel_dir = 0; if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyFlags >> 16); - pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, iButton, GameX, GameY, GuiX, GuiY, ControlDown, ShiftDown, Application.IsAltDown(), wheel_dir); + pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, iButton, GameX, GameY, GuiX, GuiY, (dwKeyFlags & MK_CONTROL) != 0, (dwKeyFlags & MK_SHIFT) != 0, (dwKeyFlags & MK_ALT) != 0, wheel_dir); } } } @@ -386,7 +340,7 @@ void C4MouseControl::DoMoveInput() if (!(pPlayer=::Players.Get(Player))) return; if (!pPlayer->ControlSet) return; if (!pPlayer->ControlSet->IsMouseControlAssigned(C4MC_Button_None)) return; - pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, C4MC_Button_None, GameX, GameY, GuiX, GuiY, ControlDown, ShiftDown, Application.IsAltDown(), 0); + pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, C4MC_Button_None, GameX, GameY, GuiX, GuiY, ControlDown, ShiftDown, AltDown, 0); } void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) @@ -409,7 +363,7 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) switch (Drag) { //------------------------------------------------------------------------------------------ - case C4MC_Drag_None: case C4MC_Drag_Moving: case C4MC_Drag_Construct: case C4MC_Drag_Script: case C4MC_Drag_Unhandled: + case C4MC_Drag_None: case C4MC_Drag_Script: case C4MC_Drag_Unhandled: // Hotspot offset: Usually, hotspot is in center iOffsetX = GfxR->fctMouseCursor.Wdt/2; iOffsetY = GfxR->fctMouseCursor.Hgt/2; @@ -425,13 +379,6 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) case C4MC_Cursor_DownLeft: iOffsetX += -GfxR->fctMouseCursor.Wdt/2; iOffsetY += +GfxR->fctMouseCursor.Hgt/2; break; case C4MC_Cursor_DownRight: iOffsetX += +GfxR->fctMouseCursor.Wdt/2; iOffsetY += +GfxR->fctMouseCursor.Hgt/2; break; } - // Add mark - bool fAddMark; fAddMark=false; - if (ShiftDown) - if ((Cursor!=C4MC_Cursor_Region) && (Cursor!=C4MC_Cursor_Select) //&& (Cursor!=C4MC_Cursor_DragMenu) - && (Cursor!=C4MC_Cursor_JumpLeft) && (Cursor!=C4MC_Cursor_JumpRight)) - if (!IsPassive()) - fAddMark=true; // Drag image if (DragImageObject || DragImageDef) { @@ -468,8 +415,6 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) pDraw->SetZoom(GameZoom); XDraw = GameX; YDraw = GameY; ZoomDraw = 1.0f; - // for drag construct: draw rounded to game pixels, because construction site will be placed at rounded game pixel positions - if (Drag == C4MC_Drag_Construct) { XDraw=floor(XDraw); YDraw=floor(YDraw); } } else { @@ -478,15 +423,11 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) } iOffsetX=int(ZoomDraw*ImageWdt/2); - if (Drag == C4MC_Drag_Construct) - iOffsetY=int(ZoomDraw*ImageHgt); - else - iOffsetY=int(ZoomDraw*ImageHgt/2); + iOffsetY=int(ZoomDraw*ImageHgt/2); C4TargetFacet ccgo; ccgo.Set(cgo.Surface, XDraw + cgo.X - iOffsetX, YDraw + cgo.Y - iOffsetY, float(ImageWdt)*ZoomDraw, float(ImageHgt)*ZoomDraw); - // TODO: Take pDef->DragImagePicture into account if (DragImageObject) { uint32_t ColorMod = DragImageObject->ColorMod; @@ -494,7 +435,7 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) DragImageObject->ColorMod = (Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/0 ? 0x8f7f0000 : 0x1f007f00); DragImageObject->BlitMode = C4GFXBLIT_MOD2; - DragImageObject->DrawPicture(ccgo, false, NULL, NULL); + DragImageObject->DrawPicture(ccgo, false, NULL); DragImageObject->ColorMod = ColorMod; DragImageObject->BlitMode = BlitMode; @@ -521,60 +462,22 @@ void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom) // Cursor if ( (!DragImageDef && !DragImageObject) || (Drag == C4MC_Drag_Script)) GfxR->fctMouseCursor.Draw(cgo.Surface,cgo.X+GuiX-iOffsetX,cgo.Y+GuiY-iOffsetY,Cursor); - // Point - if ((ShowPointX!=-1) && (ShowPointY!=-1)) - GfxR->fctMouseCursor.Draw( cgo.Surface, - int32_t(cgo.X+(ShowPointX-cgo.TargetX)*GameZoom.Zoom / GuiZoom.Zoom-GfxR->fctMouseCursor.Wdt/2), - int32_t(cgo.Y+(ShowPointY-cgo.TargetY)*GameZoom.Zoom / GuiZoom.Zoom-GfxR->fctMouseCursor.Hgt/2), - C4MC_Cursor_Point ); - // Add mark - if (fAddMark) - GfxR->fctMouseCursor.Draw( cgo.Surface, - int32_t(cgo.X+GuiX-iOffsetX+8), - int32_t(cgo.Y+GuiY-iOffsetY+8), - C4MC_Cursor_Add ); - break; - //------------------------------------------------------------------------------------------ - case C4MC_Drag_Selecting: - // Draw frame - pDraw->DrawFrameDw(cgo.Surface, - int32_t(cgo.X + GuiX), - int32_t(cgo.Y + GuiY), - int32_t(cgo.X + (DownX - cgo.TargetX) * GameZoom.Zoom / GuiZoom.Zoom), - int32_t(cgo.Y + (DownY - cgo.TargetY) * GameZoom.Zoom / GuiZoom.Zoom), - C4RGB(0xca, 0, 0)); break; //------------------------------------------------------------------------------------------ } // Draw caption - if (Caption) + if (Caption && ::pGUI) { - if (IsHelpCaption && ::pGUI) - { - // Help: Tooltip style - C4TargetFacet cgoTip; cgoTip = static_cast(cgo); - C4GUI::Screen::DrawToolTip(Caption.getData(), cgoTip, cgo.X+GuiX, cgo.Y+GuiY); - } - else - { - // Otherwise red mouse control style - int32_t iWdt,iHgt; - ::GraphicsResource.FontRegular.GetTextExtent(Caption.getData(), iWdt, iHgt, true); - pDraw->TextOut(Caption.getData(), ::GraphicsResource.FontRegular, 1.0, - cgo.Surface, - float(cgo.X)+BoundBy(GuiX,float(iWdt)/2+1,float(cgo.Wdt)-iWdt/2-1), - float(cgo.Y)+Min( CaptionBottomY ? float(CaptionBottomY-iHgt-1) : GuiY+13, float(cgo.Hgt-iHgt)), - 0xfaFF0000,ACenter); - } + C4TargetFacet cgoTip; + cgoTip = static_cast(cgo); + C4GUI::Screen::DrawToolTip(Caption.getData(), cgoTip, cgo.X+GuiX, cgo.Y+GuiY); } } void C4MouseControl::UpdateCursorTarget() { - int32_t iLastCursor = Cursor; - C4Object* OldTargetObject = TargetObject; if (Scrolling) @@ -582,12 +485,6 @@ void C4MouseControl::UpdateCursorTarget() // Scrolling: no other target TargetObject=NULL; } - else if(TargetRegion) - { - // On target region - TargetObject=NULL; - if (Help) Cursor=C4MC_Cursor_Help; - } else { // Target object @@ -617,37 +514,27 @@ void C4MouseControl::UpdateCursorTarget() TargetObject = NULL; } - // Help - if (Help) - Cursor=C4MC_Cursor_Help; // passive cursor - else if (IsPassive()) - Cursor=C4MC_Cursor_Region; + if (IsPassive()) + Cursor=C4MC_Cursor_Passive; // Time on target: caption - if (Cursor==iLastCursor) + if (TargetObject && Cursor == C4MC_Cursor_Select) { TimeOnTargetObject++; if (TimeOnTargetObject>=C4MC_Time_on_Target) { - const char* idCaption = 0; - const char *szName = ""; - bool fDouble = false; - if (TargetObject) szName=TargetObject->GetName(); - // Target caption by cursor - switch (Cursor) + if (TargetObject->Category & C4D_MouseSelect) { - case C4MC_Cursor_Select: idCaption="IDS_CON_SELECT"; break; - case C4MC_Cursor_Help: idCaption="IDS_CON_NAME"; break; - } - // Set caption - if (idCaption) if (!KeepCaption) + // set caption + if (!KeepCaption) { - // Caption by cursor - Caption.Format(LoadResStr(idCaption), szName); - if (fDouble) { Caption.AppendChar('|'); Caption.Append(LoadResStr("IDS_CON_DOUBLECLICK")); } - IsHelpCaption = false; + C4String *tooltip = TargetObject->GetPropertyStr(P_Tooltip); + if(tooltip) { + Caption = TargetObject->GetPropertyStr(P_Tooltip)->GetData(); + } } + } } } else @@ -661,8 +548,7 @@ void C4MouseControl::UpdateCursorTarget() // selectable objects around. If it turns out to be a problem we might want to // deduce these hover callbacks client-side instead. // Or, make sure to send this at most once per control frame. - Game.Input.Add(CID_Script, new C4ControlScript( - FormatString("%s(%d,Object(%d),Object(%d),Object(%d))", PSF_MouseHover, (int)Player, OldTargetObject ? (int)(OldTargetObject->Number) : 0, TargetObject ? (int)(TargetObject->Number) : 0, DragObject ? (int)(DragObject->Number) : 0).getData())); + Game.Input.Add(CID_PlrMouseMove, C4ControlPlayerMouse::Hover(::Players.Get(Player), TargetObject, OldTargetObject, DragObject)); } } @@ -685,8 +571,6 @@ void C4MouseControl::UpdateScrolling() { // Assume no scrolling Scrolling=false; - // No scrolling if on region - if (TargetRegion) return; // No scrolling if disabled by player if (pPlayer) if (pPlayer->IsViewLocked()) return; // Scrolling on border @@ -705,132 +589,42 @@ void C4MouseControl::UpdateScrolling() if ((VpX==Viewport->ViewWdt-1) && (VpY==Viewport->ViewHgt-1)) Cursor=C4MC_Cursor_DownRight; } -void C4MouseControl::UpdateTargetRegion() -{ - // Assume no region - TargetRegion=NULL; - // Find region - if (!(TargetRegion=Viewport->Regions.Find(GuiX,GuiY))) return; - // Region found: no target object - TargetObject=NULL; - // Cursor - Cursor=C4MC_Cursor_Region; - // Stop drag selecting (reset down cursor, too) - if (Drag==C4MC_Drag_Selecting) - { Drag=C4MC_Drag_None; DownCursor=C4MC_Cursor_Nothing; } - // Caption - Caption.Copy(TargetRegion->Caption); - IsHelpCaption = false; - CaptionBottomY=TargetRegion->Y; KeepCaption=0; - // Help region caption by region target object; not in menu, because this would be the cursor object - if (Help) - if (TargetRegion->Target /*&& Cursor!=C4MC_Cursor_DragMenu*/) - { - //if (TargetRegion->Target->Def->GetDesc()) - // Caption.Format("%s: %s",TargetRegion->Target->GetName(), TargetRegion->Target->Def->GetDesc()); - //else - Caption.Copy(TargetRegion->Target->GetName()); - IsHelpCaption = true; - } - // MoveOverCom (on region change) - static int32_t iLastRegionX,iLastRegionY; - if (TargetRegion->MoveOverCom) - { - if ((TargetRegion->X!=iLastRegionX) || (TargetRegion->Y!=iLastRegionY)) - { - iLastRegionX=TargetRegion->X; iLastRegionY=TargetRegion->Y; - - // Control queue - Game.Input.Add(CID_PlrControl, - new C4ControlPlayerControl(Player,TargetRegion->MoveOverCom,TargetRegion->Data)); - } - } - else - { - iLastRegionX=iLastRegionY=-1; - } -} - void C4MouseControl::LeftDown() { // Set flag LeftButtonDown=true; // Store down values (same MoveRightDown -> use StoreDown) DownX=GameX; DownY=GameY; - DownCursor=Cursor; DownTarget=TargetObject; - DownRegion.Default(); - if (TargetRegion) - { - DownRegion=(*TargetRegion); - DownTarget=TargetRegion->Target; - DownOffsetX=TargetRegion->X-GuiX; DownOffsetY=TargetRegion->Y-GuiY; - } -} - -void C4MouseControl::DragSelect() -{ - // don't select into FoW - simply don't update selection - if (FogOfWar) return; - switch (DragSelecting) - { - case C4MC_Selecting_Unknown: - // Determine selection type - // No selection in engine right now... - break; - } } void C4MouseControl::LeftUp() { + // Ignore left up after double click + if (LeftDoubleIgnoreUp) + { + LeftDoubleIgnoreUp=false; + } + else + { + // Evaluate by drag status + switch (Drag) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case C4MC_Drag_Unhandled: // nobreak + case C4MC_Drag_None: LeftUpDragNone(); break; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case C4MC_Drag_Script: ButtonUpDragScript(); break; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + } + } // Update status flag LeftButtonDown=false; if(!RightButtonDown) DownTarget = NULL; - // Ignore left up after double click - if (LeftDoubleIgnoreUp) { LeftDoubleIgnoreUp=false; return; } - // Evaluate by drag status - switch (Drag) - { - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Unhandled: // nobreak - case C4MC_Drag_None: LeftUpDragNone(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Selecting: ButtonUpDragSelecting(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Moving: ButtonUpDragMoving(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Construct: ButtonUpDragConstruct(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Script: ButtonUpDragScript(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } -} - -void C4MouseControl::DragMoving() -{ - ShowPointX=ShowPointY=-1; - - // do not drag objects into FoW - if (FogOfWar) { Cursor = C4MC_Cursor_Nothing; return; } - } void C4MouseControl::DragNone() { - // Holding left down - if (LeftButtonDown) - { - switch (Cursor) - { - // Hold down on region - case C4MC_Cursor_Region: - if (!::Game.iTick5) - if (DownRegion.HoldCom) - SendControl(DownRegion.HoldCom); - break; - } - } - // Cursor movement UpdateCursorTarget(); // Update selection @@ -841,20 +635,6 @@ void C4MouseControl::DragNone() && ((Abs(GameX-DownX)>C4MC_DragSensitivity) || (Abs(GameY-DownY)>C4MC_DragSensitivity)) ) { bool fAllowDrag = true; - switch (DownCursor) - { - /* - // Drag start selecting in landscape - case C4MC_Cursor_Crosshair: - Selection.Clear(); - Drag=C4MC_Drag_Selecting; DragSelecting=C4MC_Selecting_Unknown; - break; - */ - // Help: no dragging - case C4MC_Cursor_Help: - fAllowDrag = false; - break; - } // check if target object allows scripted dragging if (fAllowDrag && DownTarget && (!FogOfWar || (DownTarget->Category & C4D_IgnoreFoW))) { @@ -904,23 +684,11 @@ void C4MouseControl::RightDown() RightButtonDown=true; // Store down values (same MoveLeftDown -> use StoreDown) DownX=GameX; DownY=GameY; - DownCursor=Cursor; DownTarget=TargetObject; - DownRegion.Default(); - if (TargetRegion) - { - DownRegion=(*TargetRegion); - DownTarget=TargetRegion->Target; - DownOffsetX=TargetRegion->X-GuiX; DownOffsetY=TargetRegion->Y-GuiY; - } } void C4MouseControl::RightUp() { - // Update status flag - RightButtonDown=false; - if(!LeftButtonDown) DownTarget = NULL; - // Evaluate by drag status switch (Drag) { @@ -928,15 +696,12 @@ void C4MouseControl::RightUp() case C4MC_Drag_Unhandled: // nobreak case C4MC_Drag_None: RightUpDragNone(); break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Selecting: ButtonUpDragSelecting(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Moving: ButtonUpDragMoving(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Construct: ButtonUpDragConstruct(); break; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MC_Drag_Script: ButtonUpDragScript(); break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } + // Update status flag + RightButtonDown=false; + if(!LeftButtonDown) DownTarget = NULL; } void C4MouseControl::Wheel(DWORD dwFlags) @@ -976,12 +741,6 @@ bool C4MouseControl::IsValidMenu(C4Menu *pMenu) bool C4MouseControl::SendControl(int32_t iCom, int32_t iData) { - // Help - if (iCom==COM_Help) - { - Help=true; - return true; - } // Activate player menu / fullscreen main menu (local control) if (iCom==COM_PlayerMenu) { @@ -1005,18 +764,6 @@ bool C4MouseControl::SendControl(int32_t iCom, int32_t iData) return true; } -void C4MouseControl::DragConstruct() -{ - Cursor=C4MC_Cursor_Construct; - - // TODO: Re-enable something like this: -#if 0 - // Check site - DragImagePhase=1; - if (!FogOfWar && ConstructionCheck(C4Id2Def(DragID),int32_t(GameX),int32_t(GameY))) DragImagePhase=0; -#endif -} - void C4MouseControl::DragScript() { // script drag should update target and selection so selection highlight on drop target is visible @@ -1034,34 +781,11 @@ void C4MouseControl::LeftUpDragNone() // Single left click (might be on a target) switch (Cursor) { - // Region - case C4MC_Cursor_Region: - // Help click on region: ignore - if (Help) break; - // Region com & data - SendControl(DownRegion.Com,DownRegion.Data); - break; - // Selection case C4MC_Cursor_Select: // Object selection to control queue - if (!IsPassive()) Game.Input.Add(CID_PlrSelect, new C4ControlPlayerSelect(Player,Selection,false)); + if (!IsPassive() && Selection.GetObject() == DownTarget) + Game.Input.Add(CID_PlrSelect, new C4ControlPlayerSelect(Player,Selection,false)); break; - // Help - case C4MC_Cursor_Help: - if (DownTarget) - { - //if (DownTarget->Def->GetDesc()) - // Caption.Format("%s: %s",DownTarget->GetName(), DownTarget->Def->GetDesc()); - //else - Caption.Copy(DownTarget->GetName()); - KeepCaption=Caption.getLength()/2; - IsHelpCaption = true; - } - break; - // Nothing - case C4MC_Cursor_Nothing: - break; - // Movement? default: // done in script break; @@ -1070,34 +794,6 @@ void C4MouseControl::LeftUpDragNone() Selection.Clear(); } -void C4MouseControl::ButtonUpDragSelecting() -{ - // Finish drag - Drag=C4MC_Drag_None; -} - -void C4MouseControl::ButtonUpDragMoving() -{ - // Finish drag - Drag=C4MC_Drag_None; - // Clear selection - Selection.Clear(); -} - -void C4MouseControl::ButtonUpDragConstruct() -{ - // Finish drag - Drag=C4MC_Drag_None; - DragImageObject = NULL; - DragImageDef = NULL; - // Command - // FIXME: Lots and lots of dead code in this file. - //if (DragImagePhase==0) // if ConstructionCheck was okay (check again?) - //SendCommand(C4CMD_Construct,int32_t(GameX),int32_t(GameY),NULL,NULL,DragID.GetHandle()); - // Clear selection (necessary?) - Selection.Clear(); -} - void C4MouseControl::ButtonUpDragScript() { // Determine drag+drop targets @@ -1119,12 +815,7 @@ void C4MouseControl::ButtonUpDragScript() if (!pPlr || pPlr->Eliminated) return; // todo: Perform drag/drop validity check // now drag/drop is handled by script - if (DropObject) - Game.Input.Add(CID_Script, new C4ControlScript( - FormatString("%s(%d,Object(%d),Object(%d))", PSF_MouseDragDrop, (int)Player, (int)(DragObject->Number), (int)(DropObject->Number)).getData())); - else - Game.Input.Add(CID_Script, new C4ControlScript( - FormatString("%s(%d,Object(%d),nil)", PSF_MouseDragDrop, (int)Player, (int)(DragObject->Number)).getData())); + Game.Input.Add(CID_PlrMouseMove, C4ControlPlayerMouse::DragDrop(::Players.Get(Player), DropObject, DragObject)); } void C4MouseControl::SendCommand(int32_t iCommand, int32_t iX, int32_t iY, C4Object *pTarget, C4Object *pTarget2, int32_t iData, int32_t iAddMode) @@ -1146,18 +837,10 @@ void C4MouseControl::RightUpDragNone() // might be in Drag_Unknown Drag = C4MC_Drag_None; - // Region: send control - if (Cursor==C4MC_Cursor_Region) - { SendControl(DownRegion.RightCom); return; } - // Alternative object selection - if (Cursor==C4MC_Cursor_Select && !IsPassive()) + if (Cursor==C4MC_Cursor_Select && !IsPassive() && Selection.GetObject() == DownTarget) { Game.Input.Add(CID_PlrSelect, new C4ControlPlayerSelect(Player,Selection,true)); } - // Help: end - if (Help) - { Help=false; KeepCaption=0; return; } - // TODO: Evaluate right click } @@ -1171,11 +854,9 @@ void C4MouseControl::UpdateFogOfWar() { FogOfWar=true; // allow dragging, scrolling, region selection and manipulations of objects not affected by FoW - if (!TargetRegion && !Scrolling && (!TargetObject || !(TargetObject->Category & C4D_IgnoreFoW))) + if (!Scrolling && (!TargetObject || !(TargetObject->Category & C4D_IgnoreFoW))) { - Cursor=C4MC_Cursor_Nothing; - ShowPointX=ShowPointY=-1; - // dragging will reset the cursor + Cursor=C4MC_Cursor_Passive; } } } @@ -1199,7 +880,7 @@ C4Object *C4MouseControl::GetTargetObject() { // find object // gui object position currently wrong...will fall apart once GUIZoom is activated - C4Object *pObj = Game.FindVisObject(ViewX, ViewY, Player, fctViewportGame, fctViewportGUI, GameX,GameY, Help ? C4D_All : C4D_MouseSelect, GuiX-fctViewportGUI.X, GuiY-fctViewportGUI.Y); + C4Object *pObj = Game.FindVisObject(ViewX, ViewY, Player, fctViewportGame, fctViewportGUI, GameX,GameY, C4D_MouseSelect, GuiX-fctViewportGUI.X, GuiY-fctViewportGUI.Y); if (!pObj) return NULL; return pObj; } @@ -1226,16 +907,7 @@ void C4MouseControl::ScrollView(float iX, float iY, float ViewWdt, float ViewHgt bool C4MouseControl::IsDragging() { - // no selection drag; return true for object drag only - return Active && (Drag == C4MC_Drag_Moving || Drag == C4MC_Drag_Construct || Drag == C4MC_Drag_Script); -} - -void C4MouseControl::StartConstructionDrag(C4ID id) -{ - Drag=C4MC_Drag_Construct; - DragID=id; - DragImageDef = C4Id2Def(id); - Selection.Clear(); + return Active && Drag == C4MC_Drag_Script; } bool C4MouseControl::GetLastGUIPos(int32_t *x_out, int32_t *y_out) const diff --git a/src/gui/C4MouseControl.h b/src/gui/C4MouseControl.h index 7b102f850..f5cd93529 100644 --- a/src/gui/C4MouseControl.h +++ b/src/gui/C4MouseControl.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005, 2007 Sven Eberhardt - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Mouse input */ @@ -25,7 +22,6 @@ #include #include "C4ObjectList.h" -#include "C4Region.h" const int32_t C4MC_Button_None = 0, C4MC_Button_LeftDown = 1, @@ -35,7 +31,7 @@ const int32_t C4MC_Button_None = 0, C4MC_Button_LeftDouble = 5, C4MC_Button_RightDouble = 6, C4MC_Button_Wheel = 7, - C4MC_Button_MiddleDown = 8, + C4MC_Button_MiddleDown = 8, C4MC_Button_MiddleUp = 9; const int32_t C4MC_DragSensitivity = 5; @@ -44,10 +40,6 @@ const int32_t C4MC_MD_DragSource = 1, C4MC_MD_DropTarget = 2, C4MC_MD_NoClick = 4; -class C4Viewport; -class C4Menu; -class C4Player; - class C4MouseControl { friend class C4Viewport; @@ -60,43 +52,45 @@ protected: int32_t Player; C4Player *pPlayer; // valid during Move() C4Viewport *Viewport; // valid during Move() - StdStrBuf Caption; - bool IsHelpCaption; + int32_t Cursor; - int32_t DownCursor; + + StdCopyStrBuf Caption; int32_t CaptionBottomY; + int32_t KeepCaption; + int32_t VpX,VpY; // Pixel coordinates of mouse pos float ViewX,ViewY; // Game coordinate scrolling offset of viewport float GameX,GameY; // Game coordinates of mouse pos float GuiX,GuiY; // GUI coorindates of mouse pos C4Facet fctViewport, fctViewportGame, fctViewportGUI; + float DownX,DownY; // Game coordinates of mouse-down-pos while dragging - float DownOffsetX,DownOffsetY; // GUI coordinate offset from target region while dragging - int32_t ShowPointX,ShowPointY; // Game coordinates of throw point - int32_t KeepCaption; + int32_t ScrollSpeed; - int32_t Drag,DragSelecting; + int32_t Drag; + bool LeftButtonDown,RightButtonDown,LeftDoubleIgnoreUp; bool ButtonDownOnSelection; bool ControlDown; bool ShiftDown; + bool AltDown; bool Scrolling; bool InitCentered; - bool Help; bool FogOfWar; bool Visible; + + C4ObjectList Selection; //obsolete! + C4Object *DragObject; C4ID DragID; - C4ObjectList Selection; C4Def* DragImageDef; C4Object* DragImageObject; + // Target object C4Object *TargetObject; // valid during Move() C4Object *DownTarget; int32_t TimeOnTargetObject; - // Region - C4Region *TargetRegion; // valid during Move() - C4Region DownRegion; public: void Default(); void Clear(); @@ -119,23 +113,16 @@ protected: void SendPlayerSelectNext(); void UpdateFogOfWar(); void RightUpDragNone(); - void ButtonUpDragConstruct(); void ButtonUpDragScript(); - void ButtonUpDragMoving(); - void ButtonUpDragSelecting(); void LeftUpDragNone(); - void DragConstruct(); void DragScript(); void Wheel(DWORD dwFlags); void RightUp(); void RightDown(); void LeftDouble(); void DragNone(); - void DragMoving(); void LeftUp(); - void DragSelect(); void LeftDown(); - void UpdateTargetRegion(); void UpdateScrolling(); void UpdateCursorTarget(); void SendCommand(int32_t iCommand, int32_t iX=0, int32_t iY=0, C4Object *pTarget=NULL, C4Object *pTarget2=NULL, int32_t iData=0, int32_t iAddMode=C4P_Command_Set); @@ -150,11 +137,7 @@ protected: void ScrollView(float iX, float iY, float ViewWdt, float ViewHgt); // in landscape coordinates public: - bool IsHelp() { return Help; } - void SetHelp() { Help = true; } - void AbortHelp() { Help = false; } bool IsDragging(); - void StartConstructionDrag(C4ID id); int32_t GetPlayer() { return Player; } }; diff --git a/src/gui/C4PlayerInfoListBox.cpp b/src/gui/C4PlayerInfoListBox.cpp index 90aeb16a5..b0dc19cc5 100644 --- a/src/gui/C4PlayerInfoListBox.cpp +++ b/src/gui/C4PlayerInfoListBox.cpp @@ -1,27 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2005, 2007-2008 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2009 David Dormagen - * Copyright (c) 2009-2010 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Carl-Philip Hänsch - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // player listbox used in lobby and game over dlg @@ -299,7 +289,7 @@ void C4PlayerInfoListBox::PlayerListItem::UpdateIcon(C4PlayerInfo *pInfo, C4Play // join if (fHasJoinedInfo) { - // make sure we're not drawing on GraphicsRessource + // make sure we're not drawing on GraphicsResource if (!pIcon->EnsureOwnSurface()) return; // draw join info C4Facet fctDraw = pIcon->GetFacet(); diff --git a/src/gui/C4PlayerInfoListBox.h b/src/gui/C4PlayerInfoListBox.h index 7b7397d7d..b3afcc827 100644 --- a/src/gui/C4PlayerInfoListBox.h +++ b/src/gui/C4PlayerInfoListBox.h @@ -1,25 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003-2005, 2007-2008 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Carl-Philip Hänsch - * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -"Clonk" is a registered trademark of Matthes Bender. */ + * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ // player listbox used in lobby and game over dlg #ifndef INC_C4PlayerInfoListBox @@ -31,8 +24,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "C4Network2Res.h" #include "C4GameLobby.h" -class C4Team; - class C4PlayerInfoListBox : public C4GUI::ListBox { public: diff --git a/src/gui/C4Scoreboard.cpp b/src/gui/C4Scoreboard.cpp index c1f58dd48..2c64e4ee2 100644 --- a/src/gui/C4Scoreboard.cpp +++ b/src/gui/C4Scoreboard.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005, 2007-2008 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2006-2007, 2009 Günther Brammer - * Copyright (c) 2009 mizipzor - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // script-controlled InGame dialog to show player infos diff --git a/src/gui/C4Scoreboard.h b/src/gui/C4Scoreboard.h index 6d4bd3c9b..364119284 100644 --- a/src/gui/C4Scoreboard.h +++ b/src/gui/C4Scoreboard.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // script-controlled InGame dialog to show player infos diff --git a/src/gui/C4Startup.cpp b/src/gui/C4Startup.cpp index 46a6a9614..90697097b 100644 --- a/src/gui/C4Startup.cpp +++ b/src/gui/C4Startup.cpp @@ -1,28 +1,24 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2007, 2011 Sven Eberhardt - * Copyright (c) 2006-2007, 2009-2011 Günther Brammer - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start #include #include +#include #include #include #include @@ -34,7 +30,6 @@ #include #include #include -#include bool C4StartupGraphics::LoadFile(C4FacetID &rToFct, const char *szFilename) { @@ -46,14 +41,16 @@ bool C4StartupGraphics::Init() ::GraphicsResource.ProgressStart = 50; ::GraphicsResource.ProgressIncrement = 8; // load startup specific graphics from gfxsys groupset - fctScenSelBG.GetFace().SetBackground(); Game.SetInitProgress(38.0f); +#if 0 if (!LoadFile(fctScenSelBG, "StartupScenSelBG")) return false; if (!LoadFile(fctPlrSelBG, "StartupPlrSelBG")) return false; - if (!LoadFile(fctPlrPropBG, "StartupPlrPropBG")) return false; if (!LoadFile(fctNetBG, "StartupNetworkBG")) return false; +#endif + if (!LoadFile(fctDlgPaper, "StartupDlgPaper")) return false; + if (!LoadFile(fctPlrPropBG, "StartupPlrPropBG")) return false; if (!LoadFile(fctAboutBG, "StartupAboutBG")) return false; - if (!LoadFile(fctOptionsDlgPaper, "StartupDlgPaper")) return false; + fctAboutBG.GetFace().SetBackground(); if (!LoadFile(fctStartupLogo, "StartupLogo")) return false; ::GraphicsResource.ProgressStart = 92; ::GraphicsResource.ProgressIncrement = 0.5; @@ -66,14 +63,6 @@ bool C4StartupGraphics::Init() sfctBookScrollR.Set(fctBookScroll, 1); sfctBookScrollG.Set(fctBookScroll, 2); sfctBookScrollB.Set(fctBookScroll, 3); - /* if (!LoadFile(fctCrew, "StartupCrew")) return false; - currently unused - if (fctCrew.idSourceGroup != fctCrewClr.idSourceGroup) - { - if (!fctCrewClr.CreateClrByOwner(fctCrew.Surface)) { LogFatal("ClrByOwner error! (11)"); return false; } - fctCrewClr.Wdt=fctCrew.Wdt; - fctCrewClr.Hgt=fctCrew.Hgt; - fctCrewClr.idSourceGroup = fctCrew.idSourceGroup; - }*/ if (!LoadFile(fctContext, "StartupContext")) return false; fctContext.Set(fctContext.Surface,0,0,fctContext.Hgt,fctContext.Hgt); if (!LoadFile(fctScenSelIcons, "StartupScenSelIcons")) return false; @@ -95,16 +84,16 @@ bool C4StartupGraphics::Init() bool C4StartupGraphics::InitFonts() { const char *szFont = Config.General.RXFontName; - if (!::FontLoader.InitFont(BookFontCapt, szFont, C4FontLoader::C4FT_Caption, Config.General.RXFontSize, &::GraphicsResource.Files, false)) + if (!::FontLoader.InitFont(&BookFontCapt, szFont, C4FontLoader::C4FT_Caption, Config.General.RXFontSize, &::GraphicsResource.Files, false)) { LogFatal("Font Error (1)"); return false; } Game.SetInitProgress(97); - if (!::FontLoader.InitFont(BookFont, szFont, C4FontLoader::C4FT_Main, Config.General.RXFontSize, &::GraphicsResource.Files, false)) + if (!::FontLoader.InitFont(&BookFont, szFont, C4FontLoader::C4FT_Main, Config.General.RXFontSize, &::GraphicsResource.Files, false)) { LogFatal("Font Error (2)"); return false; } Game.SetInitProgress(98); - if (!::FontLoader.InitFont(BookFontTitle, szFont, C4FontLoader::C4FT_Title, Config.General.RXFontSize, &::GraphicsResource.Files, false)) + if (!::FontLoader.InitFont(&BookFontTitle, szFont, C4FontLoader::C4FT_Title, Config.General.RXFontSize, &::GraphicsResource.Files, false)) { LogFatal("Font Error (3)"); return false; } Game.SetInitProgress(99); - if (!::FontLoader.InitFont(BookSmallFont, szFont, C4FontLoader::C4FT_MainSmall, Config.General.RXFontSize, &::GraphicsResource.Files, false)) + if (!::FontLoader.InitFont(&BookSmallFont, szFont, C4FontLoader::C4FT_MainSmall, Config.General.RXFontSize, &::GraphicsResource.Files, false)) { LogFatal("Font Error (4)"); return false; } return true; } @@ -133,7 +122,6 @@ CStdFont &C4StartupGraphics::GetBlackFontByHeight(int32_t iHgt, float *pfZoom) // statics C4Startup::DialogID C4Startup::eLastDlgID = C4Startup::SDID_Main; StdCopyStrBuf C4Startup::sSubDialog = StdCopyStrBuf(); -bool C4Startup::fFirstRun = false; // startup singleton instance C4Startup *C4Startup::pInstance = NULL; @@ -242,19 +230,6 @@ void C4Startup::DoStartup() fInStartup = true; fLastDlgWasBack = false; - // first run: Splash video -#ifndef USE_CONSOLE - if (!fFirstRun) - { - fFirstRun = true; - if (!Config.Startup.NoSplash && !Application.NoSplash) - { - Game.VideoPlayer.PlayVideo(C4CFN_Splash); - } - } -#endif - - // make sure loader is drawn after splash ::GraphicsSystem.EnableLoaderDrawing(); // clear any previous @@ -375,3 +350,9 @@ bool C4Startup::SetStartScreen(const char *szScreen) else return false; return true; } + +void C4Startup::OnKeyboardLayoutChanged() +{ + // forward message to current dialog + if (pCurrDlg) pCurrDlg->OnKeyboardLayoutChanged(); +} diff --git a/src/gui/C4Startup.h b/src/gui/C4Startup.h index ee50537a7..cc5340323 100644 --- a/src/gui/C4Startup.h +++ b/src/gui/C4Startup.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2007 Sven Eberhardt - * Copyright (c) 2008, 2011 Günther Brammer - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start @@ -43,11 +40,14 @@ private: public: // backgrounds +#if 0 C4FacetID fctScenSelBG; // for scenario selection screen C4FacetID fctPlrSelBG; // for player selection screen - C4FacetID fctPlrPropBG; // for player property subpage C4FacetID fctNetBG; // for network screen +#endif + C4FacetID fctPlrPropBG; // for player property subpage C4FacetID fctAboutBG; // for about screen + C4FacetID fctDlgPaper; C4FacetID fctStartupLogo; // logo @@ -73,7 +73,7 @@ public: C4FacetID fctContext; // options dlg gfx - C4FacetID fctOptionsDlgPaper, fctOptionsIcons, fctOptionsTabClip; + C4FacetID fctOptionsIcons, fctOptionsTabClip; // net dlg gfx C4FacetID fctNetGetRef; @@ -91,6 +91,7 @@ public: C4StartupDlg(const char *szTitle) : C4GUI::FullscreenDialog(szTitle, NULL) {} virtual bool SetSubscreen(const char *szToScreen) { return false; } // go to specified subdialog, e.g. a specific property sheet in the options dlg + virtual void OnKeyboardLayoutChanged() {} }; class C4Startup @@ -109,7 +110,6 @@ private: static C4Startup *pInstance; // singleton instance static DialogID eLastDlgID; static StdCopyStrBuf sSubDialog; // subdialog to go into (e.g.: property sheet in options dialog) - static bool fFirstRun; C4StartupDlg *pLastDlg, *pCurrDlg; // startup dlg that is currently shown, and dialog that was last shown @@ -131,9 +131,9 @@ public: static void InitStartup(); static void CloseStartup(); static bool SetStartScreen(const char *szScreen); // set screen that is shown first by case insensitive identifier + void OnKeyboardLayoutChanged(); static C4Startup *Get() { assert(pInstance); return pInstance; } - static bool WasFirstRun() { return fFirstRun; } }; #endif // INC_C4Startup diff --git a/src/gui/C4StartupAboutDlg.cpp b/src/gui/C4StartupAboutDlg.cpp index c569d25b2..b91d6722a 100644 --- a/src/gui/C4StartupAboutDlg.cpp +++ b/src/gui/C4StartupAboutDlg.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // About/credits screen diff --git a/src/gui/C4StartupAboutDlg.h b/src/gui/C4StartupAboutDlg.h index f47fb71fd..64e83c429 100644 --- a/src/gui/C4StartupAboutDlg.h +++ b/src/gui/C4StartupAboutDlg.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // About/credits screen diff --git a/src/gui/C4StartupMainDlg.cpp b/src/gui/C4StartupMainDlg.cpp index 3dc88d72c..1df5f69ea 100644 --- a/src/gui/C4StartupMainDlg.cpp +++ b/src/gui/C4StartupMainDlg.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2007 Sven Eberhardt - * Copyright (c) 2005-2008 Matthes Bender - * Copyright (c) 2006 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start (stub) diff --git a/src/gui/C4StartupMainDlg.h b/src/gui/C4StartupMainDlg.h index eb4315a4b..1aa3c9128 100644 --- a/src/gui/C4StartupMainDlg.h +++ b/src/gui/C4StartupMainDlg.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start diff --git a/src/gui/C4StartupNetDlg.cpp b/src/gui/C4StartupNetDlg.cpp index 6ce721f2c..85465e531 100644 --- a/src/gui/C4StartupNetDlg.cpp +++ b/src/gui/C4StartupNetDlg.cpp @@ -1,30 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2007 Sven Eberhardt - * Copyright (c) 2006, 2008-2010 Günther Brammer - * Copyright (c) 2006-2007 Peter Wortmann - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2007-2008 Matthes Bender - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Julius Michaelis - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -"Clonk" is a registered trademark of Matthes Bender. */ + * Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ // Startup screen for non-parameterized engine start: Network game selection dialog #include @@ -762,7 +750,11 @@ C4StartupNetDlg::~C4StartupNetDlg() void C4StartupNetDlg::DrawElement(C4TargetFacet &cgo) { // draw background + typedef C4GUI::FullscreenDialog Base; + Base::DrawElement(cgo); +#if 0 DrawBackground(cgo, C4Startup::Get()->Graphics.fctNetBG); +#endif } void C4StartupNetDlg::OnShown() @@ -871,7 +863,7 @@ void C4StartupNetDlg::UpdateMasterserver() else { pMasterserverClient = new C4StartupNetListEntry(pGameSelList, NULL, this); - StdStrBuf strVersion; strVersion.Format("%d.%d.%d.%d", C4XVER1, C4XVER2, C4XVER3, C4XVER4); + StdStrBuf strVersion; strVersion.Format("%d.%d.%d", C4XVER1, C4XVER2, C4XVER3); StdStrBuf strQuery; strQuery.Format("%s?version=%s&platform=%s", Config.Network.GetLeagueServerAddress(), strVersion.getData(), C4_OS); pMasterserverClient->SetRefQuery(strQuery.getData(), C4StartupNetListEntry::NRQT_Masterserver); } diff --git a/src/gui/C4StartupNetDlg.h b/src/gui/C4StartupNetDlg.h index 0aacd564d..b2b184704 100644 --- a/src/gui/C4StartupNetDlg.h +++ b/src/gui/C4StartupNetDlg.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006-2007 Sven Eberhardt - * Copyright (c) 2006-2007 Peter Wortmann - * Copyright (c) 2010 Julius Michaelis - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Network game selection dialog @@ -159,7 +154,7 @@ private: protected: - virtual bool HasBackground() { return true; } + virtual bool HasBackground() { return false; } virtual void DrawElement(C4TargetFacet &cgo); virtual C4GUI::Control *GetDefaultControl(); // get Auto-Focus control diff --git a/src/gui/C4StartupOptionsDlg.cpp b/src/gui/C4StartupOptionsDlg.cpp index 88e4a88fb..e00a53384 100644 --- a/src/gui/C4StartupOptionsDlg.cpp +++ b/src/gui/C4StartupOptionsDlg.cpp @@ -1,26 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2008, 2011 Sven Eberhardt - * Copyright (c) 2006, 2008, 2010 Günther Brammer - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2007 Julian Raschke - * Copyright (c) 2008, 2010 Armin Burgmeier - * Copyright (c) 2009 Carli@Carli-PC - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Options dialog @@ -36,7 +27,7 @@ #include #include -#include +#include // ------------------------------------------------ // --- C4StartupOptionsDlg::SmallButton @@ -163,21 +154,17 @@ StdStrBuf C4StartupOptionsDlg::KeySelDialog::GetDlgMessage(const C4PlayerControl { // compose message asking for key, gamepad button and/or mouse button depending on used control set if (!assignment || !assignment_set) return StdStrBuf("err"); - int32_t ctrl = assignment->GetControl(); - const C4PlayerControlDef *assignment_def = Game.PlayerControlDefs.GetControlByIndex(ctrl); StdStrBuf result_string; if (assignment_set->HasGamepad()) - result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSBTN"), assignment_def ? assignment_def->GetGUIName() : "undefined", 0)); + result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSBTN"), assignment->GetGUIName(Game.PlayerControlDefs))); else - result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSKEY"), assignment_def ? assignment_def->GetGUIName() : "undefined", 0)); - if (assignment_def) + result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSKEY"), assignment->GetGUIName(Game.PlayerControlDefs))); + const char *ctrl_desc = assignment->GetGUIDesc(Game.PlayerControlDefs); + + if (ctrl_desc && *ctrl_desc) { - const char *ctrl_desc = assignment_def->GetGUIDesc(); - if (ctrl_desc && *ctrl_desc) - { - result_string.Append("||"); - result_string.Append(ctrl_desc); - } + result_string.Append("||"); + result_string.Append(ctrl_desc); } return result_string; } @@ -234,17 +221,20 @@ void C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::MouseInp // left-click to change key if (iButton == C4MC_Button_LeftDown && assignment) { - KeySelDialog *dlg = new KeySelDialog(assignment, assignment_set); - dlg->SetDelOnClose(false); - bool success = GetScreen()->ShowModalDlg(dlg, false); - C4KeyCodeEx key = dlg->GetKeyCode(); - delete dlg; - if (success) + if(!assignment->IsGUIDisabled()) { - // dialog closed by pressing a key or by the Reset button (in which case, key==KEY_Undefined) - // assign new config - C4StartupOptionsDlg::ControlConfigListBox::SetUserKey(assignment_set, assignment, key); - UpdateAssignmentString(); + KeySelDialog *dlg = new KeySelDialog(assignment, assignment_set); + dlg->SetDelOnClose(false); + bool success = GetScreen()->ShowModalDlg(dlg, false); + C4KeyCodeEx key = dlg->GetKeyCode(); + delete dlg; + if (success) + { + // dialog closed by pressing a key or by the Reset button (in which case, key==KEY_Undefined) + // assign new config + C4StartupOptionsDlg::ControlConfigListBox::SetUserKey(assignment_set, assignment, key); + UpdateAssignmentString(); + } } } // inherited @@ -256,16 +246,30 @@ void C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::UpdateAs // assignment label text from assigned key StdStrBuf strKey; C4KeyCodeEx key(0); - if (assignment) key = assignment->GetTriggerKey(); - SetText(key.ToString(true, true).getData()); - SetColor((assignment && assignment->IsKeyChanged()) ? C4GUI_CaptionFontClr : C4GUI_InactCaptionFontClr); + if (assignment) + { + SetText(assignment->GetKeysAsString(true, false).getData()); + } + else + { + SetText(""); + } + DWORD color = C4GUI_CaptionFontClr; + if (assignment) + { + if(assignment->IsGUIDisabled()) + color = C4GUI_InactCaptionFontClr; + else if(assignment->IsKeyChanged()) + color = C4GUI_Caption2FontClr; + } + SetColor(color); } // ------------------------------------------------ // --- C4StartupOptionsDlg::ControlConfigListBox::ListItem -C4StartupOptionsDlg::ControlConfigListBox::ListItem::ListItem(ControlConfigListBox *parent_list, class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set) - : C4GUI::Window(), parent_list(parent_list), assignment_label(NULL), has_extra_spacing(false) +C4StartupOptionsDlg::ControlConfigListBox::ListItem::ListItem(ControlConfigListBox *parent_list, class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set, bool has_extra_spacing) + : C4GUI::Window(), parent_list(parent_list), assignment_label(NULL), has_extra_spacing(has_extra_spacing) { int32_t margin = 2; // adding to listbox will size the element horizontally and move to proper position @@ -273,15 +277,15 @@ C4StartupOptionsDlg::ControlConfigListBox::ListItem::ListItem(ControlConfigListB SetBounds(C4Rect(0,0,42,height)); parent_list->InsertElement(this, NULL); int32_t name_col_width = GetBounds().Wdt * 2/3; - if (assignment && assignment->IsGroupStart()) has_extra_spacing = true; // child elements: two labels for two columns - int32_t con = assignment->GetControl(); - const C4PlayerControlDef *con_def = Game.PlayerControlDefs.GetControlByIndex(con); - C4GUI::Label *name_label = new C4GUI::Label(con_def ? con_def->GetGUIName() : "?undefined?", margin, margin); + const char *gui_name = assignment->GetGUIName(Game.PlayerControlDefs); + const char *gui_desc = assignment->GetGUIDesc(Game.PlayerControlDefs); + C4GUI::Label *name_label = new C4GUI::Label(gui_name ? gui_name : "?undefined?", margin, margin); C4Rect assignment_label_bounds = C4Rect(name_col_width + margin, margin, GetBounds().Wdt - name_col_width - margin, GetBounds().Hgt - 2 * margin); assignment_label = new ControlAssignmentLabel(assignment, assignment_set, assignment_label_bounds); AddElement(name_label); AddElement(assignment_label); + if (gui_desc && *gui_desc) SetToolTip(gui_desc); } @@ -303,15 +307,24 @@ void C4StartupOptionsDlg::ControlConfigListBox::SetAssignmentSet(class C4PlayerC if (set) { C4PlayerControlAssignment *assignment; - int32_t i=0; - while (assignment = set->GetAssignmentByIndex(i++)) + + std::vector grouped_assignments; + for (int32_t i=0; assignment = set->GetAssignmentByIndex(i); ++i) + grouped_assignments.push_back(assignment); + + std::stable_sort(grouped_assignments.begin(),grouped_assignments.end(),&C4StartupOptionsDlg::ControlConfigListBox::sort_by_group); + + int32_t current_group = 0; + for (std::vector::iterator i = grouped_assignments.begin(); i != grouped_assignments.end(); ++i) { + assignment = *i; + bool first_element_of_group = assignment->GetGUIGroup() > current_group; + current_group = assignment->GetGUIGroup(); // only show assignments of GUI-named controls - int32_t ctrl = assignment->GetControl(); - const C4PlayerControlDef *def = Game.PlayerControlDefs.GetControlByIndex(ctrl); - if (def && def->GetGUIName() && *def->GetGUIName()) + const char *gui_name = assignment->GetGUIName(Game.PlayerControlDefs); + if (gui_name && *gui_name) { - ListItem *element = new ListItem(this, assignment, set); + ListItem *element = new ListItem(this, assignment, set, first_element_of_group); AddElement(element); } } @@ -391,70 +404,14 @@ C4StartupOptionsDlg::ControlConfigArea::ControlConfigArea(const C4Rect &rcArea, AddElement(ppKeyControlSetBtns[i] = pBtn); pBtn->SetText(assignment_set->GetGUIName()); pBtn->SetFont(pUseFontSmall, C4StartupFontClr); - pBtn->SetToolTip("[!]Select control set to modify"); + pBtn->SetToolTip(LoadResStr("IDS_DLGTIP_CHANGECTRL")); } iSelectedCtrlSet = 0; caArea.ExpandTop(caArea.GetVMargin()); AddElement(new C4GUI::HorizontalLine(caArea.GetFromTop(2))); caArea.ExpandTop(caArea.GetVMargin()); - control_list = new ControlConfigListBox(caArea.GetFromLeft(caArea.GetInnerWidth()/2), NULL); + control_list = new ControlConfigListBox(caArea.GetFromLeft(caArea.GetInnerWidth()), NULL); AddElement(control_list); - /*C4Facet &rfctKey = ::GraphicsResource.fctKey; - int32_t iKeyAreaMaxWdt = caArea.GetWidth()-2*caArea.GetHMargin(), iKeyAreaMaxHgt = caArea.GetHeight()-2*caArea.GetVMargin(); - int32_t iKeyWdt = rfctKey.Wdt*3/2, iKeyHgt = rfctKey.Hgt*3/2; - int32_t iKeyUseWdt = iKeyWdt + iKeyHgt*3; // add space for label - int32_t iKeyMargin = 20; - int32_t iKeyAreaWdt = (iKeyUseWdt+2*iKeyMargin) * iKeyPosMaxX, iKeyAreaHgt = (iKeyHgt+2*iKeyMargin) * iKeyPosMaxY; - if (iKeyAreaWdt > iKeyAreaMaxWdt || iKeyAreaHgt > iKeyAreaMaxHgt) - { - // scale down - float fScaleX = float(iKeyAreaMaxWdt) / float(Max(iKeyAreaWdt,1)), - fScaleY = float(iKeyAreaMaxHgt) / float(Max(iKeyAreaHgt,1)), fScale; - if (fScaleX > fScaleY) fScale = fScaleY; else fScale = fScaleX; - iKeyMargin = int32_t(fScale*iKeyMargin); - iKeyWdt = int32_t(fScale*iKeyWdt); - iKeyUseWdt = int32_t(fScale*iKeyUseWdt); - iKeyHgt = int32_t(fScale*iKeyHgt); - iKeyAreaWdt = int32_t(fScale*iKeyAreaWdt); - iKeyAreaHgt = int32_t(fScale*iKeyAreaHgt); - } - C4GUI::ComponentAligner caCtrlKeys(caArea.GetFromTop(iKeyAreaHgt, iKeyAreaWdt), 0,iKeyMargin); - int32_t iKeyNum; - for (int iY = 0; iY < iKeyPosMaxY; ++iY) - { - C4GUI::ComponentAligner caCtrlKeysLine(caCtrlKeys.GetFromTop(iKeyHgt), iKeyMargin,0); - for (int iX = 0; iX < iKeyPosMaxX; ++iX) - { - C4Rect rcKey = caCtrlKeysLine.GetFromLeft(iKeyWdt); - caCtrlKeysLine.ExpandLeft(iKeyWdt - iKeyUseWdt); - if ((iKeyNum=iKeyPosis[iY][iX])<0) continue; - KeySelButton *pKeyBtn = new C4GUI::CallbackButton(iKeyNum, rcKey, 0, &C4StartupOptionsDlg::ControlConfigArea::OnCtrlKeyBtn, this); - AddElement(KeyControlBtns[iKeyNum] = pKeyBtn); - pKeyBtn->SetToolTip(KeyID2Desc(iKeyNum)); - } - } - // bottom area controls - caArea.ExpandBottom(-iKeyHgt/2); - C4GUI::ComponentAligner caKeyBottomBtns(caArea.GetFromBottom(C4GUI_ButtonHgt), 2,0); - // gamepad: Use for GUI - if (fGamepad) - { - int iWdt=100,iHgt=20; - const char *szResetText = LoadResStr("IDS_CTL_GAMEPADFORMENU"); - C4GUI::CheckBox::GetStandardCheckBoxSize(&iWdt, &iHgt, szResetText, pUseFont); - pGUICtrl = new C4GUI::CheckBox(caKeyBottomBtns.GetFromLeft(iWdt, iHgt), szResetText, !!Config.Controls.GamepadGuiControl); - pGUICtrl->SetOnChecked(new C4GUI::CallbackHandler(this, &C4StartupOptionsDlg::ControlConfigArea::OnGUIGamepadCheckChange)); - pGUICtrl->SetToolTip(LoadResStr("IDS_DESC_GAMEPADFORMENU")); - pGUICtrl->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled); - AddElement(pGUICtrl); - } - // reset button - const char *szBtnText = LoadResStr("IDS_BTN_RESETKEYBOARD"); - int32_t iButtonWidth=100, iButtonHeight=20; C4GUI::Button *btn; - ::GraphicsResource.CaptionFont.GetTextExtent(szBtnText, iButtonWidth, iButtonHeight, true); - C4Rect rcResetBtn = caKeyBottomBtns.GetFromRight(Min(iButtonWidth+iButtonHeight*4, caKeyBottomBtns.GetInnerWidth())); - AddElement(btn = new C4GUI::CallbackButton(szBtnText, rcResetBtn, &C4StartupOptionsDlg::ControlConfigArea::OnResetKeysBtn, this)); - btn->SetToolTip(LoadResStr("IDS_MSG_RESETKEYSETS"));*/ UpdateCtrlSet(); } @@ -746,13 +703,12 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D // main config area tabular pOptionsTabular = new C4GUI::Tabular(caConfigArea.GetAll(), C4GUI::Tabular::tbLeft); - pOptionsTabular->SetGfx(&C4Startup::Get()->Graphics.fctOptionsDlgPaper, &C4Startup::Get()->Graphics.fctOptionsTabClip, &C4Startup::Get()->Graphics.fctOptionsIcons, &C4Startup::Get()->Graphics.BookSmallFont, true); + pOptionsTabular->SetGfx(&C4Startup::Get()->Graphics.fctDlgPaper, &C4Startup::Get()->Graphics.fctOptionsTabClip, &C4Startup::Get()->Graphics.fctOptionsIcons, &C4Startup::Get()->Graphics.BookSmallFont, true); AddElement(pOptionsTabular); C4GUI::Tabular::Sheet *pSheetGeneral = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_PROGRAM") , 0); C4GUI::Tabular::Sheet *pSheetGraphics = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_GRAPHICS"), 1); C4GUI::Tabular::Sheet *pSheetSound = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_SOUND") , 2); - C4GUI::Tabular::Sheet *pSheetControls= pOptionsTabular->AddSheet("[!]Controls", 3); - //C4GUI::Tabular::Sheet *pSheetGamepad = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_GAMEPAD") , 4); + C4GUI::Tabular::Sheet *pSheetControls= pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_CONTROLS"), 3); C4GUI::Tabular::Sheet *pSheetNetwork = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_NETWORK") , 5); C4GUI::CheckBox *pCheck; C4GUI::Label *pLbl; @@ -814,49 +770,17 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D pCheck->SetToolTip(LoadResStr("IDS_MSG_MMTIMER_DESC")); pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled); pSheetGeneral->AddElement(pCheck); - // startup video -#ifdef _WIN32 - pCheck = new BoolConfig(caSheetProgram.GetGridCell(0,1,4,7,-1,iCheckHgt, true), LoadResStr("IDS_MSG_STARTUPVIDEO"), NULL, &Config.Startup.NoSplash, true); - pCheck->SetToolTip(LoadResStr("IDS_MSG_STARTUPVIDEO_DESC")); - pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled); - pSheetGeneral->AddElement(pCheck); -#endif // reset configuration const char *szBtnText = LoadResStr("IDS_BTN_RESETCONFIG"); C4GUI::CallbackButton *pSmallBtn; ::GraphicsResource.CaptionFont.GetTextExtent(szBtnText, iButtonWidth, iButtonHeight, true); C4Rect rcResetBtn = caSheetProgram.GetGridCell(1,2,6,7, Min(iButtonWidth+iButtonHeight*4, caSheetProgram.GetInnerWidth()*2/5), SmallButton::GetDefaultButtonHeight(), true); - pSheetGeneral->AddElement(pSmallBtn = new C4GUI::CallbackButton(szBtnText, rcResetBtn, &C4StartupOptionsDlg::OnResetConfigBtn, this)); + pSmallBtn = new C4GUI::CallbackButton(szBtnText, rcResetBtn, &C4StartupOptionsDlg::OnResetConfigBtn, this); + pSheetGeneral->AddElement(pSmallBtn); pSmallBtn->SetToolTip(LoadResStr("IDS_DESC_RESETCONFIG")); // --- page graphics C4GUI::ComponentAligner caSheetGraphics(pSheetGraphics->GetClientRect(), iIndentX1, iIndentY1, true); - // --subgroup engine - C4GUI::GroupBox *pGroupEngine = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,2,0,3)); - pGroupEngine->SetTitle(LoadResStrNoAmp("IDS_CTL_GFXENGINE")); - pGroupEngine->SetFont(pUseFont); - pGroupEngine->SetColors(C4StartupEditBorderColor, C4StartupFontClr); - pGroupEngine->SetToolTip(LoadResStr("IDS_MSG_GFXENGINE_DESC")); - pSheetGraphics->AddElement(pGroupEngine); - C4GUI::ComponentAligner caGroupEngine(pGroupEngine->GetClientRect(), iIndentX1, iIndentY2, true); - const char *szGfxEngineNames[3] = { "DirectX", "OpenGL", "DirectX Software" }; - C4GUI::BaseCallbackHandler *pGfxEngineCheckCB = new C4GUI::CallbackHandler(this, &C4StartupOptionsDlg::OnGfxEngineCheck); - for (int32_t iGfxEngine = 0; iGfxEngine<3; ++iGfxEngine) - { - pCheckGfxEngines[iGfxEngine] = new C4GUI::CheckBox(caGroupEngine.GetGridCell(0,1,iGfxEngine,3,-1,iCheckHgt,true), szGfxEngineNames[iGfxEngine], (Config.Graphics.Engine == iGfxEngine)); - pCheckGfxEngines[iGfxEngine]->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled); - pCheckGfxEngines[iGfxEngine]->SetOnChecked(pGfxEngineCheckCB); - pGroupEngine->AddElement(pCheckGfxEngines[iGfxEngine]); - } -#ifndef USE_DIRECTX - pCheckGfxEngines[GFXENGN_DIRECTX]->SetEnabled(false); - pCheckGfxEngines[GFXENGN_DIRECTXS]->SetEnabled(false); -#endif -#ifndef USE_GL - pCheckGfxEngines[GFXENGN_OPENGL]->SetEnabled(false); -#endif - pCheckGfxEngines[GFXENGN_DIRECTX]->SetEnabled(false); // as long as DX doesnt work, its disabled - pCheckGfxEngines[GFXENGN_DIRECTXS]->SetEnabled(false); // better not using this // --subgroup resolution C4GUI::GroupBox *pGroupResolution = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(1,2,0,3)); pGroupResolution->SetTitle(LoadResStrNoAmp("IDS_CTL_RESOLUTION")); @@ -887,19 +811,28 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D C4GUI::BaseCallbackHandler *pGfxClrDepthCheckCB = new C4GUI::CallbackHandler(this, &C4StartupOptionsDlg::OnGfxClrDepthCheck); for (int32_t iBitDepthIdx = 0; iBitDepthIdx<2; ++iBitDepthIdx) { - int iBitDepth = (iBitDepthIdx+1) * 16; - pCheckGfxClrDepth[iBitDepthIdx] = new C4GUI::CheckBox(caGroupEngine.GetGridCell(iBitDepthIdx,2,2,4,-1,iCheckHgt,true), FormatString("%d Bit", (int)iBitDepth).getData(), (Config.Graphics.BitDepth == iBitDepth)); + int iBitDepth = (iBitDepthIdx+1) * 16; //WORKAROUND + pCheckGfxClrDepth[iBitDepthIdx] = new C4GUI::CheckBox(caGroupResolution.GetGridCell(iBitDepthIdx,2,2,4,-1,iCheckHgt,true), FormatString("%d Bit", (int)iBitDepth).getData(), (Config.Graphics.BitDepth == iBitDepth)); pCheckGfxClrDepth[iBitDepthIdx]->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled); pCheckGfxClrDepth[iBitDepthIdx]->SetOnChecked(pGfxClrDepthCheckCB); pCheckGfxClrDepth[iBitDepthIdx]->SetToolTip(LoadResStr("IDS_CTL_BITDEPTH")); pGroupResolution->AddElement(pCheckGfxClrDepth[iBitDepthIdx]); } - // fullscreen checkbox - pCheck = new C4GUI::CheckBox(caGroupResolution.GetGridCell(0,1,3,4,-1,iCheckHgt,true), LoadResStr("IDS_MSG_FULLSCREEN"), !Config.Graphics.Windowed); - pCheck->SetOnChecked(new C4GUI::CallbackHandler(this, &C4StartupOptionsDlg::OnFullscreenChange)); - pCheck->SetToolTip(LoadResStr("IDS_MSG_FULLSCREEN_DESC")); - pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled); - pGroupResolution->AddElement(pCheck); + // fullscreen combobox + uint32_t wmax = 0; + for(int i = 0; i < 3; ++i) + { + pUseFont->GetTextExtent(GetWindowedName(i),w,q,true); + wmax = Max(w, wmax); + } + C4GUI::ComboBox * pCombo = new C4GUI::ComboBox(caGroupResolution.GetGridCell(0,1,3,4,wmax+40,C4GUI::ComboBox::GetDefaultHeight(), true)); + pCombo->SetComboCB(new C4GUI::ComboBox_FillCallback(this, &C4StartupOptionsDlg::OnWindowedModeComboFill, &C4StartupOptionsDlg::OnWindowedModeComboSelChange)); + pCombo->SetToolTip(LoadResStr("IDS_MSG_FULLSCREEN_DESC")); + pCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor); + pCombo->SetFont(pUseFont); + pCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext)); + pCombo->SetText(GetWindowedName()); + pGroupResolution->AddElement(pCombo); // --subgroup troubleshooting pGroupTrouble = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,1,1,3)); pGroupTrouble->SetTitle(LoadResStrNoAmp("IDS_CTL_TROUBLE")); @@ -1048,7 +981,7 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D } // --- page controls - pSheetControls->AddElement(new ControlConfigArea(pSheetControls->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/40, false, this)); + pSheetControls->AddElement(pControlConfigArea = new ControlConfigArea(pSheetControls->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/40, false, this)); // --- page network C4GUI::ComponentAligner caSheetNetwork(pSheetNetwork->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/20, true); @@ -1123,28 +1056,6 @@ void C4StartupOptionsDlg::OnResetConfigBtn(C4GUI::Control *btn) Application.Quit(); } -void C4StartupOptionsDlg::OnGfxEngineCheck(C4GUI::Element *pCheckBox) -{ - C4GUI::CheckBox *pCheck = static_cast(pCheckBox); - // radiogroup: do not allow unchecking! - if (!pCheck->GetChecked()) - { - pCheck->SetChecked(true); - return; - } - // get new engine - int i; - for (i=0; i<3; ++i) if (pCheck == pCheckGfxEngines[i]) break; - if (i==3 || i == Config.Graphics.Engine) return; - // okay, engine change - pCheckGfxEngines[Config.Graphics.Engine]->SetChecked(false); - StdStrBuf sTitle; sTitle.Copy(LoadResStrNoAmp("IDS_CTL_GFXENGINE")); - GetScreen()->ShowMessage(LoadResStr("IDS_MSG_RESTARTCHANGECFG"), sTitle.getData(), C4GUI::Ico_Notify, &Config.Startup.HideMsgGfxEngineChange); - SaveGfxTroubleshoot(); - Config.Graphics.Engine = i; - LoadGfxTroubleshoot(); -} - void C4StartupOptionsDlg::OnGfxMSComboFill(C4GUI::ComboBox_FillCB *pFiller) { // clear all old entries first to allow a clean refill @@ -1167,38 +1078,22 @@ void C4StartupOptionsDlg::OnGfxMSComboFill(C4GUI::ComboBox_FillCB *pFiller) bool C4StartupOptionsDlg::OnGfxMSComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection) { if(pTexMgr) pTexMgr->IntLock(); -#ifdef USE_GL +#ifndef USE_CONSOLE pDraw->InvalidateDeviceObjects(); // Note: This assumes there is only one GL context (the main context). This // is true in fullscreen mode, and since the startup dlg is only shown in // fullscreen mode we are safe this way. if(pGL) pGL->pMainCtx->Clear(); #endif -#ifdef USE_DIRECTX - // It should also be possible to clear+reinit DDraw also for GL, however, - // if ReInit() does _not_ create a new window on X11 then all rendering - // stops until the Window is being moved again (or tasked-out and back in - // in fullscreen mode). This does not happen when only reinitializing the - // GL context instead of whole DDraw so that's why we do this currently. - if(pD3D) pDraw->Clear(); -#endif - int32_t PrevMultiSampling = Config.Graphics.MultiSampling; Config.Graphics.MultiSampling = idNewSelection; bool success = Application.pWindow->ReInit(&Application); -#ifdef USE_GL +#ifndef USE_CONSOLE if(pGL) pGL->pMainCtx->Init(Application.pWindow, &Application); pDraw->RestoreDeviceObjects(); #endif -#ifdef USE_DIRECTX - // Note: Editor is hardcoded to false at this point... I guess that's OK - // because C4StartupOptionsDlg is never shown in editor mode anyway. - if(pD3D) pDraw->Init(&Application, false, false, Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.Monitor); -#endif - if(pTexMgr) pTexMgr->IntUnlock(); - if(!success) Config.Graphics.MultiSampling = PrevMultiSampling; return !success; } @@ -1207,6 +1102,7 @@ void C4StartupOptionsDlg::OnGfxResComboFill(C4GUI::ComboBox_FillCB *pFiller) { // clear all old entries first to allow a clean refill pFiller->ClearEntries(); + pFiller->AddEntry(LoadResStr("IDS_MNU_DEFAULTRESOLUTION"), -1); // fill with all possible resolutions int32_t idx = 0, iXRes, iYRes, iBitDepth; while (Application.GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, NULL, Config.Graphics.Monitor)) @@ -1225,6 +1121,8 @@ bool C4StartupOptionsDlg::OnGfxResComboSelChange(C4GUI::ComboBox *pForCombo, int { // get new resolution from string int iResX=(idNewSelection & 0xffff), iResY=(uint32_t(idNewSelection) & 0xffff0000) >> 16; + if (idNewSelection == -1) + iResX = iResY = -1; // different than current? if (iResX == Config.Graphics.ResX && iResY == Config.Graphics.ResY) return true; // try setting it @@ -1243,15 +1141,13 @@ bool C4StartupOptionsDlg::TryNewResolution(int32_t iResX, int32_t iResY) int32_t iOldFontSize = Config.General.RXFontSize; C4GUI::Screen *pScreen = GetScreen(); // resolution change may imply font size change - int32_t iNewFontSize; - if (iResX < 700) + int32_t iNewFontSize = 14; // default (at 800x600) + if (iResY >= 0 && iResY < 600) iNewFontSize = 12; - else if (iResX < 950) - iNewFontSize = 14; // default (at 800x600) - else + else if (iResY > 800) iNewFontSize = 16; // call application to set it - if (!Application.SetVideoMode(iResX, iResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed)) + if (!Application.SetVideoMode(iResX, iResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, true)) { StdCopyStrBuf strChRes(LoadResStr("IDS_MNU_SWITCHRESOLUTION")); pScreen->ShowMessage(FormatString(LoadResStr("IDS_ERR_SWITCHRES"), Application.GetLastError()).getData(), strChRes.getData(), C4GUI::Ico_Clonk, NULL); @@ -1288,12 +1184,16 @@ bool C4StartupOptionsDlg::TryNewResolution(int32_t iResX, int32_t iResY) // resolution may be kept! Config.Graphics.ResX = iResX; Config.Graphics.ResY = iResY; + if(Config.Graphics.Windowed) + Application.SetVideoMode(Application.GetConfigWidth(), Application.GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, false); return true; } StdStrBuf C4StartupOptionsDlg::GetGfxResString(int32_t iResX, int32_t iResY) { // Display in format like "640 x 480" + if (iResX == -1) + return StdStrBuf(LoadResStr("IDS_MNU_DEFAULTRESOLUTION")); return FormatString("%d x %d", (int)iResX, (int)iResY); } @@ -1320,10 +1220,30 @@ void C4StartupOptionsDlg::OnGfxClrDepthCheck(C4GUI::Element *pCheckBox) GetScreen()->ShowMessage(LoadResStr("IDS_MSG_RESTARTCHANGECFG"), sTitle.getData(), C4GUI::Ico_Notify, &Config.Startup.HideMsgGfxBitDepthChange); } -void C4StartupOptionsDlg::OnFullscreenChange(C4GUI::Element *pCheckBox) +const char * C4StartupOptionsDlg::GetWindowedName(int32_t mode /* = -1*/) { - Config.Graphics.Windowed = !static_cast(pCheckBox)->GetChecked(); + if(mode == -1) + mode = Config.Graphics.Windowed; + if(mode == 0) return LoadResStr("IDS_MSG_FULLSCREEN"); + else if(mode == 1) return LoadResStr("IDS_MSG_WINDOWED"); + else if(mode == 2) return LoadResStr("IDS_MSG_AUTOWINDOWED"); + assert(!"Requested name for config value which does not exist"); + return "ERR: Unknown"; +} + +void C4StartupOptionsDlg::OnWindowedModeComboFill(C4GUI::ComboBox_FillCB *pFiller) +{ + pFiller->ClearEntries(); + for(int32_t i = 0; i < 3; ++i) + pFiller->AddEntry(GetWindowedName(i), i); +} + +bool C4StartupOptionsDlg::OnWindowedModeComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection) +{ + Config.Graphics.Windowed = idNewSelection; Application.SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed); + pForCombo->SetText(GetWindowedName(idNewSelection)); + return true; } void C4StartupOptionsDlg::OnGfxAllResolutionsChange(C4GUI::Element *pCheckBox) @@ -1532,10 +1452,8 @@ void C4StartupOptionsDlg::SaveGfxTroubleshoot() { // get it from controls Config.Graphics.EnableShaders=pShaders->GetChecked(); - // get config set to be used - bool fUseGL = (Config.Graphics.Engine == GFXENGN_OPENGL); - // and apply them directly, if the engine is current - if (fUseGL == pDraw->IsOpenGL()) + + if (pDraw->IsOpenGL()) { pDraw->RestoreDeviceObjects(); } @@ -1606,3 +1524,10 @@ bool C4StartupOptionsDlg::KeyMusicToggle() // key processed return true; } + +void C4StartupOptionsDlg::OnKeyboardLayoutChanged() +{ + // keyboard layout changed and thus some keys might have been updated from scan codes + // update display in control set + pControlConfigArea->UpdateCtrlSet(); +} diff --git a/src/gui/C4StartupOptionsDlg.h b/src/gui/C4StartupOptionsDlg.h index 408e4f9ae..12776a5bd 100644 --- a/src/gui/C4StartupOptionsDlg.h +++ b/src/gui/C4StartupOptionsDlg.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2007, 2011 Sven Eberhardt - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Options dialog @@ -52,6 +50,7 @@ public: void DoBack(); // back to main menu virtual bool SetSubscreen(const char *szToScreen); // go to specified property sheet + virtual void OnKeyboardLayoutChanged(); // keyboard layout changed: update keys from scan codes public: void RecreateDialog(bool fFade); @@ -125,9 +124,9 @@ private: virtual const char *GetID() { return "ResChangeConfirmDialog"; } }; - void OnFullscreenChange(C4GUI::Element *pCheckBox); + void OnWindowedModeComboFill(C4GUI::ComboBox_FillCB *pFiller); + bool OnWindowedModeComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection); void OnGfxAllResolutionsChange(C4GUI::Element *pCheckBox); - void OnGfxEngineCheck(C4GUI::Element *pCheckBox); void OnGfxTroubleCheck(C4GUI::Element *pCheckBox) { SaveGfxTroubleshoot(); } // immediate save and test void OnGfxResComboFill(C4GUI::ComboBox_FillCB *pFiller); @@ -137,9 +136,10 @@ private: bool TryNewResolution(int32_t iResX, int32_t iResY); void OnGfxClrDepthCheck(C4GUI::Element *pCheckBox); StdStrBuf GetGfxResString(int32_t iResX, int32_t iResY); // convert resolution to string to be displayed in resolution choice combobox + const char * GetWindowedName(int32_t mode = -1); void OnEffectsSliderChange(int32_t iNewVal); - C4GUI::CheckBox *pCheckGfxEngines[3], *pCheckGfxClrDepth[2]; + C4GUI::CheckBox *pCheckGfxClrDepth[2]; C4GUI::GroupBox *pGroupTrouble; C4GUI::CheckBox *pShaders; int32_t iGfxTexIndent; @@ -215,11 +215,12 @@ private: virtual int32_t GetListItemTopSpacing() { return C4GUI::Window::GetListItemTopSpacing() + (has_extra_spacing*GetBounds().Hgt/2); } public: - ListItem(ControlConfigListBox *parent_list, class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set); + ListItem(ControlConfigListBox *parent_list, class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set, bool first_of_group); }; private: class C4PlayerControlAssignmentSet *set; // assignment set being configured by this box + static bool sort_by_group (C4PlayerControlAssignment *i, C4PlayerControlAssignment *j) { return i->GetGUIGroup() < j->GetGUIGroup(); } public: ControlConfigListBox(const C4Rect &rcBounds, class C4PlayerControlAssignmentSet *set); @@ -246,14 +247,17 @@ private: ControlConfigArea(const C4Rect &rcArea, int32_t iHMargin, int32_t iVMargin, bool fGamepad, C4StartupOptionsDlg *pOptionsDlg); virtual ~ControlConfigArea(); - protected: void UpdateCtrlSet(); + protected: + void OnCtrlSetBtn(C4GUI::Control *btn); void OnResetKeysBtn(C4GUI::Control *btn); void OnGUIGamepadCheckChange(C4GUI::Element *pCheckBox); }; + ControlConfigArea *pControlConfigArea; + class C4GamePadControl *GamePadCon; // network tab -------------------------------------------------------- diff --git a/src/gui/C4StartupPlrSelDlg.cpp b/src/gui/C4StartupPlrSelDlg.cpp index b5c3da595..a9e14639d 100644 --- a/src/gui/C4StartupPlrSelDlg.cpp +++ b/src/gui/C4StartupPlrSelDlg.cpp @@ -1,26 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2011 Sven Eberhardt - * Copyright (c) 2005-2006, 2008-2009 Günther Brammer - * Copyright (c) 2006-2008 Matthes Bender - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2009, 2011 Nicolas Hake - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Player selection dialog // Also contains player creation, editing and crew management @@ -44,7 +35,7 @@ #include // font clrs -const uint32_t ClrPlayerItem = 0xff000000; +const uint32_t ClrPlayerItem = 0xffffffff; // Arbitrary cut-off value for player color value. This avoids pitch black // colors which look ugly. Note that this limit is only applied in the UI, @@ -79,7 +70,7 @@ StdStrBuf DateString(int iTime) C4StartupPlrSelDlg::ListItem::ListItem(C4StartupPlrSelDlg *pForDlg, C4GUI::ListBox *pForListBox, C4GUI::Element *pInsertBeforeElement, bool fActivated) : Control(C4Rect(0,0,0,0)), pCheck(NULL), pNameLabel(NULL), pPlrSelDlg(pForDlg), pIcon(NULL) { - CStdFont &rUseFont = C4Startup::Get()->Graphics.BookFont; + CStdFont &rUseFont = GraphicsResource.FontRegular; // calc height int32_t iHeight = rUseFont.GetLineHeight() + 2 * IconLabelSpacing; // create subcomponents @@ -496,17 +487,17 @@ C4StartupPlrSelDlg::C4StartupPlrSelDlg() : C4StartupDlg("W"), eMode(PSDM_Player) rcBottomButtons = caButtonArea.GetCentered(caMain.GetWidth(), iButtonHeight); iBottomButtonWidth = (caButtonArea.GetWidth() - iButtonXSpacing * (iButtonCount-1)) / iButtonCount; C4Rect rcMain = caMain.GetAll(); - C4Rect rcPlrList = C4Rect(rcMain.Wdt/10, rcMain.Hgt*10/36, rcMain.Wdt*25/81, rcMain.Hgt*2/3); - C4Rect rcInfoWindow = C4Rect(rcMain.Wdt*371/768, rcMain.Hgt*10/36, rcMain.Wdt*121/384, rcMain.Hgt*2/3); + C4Rect rcPlrList = C4Rect(rcMain.Wdt/8, rcMain.Hgt/8, rcMain.Wdt*5/16, rcMain.Hgt*6/8); + C4Rect rcInfoWindow = C4Rect(rcMain.Wdt*9/16, rcMain.Hgt/8, rcMain.Wdt*5/16, rcMain.Hgt*6/8); AddElement(pPlrListBox = new C4GUI::ListBox(rcPlrList)); pPlrListBox->SetToolTip(LoadResStr("IDS_DLGTIP_PLAYERFILES")); - pPlrListBox->SetDecoration(false, &C4Startup::Get()->Graphics.sfctBookScroll, true); + pPlrListBox->SetDecoration(true, &C4Startup::Get()->Graphics.sfctBookScroll, true); pPlrListBox->UpdateElementPositions(); pPlrListBox->SetSelectionChangeCallbackFn(new C4GUI::CallbackHandler(this, &C4StartupPlrSelDlg::OnSelChange)); pPlrListBox->SetSelectionDblClickFn(new C4GUI::CallbackHandler(this, &C4StartupPlrSelDlg::OnSelDblClick)); AddElement(pSelectionInfo = new C4GUI::TextWindow(rcInfoWindow)); - pSelectionInfo->SetDecoration(false, false, &C4Startup::Get()->Graphics.sfctBookScroll, true); + pSelectionInfo->SetDecoration(true, true, &C4Startup::Get()->Graphics.sfctBookScroll, true); pSelectionInfo->UpdateHeight(); // bottom line buttons - positioning done in UpdateBottomButtons by UpdatePlayerList @@ -567,7 +558,11 @@ void C4StartupPlrSelDlg::AbortRenaming() void C4StartupPlrSelDlg::DrawElement(C4TargetFacet &cgo) { // draw background + typedef C4GUI::FullscreenDialog Base; + Base::DrawElement(cgo); +#if 0 DrawBackground(cgo, C4Startup::Get()->Graphics.fctPlrSelBG); +#endif } void C4StartupPlrSelDlg::UpdateBottomButtons() @@ -1060,10 +1055,18 @@ private: virtual void DoDragging(C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, DWORD dwKeyParam); private: + static const unsigned int HSPickerCursorSize = 5; + static const unsigned int VPickerCursorSize = 7; C4FacetSurface hsFacet, vFacet; // chooser backgrounds C4Rect hsPickerRect, vPickerRect; C4GUI::Picture *flagPreview, *crewPreview; uint32_t hsv; // current color + enum { + PS_Idle, // user isn't dragging anything + PS_IdleDragging, // user started the drag on empty space + PS_DragHS, // user started the drag over the HS picker + PS_DragV // user started the drag over the V picker + } state; bool HandleMouseDown(int32_t x, int32_t y); void UpdateVFacet(uint32_t h, uint32_t s); @@ -1160,35 +1163,35 @@ void C4StartupPlrColorPickerDlg::OnClosed(bool commit) } C4StartupPlrColorPickerDlg::Picker::Picker(const C4Rect &bounds) - : Control(bounds) + : Control(bounds), state(PS_Idle) { C4GUI::ComponentAligner caMain(bounds, 8, 8, true); caMain.ExpandBottom(-(caMain.GetInnerHeight() - 256)); hsPickerRect = caMain.GetFromLeft(256); - vPickerRect = caMain.GetFromLeft(16); + vPickerRect = caMain.GetFromLeft(16 + VPickerCursorSize); vPickerRect.Hgt = 256 - PlayerColorValueLowBound; C4Facet &flagPreviewPic = ::GraphicsResource.fctFlagClr; - int preview_width = std::min(flagPreviewPic.Wdt, caMain.GetInnerWidth()); + int preview_width = std::min(flagPreviewPic.Wdt, caMain.GetInnerWidth()); flagPreview = new C4GUI::Picture(caMain.GetFromTop(flagPreviewPic.GetHeightByWidth(preview_width), preview_width), true); flagPreview->SetFacet(flagPreviewPic); AddElement(flagPreview); C4Facet &crewPreviewPic = ::GraphicsResource.fctCrewClr; - preview_width = std::min(crewPreviewPic.Wdt, caMain.GetInnerWidth()); + preview_width = std::min(crewPreviewPic.Wdt, caMain.GetInnerWidth()); crewPreview = new C4GUI::Picture(caMain.GetFromTop(crewPreviewPic.GetHeightByWidth(preview_width), preview_width), true); crewPreview->SetFacet(crewPreviewPic); AddElement(crewPreview); // Pre-draw the H+S chooser background, it never changes anyway - hsFacet.Create(256, 256); + hsFacet.Create(hsPickerRect.Wdt, hsPickerRect.Hgt); hsFacet.Surface->Lock(); - for (int y = 0; y < 256; ++y) - for (int x = 0; x < 256; ++x) + for (int y = 0; y < hsFacet.Hgt; ++y) + for (int x = 0; x < hsFacet.Wdt; ++x) hsFacet.Surface->SetPixDw(x, y, HSV2RGB(C4RGB(x, 255-y, 255))); hsFacet.Surface->Unlock(); - vFacet.Create(16, 256 - PlayerColorValueLowBound); + vFacet.Create(vPickerRect.Wdt - VPickerCursorSize, vPickerRect.Hgt); UpdateVFacet(255, 255); } @@ -1196,7 +1199,7 @@ void C4StartupPlrColorPickerDlg::Picker::UpdateVFacet(uint32_t h, uint32_t s) { // Draw the V chooser background according to current H+S values vFacet.Surface->Lock(); - for (int y = 0; y < 256 - PlayerColorValueLowBound; ++y) + for (int y = 0; y < vPickerRect.Hgt; ++y) for (int x = 0; x < vFacet.Wdt; ++x) vFacet.Surface->SetPixDw(x, y, HSV2RGB(C4RGB(h, s, 255-y))); vFacet.Surface->Unlock(); @@ -1226,17 +1229,17 @@ void C4StartupPlrColorPickerDlg::Picker::DrawElement(C4TargetFacet &cgo) C4Facet cgoPicker(cgo.Surface, cgo.TargetX + hsPickerRect.x, cgo.TargetY + hsPickerRect.y, hsPickerRect.Wdt, hsPickerRect.Hgt); hsFacet.Draw(cgoPicker.Surface, cgoPicker.X, cgoPicker.Y); // H+S cursor - cgoPicker.Wdt = cgoPicker.Hgt = 5; + cgoPicker.Wdt = cgoPicker.Hgt = HSPickerCursorSize; cgoPicker.X += GetRedValue(hsv) - cgoPicker.Wdt / 2; cgoPicker.Y += 255 - GetGreenValue(hsv) - cgoPicker.Hgt / 2; pDraw->DrawLineDw(cgoPicker.Surface, cgoPicker.X, cgoPicker.Y, cgoPicker.X + cgoPicker.Wdt, cgoPicker.Y + cgoPicker.Hgt, C4RGB(0, 0, 0)); pDraw->DrawLineDw(cgoPicker.Surface, cgoPicker.X + cgoPicker.Wdt, cgoPicker.Y, cgoPicker.X, cgoPicker.Y + cgoPicker.Hgt, C4RGB(0, 0, 0)); // V chooser background - cgoPicker.Set(cgo.Surface, cgo.TargetX + vPickerRect.x, cgo.TargetY + vPickerRect.y, vPickerRect.Wdt, vPickerRect.Hgt); + cgoPicker.Set(cgo.Surface, cgo.TargetX + vPickerRect.x + VPickerCursorSize, cgo.TargetY + vPickerRect.y, vPickerRect.Wdt - VPickerCursorSize, vPickerRect.Hgt); vFacet.Draw(cgoPicker.Surface, cgoPicker.X, cgoPicker.Y); // V cursor - cgoPicker.Wdt = cgoPicker.Hgt = 7; + cgoPicker.Wdt = cgoPicker.Hgt = VPickerCursorSize; cgoPicker.X -= cgoPicker.Wdt / 2 + 1; cgoPicker.Y += 255 - GetBlueValue(hsv) - cgoPicker.Hgt / 2; for (int i = 0; i < cgoPicker.Hgt / 2 + 1; ++i) @@ -1245,30 +1248,46 @@ void C4StartupPlrColorPickerDlg::Picker::DrawElement(C4TargetFacet &cgo) bool C4StartupPlrColorPickerDlg::Picker::HandleMouseDown(int32_t x, int32_t y) { - // Check if mouse was over a picker - if (hsPickerRect.Contains(x, y)) + if (state == PS_IdleDragging) { - int h = x - hsPickerRect.x; - int s = 255 - (y - hsPickerRect.y); + // User is dragging something that is neither of the pickers. Ignore. + return false; + } + // Check if a drag starts or was originally started over a picker + else if (state == PS_DragHS || (state == PS_Idle && hsPickerRect.Contains(x, y))) + { + int h = BoundBy(x - hsPickerRect.x, 0, hsPickerRect.Wdt - 1); + assert(Inside(h, 0, 255)); + int s = 255 - BoundBy(y - hsPickerRect.y, 0, hsPickerRect.Hgt - 1); + assert(Inside(s, 0, 255)); hsv = C4RGB(h, s, GetBlueValue(hsv)); UpdateVFacet(h, s); UpdatePreview(); + state = PS_DragHS; return true; } - else if (vPickerRect.Contains(x, y)) + else if (state == PS_DragV || (state == PS_Idle && vPickerRect.Contains(x, y))) { - int v = 255 - (y - vPickerRect.y); + int v = 255 - BoundBy(y - vPickerRect.y, 0, vPickerRect.Hgt - 1); + assert(Inside(v, 0, 255)); hsv = (hsv & 0xFFFFFF00) | v; UpdatePreview(); + state = PS_DragV; return true; } - return false; + else + { + // Drag started outside of all picker areas; ignore movement until user releases mouse button. + state = PS_IdleDragging; + return false; + } } void C4StartupPlrColorPickerDlg::Picker::MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) { Control::MouseInput(rMouse, iButton, iX, iY, dwKeyParam); + if (!rMouse.IsLDown()) state = PS_Idle; if (rMouse.pDragElement) return; if (rMouse.IsLDown()) { @@ -1416,26 +1435,6 @@ C4StartupPlrPropertiesDlg::C4StartupPlrPropertiesDlg(C4StartupPlrSelDlg::PlayerL UpdatePlayerSkin(); caMain.ExpandTop(-BetweenElementDist); - // AutoStopControl: currently unused - // once we have an idea how many control schemes we have, we might revive this for selecting e.g. between "Mouse+Keyboard" and "Gamepad". - // place AutoStopControl label - //AddElement(new C4GUI::Label(FormatString("%s:", LoadResStr("IDS_DLG_MOVEMENT")).getData(), caMain.GetFromTop(pSmallFont->GetLineHeight()), ALeft, C4StartupFontClr, pSmallFont, false)); - // place AutoStopControl controls - //C4Facet &rfctMovementIcons = C4Startup::Get()->Graphics.fctPlrCtrlType; - //C4GUI::ComponentAligner caMovement(caMain.GetFromTop(rfctMovementIcons.Hgt), 5, 0); - //C4Rect rcBtn = caMovement.GetFromLeft(rfctMovementIcons.GetWidthByHeight(caMovement.GetHeight())); - //AddElement(pLbl = new C4GUI::Label(LoadResStr("IDS_DLG_JUMPANDRUN"), rcBtn.x+rcBtn.Wdt/2, rcBtn.y+rcBtn.Hgt-6, ACenter, C4StartupFontClr, pSmallFont, false)); - //szTip = LoadResStr("IDS_DLGTIP_JUMPANDRUN"); - //pLbl->SetToolTip(szTip); - //AddElement(pJumpNRunBtn = new C4GUI::CallbackButton(C4GUI::Ico_None, rcBtn, 'J' /* 2do */, &C4StartupPlrPropertiesDlg::OnMovementBtn)); - //pJumpNRunBtn->SetToolTip(szTip); - //rcBtn = caMovement.GetFromRight(rfctMovementIcons.GetWidthByHeight(caMovement.GetHeight())); - //AddElement(pLbl = new C4GUI::Label(LoadResStr("IDS_DLG_CLASSIC"), rcBtn.x+rcBtn.Wdt/2, rcBtn.y+rcBtn.Hgt-6, ACenter, C4StartupFontClr, pSmallFont, false)); - //szTip = LoadResStr("IDS_DLGTIP_CLASSIC"); - //pLbl->SetToolTip(szTip); - //AddElement(pClassicBtn = new C4GUI::CallbackButton(C4GUI::Ico_None, rcBtn, 'C' /* 2do */, &C4StartupPlrPropertiesDlg::OnMovementBtn)); - //pClassicBtn->SetToolTip(szTip); - //UpdatePlayerMovement(); // place buttons // OK C4GUI::Button *pBtnOK = new C4GUI::OKIconButton(C4Rect(147-GetMarginLeft(), 295+35-GetMarginTop(), 54, 33), C4GUI::Ico_None); diff --git a/src/gui/C4StartupPlrSelDlg.h b/src/gui/C4StartupPlrSelDlg.h index 3bd99dcf5..40131c6c1 100644 --- a/src/gui/C4StartupPlrSelDlg.h +++ b/src/gui/C4StartupPlrSelDlg.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2008 Sven Eberhardt - * Copyright (c) 2005, 2008 Günther Brammer - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Player selection dialog // Also contains player creation, editing and crew management @@ -206,7 +203,7 @@ protected: protected: virtual int32_t GetMarginTop() { return (rcBounds.Hgt/7); } - virtual bool HasBackground() { return true; } + virtual bool HasBackground() { return false; } virtual void DrawElement(C4TargetFacet &cgo); virtual bool OnEnter() { return false; } // Enter ignored diff --git a/src/gui/C4StartupScenSelDlg.cpp b/src/gui/C4StartupScenSelDlg.cpp index 3c380a11c..f6faefabd 100644 --- a/src/gui/C4StartupScenSelDlg.cpp +++ b/src/gui/C4StartupScenSelDlg.cpp @@ -1,27 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2008 Sven Eberhardt - * Copyright (c) 2005-2006, 2008-2010 Günther Brammer - * Copyright (c) 2005, 2007-2008 Matthes Bender - * Copyright (c) 2006 Florian Groß - * Copyright (c) 2008 Peter Wortmann - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Carl-Philip Hänsch - * Copyright (c) 2011 Armin Burgmeier - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Scenario selection dialog @@ -127,7 +117,7 @@ bool C4MapFolderData::Load(C4Group &hGroup, C4ScenarioListLoader::Folder *pScenL Clear(); // load localization info C4LangStringTable LangTable; - bool fHasLangTable = !!LangTable.LoadEx(hGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx); + bool fHasLangTable = C4Language::LoadComponentHost(&LangTable, hGroup, C4CFN_ScriptStringTbl, Config.General.LanguageEx); // load core data StdStrBuf Buf; if (!hGroup.LoadEntryString(C4CFN_MapFolderData, &Buf)) return false; @@ -482,7 +472,7 @@ bool C4ScenarioListLoader::Entry::Load(C4Group *pFromGrp, const StdStrBuf *psFil return false; // Load entry name C4ComponentHost DefNames; - if (DefNames.LoadEx(Group, C4CFN_Title, Config.General.LanguageEx)) + if (C4Language::LoadComponentHost(&DefNames, Group, C4CFN_Title, Config.General.LanguageEx)) if (DefNames.GetLanguageString(Config.General.LanguageEx, sName)) fNameLoaded = true; // load entry icon @@ -523,15 +513,14 @@ bool C4ScenarioListLoader::Entry::Load(C4Group *pFromGrp, const StdStrBuf *psFil { // load desc C4ComponentHost DefDesc; - if (DefDesc.LoadEx(Group, C4CFN_ScenarioDesc, Config.General.LanguageEx)) + if (C4Language::LoadComponentHost(&DefDesc, Group, C4CFN_ScenarioDesc, Config.General.LanguageEx)) { C4RTFFile rtf; rtf.Load(StdBuf(DefDesc.GetData(), SLen(DefDesc.GetData()))); sDesc.Take(rtf.GetPlainText()); } // load title - if (!fctTitle.Load(Group, C4CFN_ScenarioTitlePNG, C4FCT_Full, C4FCT_Full, false, true)) - fctTitle.Load(Group, C4CFN_ScenarioTitle, C4FCT_Full, C4FCT_Full, true, true); + fctTitle.Load(Group, C4CFN_ScenarioTitle,C4FCT_Full,C4FCT_Full,false,true); fExLoaded = true; // load version Group.LoadEntryString(C4CFN_Version, &sVersion); @@ -939,7 +928,11 @@ bool C4ScenarioListLoader::SubFolder::LoadCustom(C4Group &rGrp, bool fNameLoaded { // default icon fallback if (!fIconLoaded) - fctIcon.Set(C4Startup::Get()->Graphics.fctScenSelIcons.GetSection(C4StartupScenSel_DefaultIcon_Folder)); + { + if(WildcardMatch(C4CFN_Savegames, GetFilename(sFilename.getData()))) iIconIndex = C4StartupScenSel_DefaultIcon_SavegamesFolder; + else iIconIndex = C4StartupScenSel_DefaultIcon_Folder; + fctIcon.Set(C4Startup::Get()->Graphics.fctScenSelIcons.GetSection(iIconIndex)); + } // folder index iFolderIndex = C4F.Head.Index; return true; @@ -1342,22 +1335,29 @@ C4StartupScenSelDlg::C4StartupScenSelDlg(bool fNetwork) : C4StartupDlg(LoadResSt C4GUI::ComponentAligner caMain(GetClientRect(), 0,0, true); C4GUI::ComponentAligner caButtonArea(caMain.GetFromBottom(caMain.GetHeight()/8),rcBounds.Wdt/(rcBounds.Wdt >= 700 ? 128 : 256),0); C4Rect rcMap = caMain.GetCentered(caMain.GetWidth(), caMain.GetHeight()); +#if 0 + // Was used for the custom map scenario selection style int iYOversize = caMain.GetHeight()/10; // overlap of map to top rcMap.y -= iYOversize; rcMap.Hgt += iYOversize; - C4GUI::ComponentAligner caMap(rcMap, 0,0, true); +#endif + C4GUI::ComponentAligner caMap(rcMap, caMain.GetWidth()/10,0, true); +#if 0 caMap.ExpandTop(-iYOversize); - C4GUI::ComponentAligner caBook(caMap.GetCentered(caMap.GetWidth()*11/12-4*iExtraHPadding, caMap.GetHeight()), rcBounds.Wdt/30,iExtraVPadding, false); - C4GUI::ComponentAligner caBookLeft(caBook.GetFromLeft(iBookPageWidth=caBook.GetWidth()*4/9+4-iExtraHPadding*2), 0,5); +#endif // tabular for different scenario selection designs pScenSelStyleTabular = new C4GUI::Tabular(rcMap, C4GUI::Tabular::tbNone); pScenSelStyleTabular->SetSheetMargin(0); - pScenSelStyleTabular->SetDrawDecoration(false); + //pScenSelStyleTabular->SetDrawDecoration(false); + pScenSelStyleTabular->SetGfx(&C4Startup::Get()->Graphics.fctDlgPaper, &C4Startup::Get()->Graphics.fctOptionsTabClip, &C4Startup::Get()->Graphics.fctOptionsIcons, &C4Startup::Get()->Graphics.BookSmallFont, false); AddElement(pScenSelStyleTabular); C4GUI::Tabular::Sheet *pSheetBook = pScenSelStyleTabular->AddSheet(NULL); /* C4GUI::Tabular::Sheet *pSheetMap = */ pScenSelStyleTabular->AddSheet(NULL); // scenario selection list + C4GUI::ComponentAligner caBook(pSheetBook->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/20, true); + C4GUI::ComponentAligner caBookLeft(caBook.GetFromLeft(iBookPageWidth=caBook.GetWidth()*4/9+4-iExtraHPadding*2), 0,5); + CStdFont &rScenSelCaptionFont = C4Startup::Get()->Graphics.BookFontTitle; pScenSelCaption = new C4GUI::Label("", caBookLeft.GetFromTop(rScenSelCaptionFont.GetLineHeight()), ACenter, ClrScenarioItem, &rScenSelCaptionFont, false); pSheetBook->AddElement(pScenSelCaption); @@ -1373,7 +1373,21 @@ C4StartupScenSelDlg::C4StartupScenSelDlg(bool fNetwork) : C4StartupDlg(LoadResSt pSheetBook->AddElement(pScenSelProgressLabel); // right side of book: Displaying current selection - pSelectionInfo = new C4GUI::TextWindow(caBook.GetFromRight(iBookPageWidth), C4StartupScenSel_TitlePictureWdt+2*C4StartupScenSel_TitleOverlayMargin, C4StartupScenSel_TitlePictureHgt+2*C4StartupScenSel_TitleOverlayMargin, + C4Rect bounds = caBook.GetFromRight(iBookPageWidth); + const int32_t AvailWidth = bounds.Wdt; + const int32_t AvailHeight = 2 * bounds.Hgt / 5; + int32_t PictureWidth, PictureHeight; + if(AvailWidth * C4StartupScenSel_TitlePictureHgt < AvailHeight * C4StartupScenSel_TitlePictureWdt) + { + PictureWidth = C4StartupScenSel_TitlePictureWdt * AvailWidth / C4StartupScenSel_TitlePictureWdt; + PictureHeight = C4StartupScenSel_TitlePictureHgt * AvailWidth / C4StartupScenSel_TitlePictureWdt; + } + else + { + PictureWidth = C4StartupScenSel_TitlePictureWdt * AvailHeight / C4StartupScenSel_TitlePictureHgt; + PictureHeight = C4StartupScenSel_TitlePictureHgt * AvailHeight / C4StartupScenSel_TitlePictureHgt; + } + pSelectionInfo = new C4GUI::TextWindow(bounds, PictureWidth+2*C4StartupScenSel_TitleOverlayMargin, PictureHeight+2*C4StartupScenSel_TitleOverlayMargin, C4StartupScenSel_TitlePicturePadding, 100, 4096, NULL, true, &C4Startup::Get()->Graphics.fctScenSelTitleOverlay, C4StartupScenSel_TitleOverlayMargin); pSelectionInfo->SetDecoration(false, false, &C4Startup::Get()->Graphics.sfctBookScroll, true); pSheetBook->AddElement(pSelectionInfo); @@ -1409,7 +1423,7 @@ C4StartupScenSelDlg::C4StartupScenSelDlg(bool fNetwork) : C4StartupDlg(LoadResSt new C4GUI::ControlKeyDlgCB(pScenSelList, *this, &C4StartupScenSelDlg::KeyRename), C4CustomKey::PRIO_CtrlOverride); pKeyDelete = new C4KeyBinding(C4KeyCodeEx(K_DELETE), "StartupScenSelDelete", KEYSCOPE_Gui, new C4GUI::ControlKeyDlgCB(pScenSelList, *this, &C4StartupScenSelDlg::KeyDelete), C4CustomKey::PRIO_CtrlOverride); - pKeyCheat = new C4KeyBinding(C4KeyCodeEx(KEY_M, KEYS_Alt), "StartupScenSelCheat", KEYSCOPE_Gui, + pKeyCheat = new C4KeyBinding(C4KeyCodeEx(K_M, KEYS_Alt), "StartupScenSelCheat", KEYSCOPE_Gui, new C4GUI::ControlKeyDlgCB(pScenSelList, *this, &C4StartupScenSelDlg::KeyCheat), C4CustomKey::PRIO_CtrlOverride); } @@ -1430,8 +1444,10 @@ void C4StartupScenSelDlg::DrawElement(C4TargetFacet &cgo) // draw background if (pfctBackground) DrawBackground(cgo, *pfctBackground); +#if 0 else DrawBackground(cgo, C4Startup::Get()->Graphics.fctScenSelBG); +#endif } void C4StartupScenSelDlg::OnShown() diff --git a/src/gui/C4StartupScenSelDlg.h b/src/gui/C4StartupScenSelDlg.h index dbf9ceed6..66868e066 100644 --- a/src/gui/C4StartupScenSelDlg.h +++ b/src/gui/C4StartupScenSelDlg.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006 Sven Eberhardt - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2008 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Startup screen for non-parameterized engine start: Scenario selection dialog @@ -33,14 +28,15 @@ class C4StartupScenSelDlg; const int32_t C4StartupScenSel_DefaultIcon_Scenario = 14, - C4StartupScenSel_DefaultIcon_Folder = 0, - C4StartupScenSel_DefaultIcon_WinFolder = 44, - C4StartupScenSel_DefaultIcon_OldIconBG = 18, - C4StartupScenSel_IconCount = 45, - C4StartupScenSel_TitlePictureWdt = 200, - C4StartupScenSel_TitlePictureHgt = 150, - C4StartupScenSel_TitlePicturePadding = 10, - C4StartupScenSel_TitleOverlayMargin = 10; // number of pixels to each side of title overlay picture + C4StartupScenSel_DefaultIcon_Folder = 0, + C4StartupScenSel_DefaultIcon_SavegamesFolder = 29, + C4StartupScenSel_DefaultIcon_WinFolder = 44, + C4StartupScenSel_DefaultIcon_OldIconBG = 18, + C4StartupScenSel_IconCount = 45, + C4StartupScenSel_TitlePictureWdt = 200, + C4StartupScenSel_TitlePictureHgt = 150, + C4StartupScenSel_TitlePicturePadding = 10, + C4StartupScenSel_TitleOverlayMargin = 10; // number of pixels to each side of title overlay picture // a list of loaded scenarios class C4ScenarioListLoader @@ -418,7 +414,7 @@ public: protected: virtual int32_t GetMarginTop() { return (rcBounds.Hgt/7); } - virtual bool HasBackground() { return true; } + virtual bool HasBackground() { return false; } virtual void DrawElement(C4TargetFacet &cgo); virtual bool OnEnter() { DoOK(); return true; } diff --git a/src/gui/C4UpdateDlg.cpp b/src/gui/C4UpdateDlg.cpp index 5e78de234..815890b97 100644 --- a/src/gui/C4UpdateDlg.cpp +++ b/src/gui/C4UpdateDlg.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2007 Günther Brammer - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // dialogs for update, and the actual update application code // is only compiled WITH_AUTOMATIC_UPDATE @@ -209,10 +203,17 @@ bool C4UpdateDlg::ApplyUpdate(const char *strUpdateFile, bool fDeleteUpdate, C4G if (IsWindowsWithUAC()) strUpdateProgEx.Copy(Config.AtTempPath("setup.exe")); // Extract update program (the update should be applied using the new version) C4Group UpdateGroup, SubGroup; - if (!UpdateGroup.Open(strUpdateFile)) return false; + if (!UpdateGroup.Open(strUpdateFile)) + { + LogF("Error opening \"%s\": %s", strUpdateFile, UpdateGroup.GetError()); + return false; + } // Look for update program at top level if (!UpdateGroup.ExtractEntry(strUpdateProg.getData(), strUpdateProgEx.getData())) + { + LogF("Error extracting \"%s\": %s", strUpdateProg.getData(), UpdateGroup.GetError()); return false; + } #if 0 char strSubGroup[1024+1]; // ASK: What is this? Why should an update program not be found at the top @@ -317,7 +318,7 @@ bool C4UpdateDlg::CheckForUpdates(C4GUI::Screen *pScreen, bool fAutomatic) C4Network2UpdateClient UpdateClient; bool fSuccess = false, fAborted = false; - StdStrBuf strVersion; strVersion.Format("%d.%d.%d.%d", C4XVER1, C4XVER2, C4XVER3, C4XVER4); + StdStrBuf strVersion; strVersion.Format("%d.%d.%d", C4XVER1, C4XVER2, C4XVER3); StdStrBuf strQuery; strQuery.Format("%s?version=%s&platform=%s&action=version", Config.Network.UpdateServerAddress, strVersion.getData(), C4_OS); if (UpdateClient.Init() && UpdateClient.SetServer(strQuery.getData()) && UpdateClient.QueryUpdateURL()) { diff --git a/src/gui/C4UpdateDlg.h b/src/gui/C4UpdateDlg.h index 895944f2d..9c600278b 100644 --- a/src/gui/C4UpdateDlg.h +++ b/src/gui/C4UpdateDlg.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2007 Sven Eberhardt - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2010 Tobias Zwick - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // dialogs for update diff --git a/src/gui/C4UpperBoard.cpp b/src/gui/C4UpperBoard.cpp index f7b1dbba6..805180383 100644 --- a/src/gui/C4UpperBoard.cpp +++ b/src/gui/C4UpperBoard.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2006, 2009-2010 Günther Brammer - * Copyright (c) 2007 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include #include diff --git a/src/gui/C4UpperBoard.h b/src/gui/C4UpperBoard.h index 535dc3623..26b6c52d7 100644 --- a/src/gui/C4UpperBoard.h +++ b/src/gui/C4UpperBoard.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2001 Michael Käser - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_C4UpperBoard #define INC_C4UpperBoard diff --git a/src/gui/C4UserMessages.h b/src/gui/C4UserMessages.h deleted file mode 100644 index b7735e910..000000000 --- a/src/gui/C4UserMessages.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Custom windows messages */ - -#ifndef INC_C4UserMessages -#define INC_C4UserMessages - -#define WM_USER_RELOADFILE (WM_USER+8) -#define WM_USER_DROPDEF (WM_USER+10) -#define WM_USER_LOG (WM_USER+11) - -#endif diff --git a/src/game/landscape/C4Landscape.cpp b/src/landscape/C4Landscape.cpp similarity index 86% rename from src/game/landscape/C4Landscape.cpp rename to src/landscape/C4Landscape.cpp index bcdbe99e2..523823964 100644 --- a/src/game/landscape/C4Landscape.cpp +++ b/src/landscape/C4Landscape.cpp @@ -1,26 +1,18 @@ -/* +/* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001-2008, 2010-2011 Sven Eberhardt - * Copyright (c) 2002, 2004-2008, 2011 Peter Wortmann - * Copyright (c) 2006-2011 Günther Brammer - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles landscape and sky */ @@ -52,9 +44,12 @@ #include #include #include -#include +#include #include #include +#include +#include +#include C4Landscape::C4Landscape() { @@ -130,7 +125,8 @@ void C4Landscape::ExecuteScan() return; #ifdef DEBUGREC_MATSCAN - AddDbgRec(RCT_MatScan, &ScanX, sizeof(ScanX)); + if (Config.General.DebugRec) + AddDbgRec(RCT_MatScan, &ScanX, sizeof(ScanX)); #endif for (int32_t cnt=0; cnt-1) && DensitySolid(::MaterialMap.Map[conv_to].Density); for (cy2 = cy; mconvs >= 0 && Inside(cy2, 0, GBackHgt-1); cy2 += ydir, mconvs--) { // material changed? @@ -252,7 +252,7 @@ int32_t C4Landscape::DoScan(int32_t cx, int32_t cy, int32_t mat, int32_t dir) #endif // set mat SBackPix(cx,cy2,MatTex2PixCol(conv_to_tex)+PixColIFT(pix)); - CheckInstabilityRange(cx,cy2); + if (!conv_to_is_solid) CheckInstabilityRange(cx,cy2); } // return pixel converted return Abs(cy2 - cy); @@ -375,22 +375,22 @@ void C4Landscape::ClearFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt ForPolygon(&vertices[0],vertices.size()/2,&C4Landscape::ClearPix); } -int32_t C4Landscape::DigFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, C4Object *by_object, bool no_dig2objects) +int32_t C4Landscape::DigFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, C4Object *by_object, bool no_dig2objects, bool no_instability_check) { std::vector vertices(GetRectangle(tx,ty,wdt,hgt)); - return DigFreeShape(&vertices[0],vertices.size(),by_object, no_dig2objects); + return DigFreeShape(&vertices[0],vertices.size(),by_object, no_dig2objects, no_instability_check); } -int32_t C4Landscape::DigFree(int32_t tx, int32_t ty, int32_t rad, C4Object *by_object, bool no_dig2objects) +int32_t C4Landscape::DigFree(int32_t tx, int32_t ty, int32_t rad, C4Object *by_object, bool no_dig2objects, bool no_instability_check) { std::vector vertices(GetRoundPolygon(tx,ty,rad,80)); - return DigFreeShape(&vertices[0],vertices.size(),by_object, no_dig2objects); + return DigFreeShape(&vertices[0],vertices.size(),by_object, no_dig2objects, no_instability_check); } -void C4Landscape::BlastFree(int32_t tx, int32_t ty, int32_t rad, int32_t caused_by, C4Object *by_object) +void C4Landscape::BlastFree(int32_t tx, int32_t ty, int32_t rad, int32_t caused_by, C4Object *by_object, int32_t iMaxDensity) { std::vector vertices(GetRoundPolygon(tx,ty,rad,30)); - BlastFreeShape(&vertices[0],vertices.size(),by_object,caused_by); + BlastFreeShape(&vertices[0],vertices.size(),by_object,caused_by,iMaxDensity); } void C4Landscape::ShakeFree(int32_t tx, int32_t ty, int32_t rad) @@ -399,19 +399,58 @@ void C4Landscape::ShakeFree(int32_t tx, int32_t ty, int32_t rad) ForPolygon(&vertices[0],vertices.size()/2,&C4Landscape::ShakeFreePix); } -int32_t C4Landscape::DigFreeShape(int *vtcs, int length, C4Object *by_object, bool no_dig2objects) +C4ValueArray *C4Landscape::PrepareFreeShape(C4Rect &BoundingBox, C4Object *by_object) +{ + // Remember any collectible objects in area + C4FindObjectInRect fo_inrect(BoundingBox); + C4FindObjectOCF fo_collectible(OCF_Carryable); + C4FindObjectOCF fo_insolid(OCF_InSolid); + C4FindObjectLayer fo_layer(by_object ? by_object->Layer : NULL); + C4FindObject *fo_list[] = {&fo_inrect, &fo_collectible, &fo_insolid, &fo_layer}; + C4FindObjectAndStatic fo_srch(4, fo_list); + return fo_srch.FindMany(::Objects, ::Objects.Sectors); +} + +void C4Landscape::PostFreeShape(C4ValueArray *dig_objects, C4Object *by_object) +{ + // Do callbacks to digger for objects that are now dug free + if (by_object) + { + for (int32_t i=0; iGetSize(); ++i) + { + C4Object *dig_object = dig_objects->GetItem(i).getObj(); + if (dig_object && !GBackSolid(dig_object->GetX(), dig_object->GetY())) + if (!dig_object->Contained && dig_object->Status) + { + C4AulParSet pars(C4VObj(dig_object)); + by_object->Call(PSF_DigOutObject, &pars); + } + } + } +} + +int32_t C4Landscape::DigFreeShape(int *vtcs, int length, C4Object *by_object, bool no_dig2objects, bool no_instability_check) { C4Rect BoundingBox = getBoundingBox(vtcs,length); int32_t amount; + // Remember any collectible objects in area + std::unique_ptr dig_objects(PrepareFreeShape(BoundingBox, by_object)); + if(by_object) { if(!by_object->MaterialContents) by_object->MaterialContents = new C4MaterialList; - amount = ForPolygon(vtcs,length/2,&C4Landscape::DigFreePix,by_object->MaterialContents); + if (no_instability_check) + amount = ForPolygon(vtcs,length/2,&C4Landscape::DigFreePixNoInstability,by_object->MaterialContents); + else + amount = ForPolygon(vtcs,length/2,&C4Landscape::DigFreePix,by_object->MaterialContents); } else - amount = ForPolygon(vtcs,length/2,&C4Landscape::DigFreePix,NULL); + if (no_instability_check) + amount = ForPolygon(vtcs,length/2,&C4Landscape::DigFreePixNoInstability,NULL); + else + amount = ForPolygon(vtcs,length/2,&C4Landscape::DigFreePix,NULL); // create objects from the material if(!::Game.iTick5) @@ -424,25 +463,39 @@ int32_t C4Landscape::DigFreeShape(int *vtcs, int length, C4Object *by_object, bo DigMaterial2Objects(tx,ty,by_object->MaterialContents, by_object); } } + + // Do callbacks to digger for objects that are now dug free + PostFreeShape(dig_objects.get(), by_object); + return amount; } -void C4Landscape::BlastFreeShape(int *vtcs, int length, C4Object *by_object, int32_t by_player) +void C4Landscape::BlastFreeShape(int *vtcs, int length, C4Object *by_object, int32_t by_player, int32_t iMaxDensity) { C4MaterialList *MaterialContents = NULL; C4Rect BoundingBox = getBoundingBox(vtcs,length); + // Remember any collectible objects in area + std::unique_ptr dig_objects(PrepareFreeShape(BoundingBox, by_object)); + + uint8_t *pblast_tbl = NULL, blast_tbl[256]; + if (iMaxDensity < C4M_Vehicle) + { + for (int32_t i=0; i<256; ++i) blast_tbl[i] = (GetPixDensity(i)<=iMaxDensity); + pblast_tbl = blast_tbl; + } + if(by_object) { if(!by_object->MaterialContents) by_object->MaterialContents = new C4MaterialList; - ForPolygon(vtcs,length/2,&C4Landscape::BlastFreePix,by_object->MaterialContents); + ForPolygon(vtcs,length/2,&C4Landscape::BlastFreePix,by_object->MaterialContents, 0, pblast_tbl); } else { MaterialContents = new C4MaterialList; - ForPolygon(vtcs,length/2,&C4Landscape::BlastFreePix,MaterialContents); + ForPolygon(vtcs,length/2,&C4Landscape::BlastFreePix,MaterialContents,iMaxDensity); } // create objects from the material @@ -453,12 +506,15 @@ void C4Landscape::BlastFreeShape(int *vtcs, int length, C4Object *by_object, int mat_list = MaterialContents; int32_t tx = BoundingBox.GetMiddleX(), ty = BoundingBox.GetMiddleY(); - BlastMaterial2Objects(tx,ty,mat_list,by_player,(BoundingBox.Wdt+BoundingBox.Hgt)/4); + BlastMaterial2Objects(tx,ty,mat_list,by_player,(BoundingBox.Wdt+BoundingBox.Hgt)/4, dig_objects.get()); if(MaterialContents) delete MaterialContents; + + // Do callbacks to digger for objects that are now dug free + PostFreeShape(dig_objects.get(), by_object); } -void C4Landscape::BlastMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, int32_t caused_by, int32_t str) +void C4Landscape::BlastMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, int32_t caused_by, int32_t str, C4ValueArray *out_objects) { for (int32_t mat=0; mat< ::MaterialMap.Num; mat++) { @@ -478,7 +534,7 @@ void C4Landscape::BlastMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList * if (::MaterialMap.Map[mat].Blast2ObjectRatio != 0) { blastamount = mat_list->Amount[mat]/::MaterialMap.Map[mat].Blast2ObjectRatio; - Game.CastObjects(::MaterialMap.Map[mat].Blast2Object, NULL, blastamount, cast_strength, tx, ty, NO_OWNER, caused_by); + Game.CastObjects(::MaterialMap.Map[mat].Blast2Object, NULL, blastamount, cast_strength, tx, ty, NO_OWNER, caused_by, out_objects); } } @@ -516,6 +572,18 @@ void C4Landscape::DigMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *ma } } +bool C4Landscape::DigFreePixNoInstability(int32_t tx, int32_t ty) +{ + int32_t mat = GetMat(tx,ty); + if (MatValid(mat)) + if (::MaterialMap.Map[mat].DigFree) + { + ClearPix(tx,ty); + return true; + } + return false; +} + bool C4Landscape::DigFreePix(int32_t tx, int32_t ty) { int32_t mat = GetMat(tx,ty); @@ -578,11 +646,12 @@ bool C4Landscape::ClearPix(int32_t tx, int32_t ty) } bool C4Landscape::SetPix(int32_t x, int32_t y, BYTE npix) { -#ifdef DEBUGREC - C4RCSetPix rc; - rc.x=x; rc.y=y; rc.clr=npix; - AddDbgRec(RCT_SetPix, &rc, sizeof(rc)); -#endif + if (Config.General.DebugRec) + { + C4RCSetPix rc; + rc.x=x; rc.y=y; rc.clr=npix; + AddDbgRec(RCT_SetPix, &rc, sizeof(rc)); + } // check bounds if (x < 0 || y < 0 || x >= Width || y >= Height) return false; @@ -606,11 +675,12 @@ bool C4Landscape::SetPix(int32_t x, int32_t y, BYTE npix) bool C4Landscape::_SetPix(int32_t x, int32_t y, BYTE npix) { -#ifdef DEBUGREC - C4RCSetPix rc; - rc.x=x; rc.y=y; rc.clr=npix; - AddDbgRec(RCT_SetPix, &rc, sizeof(rc)); -#endif + if (Config.General.DebugRec) + { + C4RCSetPix rc; + rc.x=x; rc.y=y; rc.clr=npix; + AddDbgRec(RCT_SetPix, &rc, sizeof(rc)); + } assert(x >= 0 && y >= 0 && x < Width && y < Height); // get and check pixel BYTE opix = _GetPix(x, y); @@ -678,12 +748,27 @@ bool C4Landscape::_SetPixIfMask(int32_t x, int32_t y, BYTE npix, BYTE nMask) return true; } -bool C4Landscape::CheckInstability(int32_t tx, int32_t ty) +bool C4Landscape::CheckInstability(int32_t tx, int32_t ty, int32_t recursion_count) { int32_t mat=GetMat(tx,ty); if (MatValid(mat)) if (::MaterialMap.Map[mat].Instable) return ::MassMover.Create(tx,ty); + // Get rid of single pixels + else if (::MaterialMap.Map[mat].DigFree && recursion_count<10) + if ((!::GBackSolid(tx,ty+1)) + (!::GBackSolid(tx,ty-1)) + (!::GBackSolid(tx+1,ty)) + (!::GBackSolid(tx-1,ty)) >= 3) + { + if (!ClearPix(tx,ty)) return false; + ::PXS.Create(mat,itofix(tx),itofix(ty)); + // check other pixels around this + // Note this cannot lead to an endless recursion (unless you do funny stuff like e.g. set DigFree=1 in material Tunnel). + // Check recursion anyway, because very large strips of single pixel width might cause sufficient recursion to crash + CheckInstability(tx+1,ty,++recursion_count); + CheckInstability(tx-1,ty,recursion_count); + CheckInstability(tx,ty-1,recursion_count); + CheckInstability(tx,ty+1,recursion_count); + return true; + } return false; } @@ -702,8 +787,7 @@ void C4Landscape::DrawMaterialRect(int32_t mat, int32_t tx, int32_t ty, int32_t int32_t cx,cy; for (cy=ty; cyGetDensity(cx,cy)) - || ((MatDensity(mat)==GetDensity(cx,cy)) && (MatDigFree(mat)<=MatDigFree(GetMat(cx,cy)))) ) + if ( (MatDensity(mat)>=GetDensity(cx,cy))) SetPix(cx,cy,Mat2PixColDefault(mat)+GBackIFT(cx,cy)); } @@ -734,58 +818,72 @@ int32_t C4Landscape::ExtractMaterial(int32_t fx, int32_t fy) return mat; } -bool C4Landscape::InsertMaterial(int32_t mat, int32_t tx, int32_t ty, int32_t vx, int32_t vy) +bool C4Landscape::InsertMaterial(int32_t mat, int32_t *tx, int32_t *ty, int32_t vx, int32_t vy, bool query_only) { + assert(tx); assert(ty); int32_t mdens; if (!MatValid(mat)) return false; - mdens=MatDensity(mat); + mdens=Min(MatDensity(mat), C4M_Solid); if (!mdens) return true; // Bounds - if (!Inside(tx,0,Width-1) || !Inside(ty,0,Height)) return false; + if (!Inside(*tx,0,Width-1) || !Inside(*ty,0,Height)) return false; if (Game.C4S.Game.Realism.LandscapePushPull) { // Same or higher density? - if (GetDensity(tx, ty) >= mdens) + if (GetDensity(*tx, *ty) >= mdens) // Push - if (!FindMatPathPush(tx, ty, mdens, ::MaterialMap.Map[mat].MaxSlide, !! ::MaterialMap.Map[mat].Instable)) + if (!FindMatPathPush(*tx, *ty, mdens, ::MaterialMap.Map[mat].MaxSlide, !! ::MaterialMap.Map[mat].Instable)) // Or die return false; } else { // Move up above same density - while (mdens==GetDensity(tx,ty)) + while (mdens==Min(GetDensity(*tx,*ty),C4M_Solid)) { - ty--; if (ty<0) return false; + (*ty)--; if (*ty<0) return false; // Primitive slide (1) - if (GetDensity(tx-1,ty)mdens) return false; + if (GetDensity(*tx,*ty)>mdens) return false; } // Try slide - while (FindMatSlide(tx,ty,+1,mdens,::MaterialMap.Map[mat].MaxSlide)) - if (GetDensity(tx,ty+1)pFunc)(pReact, tx,ty, tx,ty+Sign(GravAccel), fvx,fvy, mat,tmat, meePXSPos,NULL)) + // since tx and ty changed, we need to re-check the bounds here + // if we really inserted it, the check is made again in InsertDeadMaterial + if (!Inside(*tx,0,Width-1) || !Inside(*ty,0,Height)) return false; + return true; + } + + // Try reaction with material below and at insertion position + C4MaterialReaction *pReact; int32_t tmat; + int32_t check_dir = 0; + for (int32_t i=0; i<2; ++i) + { + if ((pReact = ::MaterialMap.GetReactionUnsafe(mat, tmat=GetMat(*tx,*ty+check_dir)))) { - // the material to be inserted killed itself in some material reaction below - return true; + C4Real fvx=C4REAL10(vx), fvy=C4REAL10(vy); + if ((*pReact->pFunc)(pReact, *tx,*ty, *tx,*ty+check_dir, fvx,fvy, mat,tmat, meePXSPos,NULL)) + { + // the material to be inserted killed itself in some material reaction below + return true; + } } + if (!(check_dir = Sign(GravAccel))) break; } // Insert as dead material - return InsertDeadMaterial(mat, tx, ty); + return InsertDeadMaterial(mat, *tx, *ty); } bool C4Landscape::InsertDeadMaterial(int32_t mat, int32_t tx, int32_t ty) @@ -817,7 +915,10 @@ bool C4Landscape::InsertDeadMaterial(int32_t mat, int32_t tx, int32_t ty) // Search a position for the old material pixel if (Game.C4S.Game.Realism.LandscapeInsertThrust && MatValid(omat)) - InsertMaterial(omat, tx, ty-1); + { + int32_t tyo = ty-1; + InsertMaterial(omat, &tx, &tyo); + } return true; } @@ -961,21 +1062,27 @@ int32_t C4Landscape::ForPolygon(int *vtcs, int length, bool (C4Landscape::*fnCal // Fix coordinates if (x1>x2) Swap(x1,x2); // Set line - if (conversion_table) - for (int xcnt=x2-x1-1; xcnt>=0; xcnt--) Surface8->SetPix(x1+xcnt, y, conversion_table[uint8_t(GetPix(x1+xcnt, y))]); - else if(col) - for (int xcnt=x2-x1-1; xcnt>=0; xcnt--) Surface8->SetPix(x1+xcnt, y, col); - else + if (fnCallback) + { for (int xcnt=x2-x1-1; xcnt>=0; xcnt--) { - int32_t mat = GetMat(x1+xcnt,y); - if((this->*fnCallback)(x1+xcnt,y)) - if(mats_count) - { - mats_count->Add(mat,1); - amount++; - } + uint8_t pix = GetPix(x1+xcnt, y); + if (!conversion_table || conversion_table[pix]) + { + int32_t mat = GetPixMat(pix); + if((this->*fnCallback)(x1+xcnt,y)) + if(mats_count) + { + mats_count->Add(mat,1); + amount++; + } + } } + } + else if (conversion_table) + for (int xcnt=x2-x1-1; xcnt>=0; xcnt--) Surface8->SetPix(x1+xcnt, y, conversion_table[uint8_t(GetPix(x1+xcnt, y))]); + else + for (int xcnt=x2-x1-1; xcnt>=0; xcnt--) Surface8->SetPix(x1+xcnt, y, col); edge = edge->next->next; } @@ -1019,7 +1126,7 @@ int32_t C4Landscape::ForPolygon(int *vtcs, int length, bool (C4Landscape::*fnCal void C4Landscape::ScenarioInit() { // Gravity - Gravity = C4REAL100(Game.C4S.Landscape.Gravity.Evaluate()) /5; + Gravity = C4REAL100(Game.C4S.Landscape.Gravity.Evaluate()) * DefaultGravAccel; // Opens LeftOpen=Game.C4S.Landscape.LeftOpen; RightOpen=Game.C4S.Landscape.RightOpen; @@ -1029,13 +1136,14 @@ void C4Landscape::ScenarioInit() if (Game.C4S.Landscape.AutoScanSideOpen) ScanSideOpen(); } -void C4Landscape::Clear(bool fClearMapCreator, bool fClearSky) +void C4Landscape::Clear(bool fClearMapCreator, bool fClearSky, bool fClearRenderer) { if (pMapCreator && fClearMapCreator) { delete pMapCreator; pMapCreator=NULL; } // clear sky if (fClearSky) Sky.Clear(); // clear surfaces, if assigned - delete pLandscapeRender; pLandscapeRender=NULL; + if (fClearRenderer) { delete pLandscapeRender; pLandscapeRender=NULL; } + delete [] BottomRowPix; BottomRowPix=NULL; delete Surface8; Surface8=NULL; delete Map; Map=NULL; // clear initial landscape @@ -1047,7 +1155,7 @@ void C4Landscape::Clear(bool fClearMapCreator, bool fClearSky) delete [] PixCnt; PixCnt = NULL; PixCntPitch = 0; // clear bridge material conversion temp buffers - for (int32_t i = 0; iValue(mkNamingAdapt(RightOpen, "RightOpen", 0)); pComp->Value(mkNamingAdapt(TopOpen, "TopOpen", 0)); pComp->Value(mkNamingAdapt(BottomOpen, "BottomOpen", 0)); - pComp->Value(mkNamingAdapt(mkCastIntAdapt(Gravity), "Gravity", C4REAL100(20))); + pComp->Value(mkNamingAdapt(mkCastIntAdapt(Gravity), "Gravity", DefaultGravAccel)); pComp->Value(mkNamingAdapt(Modulation, "MatModulation", 0U)); pComp->Value(mkNamingAdapt(Mode, "Mode", C4LSC_Undefined)); } -static CSurface8 *GroupReadSurface8(CStdStream &hGroup) -{ - // create surface - CSurface8 *pSfc=new CSurface8(); - if (!pSfc->Read(hGroup)) - { delete pSfc; return NULL; } - return pSfc; -} -static CSurface8 *GroupReadSurfaceOwnPal8(CStdStream &hGroup) +static CSurface8 *GroupReadSurface8(C4Group &hGroup, const char *szWildCard) { + if (!hGroup.AccessEntry(szWildCard)) + return NULL; // create surface CSurface8 *pSfc=new CSurface8(); if (!pSfc->Read(hGroup)) @@ -1114,30 +1216,23 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo { CSurface8 * sfcMap=NULL; // Static map from scenario - if (hGroup.AccessEntry(C4CFN_Map)) - if ((sfcMap=GroupReadSurface8(hGroup))) - if (!fLandscapeModeSet) Mode=C4LSC_Static; + if ((sfcMap=GroupReadSurface8(hGroup, C4CFN_Map))) + if (!fLandscapeModeSet) Mode=C4LSC_Static; - // allow C4CFN_Landscape as map for downwards compatibility - if (!sfcMap) - if (hGroup.AccessEntry(C4CFN_Landscape)) - if ((sfcMap=GroupReadSurface8(hGroup))) - { - if (!fLandscapeModeSet) Mode=C4LSC_Static; - fMapChanged = true; - } - - // dynamic map from file + // dynamic map from Landscape.txt if (!sfcMap) if ((sfcMap=CreateMapS2(hGroup))) if (!fLandscapeModeSet) Mode=C4LSC_Dynamic; + // script may create or edit map + if (MapScript.InitializeMap(hGroup, &sfcMap)) + if (!fLandscapeModeSet) Mode=C4LSC_Dynamic; + // Dynamic map by scenario if (!sfcMap && !fOverloadCurrent) if ((sfcMap=CreateMap())) if (!fLandscapeModeSet) Mode=C4LSC_Dynamic; - // No map failure if (!sfcMap) { @@ -1147,10 +1242,11 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo return true; } -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "|---MAP---|", 12); - AddDbgRec(RCT_Map, sfcMap->Bits, sfcMap->Pitch*sfcMap->Hgt); -#endif + if (Config.General.DebugRec) + { + AddDbgRec(RCT_Block, "|---MAP---|", 12); + AddDbgRec(RCT_Map, sfcMap->Bits, sfcMap->Pitch*sfcMap->Hgt); + } // Store map size and calculate map zoom int iWdt, iHgt; @@ -1167,7 +1263,7 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo // if overloading, clear current landscape (and sections, etc.) // must clear, of course, before new sky is eventually read - if (fOverloadCurrent) Clear(!Game.C4S.Landscape.KeepMapCreator, fLoadSky); + if (fOverloadCurrent) Clear(!Game.C4S.Landscape.KeepMapCreator, fLoadSky, false); // assign new map Map = sfcMap; @@ -1198,9 +1294,6 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo // progress Game.SetInitProgress(80); - // mark as new-style - Game.C4S.Landscape.NewStyleLandscape = 2; - // copy noscan-var NoScan=Game.C4S.Landscape.NoScan!=0; @@ -1209,26 +1302,38 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo // map to big surface and sectionize it // (not for shaders though - they require continous textures) - // Create landscape surface - Surface8 = new CSurface8(); - if (!Surface8->Create(Width, Height) || !Mat2Pal()) + if (!Game.C4S.Landscape.ExactLandscape) { - delete Surface8; Surface8 = 0; - return false; + // Create landscape surface + Surface8 = new CSurface8(); + if (!Surface8->Create(Width, Height) || !Mat2Pal()) + { + delete Surface8; Surface8 = 0; + return false; + } + + // Map to landscape + // Landscape render disabled during initial landscape zoom (will be updated later) + C4LandscapeRender *lsrender_backup = pLandscapeRender; + pLandscapeRender = NULL; + bool map2landscape_success = MapToLandscape(); + pLandscapeRender = lsrender_backup; + if (!map2landscape_success) return false; } - // Map to landscape - if (!MapToLandscape()) return false; + // Init out-of-landscape pixels for bottom + InitBottomRowPix(); + Game.SetInitProgress(84); -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "|---LANDSCAPE---|", 18); - AddDbgRec(RCT_Map, Surface8->Bits, Surface8->Pitch*Surface8->Hgt); -#endif + if (Config.General.DebugRec) + { + AddDbgRec(RCT_Block, "|---LANDSCAPE---|", 18); + AddDbgRec(RCT_Map, Surface8->Bits, Surface8->Pitch*Surface8->Hgt); + } // Create renderer - pLandscapeRender = NULL; -#ifdef USE_GL +#ifndef USE_CONSOLE if (!pLandscapeRender && ::Config.Graphics.HighResLandscape) pLandscapeRender = new C4LandscapeRenderGL(); #endif @@ -1240,17 +1345,26 @@ bool C4Landscape::Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bo if(pLandscapeRender) { // Initialize renderer - if(!pLandscapeRender->Init(Width, Height, &::TextureMap, &::GraphicsResource.Files)) - return false; + if (fOverloadCurrent) + { + if(!pLandscapeRender->ReInit(Width, Height)) + return false; + } + else + { + if(!pLandscapeRender->Init(Width, Height, &::TextureMap, &::GraphicsResource.Files)) + return false; + } // Write landscape data pLandscapeRender->Update(C4Rect(0, 0, Width, Height), this); Game.SetInitProgress(87); } -#ifdef DEBUGREC - AddDbgRec(RCT_Block, "|---LS---|", 11); - AddDbgRec(RCT_Ls, Surface8->Bits, Surface8->Pitch*Surface8->Hgt); -#endif + if (Config.General.DebugRec) + { + AddDbgRec(RCT_Block, "|---LS---|", 11); + AddDbgRec(RCT_Ls, Surface8->Bits, Surface8->Pitch*Surface8->Hgt); + } // Create pixel count array @@ -1394,57 +1508,24 @@ bool C4Landscape::SaveInitial() bool C4Landscape::Load(C4Group &hGroup, bool fLoadSky, bool fSavegame) { // Load exact landscape from group - if (!hGroup.AccessEntry(C4CFN_Landscape)) return false; - if (!(Surface8=GroupReadSurfaceOwnPal8(hGroup))) return false; + if (!(Surface8=GroupReadSurface8(hGroup, C4CFN_Landscape))) return false; int iWidth, iHeight; Surface8->GetSurfaceSize(iWidth,iHeight); Width = iWidth; Height = iHeight; // adjust pal if (!Mat2Pal()) return false; - // no PNG: convert old-style landscapes - if (!Game.C4S.Landscape.NewStyleLandscape) - { - // convert all pixels - for (int32_t y=0; yGetPix(x, y); + int32_t iMat = PixCol2Mat(byPix); + if (byPix && !MatValid(iMat)) { - BYTE byPix = Surface8->GetPix(x, y); - int32_t iMat = PixCol2MatOld(byPix); BYTE byIFT = PixColIFTOld(byPix); - if (byIFT) byIFT = IFT; - // set pixel in 8bpp-surface only, so old-style landscapes won't be screwed up! - Surface8->SetPix(x, y, Mat2PixColDefault(iMat)+byIFT); + LogFatal(FormatString("Landscape loading error at (%d/%d): Pixel value %d not a valid material!", (int) x, (int) y, (int) byPix).getData()); + return false; } - // NewStyleLandscape-flag will be set in C4Landscape::Init later - } - // New style landscape first generation: just correct - if (Game.C4S.Landscape.NewStyleLandscape == 1) - { - // convert all pixels - for (int32_t y=0; yGetPix(x, y); - int32_t iMat = PixCol2MatOld2(byPix); - if (MatValid(iMat)) - // insert pixel - Surface8->SetPix(x, y, Mat2PixColDefault(iMat) + (byPix & IFT)); - else - Surface8->SetPix(x, y, 0); - } - } - else - { - // Landscape should be in correct format: Make sure it is! - for (int32_t y=0; yGetPix(x, y); - int32_t iMat = PixCol2Mat(byPix); - if (byPix && !MatValid(iMat)) - { - LogFatal(FormatString("Landscape loading error at (%d/%d): Pixel value %d not a valid material!", (int) x, (int) y, (int) byPix).getData()); - return false; - } - } - } + } // Init sky if (fLoadSky) { @@ -1458,8 +1539,7 @@ bool C4Landscape::ApplyDiff(C4Group &hGroup) { CSurface8 *pDiff; // Load diff landscape from group - if (!hGroup.AccessEntry(C4CFN_DiffLandscape)) return false; - if (!(pDiff=GroupReadSurfaceOwnPal8(hGroup))) return false; + if (!(pDiff=GroupReadSurface8(hGroup, C4CFN_DiffLandscape))) return false; // convert all pixels: keep if same material; re-set if different material BYTE byPix; for (int32_t y=0; ySave(Config.AtTempPath(C4CFN_TempMap), bypPalette)) + if (!Map->Save(Config.AtTempPath(C4CFN_TempMap), &Palette)) return false; // Move temp file to group @@ -1582,6 +1663,35 @@ bool C4Landscape::SaveTextures(C4Group &hGroup) return true; } +bool C4Landscape::InitBottomRowPix() +{ + // Init BottomRowPix array, which determines if out-of-landscape pixels on bottom side of the map are solid or not + // In case of BottomOpen=2, unit by map and not landscape to avoid runtime join sync losses + delete [] BottomRowPix; // safety + if (!Width) return true; + BottomRowPix = new uint8_t[Width]; + // must access Game.C4S here because Landscape.BottomOpen may not be initialized yet + // why is there a local copy of that static variable anyway? + int32_t bottom_open_flag = Game.C4S.Landscape.BottomOpen; + if (bottom_open_flag == 2 && !Map) bottom_open_flag = 1; + switch (bottom_open_flag) + { + // BottomOpen=0: Bottom is closed + case 0: for (int32_t x=0; xGetPix(x/MapZoom,Map->Hgt-1); + BottomRowPix[x] = ((map_pix & IFT) ? MCVehic : 0); + } + break; + // BottomOpen=1: Bottom is open + default: for (int32_t x=0; xGetMaterial(); if (!pMaterial) return; - C4MaterialCoreShape iChunkType = pMaterial->MapChunkType; + C4MaterialCoreShape iChunkType = ::Game.C4S.Landscape.FlatChunkShapes ? C4M_Flat : pMaterial->MapChunkType; BYTE byColor = MatTex2PixCol(iTexture); // Get map & landscape size int iMapWidth, iMapHeight; @@ -1825,8 +1935,17 @@ bool C4Landscape::GetTexUsage(CSurface8 * sfcMap, int32_t iMapX, int32_t iMapY, // Scan map pixels for (iY = iMapY; iY < iMapY+iMapHgt; iY++) for (iX = iMapX; iX < iMapX + iMapWdt; iX++) + { + int32_t tex = sfcMap->GetPix(iX, iY) & (IFT - 1); // Count texture map index only (no IFT) - dwpTextureUsage[sfcMap->GetPix(iX, iY) & (IFT - 1)]++; + if (!dwpTextureUsage[tex]++) if (tex) + { + // Check if texture actually exists + if (!::TextureMap.GetEntry(tex)->GetMaterial()) + LogF("Map2Landscape error: Texture index %d at (%d/%d) not defined in texture map!", (int) tex, (int) iX, (int) iY); + // No error. Landscape is usually fine but might contain some holes where material should be + } + } // Done return true; } @@ -2114,14 +2233,14 @@ bool FindTunnelHeight(int32_t cx, int32_t &ry, int32_t hgt) // Check upwards if (cy1>=0) { - if (GBackIFT(cx,cy1) && MatDensity(GBackMat(cx,cy1)) < 25) + if (GBackIFT(cx,cy1) && MatDensity(GBackMat(cx,cy1)) < C4M_Liquid) { rl1++; if (rl1>=hgt) { ry=cy1+hgt/2; return true; } } else rl1=0; } // Check downwards if (cy2+1=hgt) { ry=cy2-hgt/2; return true; } } else rl2=0; } @@ -2381,9 +2500,104 @@ bool PathFreePix(int32_t x, int32_t y, int32_t par) return !GBackSolid(x,y); } +bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2) +{ + return ForLine(x1,y1,x2,y2,&PathFreePix,0,0,0); +} + bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix, int32_t *iy) { - return ForLine(x1,y1,x2,y2,&PathFreePix,0,ix,iy); + // use the standard Bresenham algorithm and just adjust it to behave correctly in the inversed case + bool reverse = false; + bool steep = Abs(y2 - y1) > Abs(x2 - x1); + + if (steep) + { + Swap(x1, y1); + Swap(x2, y2); + } + + if (x1 > x2) + { + Swap(x1, x2); + Swap(y1, y2); + reverse = true; + } + + if (!reverse) + { + int32_t deltax = x2 - x1; + int32_t deltay = Abs(y2 - y1); + int32_t error = 0; + int32_t ystep = (y1 < y2) ? 1 : -1; + int32_t y = y1; + + for (int32_t x = x1; x <= x2; x++) + { + if (steep) + { + if (GBackSolid(y, x)) + { + if (ix) {*ix = y; *iy = x;} + return false; + } + } + else + { + if (GBackSolid(x, y)) + { + if (ix) {*ix = x; *iy = y;} + return false; + } + } + + error += deltay; + if (2 * error >= deltax) + { + y += ystep; + error -= deltax; + } + } + } + else // reverse + { + int32_t deltax = x2 - x1; + int32_t deltay = Abs(y2 - y1); + int32_t error = 0; + int32_t ystep = (y1 < y2) ? 1 : -1; + int32_t y = y2; + + // normal (inverse) routine + for (int32_t x = x2; x >= x1; x--) + { + if (steep) + { + if (GBackSolid(y, x)) + { + if (ix) {*ix = y; *iy = x;} + return false; + } + } + else + { + if (GBackSolid(x, y)) + { + if (ix) {*ix = x; *iy = y;} + return false; + } + } + + error -= deltay; + if (2 * error <= -deltax) + { + y -= ystep; + error += deltax; + } + + } + } + // no solid material encountered: path free! + return true; } bool PathFreeIgnoreVehiclePix(int32_t x, int32_t y, int32_t par) @@ -2509,6 +2723,8 @@ bool ConstructionCheck(C4PropList * PropList, int32_t iX, int32_t iY, C4Object * // Finds the next pixel position moving to desired slide. bool C4Landscape::FindMatPath(int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide) { + assert(mdens<=C4M_Solid); // mdens normalized in InsertMaterial + int32_t cslide; bool fLeft=true,fRight=true; @@ -2542,6 +2758,7 @@ bool C4Landscape::FindMatPath(int32_t &fx, int32_t &fy, int32_t ydir, int32_t md // Finds the closest immediate slide position. bool C4Landscape::FindMatSlide(int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide) { + assert(mdens<=C4M_Solid); // mdens normalized in InsertMaterial and mrfInsertCheck int32_t cslide; bool fLeft=true,fRight=true; @@ -2927,6 +3144,7 @@ bool C4Landscape::DrawChunks(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, i if (!GetMapColorIndex(szMaterial, szTexture, bIFT, byColor)) return false; int32_t iMaterial = ::MaterialMap.Get(szMaterial); if (!MatValid(iMaterial)) return false; + C4MaterialCoreShape shape = ::Game.C4S.Landscape.FlatChunkShapes ? C4M_Flat : ::MaterialMap.Map[iMaterial].MapChunkType; C4Rect BoundingBox(tx - 5, ty - 5, wdt + 10, hgt + 10); PrepareChange(BoundingBox); @@ -2939,7 +3157,7 @@ bool C4Landscape::DrawChunks(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, i int32_t x, y; for (x = 0; x < icntx; x++) for (y = 0; y < icnty; y++) - DrawChunk(tx+wdt*x/icntx,ty+hgt*y/icnty,wdt/icntx,hgt/icnty,byColor,::MaterialMap.Map[iMaterial].MapChunkType,Random(1000)); + DrawChunk(tx+wdt*x/icntx,ty+hgt*y/icnty,wdt/icntx,hgt/icnty,byColor,shape,Random(1000)); // remove clipper Surface8->NoClip(); @@ -2971,8 +3189,7 @@ bool C4Landscape::DrawPolygon(int *vtcs, int length, const char *szMaterial, boo uint8_t *conversion_map = NULL; if (fDrawBridge) { - int32_t iMat = GetPixMat(iMatTex); - conversion_map = GetBridgeMatConversion(iMat); + conversion_map = GetBridgeMatConversion(MatTex2PixCol(iMatTex)); } // prepare pixel count update C4Rect BoundingBox = getBoundingBox(vtcs,length); @@ -2983,22 +3200,22 @@ bool C4Landscape::DrawPolygon(int *vtcs, int length, const char *szMaterial, boo return true; } -uint8_t *C4Landscape::GetBridgeMatConversion(int for_material) +uint8_t *C4Landscape::GetBridgeMatConversion(int32_t for_material_col) { // safety + int32_t for_material = GetPixMat(for_material_col); if (for_material < 0 || for_material >= MaterialMap.Num) return NULL; // query map. create if not done yet - uint8_t *conv_map = BridgeMatConversion[for_material]; + uint8_t *conv_map = BridgeMatConversion[for_material_col]; if (!conv_map) { conv_map = new uint8_t[256]; for (int32_t i=0; i<256; ++i) { - if ( (MatDensity(for_material)>GetPixDensity(i)) - || ((MatDensity(for_material)==GetPixDensity(i)) && (MatDigFree(for_material)<=MatDigFree(GetPixMat(i)))) ) + if ( (MatDensity(for_material)>=GetPixDensity(i))) { // bridge pixel OK here. change pixel; keep IFT. - conv_map[i] = (i & IFT) + Mat2PixColDefault(for_material); + conv_map[i] = (i & IFT) + for_material_col; } else { @@ -3276,7 +3493,7 @@ void C4Landscape::UpdatePixMaps() for (i = 0; i < 256; i++) Pix2Place[i] = MatValid(Pix2Mat[i]) ? ::MaterialMap.Map[Pix2Mat[i]].Placement : 0; Pix2Place[0] = 0; // clear bridge mat conversion buffers - for (int32_t i = 0; iGetPattern().PatternClr(0, 0); - for (rgb=0; rgb<3; rgb++) - Surface8->pPal->Colors[MatTex2PixCol(tex)*3+rgb] - = Surface8->pPal->Colors[(MatTex2PixCol(tex)+IFT)*3+rgb] - = uint8_t(dwPix >> ((2-rgb) * 8)); - // alpha - Surface8->pPal->Alpha[MatTex2PixCol(tex)] = 0xff; - Surface8->pPal->Alpha[MatTex2PixCol(tex)+IFT] = 0xff; + Surface8->pPal->Colors[MatTex2PixCol(tex)] = dwPix; + Surface8->pPal->Colors[MatTex2PixCol(tex) + IFT] = dwPix; } // success return true; diff --git a/src/game/landscape/C4Landscape.h b/src/landscape/C4Landscape.h similarity index 87% rename from src/game/landscape/C4Landscape.h rename to src/landscape/C4Landscape.h index f911ac7e8..9c4a9e5d5 100644 --- a/src/game/landscape/C4Landscape.h +++ b/src/landscape/C4Landscape.h @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2005-2007 Peter Wortmann - * Copyright (c) 2006-2007, 2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Handles landscape and sky */ @@ -30,13 +24,10 @@ #include "C4Shape.h" #include "C4LandscapeRender.h" -#include +#include #include -const uint8_t GBM = 128, - GBM_ColNum = 64, - IFT = 0x80, - IFTOld = GBM_ColNum; +const uint8_t IFT = 0x80; const uint8_t CSkyDef1=104,CSkyDef2=123; @@ -49,10 +40,6 @@ const int32_t C4LSC_Undefined = 0, const int32_t C4LS_MaxRelights = 50; -class C4MapCreatorS2; -class C4Object; -class C4PropList; - class C4Landscape { public: @@ -65,7 +52,7 @@ public: CSurface8 * Map; DWORD MatCount[C4MaxMaterial]; // NoSave // DWORD EffectiveMatCount[C4MaxMaterial]; // NoSave // - uint8_t *BridgeMatConversion[C4MaxMaterial]; // NoSave // + uint8_t *BridgeMatConversion[128]; // NoSave // bool NoScan; // ExecuteScan() disabled int32_t ScanX,ScanSpeed; // SyncClearance-NoSave // @@ -79,6 +66,7 @@ public: BYTE *pInitial; // Initial landscape after creation - used for diff protected: CSurface8 * Surface8; + uint8_t * BottomRowPix; // array size of landscape width: Filled with 0s for bottom row pixels that are open and MCVehic for pixels that are closed C4LandscapeRender *pLandscapeRender; int32_t Pix2Mat[256], Pix2Dens[256], Pix2Place[256]; int32_t PixCntPitch; @@ -86,7 +74,7 @@ protected: C4Rect Relights[C4LS_MaxRelights]; public: void Default(); - void Clear(bool fClearMapCreator=true, bool fClearSky=true); + void Clear(bool fClearMapCreator=true, bool fClearSky=true, bool fClearRenderer=true); void Execute(); void Synchronize(); void Draw(C4TargetFacet &cgo, int32_t iPlayer=-1); @@ -114,7 +102,7 @@ public: bool SetPix(int32_t x, int32_t y, BYTE npix); // set landscape pixel (bounds checked) bool _SetPix(int32_t x, int32_t y, BYTE npix); // set landsape pixel (bounds not checked) bool _SetPixIfMask(int32_t x, int32_t y, BYTE npix, BYTE nMask) ; // set landscape pixel, if it matches nMask color (no bound-checks) - bool InsertMaterial(int32_t mat, int32_t tx, int32_t ty, int32_t vx = 0, int32_t vy = 0); + bool InsertMaterial(int32_t mat, int32_t *tx, int32_t *ty, int32_t vx = 0, int32_t vy = 0, bool query_only=false); // modifies tx/ty to actual insertion position bool InsertDeadMaterial(int32_t mat, int32_t tx, int32_t ty); bool FindMatPath(int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide); bool FindMatSlide(int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide); @@ -156,8 +144,7 @@ public: } if (y>=Height) { - if (BottomOpen) return 0; - else return MCVehic; + return BottomRowPix[x]; } return Surface8->_GetPix(x,y); } @@ -219,6 +206,7 @@ protected: bool TexOZoom(CSurface8 * sfcMap, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, DWORD *dwpTextureUsage, int32_t iToX=0,int32_t iToY=0); bool MapToSurface(CSurface8 * sfcMap, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iToX, int32_t iToY, int32_t iToWdt, int32_t iToHgt, int32_t iOffX, int32_t iOffY); bool MapToLandscape(CSurface8 * sfcMap, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iOffsX = 0, int32_t iOffsY = 0, bool noClear = false); // zoom map segment to surface (or sector surfaces) + bool InitBottomRowPix(); // inti out-of-landscape pixels for bottom side bool GetMapColorIndex(const char *szMaterial, const char *szTexture, bool fIFT, BYTE &rbyCol); bool SkyToLandscape(int32_t iToX, int32_t iToY, int32_t iToWdt, int32_t iToHgt, int32_t iOffX, int32_t iOffY); CSurface8 * CreateMap(); // create map by landscape attributes @@ -231,7 +219,7 @@ protected: void PrepareChange(C4Rect BoundingBox); void FinishChange(C4Rect BoundingBox); static bool DrawLineLandscape(int32_t iX, int32_t iY, int32_t iGrade); - uint8_t *GetBridgeMatConversion(int for_material); + uint8_t *GetBridgeMatConversion(int for_material_col); bool SaveInternal(C4Group &hGroup); bool SaveDiffInternal(C4Group &hGroup, bool fSyncSave); @@ -239,17 +227,17 @@ public: int32_t ForPolygon(int *vtcs, int length, bool (C4Landscape::*fnCallback)(int32_t, int32_t), C4MaterialList *mats_count = NULL, int col = 0, uint8_t *conversion_table = NULL); - int32_t DigFreeShape(int *vtcs, int length, C4Object *by_object = NULL, bool no_dig2objects = false); - void BlastFreeShape(int *vtcs, int length, C4Object *by_object = NULL, int32_t by_player = NO_OWNER); + int32_t DigFreeShape(int *vtcs, int length, C4Object *by_object = NULL, bool no_dig2objects = false, bool no_instability_check = false); + void BlastFreeShape(int *vtcs, int length, C4Object *by_object = NULL, int32_t by_player = NO_OWNER, int32_t iMaxDensity = C4M_Vehicle); void ClearFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt); - int32_t DigFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, C4Object *by_object = NULL, bool no_dig2objects = false); - int32_t DigFree(int32_t tx, int32_t ty, int32_t rad, C4Object *by_object = NULL, bool no_dig2objects = false); + int32_t DigFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, C4Object *by_object = NULL, bool no_dig2objects = false, bool no_instability_check = false); + int32_t DigFree(int32_t tx, int32_t ty, int32_t rad, C4Object *by_object = NULL, bool no_dig2objects = false, bool no_instability_check = false); void ShakeFree(int32_t tx, int32_t ty, int32_t rad); - void BlastFree(int32_t tx, int32_t ty, int32_t rad, int32_t caused_by = NO_OWNER, C4Object *by_object = NULL); + void BlastFree(int32_t tx, int32_t ty, int32_t rad, int32_t caused_by = NO_OWNER, C4Object *by_object = NULL, int32_t iMaxDensity = C4M_Vehicle); void CheckInstabilityRange(int32_t tx, int32_t ty); - bool CheckInstability(int32_t tx, int32_t ty); + bool CheckInstability(int32_t tx, int32_t ty, int32_t recursion_count=0); bool ClearPix(int32_t tx, int32_t ty); // also used by mass mover (corrode) @@ -259,12 +247,16 @@ private: C4Rect getBoundingBox(int *vtcs, int length) const; void DigMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, C4Object *pCollect = NULL); - void BlastMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, int32_t caused_by, int32_t str); + void BlastMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, int32_t caused_by, int32_t str, C4ValueArray *out_objects); bool DigFreePix(int32_t tx, int32_t ty); + bool DigFreePixNoInstability(int32_t tx, int32_t ty); bool BlastFreePix(int32_t tx, int32_t ty); bool ShakeFreePix(int32_t tx, int32_t ty); + C4ValueArray *PrepareFreeShape(C4Rect &BoundingBox, C4Object *by_object); + void PostFreeShape(C4ValueArray *dig_objects, C4Object *by_object); + public: void CompileFunc(StdCompiler *pComp); // without landscape bitmaps and sky bool DebugSave(const char *szFilename); @@ -284,7 +276,8 @@ bool FindSurfaceLiquid(int32_t &rx, int32_t &ry, int32_t width, int32_t height); bool FindLevelGround(int32_t &rx, int32_t &ry, int32_t width, int32_t hrange); bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt, int32_t Plane, int32_t hrange=-1); bool FindThrowingPosition(int32_t iTx, int32_t iTy, C4Real fXDir, C4Real fYDir, int32_t iHeight, int32_t &rX, int32_t &rY); -bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix=NULL, int32_t *iy=NULL); +bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2); +bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix, int32_t *iy); bool PathFreeIgnoreVehicle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix=NULL, int32_t *iy=NULL); bool FindClosestFree(int32_t &rX, int32_t &rY, int32_t iAngle1, int32_t iAngle2, int32_t iExcludeAngle1, int32_t iExcludeAngle2); bool ConstructionCheck(C4PropList *, int32_t iX, int32_t iY, C4Object *pByObj=NULL); @@ -319,13 +312,6 @@ inline BYTE PixColIFT(BYTE pixc) return pixc & IFT; } -// always use OldGfx-version (used for convert) -inline BYTE PixColIFTOld(BYTE pixc) -{ - if (pixc>=GBM+IFTOld) return IFTOld; - return 0; -} - inline int32_t PixCol2Tex(BYTE pixc) { // Remove IFT diff --git a/src/game/landscape/C4LandscapeRender.cpp b/src/landscape/C4LandscapeRender.cpp similarity index 95% rename from src/game/landscape/C4LandscapeRender.cpp rename to src/landscape/C4LandscapeRender.cpp index 5a658bef0..c6b455582 100644 --- a/src/game/landscape/C4LandscapeRender.cpp +++ b/src/landscape/C4LandscapeRender.cpp @@ -8,10 +8,10 @@ #include "C4GroupSet.h" #include "C4Components.h" -#include "StdGL.h" +#include "C4DrawGL.h" #include "StdColors.h" -#ifdef USE_GL +#ifndef USE_CONSOLE // Automatically reload shaders when changed at runtime? #define AUTO_RELOAD_SHADERS @@ -34,7 +34,7 @@ const int C4LR_BiasDistanceY = 8; // Workarounds to try if shader fails to compile const char *C4LR_ShaderWorkarounds[] = { "#define NO_TEXTURE_LOD_IN_FRAGMENT\n", - "#define BROKEN_ARRAYS_WORKAROUND\n", + "#define NO_BROKEN_ARRAYS_WORKAROUND\n", "#define SCALER_IN_GPU\n", }; const int C4LR_ShaderWorkaroundCount = sizeof(C4LR_ShaderWorkarounds) / sizeof(*C4LR_ShaderWorkarounds); @@ -54,6 +54,7 @@ static const char *GetUniformName(int iUniform) case C4LRU_MatMap: return "matMap"; case C4LRU_MatMapTex: return "matMapTex"; case C4LRU_MaterialDepth:return "materialDepth"; + case C4LRU_MaterialSize: return "materialSize"; } assert(false); return "mysterious"; @@ -113,6 +114,28 @@ bool C4LandscapeRenderGL::Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pT return true; } +bool C4LandscapeRenderGL::ReInit(int32_t iWidth, int32_t iHeight) +{ + // Safe info + this->iWidth = iWidth; + this->iHeight = iHeight; + + // Clear old landscape textures + for (int i = 0; i < C4LR_SurfaceCount; i++) + { + delete Surfaces[i]; + Surfaces[i] = NULL; + } + + // Allocate new landscape textures + if (!InitLandscapeTexture()) + { + LogFatal("[!] Could not initialize landscape texture!"); + return false; + } + return true; +} + void C4LandscapeRenderGL::Clear() { ClearShaders(); @@ -193,6 +216,8 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs) LogF(" gl: Too many material textures! GPU only supports 3D texture depth of %d!", iMaxTexSize); return false; } + iMaterialWidth = iTexWdt; + iMaterialHeight = iTexHgt; // Compose together data of all textures const int iBytesPP = pRefSfc->byBytesPP; @@ -255,16 +280,11 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs) // Clear error error(s?) while(glGetError()) {} - int iMMLevels = 3; - while(iTexWdt <= (1 >> iMMLevels) || iTexHgt <= (1 >> iMMLevels)) - iMMLevels--; - // Alloc 3D textures glEnable(GL_TEXTURE_3D); - glGenTextures(iMMLevels, hMaterialTexture); + glGenTextures(C4LR_MipMapCount, hMaterialTexture); // Generate textures (mipmaps too!) - int iFullWdt = iTexWdt, iFullHgt = iTexHgt; int iSizeSum = 0; BYTE *pLastData = new BYTE [iSize / 4]; for(int iMMLevel = 0; iMMLevel < C4LR_MipMapCount; iMMLevel++) @@ -333,9 +353,9 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs) } // Announce the good news - LogF(" gl: Texturing uses %d slots at %dx%d, %d levels (%d MB total)", + LogF(" gl: Texturing uses %d slots at %dx%d, %d levels (%d MB total)", static_cast(MaterialTextureMap.size()), - iFullWdt, iFullHgt, + iMaterialWidth, iMaterialHeight, C4LR_MipMapCount, iSizeSum / 1000000); @@ -547,6 +567,13 @@ GLhandleARB C4LandscapeRenderGL::CreateShader(GLenum iShaderType, const char *sz szCodeRest = szVersion; } + // Get number of available uniforms from driver + GLint max_uniforms = 0; + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &max_uniforms); + Version.AppendFormat("#define MAX_FRAGMENT_UNIFORM_COMPONENTS %d\n", max_uniforms); + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &max_uniforms); + Version.AppendFormat("#define MAX_VERTEX_UNIFORM_COMPONENTS %d\n", max_uniforms); + // Build code const char *szCodes[C4LR_ShaderWorkaroundCount + 2]; szCodes[0] = Version.getData(); @@ -902,7 +929,7 @@ void C4LandscapeRenderGL::BuildMatMap(GLfloat *pFMap, GLubyte *pIMap) while(p = strchr(p, '-')) { p++; iPhases++; } // Hard-coded hack. Fix me! const int iPhaseLength = 300; - float phase = (iPhases == 1 ? 0 : float(GetTime() % (iPhases * iPhaseLength)) / iPhaseLength); + float phase = (iPhases == 1 ? 0 : float(C4TimeMilliseconds::Now().AsInt() % (iPhases * iPhaseLength)) / iPhaseLength); // Find our transition const char *pFrom = pEntry->GetTextureName(); @@ -966,7 +993,10 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo) } if (hUniforms[C4LRU_MaterialDepth] != GLhandleARB(-1)) glUniform1iARB(hUniforms[C4LRU_MaterialDepth], iMaterialTextureDepth); - + if (hUniforms[C4LRU_MaterialSize] != GLhandleARB(-1)) + glUniform2fARB(hUniforms[C4LRU_MaterialSize], float(iMaterialWidth) / ::Game.C4S.Landscape.MaterialZoom, + float(iMaterialHeight) / ::Game.C4S.Landscape.MaterialZoom); + // Setup facilities for texture unit allocation (gimme local functions...) int iUnit = 0; int iUnitMap[32]; ZeroMem(iUnitMap, sizeof(iUnitMap)); #define ALLOC_UNIT(hUniform, iType) do { \ @@ -993,8 +1023,8 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo) ALLOC_UNIT(hUniforms[C4LRU_MaterialTex], GL_TEXTURE_3D); // Decide which mip-map level to use - double z = 2.0; int iMM = 0; - while(pGL->Zoom < z && iMM + 1 Zoom < z * ::Game.C4S.Landscape.MaterialZoom && iMM + 1 MaterialTextureMap; // depth of material texture in layers int32_t iMaterialTextureDepth; + // size of material textures (unzoomed) + int32_t iMaterialWidth, iMaterialHeight; // scaler image C4FacetSurface fctScaler; public: + virtual bool ReInit(int32_t iWidth, int32_t iHeight); virtual bool Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pMap, C4GroupSet *pGraphics); virtual void Clear(); @@ -143,6 +148,7 @@ private: C4Surface *Surface32; public: + virtual bool ReInit(int32_t iWidth, int32_t iHeight); virtual bool Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pMap, C4GroupSet *pGraphics); virtual void Clear(); diff --git a/src/game/landscape/C4LandscapeRenderClassic.cpp b/src/landscape/C4LandscapeRenderClassic.cpp similarity index 94% rename from src/game/landscape/C4LandscapeRenderClassic.cpp rename to src/landscape/C4LandscapeRenderClassic.cpp index 59854b995..7846b8951 100644 --- a/src/game/landscape/C4LandscapeRenderClassic.cpp +++ b/src/landscape/C4LandscapeRenderClassic.cpp @@ -17,9 +17,10 @@ C4LandscapeRenderClassic::~C4LandscapeRenderClassic() Clear(); } -bool C4LandscapeRenderClassic::Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pTexs, C4GroupSet *pGraphics) +bool C4LandscapeRenderClassic::ReInit(int32_t iWidth, int32_t iHeight) { // Create surface + delete Surface32; Surface32 = NULL; Surface32 = new C4Surface(); // without shaders, the FoW is only as detailed as the landscape has tiles. if(!Surface32->Create(iWidth, iHeight,false,false,pDraw->IsShaderific() ? 0 : 64)) @@ -27,6 +28,13 @@ bool C4LandscapeRenderClassic::Init(int32_t iWidth, int32_t iHeight, C4TextureMa // Safe back info this->iWidth = iWidth; this->iHeight = iHeight; + return true; +} + +bool C4LandscapeRenderClassic::Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pTexs, C4GroupSet *pGraphics) +{ + // Init proc + if (!ReInit(iWidth, iHeight)) return false; this->pTexs = pTexs; return true; } diff --git a/src/game/landscape/C4Map.cpp b/src/landscape/C4Map.cpp similarity index 90% rename from src/game/landscape/C4Map.cpp rename to src/landscape/C4Map.cpp index c9032def6..9aece16a8 100644 --- a/src/game/landscape/C4Map.cpp +++ b/src/landscape/C4Map.cpp @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Create map from dynamic landscape data in scenario */ @@ -27,7 +24,7 @@ #include #include -#include +#include #include C4MapCreator::C4MapCreator() diff --git a/src/game/landscape/C4Map.h b/src/landscape/C4Map.h similarity index 62% rename from src/game/landscape/C4Map.h rename to src/landscape/C4Map.h index c47d7d64f..a93582d3f 100644 --- a/src/game/landscape/C4Map.h +++ b/src/landscape/C4Map.h @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Create map from dynamic landscape data in scenario */ @@ -24,9 +22,6 @@ #include -class CSurface8; -class C4TextureMap; - class C4MapCreator { public: diff --git a/src/game/landscape/C4MapCreatorS2.cpp b/src/landscape/C4MapCreatorS2.cpp similarity index 94% rename from src/game/landscape/C4MapCreatorS2.cpp rename to src/landscape/C4MapCreatorS2.cpp index 477e9bb1e..9dfc3aeae 100644 --- a/src/game/landscape/C4MapCreatorS2.cpp +++ b/src/landscape/C4MapCreatorS2.cpp @@ -1,24 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001-2002, 2008 Peter Wortmann - * Copyright (c) 2001-2002, 2005 Sven Eberhardt - * Copyright (c) 2004, 2006-2009 Günther Brammer - * Copyright (c) 2005-2006 Matthes Bender - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // complex dynamic landscape creator @@ -196,13 +189,17 @@ C4MCNode::C4MCNode(C4MCNode *pOwner) *Name=0; } -C4MCNode::C4MCNode(C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone) +C4MCNode::C4MCNode(C4MCParser* pParser, C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone) { + // Make sure the template is not used recursively within itself + for(C4MCNode* pParent = pOwner; pParent != NULL; pParent = pParent->Owner) + if(pParent == &rTemplate) + throw C4MCParserErr(pParser, C4MCErr_NoRecTemplate, rTemplate.Name); // set owner and stuff Reg2Owner(pOwner); // copy children from template for (C4MCNode *pChild=rTemplate.Child0; pChild; pChild=pChild->Next) - pChild->clone(this); + pChild->clone(pParser, this); // no name *Name=0; } @@ -324,7 +321,7 @@ C4MCOverlay::C4MCOverlay(C4MCNode *pOwner) : C4MCNode(pOwner) pEvaluateFunc=pDrawFunc=NULL; } -C4MCOverlay::C4MCOverlay(C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone) : C4MCNode(pOwner, rTemplate, fClone) +C4MCOverlay::C4MCOverlay(C4MCParser* pParser, C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone) : C4MCNode(pParser, pOwner, rTemplate, fClone) { // copy fields X=rTemplate.X; Y=rTemplate.Y; Wdt=rTemplate.Wdt; Hgt=rTemplate.Hgt; @@ -428,7 +425,7 @@ bool C4MCOverlay::SetField(C4MCParser *pParser, const char *szField, const char case C4MCV_ScriptFunc: { // get script func of main script - C4AulFunc *pSFunc = ::GameScript.ScenPropList->GetFunc(StrPar); + C4AulFunc *pSFunc = ::GameScript.ScenPropList._getPropList()->GetFunc(StrPar); if (!pSFunc) throw C4MCParserErr(pParser, C4MCErr_SFuncNotFound, StrPar); // add to main Target.As() = new C4MCCallbackArray(pSFunc, MapCreator); @@ -485,7 +482,12 @@ void C4MCOverlay::Evaluate() } } // calc seed - if (!(Seed=FixedSeed)) Seed=(Random(32768)<<16) | Random(65536); + if (!(Seed=FixedSeed)) + { + int32_t r1=Random(32768); + int32_t r2=Random(65536); + Seed=(r1<<16) | r2; + } } C4MCOverlay *C4MCOverlay::FirstOfChain() @@ -507,11 +509,12 @@ bool C4MCOverlay::CheckMask(int32_t iX, int32_t iY) { // bounds match? if (!LooseBounds) if (iX=X+Wdt || iY>=Y+Hgt) return false; -#ifdef DEBUGREC - C4RCTrf rc; - rc.x=iX; rc.y=iY; rc.Rotate=Rotate; rc.Turbulence=Turbulence; - AddDbgRec(RCT_MCT1, &rc, sizeof(rc)); -#endif + if (Config.General.DebugRec) + { + C4RCTrf rc; + rc.x=iX; rc.y=iY; rc.Rotate=Rotate; rc.Turbulence=Turbulence; + AddDbgRec(RCT_MCT1, &rc, sizeof(rc)); + } C4Real dX=itofix(iX); C4Real dY=itofix(iY); // apply turbulence if (Turbulence) @@ -549,11 +552,12 @@ bool C4MCOverlay::CheckMask(int32_t iX, int32_t iY) { iX=fixtoi(dX, ZoomX); iY=fixtoi(dY, ZoomY); } else { iX*=ZoomX; iY*=ZoomY; } -#ifdef DEBUGREC - C4RCPos rc2; - rc2.x=iX; rc2.y=iY; - AddDbgRec(RCT_MCT2, &rc2, sizeof(rc2)); -#endif + if (Config.General.DebugRec) + { + C4RCPos rc2; + rc2.x=iX; rc2.y=iY; + AddDbgRec(RCT_MCT2, &rc2, sizeof(rc2)); + } // apply offset iX-=OffX*ZoomX; iY-=OffY*ZoomY; // check bounds, if loose @@ -637,7 +641,7 @@ C4MCPoint::C4MCPoint(C4MCNode *pOwner) : C4MCNode(pOwner) X=Y=0; } -C4MCPoint::C4MCPoint(C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone) : C4MCNode(pOwner, rTemplate, fClone) +C4MCPoint::C4MCPoint(C4MCParser* pParser, C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone) : C4MCNode(pParser, pOwner, rTemplate, fClone) { // copy fields X=rTemplate.X; Y=rTemplate.Y; @@ -690,7 +694,7 @@ C4MCMap::C4MCMap(C4MCNode *pOwner) : C4MCOverlay(pOwner) } -C4MCMap::C4MCMap(C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone) : C4MCOverlay(pOwner, rTemplate, fClone) +C4MCMap::C4MCMap(C4MCParser* pParser, C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone) : C4MCOverlay(pParser, pOwner, rTemplate, fClone) { } @@ -700,12 +704,7 @@ void C4MCMap::Default() // inherited C4MCOverlay::Default(); // size by landscape def - Wdt=MapCreator->Landscape->MapWdt.Evaluate(); - Hgt=MapCreator->Landscape->MapHgt.Evaluate(); - // map player extend - MapCreator->PlayerCount = Max(MapCreator->PlayerCount, 1); - if (MapCreator->Landscape->MapPlayerExtend) - Wdt = Min(Wdt * Min(MapCreator->PlayerCount, (int) C4S_MaxMapPlayerExtend), (int) MapCreator->Landscape->MapWdt.Max); + MapCreator->Landscape->GetMapSize(Wdt, Hgt, MapCreator->PlayerCount); } bool C4MCMap::RenderTo(BYTE *pToBuf, int32_t iPitch) @@ -895,7 +894,7 @@ BYTE *C4MapCreatorS2::RenderBuf(const char *szMapName, int32_t &sfcWdt, int32_t C4MCParserErr::C4MCParserErr(C4MCParser *pParser, const char *szMsg) { // create error message - sprintf(Msg, "%s: %s (%d)", pParser->Filename, szMsg, pParser->Code ? SGetLine(pParser->Code, pParser->CPos) : 0); + sprintf(Msg, "%s: %s (%d)", pParser->Filename, szMsg, pParser->BPos ? SGetLine(pParser->BPos, pParser->CPos) : 0); } C4MCParserErr::C4MCParserErr(C4MCParser *pParser, const char *szMsg, const char *szPar) @@ -903,7 +902,7 @@ C4MCParserErr::C4MCParserErr(C4MCParser *pParser, const char *szMsg, const char char Buf[C4MaxMessage]; // create error message sprintf(Buf, szMsg, szPar); - sprintf(Msg, "%s: %s (%d)", pParser->Filename, Buf, pParser->Code ? SGetLine(pParser->Code, pParser->CPos) : 0); + sprintf(Msg, "%s: %s (%d)", pParser->Filename, Buf, pParser->BPos ? SGetLine(pParser->BPos, pParser->CPos) : 0); } void C4MCParserErr::show() @@ -920,7 +919,7 @@ C4MCParser::C4MCParser(C4MapCreatorS2 *pMapCreator) // store map creator MapCreator=pMapCreator; // reset some fields - Code=NULL; CPos=NULL; *Filename=0; + Code=NULL; BPos = NULL; CPos=NULL; *Filename=0; } C4MCParser::~C4MCParser() @@ -932,7 +931,7 @@ C4MCParser::~C4MCParser() void C4MCParser::Clear() { // clear code if present - if (Code) delete [] Code; Code=NULL; CPos=NULL; + if (Code) delete [] Code; Code=NULL; BPos = NULL; CPos=NULL; // reset filename *Filename=0; } @@ -1124,7 +1123,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) if (SEqual(CurrTokenIdtf, C4MC_Overlay)) { // overlay: create overlay node, using default template - pNewNode = new C4MCOverlay(pToNode, MapCreator->DefaultOverlay, false); + pNewNode = new C4MCOverlay(this, pToNode, MapCreator->DefaultOverlay, false); State=PS_KEYWD1; } else if (SEqual(CurrTokenIdtf, C4MC_Point) && !pToNode->GetNodeByName(CurrTokenIdtf)) @@ -1133,7 +1132,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) if (!pToNode->Type() == MCN_Overlay) throw C4MCParserErr(this, C4MCErr_PointOnlyOvl); // create point node, using default template - pNewNode = new C4MCPoint(pToNode, MapCreator->DefaultPoint, false); + pNewNode = new C4MCPoint(this, pToNode, MapCreator->DefaultPoint, false); State=PS_KEYWD1; } else if (SEqual(CurrTokenIdtf, C4MC_Map)) @@ -1142,7 +1141,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) if (!pToNode->GlobalScope()) throw C4MCParserErr(this, C4MCErr_MapNoGlobal); // create map node, using default template - pNewNode = new C4MCMap(pToNode, MapCreator->DefaultMap, false); + pNewNode = new C4MCMap(this, pToNode, MapCreator->DefaultMap, false); State=PS_KEYWD1; } else @@ -1224,7 +1223,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) { case MCN_Overlay: // create overlay - pNewNode=new C4MCOverlay(pToNode, *((C4MCOverlay *) pCpyNode), false); + pNewNode=new C4MCOverlay(this, pToNode, *((C4MCOverlay *) pCpyNode), false); break; case MCN_Map: // maps not allowed @@ -1458,6 +1457,7 @@ void C4MCParser::ParseFile(const char *szFilename, C4Group *pGrp) pGrp->Read((void *) Code, iSize); Code[iSize]=0; // parse it + BPos=Code; CPos=Code; ParseTo(MapCreator); if (0) PrintNodeTree(MapCreator, 0); @@ -1471,6 +1471,7 @@ void C4MCParser::Parse(const char *szScript) // clear any old data Clear(); // parse it + BPos=szScript; CPos=szScript; ParseTo(MapCreator); if (0) PrintNodeTree(MapCreator, 0); @@ -1480,6 +1481,20 @@ void C4MCParser::Parse(const char *szScript) } +void C4MCParser::ParseMemFile(const char *szScript, const char *szFilename) +{ + // clear any old data + Clear(); + // store filename + SCopy(szFilename, Filename, C4MaxName); + // parse it + BPos=szScript; + CPos=szScript; + ParseTo(MapCreator); + // on errors, this will be done be destructor + Clear(); +} + // algorithms --------------------- diff --git a/src/game/landscape/C4MapCreatorS2.h b/src/landscape/C4MapCreatorS2.h similarity index 88% rename from src/game/landscape/C4MapCreatorS2.h rename to src/landscape/C4MapCreatorS2.h index 10167628e..187151ce4 100644 --- a/src/game/landscape/C4MapCreatorS2.h +++ b/src/landscape/C4MapCreatorS2.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001-2002, 2005 Sven Eberhardt - * Copyright (c) 2004, 2007, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // complex dynamic landscape creator @@ -25,11 +22,6 @@ #include #include -class C4AulFunc; -class C4TextureMap; -class C4MaterialMap; -class CSurface8; - #define C4MC_SizeRes 100 // positions in percent #define C4MC_ZoomRes 100 // zoom resolution (-100 to +99) @@ -68,6 +60,7 @@ class CSurface8; #define C4MCErr_AlgoNotFound "algorithm '%s' not found" #define C4MCErr_SFuncNotFound "script func '%s' not found in scenario script" #define C4MCErr_PointOnlyOvl "point only allowed in overlays" +#define C4MCErr_NoRecTemplate "cannot use template '%s' within itself" // predef class C4MCCallbackArray; @@ -161,10 +154,10 @@ public: public: C4MCNode(C4MCNode *pOwner=NULL); // constructor - C4MCNode(C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone); // constructor using template + C4MCNode(C4MCParser* pParser, C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone); // constructor using template virtual ~C4MCNode(); // destructor - virtual C4MCNode *clone(C4MCNode *pToNode) { return new C4MCNode(pToNode, *this, true); } + virtual C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCNode(pParser, pToNode, *this, true); } void Clear(); // clear all child nodes void Reg2Owner(C4MCNode *pOwner); // register into list @@ -206,9 +199,9 @@ class C4MCOverlay : public C4MCNode { public: C4MCOverlay(C4MCNode *pOwner=NULL); // constructor - C4MCOverlay(C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone); // construct of template + C4MCOverlay(C4MCParser* pParser, C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone); // construct of template - C4MCNode *clone(C4MCNode *pToNode) { return new C4MCOverlay(pToNode, *this, true); } + C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCOverlay(pParser, pToNode, *this, true); } protected: void Default(); // set default values for default presets @@ -259,9 +252,9 @@ class C4MCPoint : public C4MCNode { public: C4MCPoint(C4MCNode *pOwner=NULL); // constructor - C4MCPoint(C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone); // construct of template + C4MCPoint(C4MCParser* pParser, C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone); // construct of template - C4MCNode *clone(C4MCNode *pToNode) { return new C4MCPoint(pToNode, *this, true); } + C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCPoint(pParser, pToNode, *this, true); } protected: void Default(); // set default values for default presets @@ -285,9 +278,9 @@ class C4MCMap : public C4MCOverlay { public: C4MCMap(C4MCNode *pOwner=NULL); // constructor - C4MCMap(C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone); // construct of template + C4MCMap(C4MCParser* pParser, C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone); // construct of template - C4MCNode *clone(C4MCNode *pToNode) { return new C4MCMap(pToNode, *this, true); } + C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCMap(pParser, pToNode, *this, true); } protected: void Default(); // set default values for default presets @@ -366,7 +359,8 @@ class C4MCParser { private: C4MapCreatorS2 *MapCreator; // map creator parsing into - char *Code; // loaded code + char *Code; // loaded code, can be NULL if externally owned + const char *BPos; // Beginning of code const char *CPos; // current parser pos in code C4MCTokenType CurrToken; // last token read char CurrTokenIdtf[C4MaxName]; // current token string @@ -386,6 +380,7 @@ public: void ParseFile(const char *szFilename, C4Group *pGrp); // load and parse file void Parse(const char *szScript); // load and parse from mem + void ParseMemFile(const char *szScript, const char *szFilename); // parse file previosuly loaded into mem friend class C4MCParserErr; }; diff --git a/src/landscape/C4MapScript.cpp b/src/landscape/C4MapScript.cpp new file mode 100644 index 000000000..750878396 --- /dev/null +++ b/src/landscape/C4MapScript.cpp @@ -0,0 +1,608 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, 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. + */ + +/* Handles scripted map creation */ + +#include +#include +#include +#include +#include +#include + +C4MapScriptAlgo *FnParAlgo(C4PropList *algo_par); + +static const char *DrawFn_Transparent_Name = "Transparent"; +static const char *DrawFn_Sky_Name = "Sky"; +static const char *DrawFn_Background_Name = "Background"; +static const char *DrawFn_Liquid_Name = "Liquid"; +static const char *DrawFn_Solid_Name = "Solid"; + +int32_t FnParTexCol(C4String *mattex, int32_t default_col = -1) +{ + // Return index of material-texture definition for a single color + // Defaults to underground (tunnel background) color. Prefix material with ^ to get overground (sky background) color. + if (!mattex || !mattex->GetCStr()) return default_col; + if (mattex->GetData() == DrawFn_Transparent_Name) return 0; + if (mattex->GetData() == DrawFn_Sky_Name) return IFT; + const char *cmattex = mattex->GetCStr(); + int32_t ift = IFT; + if (*cmattex == '^') { ift=0; ++cmattex; } + int32_t col = ::TextureMap.GetIndexMatTex(cmattex); + return col ? col|ift : default_col; +} + +void C4MapScriptMatTexMask::UnmaskSpec(C4String *spec) +{ + // Mask all indices of material-texture definitions + // Possible definitions: + // Material-Texture - Given material-texture combination (both sky and tunnel background) + // Material - All defined default textures of given material + // * - All materials + // Sky - Index IFT + // Transparent - Index 0 + // Background - All tunnel materials plus sky + // Liquid - All liquid materials + // Solid - All solid materials + // Possible modifiers: + // ^Material - Given material only with sky background + // &Material - Given material only with tunnel background + // ~Material - Inverse of given definition; i.e. everything except Material + if (!spec || !spec->GetCStr()) return; + const char *cspec = spec->GetCStr(); + bool invert=false, bgsky=false, bgtunnel=false, prefix_done=false; + while (*cspec) + { + switch (*cspec) + { + case '~': invert=!invert; break; + case '^': bgsky=true; break; + case '&': bgtunnel=true; break; + default: prefix_done=true; break; + } + if (prefix_done) break; + ++cspec; + } + std::vector mat_mask(IFT, false); + if (SEqual(cspec, DrawFn_Transparent_Name)) + { + // "Transparent" is zero index. Force to non-IFT + mat_mask[0] = true; + bgsky = true; bgtunnel = false; + } + else if (SEqual(cspec, DrawFn_Sky_Name)) + { + // Sky material: Force to IFT + mat_mask[0] = true; + bgsky = false; bgtunnel = true; + } + else if (SEqual(cspec, DrawFn_Background_Name)) + { + // All background materials + for (int32_t i=0; imask. Apply bgsky, bgtunnel and invert. + for (int32_t i=0; iGetSize(); ++i) + { + C4String *smask = arr->GetItem(i).getStr(); + if (!smask) throw new C4AulExecError(FormatString("MatTexMask expected string as %dth element in array.", (int)i).getData()); + UnmaskSpec(smask); + } + } + else + { + // Init by string + C4String *smask = spec.getStr(); + if (smask) + UnmaskSpec(smask); + else + { + if (spec) throw new C4AulExecError("MatTexMask expected string or array of strings."); + // nil defaults to everything except index zero unmasked + mask = std::vector(256, true); + mask[0] = false; + } + } +} + + +bool FnParRect(C4MapScriptLayer *layer, C4ValueArray *rect, C4Rect *rc_bounds) +{ + // Convert rect parameter passed to script function to C4Rect structure + // and makes sure it is completely contained in bounding rectangle of layer + // rect==NULL defaults to bounding rectangle of layer + *rc_bounds = layer->GetBounds(); + if (!rect) return true; // nil is OK for rect parameter. Defaults to bounds rectangle + if (rect->GetSize() != 4) return false; + rc_bounds->Intersect(C4Rect(rect->GetItem(0).getInt(), rect->GetItem(1).getInt(), rect->GetItem(2).getInt(), rect->GetItem(3).getInt())); + return true; +} + +static bool FnLayerDraw(C4PropList * _this, C4String *mattex, C4PropList *mask_algo, C4ValueArray *rect) +{ + // Layer script function: Draw material mattex in shape of mask_algo in _this layer within bounds given by rect + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + int32_t icol = FnParTexCol(mattex); + if (!layer || icol<0) return false; + C4Rect rcBounds; + if (!FnParRect(layer, rect, &rcBounds)) return false; + std::unique_ptr algo(FnParAlgo(mask_algo)); + return layer->Fill(icol, rcBounds, algo.get()); +} + +static bool FnLayerBlit(C4PropList * _this, C4PropList *mask_algo, C4ValueArray *rect) +{ + // Layer script function: Blit mask_algo onto surface of _this within bounds given by rect + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return false; + C4Rect rcBounds; + if (!FnParRect(layer, rect, &rcBounds)) return false; + std::unique_ptr algo(FnParAlgo(mask_algo)); + if (!algo.get()) return false; + return layer->Blit(rcBounds, algo.get()); +} + +static C4PropList *FnCreateLayer(C4PropList * _this, C4String *mattex_fill, int32_t width, int32_t height) +{ + // Layer script function: Create new layer filled by mattex_fill of size width,height as sub layer of _this map + // Size defaults to _this layer size + int32_t icol = FnParTexCol(mattex_fill, 0); + if (icol<0) throw new C4AulExecError(FormatString("CreateLayer: Invalid fill material.").getData()); + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return NULL; + if (!width && !height) + { + width = layer->GetWdt(); + height = layer->GetHgt(); + } + if (width<=0 || height<=0) throw new C4AulExecError(FormatString("CreateLayer: Invalid size (%d*%d).", (int)width, (int)height).getData()); + C4MapScriptMap *map = layer->GetMap(); + if (!map) return NULL; + layer = map->CreateLayer(width, height); + if (icol) layer->Fill(icol, layer->GetBounds(), NULL); + return layer; +} + +static C4PropList *FnLayerDuplicate(C4PropList * _this, const C4Value &mask_spec, C4ValueArray *rect) +{ + // Layer script function: Create a copy of _this layer within bounds. If mask_spec is specified, copy only materials selected by mask spec + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return NULL; + C4MapScriptMap *map = layer->GetMap(); + if (!map) return NULL; + C4MapScriptMatTexMask mat_mask(mask_spec); + C4Rect src_rect; + if (!FnParRect(layer, rect, &src_rect)) return NULL; + if (!src_rect.Wdt || !src_rect.Hgt) return NULL; + C4MapScriptLayer *new_layer = map->CreateLayer(src_rect.Wdt, src_rect.Hgt); + new_layer->Blit(layer, src_rect, mat_mask, 0,0); + return new_layer; +} + +static int32_t FnLayerGetPixel(C4PropList * _this, int32_t x, int32_t y) +{ + // Layer script function: Query pixel at position x,y from _this layer + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return 0; + return layer->GetPix(x,y,0); +} + +static bool FnLayerSetPixel(C4PropList * _this, int32_t x, int32_t y, const C4Value &to_value_c4v) +{ + // Layer script function: Set pixel at position x,y to to_value in _this layer + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return false; + int32_t to_value; C4String *to_value_s; + if (to_value_s = to_value_c4v.getStr()) + { + to_value = FnParTexCol(to_value_s); + } + else + { + to_value = to_value_c4v.getInt(); + } + if (!Inside(to_value, 0, 255)) throw new C4AulExecError("MapLayer::SetPixel: Trying to set invalid pixel value."); + return layer->SetPix(x,y,to_value); +} + +static int32_t FnLayerGetPixelCount(C4PropList * _this, const C4Value &mask_spec, C4ValueArray *rect) +{ + // Layer script function: Count all pixels within rect that match mask_spec specification + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return -1; + C4MapScriptMatTexMask mat_mask(mask_spec); + C4Rect check_rect; + if (!FnParRect(layer, rect, &check_rect)) return -1; + return layer->GetPixCount(check_rect, mask_spec); +} + +static bool FnLayerResize(C4PropList * _this, int32_t new_wdt, int32_t new_hgt) +{ + // Layer script function: Recreate layer in new size. Resulting layer is empty (color 0) + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + // safety + if (!layer || new_wdt<=0 || new_hgt<=0) return false; + // recreate surface in new size + layer->ClearSurface(); + return layer->CreateSurface(new_wdt, new_hgt); +} + +static bool FnLayerFindPosition(C4PropList * _this, C4PropList *out_pos, const C4Value &mask_spec, C4ValueArray *rect, int32_t max_tries) +{ + // Layer script function: Find a position (x,y) that has a color matching mask_spec. Set resulting position as X,Y properties in out_pos prop list + C4MapScriptLayer *layer = _this->GetMapScriptLayer(); + if (!layer) return NULL; + C4MapScriptMatTexMask mat_mask(mask_spec); + C4Rect search_rect; + if (!FnParRect(layer, rect, &search_rect)) return NULL; + int32_t x,y; bool result; + if (!max_tries) max_tries = 500; + if (result = layer->FindPos(search_rect, mat_mask, &x, &y, max_tries)) + { + if (out_pos && !out_pos->IsFrozen()) + { + out_pos->SetProperty(P_X, C4VInt(x)); + out_pos->SetProperty(P_Y, C4VInt(y)); + } + } + return result; +} + +static C4ValueArray *FnLayerCreateMatTexMask(C4PropList * _this, const C4Value &mask_spec) +{ + // layer script function: Generate an array 256 bools representing the given mask_spec + C4MapScriptMatTexMask mat_mask(mask_spec); + C4ValueArray *result = new C4ValueArray(256); + for (int32_t i=0; i<256; ++i) + { + result->SetItem(i, C4VBool(mat_mask(uint8_t(i)))); + } + return result; +} + +C4MapScriptLayer::C4MapScriptLayer(C4PropList *prototype, C4MapScriptMap *map) : C4PropListNumbered(prototype), surface(NULL), surface_owned(false), map(map) +{ + // It seems like numbered PropLists need a number. I don't know why. + AcquireNumber(); +} + +bool C4MapScriptLayer::CreateSurface(int32_t wdt, int32_t hgt) +{ + // Create new surface of given size. Surface is filled with color 0 + ClearSurface(); + if (wdt<=0 || hgt<=0) return false; + surface = new CSurface8; + surface_owned = true; + if (!surface->Create(wdt, hgt)) + { + ClearSurface(); + return false; + } + UpdateSurfaceSize(); + return true; +} + +void C4MapScriptLayer::ClearSurface() +{ + // Delete surface if owned or just set to zero if unowned + if (surface_owned) delete surface; + surface=NULL; surface_owned=false; + // if there is no surface, width and height parameters are undefined. no need to update them. +} + +void C4MapScriptLayer::UpdateSurfaceSize() +{ + // Called when surface size changes: Update internal property values + if (surface) + { + SetProperty(P_Wdt, C4VInt(surface->Wdt)); + SetProperty(P_Hgt, C4VInt(surface->Hgt)); + } +} + +void C4MapScriptLayer::ConvertSkyToTransparent() +{ + // Convert all sky (color==IFT) pixels to transparent (color==0) + // Needed because C4Landscape map zoom assumes sky to be 0 + if (!HasSurface()) return; + for (int32_t y=0; yHgt; ++y) + for (int32_t x=0; xWdt; ++x) + if (surface->_GetPix(x,y) == IFT) + surface->_SetPix(x,y, 0); +} + +C4Rect C4MapScriptLayer::GetBounds() const +{ + // Return bounding rectangle of surface. Surface always starts at 0,0. + return surface ? C4Rect(0,0,surface->Wdt,surface->Hgt) : C4Rect(); +} + +bool C4MapScriptLayer::Fill(int col, const C4Rect &rcBounds, const C4MapScriptAlgo *algo) +{ + // safety + if (!HasSurface()) return false; + assert(rcBounds.x>=0 && rcBounds.y>=0 && rcBounds.x+rcBounds.Wdt<=surface->Wdt && rcBounds.y+rcBounds.Hgt<=surface->Hgt); + // set all non-masked pixels within bounds that fulfill algo + for (int32_t y=rcBounds.y; y_SetPix(x,y,col); + return true; +} + +bool C4MapScriptLayer::Blit(const C4Rect &rcBounds, const C4MapScriptAlgo *algo) +{ + // safety + if (!HasSurface()) return false; + assert(rcBounds.x>=0 && rcBounds.y>=0 && rcBounds.x+rcBounds.Wdt<=surface->Wdt && rcBounds.y+rcBounds.Hgt<=surface->Hgt); + assert(algo); + // set all pixels within bounds by algo, if algo is not transparent + uint8_t col; + for (int32_t y=rcBounds.y; y_SetPix(x,y,col); + return true; +} + +bool C4MapScriptLayer::Blit(const C4MapScriptLayer *src, const C4Rect &src_rect, const C4MapScriptMatTexMask &col_mask, int32_t tx, int32_t ty) +{ + // safety + assert(src); + if (!HasSurface() || !src->HasSurface()) return false; + // cannot assert this, because C4Rect::Contains(C4Rect &) has an off-by-one-error which I don't dare to fix right now + // TODO: Fix C4Rect::Contains and check if the sector code still works + // assert(src->GetBounds().Contains(src_rect)); + // copy all pixels that aren't masked + uint8_t col; + for (int32_t y=src_rect.y; ysurface->_GetPix(x,y))) + surface->_SetPix(x-src_rect.x+tx,y-src_rect.y+ty,col); + return true; +} + +int32_t C4MapScriptLayer::GetPixCount(const C4Rect &rcBounds, const C4MapScriptMatTexMask &col_mask) +{ + // safety + if (!HasSurface()) return 0; + assert(rcBounds.x>=0 && rcBounds.y>=0 && rcBounds.x+rcBounds.Wdt<=surface->Wdt && rcBounds.y+rcBounds.Hgt<=surface->Hgt); + // count matching pixels in rect + int32_t count = 0; + for (int32_t y=rcBounds.y; y_GetPix(x,y)); + return count; +} + +bool C4MapScriptLayer::FindPos(const C4Rect &search_rect, const C4MapScriptMatTexMask &col_mask, int32_t *out_x, int32_t *out_y, int32_t max_tries) +{ + // safety + if (!HasSurface() || search_rect.Wdt<=0 || search_rect.Hgt<=0) return false; + // Search random positions + for (int32_t i=0; i_GetPix(x,y))) { *out_x=x; *out_y=y; return true; } + } + // Nothing found yet: Start at a random position and search systemically + // (this guantuess to find a pixel if there is one, but favours border pixels) + int32_t sx=search_rect.x + Random(search_rect.Wdt); + int32_t sy=search_rect.y + Random(search_rect.Hgt); + for (int32_t x=sx; xWdt; ++x) + if (col_mask(surface->_GetPix(x,sy))) { *out_x=x; *out_y=sy; return true; } + for (int32_t y=sy+1; yHgt; ++y) + for (int32_t x=0; xWdt; ++x) + if (col_mask(surface->_GetPix(x,y))) { *out_x=x; *out_y=y; return true; } + for (int32_t y=0; yWdt; ++x) + if (col_mask(surface->_GetPix(x,y))) { *out_x=x; *out_y=y; return true; } + for (int32_t x=0; x_GetPix(x,sy))) { *out_x=x; *out_y=sy; return true; } + // Nothing found + return false; +} + +void C4MapScriptMap::Clear() +{ + // Layers are owned by map. Free them. + for (std::list::iterator i=layers.begin(); i!=layers.end(); ++i) delete *i; + layers.clear(); +} + +C4MapScriptLayer *C4MapScriptMap::CreateLayer(int32_t wdt, int32_t hgt) +{ + // Create layer and register to map. Layer's created by a map are freed when the map is freed. + C4MapScriptLayer *new_layer = new C4MapScriptLayer(MapScript.GetLayerPrototype(), this); + layers.push_back(new_layer); // push before CreateSurface for exception safety + if (!new_layer->CreateSurface(wdt, hgt)) + { + layers.remove(new_layer); + delete new_layer; + return NULL; + } + return new_layer; +} + +C4MapScriptHost::C4MapScriptHost(): LayerPrototype(NULL), MapPrototype(NULL) { } + +C4MapScriptHost::~C4MapScriptHost() { Clear(); } + +void C4MapScriptHost::InitFunctionMap(C4AulScriptEngine *pEngine) +{ + // Register script host. Add Map and MapLayer prototypes, related constants and engine functions + assert(pEngine && pEngine->GetPropList()); + Clear(); + LayerPrototype = new C4PropListStaticMember(NULL, NULL, ::Strings.RegString("MapLayer")); + MapPrototype = new C4PropListStaticMember(LayerPrototype, NULL, ::Strings.RegString("Map")); + LayerPrototype->SetName("MapLayer"); + MapPrototype->SetName("Map"); + ::ScriptEngine.RegisterGlobalConstant("MapLayer", C4VPropList(LayerPrototype)); + ::ScriptEngine.RegisterGlobalConstant("Map", C4VPropList(MapPrototype)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Layer", C4VInt(MAPALGO_Layer)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_RndChecker", C4VInt(MAPALGO_RndChecker)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_And", C4VInt(MAPALGO_And)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Or", C4VInt(MAPALGO_Or)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Xor", C4VInt(MAPALGO_Xor)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Not", C4VInt(MAPALGO_Not)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Scale", C4VInt(MAPALGO_Scale)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Rotate", C4VInt(MAPALGO_Rotate)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Offset", C4VInt(MAPALGO_Offset)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Rect", C4VInt(MAPALGO_Rect)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Ellipsis", C4VInt(MAPALGO_Ellipsis)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Polygon", C4VInt(MAPALGO_Polygon)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Lines", C4VInt(MAPALGO_Lines)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Turbulence", C4VInt(MAPALGO_Turbulence)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Border", C4VInt(MAPALGO_Border)); + ::ScriptEngine.RegisterGlobalConstant("MAPALGO_Filter", C4VInt(MAPALGO_Filter)); + Reg2List(pEngine); + AddEngineFunctions(); +} + +void C4MapScriptHost::AddEngineFunctions() +{ + // adds all engine functions to the MapLayer context + ::AddFunc(this, "Draw", FnLayerDraw); + ::AddFunc(this, "Blit", FnLayerBlit); + ::AddFunc(this, "CreateLayer", FnCreateLayer); + ::AddFunc(this, "Duplicate", FnLayerDuplicate); + ::AddFunc(this, "GetPixel", FnLayerGetPixel); + ::AddFunc(this, "SetPixel", FnLayerSetPixel); + ::AddFunc(this, "GetPixelCount", FnLayerGetPixelCount); + ::AddFunc(this, "Resize", FnLayerResize); + ::AddFunc(this, "FindPosition", FnLayerFindPosition); + ::AddFunc(this, "CreateMatTexMask", FnLayerCreateMatTexMask); +} + +bool C4MapScriptHost::Load(C4Group & g, const char * f, const char * l, C4LangStringTable * t) +{ + assert(LayerPrototype && MapPrototype); + return C4ScriptHost::Load(g, f, l, t); +} + +void C4MapScriptHost::Clear() +{ + delete LayerPrototype; delete MapPrototype; + LayerPrototype = MapPrototype = NULL; + C4ScriptHost::Clear(); +} + +C4PropListStatic * C4MapScriptHost::GetPropList() +{ + // Scripts are compiled in the MapLayer context so it's possible to use all map drawing functions directly without "map->" prefix + return LayerPrototype; +} + +C4MapScriptMap *C4MapScriptHost::CreateMap() +{ + return new C4MapScriptMap(MapPrototype); +} + +bool C4MapScriptHost::InitializeMap(C4Group &group, CSurface8 **pmap_surface) +{ + // Init scripted map by calling InitializeMap in the proper scripts. If *pmap_surface is given, it will pass the existing map to be modified by script. + assert(pmap_surface); + // Don't bother creating surfaces if the functions aren't defined + if (!LayerPrototype->GetFunc(PSF_InitializeMap)) + { + C4PropList *scen_proplist = ::GameScript.ScenPropList._getPropList(); + if (!scen_proplist || !scen_proplist->GetFunc(PSF_InitializeMap)) return false; + } + // Create proplist as script context + std::unique_ptr map(CreateMap()); + // Drawing on existing map or create new? + if (*pmap_surface) + { + // Existing map + map->SetSurface(*pmap_surface); + } + else + { + // No existing map. Create new. + int32_t map_wdt,map_hgt; + ::Game.C4S.Landscape.GetMapSize(map_wdt, map_hgt, ::Game.StartupPlayerCount); + if (!map->CreateSurface(map_wdt, map_hgt)) return false; + } + C4AulParSet Pars(C4VPropList(map.get())); + C4Value result = map->Call(PSF_InitializeMap, &Pars); + if (!result) result = ::GameScript.Call(PSF_InitializeMap, &Pars); + // Map creation done. + if (result) + { + map->ConvertSkyToTransparent(); + *pmap_surface = map->ReleaseSurface(); + } + return !!result; +} + +C4MapScriptHost MapScript; \ No newline at end of file diff --git a/src/landscape/C4MapScript.h b/src/landscape/C4MapScript.h new file mode 100644 index 000000000..1b457b64f --- /dev/null +++ b/src/landscape/C4MapScript.h @@ -0,0 +1,339 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, 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. + */ + +/* Handles scripted map creation */ + +#ifndef INC_C4MapScript +#define INC_C4MapScript + +#include +#include +#include +#include +#include +#include + +// mattex masks: Array of bools for each possible material-texture index +class C4MapScriptMatTexMask +{ + std::vector mask; // vector of size 256: true means pixel color is let through; false means it is blocked + + void UnmaskSpec(C4String *spec); +public: + C4MapScriptMatTexMask() : mask(256,false) { } + C4MapScriptMatTexMask(const C4Value &spec) : mask(256,false) { Init(spec); } + void Init(const C4Value &spec); + + bool operator()(uint8_t mattex) const { return mask[mattex]; } +}; + +// algorithms may be either indicator functions (int,int)->bool that tell whether a map pixel should be +// set (to be used in C4MapScriptLayer::Fill) or functions (int,int)->int that tell which material should +// be set (to be used in Fill or C4MapScriptLayer::Blit). +class C4MapScriptAlgo +{ +protected: + bool GetXYProps(const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults); +public: + virtual uint8_t operator () (int32_t x, int32_t y) const = 0; + virtual ~C4MapScriptAlgo() {} +}; + +// List of possible algorithms. Also registered as script constants in void C4MapScriptHost::InitFunctionMap. +enum C4MapScriptAlgoType +{ + MAPALGO_None = 0, + + MAPALGO_Layer = 1, + + MAPALGO_RndChecker = 10, + + MAPALGO_Rect = 20, + MAPALGO_Ellipsis = 21, + MAPALGO_Polygon = 22, + MAPALGO_Lines = 23, + + MAPALGO_And = 30, + MAPALGO_Or = 31, + MAPALGO_Not = 32, + MAPALGO_Xor = 33, + + MAPALGO_Offset = 40, + MAPALGO_Scale = 41, + MAPALGO_Rotate = 42, + MAPALGO_Turbulence = 43, + + MAPALGO_Border = 50, + MAPALGO_Filter = 51, +}; + +// MAPALGO_Layer: Just query pixel in layer. Pixels outside the layer range are zero. +class C4MapScriptAlgoLayer : public C4MapScriptAlgo +{ + const class C4MapScriptLayer *layer; +public: + C4MapScriptAlgoLayer(const C4MapScriptLayer *layer) : layer(layer) {} + C4MapScriptAlgoLayer(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_RndChecker: checkerboard on which areas are randomly set or unset +class C4MapScriptAlgoRndChecker : public C4MapScriptAlgo +{ + int32_t seed, set_percentage, checker_wdt, checker_hgt; + bool is_fixed_offset; +public: + C4MapScriptAlgoRndChecker(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Rect: 1 for pixels contained in rect, 0 otherwise +class C4MapScriptAlgoRect : public C4MapScriptAlgo +{ + C4Rect rect; +public: + C4MapScriptAlgoRect(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Ellipsis: 1 for pixels within ellipsis, 0 otherwise +class C4MapScriptAlgoEllipsis : public C4MapScriptAlgo +{ + int32_t cx,cy; + int32_t wdt,hgt; +public: + C4MapScriptAlgoEllipsis(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Polygon: 1 for pixels within polygon or on border, 0 otherwise +class C4MapScriptAlgoPolygon : public C4MapScriptAlgo +{ + struct Pt { int32_t x,y; }; + std::vector poly; + int32_t wdt; + bool empty; // don't fill inside of polygon + bool open; // don't draw closing segment. only valid if empty=true +public: + C4MapScriptAlgoPolygon(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Lines: 1 for pixels on stripes in direction ("X","Y"). Stripe distance "Distance". Optional offset "OffX", "OffY" +class C4MapScriptAlgoLines : public C4MapScriptAlgo +{ + int32_t lx,ly,distance,ox,oy; + int64_t ll,dl; // (line width)^2 and distance * line width +public: + C4MapScriptAlgoLines(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// base class for algo that takes one or more operands +class C4MapScriptAlgoModifier : public C4MapScriptAlgo +{ +protected: + std::vector operands; +public: + C4MapScriptAlgoModifier(const C4PropList *props, int32_t min_ops=0, int32_t max_ops=0); + virtual ~C4MapScriptAlgoModifier() { Clear(); } + void Clear(); +}; + +// MAPALGO_And: 0 if any of the operands is 0. Otherwise, returns value of last operand. +class C4MapScriptAlgoAnd : public C4MapScriptAlgoModifier +{ +public: + C4MapScriptAlgoAnd(const C4PropList *props) : C4MapScriptAlgoModifier(props) { } + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Or: First nonzero operand +class C4MapScriptAlgoOr : public C4MapScriptAlgoModifier +{ +public: + C4MapScriptAlgoOr(const C4PropList *props) : C4MapScriptAlgoModifier(props) { } + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Not: 1 if operand is 0, 0 otherwise. +class C4MapScriptAlgoNot : public C4MapScriptAlgoModifier +{ +public: + C4MapScriptAlgoNot(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) { } + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Xor: If exactly one of the two operands is nonzero, return it. Otherwise, return zero. +class C4MapScriptAlgoXor : public C4MapScriptAlgoModifier +{ +public: + C4MapScriptAlgoXor(const C4PropList *props) : C4MapScriptAlgoModifier(props,2,2) { } + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Offset: Base layer shifted by ox,oy +class C4MapScriptAlgoOffset : public C4MapScriptAlgoModifier +{ + int32_t ox,oy; +public: + C4MapScriptAlgoOffset(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Scale: Base layer scaled by sx,sy percent from fixed point cx,cy +class C4MapScriptAlgoScale : public C4MapScriptAlgoModifier +{ + int32_t sx,sy,cx,cy; +public: + C4MapScriptAlgoScale(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Rotate: Base layer rotated by angle r around point ox,oy +class C4MapScriptAlgoRotate : public C4MapScriptAlgoModifier +{ + int32_t sr,cr,ox,oy; + enum {Precision=1000}; +public: + C4MapScriptAlgoRotate(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Turbulence: move by a random offset iterations times +class C4MapScriptAlgoTurbulence : public C4MapScriptAlgoModifier +{ + int32_t amp[2], scale[2], seed, iterations; +public: + C4MapScriptAlgoTurbulence(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Border: Border of operand layer +class C4MapScriptAlgoBorder : public C4MapScriptAlgoModifier +{ + int32_t left[2], top[2], right[2], bottom[2]; + void ResolveBorderProps(int32_t *p); +public: + C4MapScriptAlgoBorder(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// MAPALGO_Filter: Original color of operand if it's marked to go through filter. 0 otherwise. +class C4MapScriptAlgoFilter : public C4MapScriptAlgoModifier +{ + C4MapScriptMatTexMask filter; +public: + C4MapScriptAlgoFilter(const C4PropList *props); + + virtual uint8_t operator () (int32_t x, int32_t y) const; +}; + +// layer of a script-controlled map +// IFT can be used to mark Sky +class C4MapScriptLayer : public C4PropListNumbered +{ + CSurface8 *surface; + bool surface_owned; +protected: + class C4MapScriptMap *map; + +public: + C4MapScriptLayer(C4PropList *prototype, C4MapScriptMap *map); + virtual ~C4MapScriptLayer() { ClearSurface(); } + virtual C4MapScriptLayer * GetMapScriptLayer() { return this; } + class C4MapScriptMap *GetMap() { return map; } + + // Surface management + bool CreateSurface(int32_t wdt, int32_t hgt); + void ClearSurface(); + CSurface8 *ReleaseSurface() { surface_owned=false; return surface; } // return surface and mark it as not owned by self + void SetSurface(CSurface8 *s) { ClearSurface(); surface=s; UpdateSurfaceSize(); } + bool HasSurface() const { return surface && surface->Bits; } + + // Size management + void UpdateSurfaceSize(); // updates width and height properties by current surface + C4Rect GetBounds () const; + int32_t GetWdt() const { return surface ? surface->Wdt : 0; } + int32_t GetHgt() const { return surface ? surface->Hgt : 0; } + + // Pixel functions + uint8_t GetPix(int32_t x, int32_t y, uint8_t outside_col) const { return (!HasSurface()||x<0||y<0||x>=surface->Wdt||y>=surface->Hgt) ? outside_col : surface->_GetPix(x,y); } + bool SetPix(int32_t x, int32_t y, uint8_t col) const { if (!HasSurface()||x<0||y<0||x>=surface->Wdt||y>=surface->Hgt) return false; surface->_SetPix(x,y,col); return true; } + bool IsPixMasked(int32_t x, int32_t y) const { return GetPix(x,y,0)!=0; } // masking: If pixel is inside surface and not transparent + void ConvertSkyToTransparent(); // change all pixels that are IFT to 0 + int32_t GetPixCount(const C4Rect &rcBounds, const C4MapScriptMatTexMask &col_mask); // return number of pixels that match mask + + // Drawing functions + bool Fill(int col, const C4Rect &rcBounds, const C4MapScriptAlgo *algo); + bool Blit(const C4Rect &rcBounds, const C4MapScriptAlgo *algo); + bool Blit(const C4MapScriptLayer *src, const C4Rect &src_rect, const C4MapScriptMatTexMask &col_mask, int32_t tx, int32_t ty); + + // Search functions + bool FindPos(const C4Rect &search_rect, const C4MapScriptMatTexMask &col_mask, int32_t *out_x, int32_t *out_y, int32_t max_tries); +}; + +class C4MapScriptMap : public C4MapScriptLayer +{ + std::list layers; +public: + C4MapScriptMap(C4PropList *prototype) : C4MapScriptLayer(prototype, NULL) { map=this; } + ~C4MapScriptMap() { Clear(); } + void Clear(); + virtual C4MapScriptMap * GetMapScriptMap() { return this; } + + C4MapScriptLayer *CreateLayer(int32_t wdt, int32_t hgt); +}; + +// Script host for scenario Map.c, parsed in static MapLayer prop list context +// Also hosts engine functions MapLayer prop list. +class C4MapScriptHost : public C4ScriptHost +{ +private: + C4PropListStaticMember *LayerPrototype, *MapPrototype; + + C4MapScriptMap *CreateMap(); +public: + C4MapScriptHost(); + ~C4MapScriptHost(); + void InitFunctionMap(C4AulScriptEngine *pEngine); + virtual void AddEngineFunctions(); + virtual bool Load(C4Group &, const char *, const char *, C4LangStringTable *); + void Clear(); + virtual C4PropListStatic * GetPropList(); + bool InitializeMap(C4Group &group, CSurface8 **pmap_surface); + C4PropListStatic *GetLayerPrototype() { return LayerPrototype; } +}; + +extern C4MapScriptHost MapScript; + +#endif \ No newline at end of file diff --git a/src/landscape/C4MapScriptAlgo.cpp b/src/landscape/C4MapScriptAlgo.cpp new file mode 100644 index 000000000..7a0ebecf8 --- /dev/null +++ b/src/landscape/C4MapScriptAlgo.cpp @@ -0,0 +1,509 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, 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. + */ + +/* Handles scripted map creation */ + +#include +#include +#include + +C4MapScriptAlgo *FnParAlgo(C4PropList *algo_par); + +bool C4MapScriptAlgo::GetXYProps(const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults) +{ + // Evaluate property named "k" in proplist props to store two numbers in out_xy: + // If props->k is a single integer, fill both numbers in out_xy with it + // If props->k is an array, check that it contains two numbers and store them in out_xy + if (!props->HasProperty(&Strings.P[k])) + { + if (zero_defaults) out_xy[0] = out_xy[1] = 0; + return false; + } + C4Value val; C4ValueArray *arr; + props->GetProperty(k, &val); + if (arr = val.getArray()) + { + if (arr->GetSize() != 2) + throw new C4AulExecError(FormatString("C4MapScriptAlgo: Expected either integer or array with two integer elements in property \"%s\".", Strings.P[k].GetCStr()).getData()); + out_xy[0] = arr->GetItem(0).getInt(); + out_xy[1] = arr->GetItem(1).getInt(); + } + else + { + out_xy[0] = out_xy[1] = val.getInt(); + } + return true; +} + +C4MapScriptAlgoLayer::C4MapScriptAlgoLayer(const C4PropList *props) +{ + // Get MAPALGO_Layer properties + C4PropList *layer_pl = props->GetPropertyPropList(P_Layer); + if (!layer_pl || !(layer = layer_pl->GetMapScriptLayer())) + throw new C4AulExecError("C4MapScriptAlgoLayer: Expected layer in \"Layer\" property."); +} + +uint8_t C4MapScriptAlgoLayer::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Layer at x,y: Just query pixel in layer. Pixels outside the layer range are zero. + return layer->GetPix(x,y,0); +} + +C4MapScriptAlgoRndChecker::C4MapScriptAlgoRndChecker(const C4PropList *props) +{ + // Get MAPALGO_RndChecker properties + seed = props->GetPropertyInt(P_Seed); + if (!seed) seed = Random(65536); + set_percentage = BoundBy(props->GetPropertyInt(P_Ratio), 0, 100); + if (!set_percentage) set_percentage = 50; + checker_wdt = Abs(props->GetPropertyInt(P_Wdt)); + if (!checker_wdt) checker_wdt = 10; + checker_hgt = Abs(props->GetPropertyInt(P_Hgt)); + if (!checker_hgt) checker_hgt = 10; + C4Value is_fixed_offset_v; + if (props->GetProperty(P_FixedOffset, &is_fixed_offset_v)) + is_fixed_offset = is_fixed_offset_v.getBool(); + else + is_fixed_offset = false; +} + +// Division and modulo operators that always round downwards +// Both assuming b>0 +static int32_t divD(int32_t a, int32_t b) { return a/b-(a%b<0); } +static int32_t modD(int32_t a, int32_t b) { return (a>=0)?a%b:b-(-a)%b; } + +// Creates a field of random numbers between 0 and scale-1. Returns the value of the field at position x,y +// Function should be deterministic for the same value of x,y, but should look somewhat random wrt neighbouring values of x,y +int32_t QuerySeededRandomField(int32_t seed, int32_t x, int32_t y, int32_t scale) +{ + return modD((((seed ^ (x*214013))*214013) ^ (y*214013)), scale); +} + +uint8_t C4MapScriptAlgoRndChecker::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_RndChecker at x,y: Query a seeded random field scaled by checker_wdt,checker_hgt + if (!is_fixed_offset) { x+=seed%checker_wdt; y+=((seed*214013)%checker_hgt); } + x = divD(x, checker_wdt); y = divD(y, checker_hgt); + return QuerySeededRandomField(seed, x,y, 100) < set_percentage; +} + +C4MapScriptAlgoRect::C4MapScriptAlgoRect(const C4PropList *props) +{ + // Get MAPALGO_Rect properties + rect = C4Rect(props->GetPropertyInt(P_X), props->GetPropertyInt(P_Y), props->GetPropertyInt(P_Wdt), props->GetPropertyInt(P_Hgt)); +} + +uint8_t C4MapScriptAlgoRect::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Rect at x,y: Return 1 for pixels contained in rect, 0 otherwise + return rect.Contains(x, y); +} + +C4MapScriptAlgoEllipsis::C4MapScriptAlgoEllipsis(const C4PropList *props) +{ + // Get MAPALGO_Ellipsis properties + cx = props->GetPropertyInt(P_X); + cy = props->GetPropertyInt(P_Y); + wdt = Abs(props->GetPropertyInt(P_Wdt)); + hgt = Abs(props->GetPropertyInt(P_Hgt)); + if (!wdt) wdt = 10; + if (!hgt) hgt = wdt; +} + +uint8_t C4MapScriptAlgoEllipsis::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Ellipsis at x,y: Return 1 for pixels within ellipsis, 0 otherwise + // warning: overflows for large values (wdt or hgt >=256) + // but who would draw such large ellipsis anyway? + uint64_t dx = Abs((cx-x)*hgt), dy = Abs((cy-y)*wdt); + return dx*dx+dy*dy < uint64_t(wdt)*wdt*hgt*hgt; +} + +C4MapScriptAlgoPolygon::C4MapScriptAlgoPolygon(const C4PropList *props) +{ + // Get MAPALGO_Polygon properties + C4Value vptx, vpty; + props->GetProperty(P_X, &vptx); props->GetProperty(P_Y, &vpty); + C4ValueArray *ptx = vptx.getArray(), *pty = vpty.getArray(); + if (!ptx || !pty || ptx->GetSize() != pty->GetSize()) + throw new C4AulExecError("C4MapScriptAlgoPolygon: Expected two equally sized int arrays in properties \"X\" and \"Y\"."); + poly.resize(ptx->GetSize()); + for (int32_t i=0; iGetSize(); ++i) + { + poly[i].x = ptx->GetItem(i).getInt(); + poly[i].y = pty->GetItem(i).getInt(); + } + wdt = props->GetPropertyInt(P_Wdt); + if (!wdt) wdt = 1; + empty = !!props->GetPropertyInt(P_Empty); + open = !!props->GetPropertyInt(P_Open); + if (open && !empty) throw new C4AulExecError("C4MapScriptAlgoPolygon: Only empty polygons may be open."); +} + +uint8_t C4MapScriptAlgoPolygon::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Polygon at x,y: Return 1 for pixels within the polygon or its borders, 0 otherwise + int32_t crossings = 0; + for (size_t i=0; idy*pdx/pdy); + } + } + // x/y lies inside polygon + return (crossings % 2)==1; +} + +C4MapScriptAlgoLines::C4MapScriptAlgoLines(const C4PropList *props) +{ + // Get MAPALGO_Lines properties + lx = props->GetPropertyInt(P_X); + ly = props->GetPropertyInt(P_Y); + if (!lx && !ly) throw new C4AulExecError("C4MapScriptAlgoLines: Invalid direction vector. Either \"X\" or \"Y\" must be nonzero!"); + ox = props->GetPropertyInt(P_OffX); + oy = props->GetPropertyInt(P_OffY); + // use sync-safe distance function to calculate line width + int32_t l = Distance(0,0,lx,ly); + // default distance: double line width, so lines and gaps have same width + distance = props->GetPropertyInt(P_Distance); + if (!distance) distance = l+l; // 1+1=2 + // cache for calculation + ll = int64_t(lx)*lx+int64_t(ly)*ly; + dl = int64_t(distance) * l; +} + +uint8_t C4MapScriptAlgoLines::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Lines at x,y: Return 1 for pixels contained in lines, 0 for pixels between lines + int64_t ax = int64_t(x)-ox; + int64_t ay = int64_t(y)-oy; + int64_t line_pos = (ax*lx + ay*ly) % dl; + if (line_pos < 0) line_pos += dl; + return line_pos < ll; +} + +C4MapScriptAlgoModifier::C4MapScriptAlgoModifier(const C4PropList *props, int32_t min_ops, int32_t max_ops) +{ + // Evaluate "Op" property of all algos that take another algo or layer as an operand + // Op may be a proplist or an array of proplists + C4Value vops; int32_t n; C4ValueArray temp_ops; + props->GetProperty(P_Op, &vops); + C4ValueArray *ops = vops.getArray(); + if (!ops) + { + C4PropList *op = vops.getPropList(); + if (op) + { + temp_ops.SetItem(0, vops); + ops = &temp_ops; + n = 1; + } + } + else + { + n = ops->GetSize(); + } + if (!ops || nmax_ops)) + throw new C4AulExecError(FormatString("C4MapScriptAlgo: Expected between %d and %d operands in property \"Op\".", (int)min_ops, (int)max_ops).getData()); + operands.resize(n); + try + { + // can easily crash this by building a recursive prop list + // unfortunately, protecting against that is not trivial + for (int32_t i=0; iGetItem(i).getPropList()); + if (!new_algo) throw new C4AulExecError(FormatString("C4MapScriptAlgo: Operand %d in property \"Op\" not valid.", (int)min_ops, (int)max_ops).getData()); + operands[i] = new_algo; + } + } + catch (...) + { + Clear(); + throw; + } +} + +void C4MapScriptAlgoModifier::Clear() +{ + // Child algos are owned by this algo, so delete them + for (std::vector::iterator i=operands.begin(); i != operands.end(); ++i) delete *i; + operands.clear(); +} + +uint8_t C4MapScriptAlgoAnd::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_And at x,y: + // Return 0 if any of the operands is 0. Otherwise, returns value of last operand. + uint8_t val=0; + for (std::vector::const_iterator i=operands.begin(); i != operands.end(); ++i) + if (!(val=(**i)(x,y))) return false; + return val; +} + +uint8_t C4MapScriptAlgoOr::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Or at x,y: + // Return first nonzero operand + uint8_t val; + for (std::vector::const_iterator i=operands.begin(); i != operands.end(); ++i) + if (val=(**i)(x,y)) return val; + // If all operands are zero, return zero. + return 0; +} + +uint8_t C4MapScriptAlgoNot::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Not at x,y: + assert(operands.size()==1); + // Return zero if operand is set and one otherwise + return !(*operands[0])(x,y); +} + +uint8_t C4MapScriptAlgoXor::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Xor at x,y: + assert(operands.size()==2); + // If exactly one of the two operands is nonzero, return it. Otherwise, return zero. + uint8_t v1=(*operands[0])(x,y), v2=(*operands[1])(x,y); + return v1?v2 ?0: v1:v2; +} + +C4MapScriptAlgoOffset::C4MapScriptAlgoOffset(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) +{ + // Get MAPALGO_Offset properties + ox = props->GetPropertyInt(P_OffX); + oy = props->GetPropertyInt(P_OffY); +} + +uint8_t C4MapScriptAlgoOffset::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Offset at x,y: + assert(operands.size()==1); + // Return base layer shifted by ox,oy + return (*operands[0])(x-ox,y-oy); +} + +C4MapScriptAlgoScale::C4MapScriptAlgoScale(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) +{ + // Get MAPALGO_Scale properties + sx = props->GetPropertyInt(P_X); + sy = props->GetPropertyInt(P_Y); + if (!sx) sx=100; + if (!sy) sy=100; + cx = props->GetPropertyInt(P_OffX); + cy = props->GetPropertyInt(P_OffY); +} + +uint8_t C4MapScriptAlgoScale::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Scale at x,y: + assert(operands.size()==1); + // Return base layer scaled by sx,sy percent from fixed point cx,cy + return (*operands[0])((x-cx)*100/sx+cx,(y-cy)*100/sy+cy); +} + +C4MapScriptAlgoRotate::C4MapScriptAlgoRotate(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) +{ + // Get MAPALGO_Rotate properties + int32_t r = props->GetPropertyInt(P_R); + sr=fixtoi(Sin(itofix(r)), Precision); + cr=fixtoi(Cos(itofix(r)), Precision); + ox = props->GetPropertyInt(P_OffX); + oy = props->GetPropertyInt(P_OffY); +} + +uint8_t C4MapScriptAlgoRotate::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Rotate at x,y: + assert(operands.size()==1); + // Return base layer rotated by angle r around point ox,oy + x-=ox; y-=oy; + return (*operands[0])(x*cr/Precision-y*sr/Precision+ox,x*sr/Precision+y*cr/Precision+oy); +} + +C4MapScriptAlgoTurbulence::C4MapScriptAlgoTurbulence(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) +{ + // Get MAPALGO_Turbulence properties + seed = props->GetPropertyInt(P_Seed); + if (!seed) seed = Random(65536); + GetXYProps(props, P_Amplitude, amp, true); + GetXYProps(props, P_Scale, scale, true); + if (!scale[0]) scale[0] = 10; if (!scale[1]) scale[1] = 10; + if (!amp[0] && !amp[1]) { amp[0] = amp[1] = 10; } + iterations = props->GetPropertyInt(P_Iterations); + if (!iterations) iterations = 2; +} + +uint8_t C4MapScriptAlgoTurbulence::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Turbulence at x,y: + // move by a random offset iterations times + assert(operands.size()==1); + int32_t xy[] = {x, y}; + for (int32_t iter=0; iter0) inner=p[i]; else if (p[i]<0) outer=-p[i]; + p[0] = inner; p[1] = outer; +} + +C4MapScriptAlgoBorder::C4MapScriptAlgoBorder(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) +{ + // Get MAPALGO_Border properties + int32_t wdt[2] = {0,0}; + // Parameter Wdt fills all directions + int32_t n_borders = 0; + n_borders += GetXYProps(props, P_Wdt, wdt, false); + for (int32_t i=0; i<2; ++i) left[i]=top[i]=right[i]=bottom[i]=wdt[i]; + // Individual direction parameters + n_borders += GetXYProps(props, P_Left, left, false); + n_borders += GetXYProps(props, P_Top, top, false); + n_borders += GetXYProps(props, P_Right, right, false); + n_borders += GetXYProps(props, P_Bottom, bottom, false); + // Resolve negative/positive values to inner/outer borders + ResolveBorderProps(left); + ResolveBorderProps(top); + ResolveBorderProps(right); + ResolveBorderProps(bottom); + // If nothing was specified, fill all directions with a default: Draw 1px of outer border + if (!n_borders) + { + left[1] = top[1] = right[1] = bottom[1] = 1; + } +} + +uint8_t C4MapScriptAlgoBorder::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Border at x,y: Check if position is at a border of operand layer + // For borders inside operand layer, return the operand material. For outside borders, just return 1. For non-borders, return 0. + // Are we inside or outside? + const C4MapScriptAlgo &l = *operands[0]; + uint8_t mat = l(x,y); + bool inside = !!mat; + if (!mat) mat=1; // return 1 for outside borders + // Check four sideways directions + const int32_t *ymove[] = { top, bottom }, *xmove [] ={ left, right }; + const int32_t d[] = { -1, +1 }; + for (int32_t dir=0; dir<2; ++dir) + { + int32_t hgt = ymove[inside!=!dir][!inside]; + for (int32_t dy=0; dyGetProperty(P_Filter, &spec)) + throw new C4AulExecError("MapScriptAlgoFilter without Filter property."); + filter.Init(spec); +} + +uint8_t C4MapScriptAlgoFilter::operator () (int32_t x, int32_t y) const +{ + // Evaluate MAPALGO_Filter at x,y: + // Return original color if it's marked to go through filter + uint8_t col = (*operands[0])(x,y); + return filter(col) ? col : 0; +} + +C4MapScriptAlgo *FnParAlgo(C4PropList *algo_par) +{ + // Convert script function parameter to internal C4MapScriptAlgo class. Also resolve all parameters and nested child algos. + if (!algo_par) return NULL; + // if algo is a layer, take that directly + C4MapScriptLayer *algo_layer = algo_par->GetMapScriptLayer(); + if (algo_layer) return new C4MapScriptAlgoLayer(algo_layer); + // otherwise, determine by proplist parameter "algo" + switch (algo_par->GetPropertyInt(P_Algo)) + { + case MAPALGO_Layer: return new C4MapScriptAlgoLayer(algo_par); + case MAPALGO_RndChecker: return new C4MapScriptAlgoRndChecker(algo_par); + case MAPALGO_And: return new C4MapScriptAlgoAnd(algo_par); + case MAPALGO_Or: return new C4MapScriptAlgoOr(algo_par); + case MAPALGO_Xor: return new C4MapScriptAlgoXor(algo_par); + case MAPALGO_Not: return new C4MapScriptAlgoNot(algo_par); + case MAPALGO_Offset: return new C4MapScriptAlgoOffset(algo_par); + case MAPALGO_Scale: return new C4MapScriptAlgoScale(algo_par); + case MAPALGO_Rotate: return new C4MapScriptAlgoRotate(algo_par); + case MAPALGO_Rect: return new C4MapScriptAlgoRect(algo_par); + case MAPALGO_Ellipsis: return new C4MapScriptAlgoEllipsis(algo_par); + case MAPALGO_Polygon: return new C4MapScriptAlgoPolygon(algo_par); + case MAPALGO_Lines: return new C4MapScriptAlgoLines(algo_par); + case MAPALGO_Turbulence: return new C4MapScriptAlgoTurbulence(algo_par); + case MAPALGO_Border: return new C4MapScriptAlgoBorder(algo_par); + case MAPALGO_Filter: return new C4MapScriptAlgoFilter(algo_par); + default: + throw new C4AulExecError(FormatString("got invalid algo: %d", algo_par->GetPropertyInt(P_Algo)).getData()); + } + return NULL; +} diff --git a/src/game/landscape/C4MassMover.cpp b/src/landscape/C4MassMover.cpp similarity index 85% rename from src/game/landscape/C4MassMover.cpp rename to src/landscape/C4MassMover.cpp index f376df84b..0d183723e 100644 --- a/src/game/landscape/C4MassMover.cpp +++ b/src/landscape/C4MassMover.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005-2006 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005-2006, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Move liquids in the landscape using individual transport spots */ @@ -75,11 +71,12 @@ void C4MassMoverSet::Execute() bool C4MassMoverSet::Create(int32_t x, int32_t y, bool fExecute) { if (Count == C4MassMoverChunk) return false; -#ifdef DEBUGREC - C4RCMassMover rc; - rc.x=x; rc.y=y; - AddDbgRec(RCT_MMC, &rc, sizeof(rc)); -#endif + if (Config.General.DebugRec) + { + C4RCMassMover rc; + rc.x=x; rc.y=y; + AddDbgRec(RCT_MMC, &rc, sizeof(rc)); + } int32_t cptr=CreatePtr; do { @@ -118,11 +115,12 @@ bool C4MassMover::Init(int32_t tx, int32_t ty) void C4MassMover::Cease() { -#ifdef DEBUGREC - C4RCMassMover rc; - rc.x=x; rc.y=y; - AddDbgRec(RCT_MMD, &rc, sizeof(rc)); -#endif + if (Config.General.DebugRec) + { + C4RCMassMover rc; + rc.x=x; rc.y=y; + AddDbgRec(RCT_MMD, &rc, sizeof(rc)); + } ::MassMover.Count--; Mat=MNone; } @@ -164,7 +162,7 @@ bool C4MassMover::Execute() if (Random(10)) ::Landscape.InsertDeadMaterial(mat, tx, ty); else - ::Landscape.InsertMaterial(mat, tx, ty, 0, 1); + ::Landscape.InsertMaterial(mat, &tx, &ty, 0, 1); // modifies tx/ty to actual insertion position // Create new mover at target ::MassMover.Create(tx,ty,!Random(3)); diff --git a/src/game/landscape/C4MassMover.h b/src/landscape/C4MassMover.h similarity index 60% rename from src/game/landscape/C4MassMover.h rename to src/landscape/C4MassMover.h index a2158dd32..34b0acbfc 100644 --- a/src/game/landscape/C4MassMover.h +++ b/src/landscape/C4MassMover.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Move liquids in the landscape using individual transport spots */ @@ -25,9 +22,6 @@ const int32_t C4MassMoverChunk = 10000; -class C4Group; -class C4MassMoverSet; - class C4MassMover { friend class C4MassMoverSet; diff --git a/src/game/landscape/C4Material.cpp b/src/landscape/C4Material.cpp similarity index 92% rename from src/game/landscape/C4Material.cpp rename to src/landscape/C4Material.cpp index 0634f7eaa..bd502f0e8 100644 --- a/src/game/landscape/C4Material.cpp +++ b/src/landscape/C4Material.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001-2002, 2005-2007, 2011 Sven Eberhardt - * Copyright (c) 2006-2007 Peter Wortmann - * Copyright (c) 2006-2007, 2009 Günther Brammer - * Copyright (c) 2010-2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Material definitions used by the landscape */ @@ -34,8 +29,7 @@ #include #include #include -#include -#include +#include #include #include // For GravAccel @@ -66,18 +60,18 @@ void C4MaterialReaction::CompileFunc(StdCompiler *pComp) StdStrBuf sReactionFuncName; int32_t i=0; while (ReactionFuncMap[i].szRFName && (ReactionFuncMap[i].pFunc != pFunc)) ++i; sReactionFuncName = ReactionFuncMap[i].szRFName; - pComp->Value(mkNamingAdapt(sReactionFuncName, "Type", StdStrBuf() )); + pComp->Value(mkNamingAdapt(mkParAdapt(sReactionFuncName, StdCompiler::RCT_IdtfAllowEmpty), "Type", StdCopyStrBuf() )); i=0; while (ReactionFuncMap[i].szRFName && !SEqual(ReactionFuncMap[i].szRFName, sReactionFuncName.getData())) ++i; pFunc = ReactionFuncMap[i].pFunc; // compile the rest - pComp->Value(mkNamingAdapt(TargetSpec, "TargetSpec", StdCopyStrBuf() )); - pComp->Value(mkNamingAdapt(ScriptFunc, "ScriptFunc", StdCopyStrBuf() )); + pComp->Value(mkNamingAdapt(mkParAdapt(TargetSpec, StdCompiler::RCT_All), "TargetSpec", StdCopyStrBuf() )); + pComp->Value(mkNamingAdapt(mkParAdapt(ScriptFunc, StdCompiler::RCT_IdtfAllowEmpty), "ScriptFunc", StdCopyStrBuf() )); pComp->Value(mkNamingAdapt(iExecMask, "ExecMask", ~0u )); pComp->Value(mkNamingAdapt(fReverse, "Reverse", false )); pComp->Value(mkNamingAdapt(fInverseSpec, "InverseSpec", false )); pComp->Value(mkNamingAdapt(fInsertionCheck, "CheckSlide", true )); pComp->Value(mkNamingAdapt(iDepth, "Depth", 0 )); - pComp->Value(mkNamingAdapt(sConvertMat, "ConvertMat", StdCopyStrBuf() )); + pComp->Value(mkNamingAdapt(mkParAdapt(sConvertMat, StdCompiler::RCT_IdtfAllowEmpty), "ConvertMat", StdCopyStrBuf() )); pComp->Value(mkNamingAdapt(iCorrosionRate, "CorrosionRate", 100 )); } @@ -483,7 +477,7 @@ int32_t C4MaterialMap::Get(const char *szMaterial) } -bool C4MaterialMap::CrossMapMaterials() // Called after load +bool C4MaterialMap::CrossMapMaterials(const char* szEarthMaterial) // Called after load { // Check material number if (::MaterialMap.Num>C4MaxMaterial) @@ -502,8 +496,8 @@ bool C4MaterialMap::CrossMapMaterials() // Called after load // natural stuff: material conversion here? if (pMatPXS && pMatPXS->sInMatConvert.getLength() && SEqualNoCase(pMatPXS->sInMatConvert.getData(), pMatLS ? pMatLS->Name : C4TLS_MatSky)) pReaction = &DefReactConvert; - // the rest is happening for same/higher densities only - else if ((MatDensity(iMatPXS) <= MatDensity(iMatLS)) && pMatPXS && pMatLS) + // non-sky reactions + else if (pMatPXS && pMatLS) { // incindiary vs extinguisher if ((pMatPXS->Incindiary && pMatLS->Extinguisher) || (pMatPXS->Extinguisher && pMatLS->Incindiary)) @@ -514,8 +508,11 @@ bool C4MaterialMap::CrossMapMaterials() // Called after load // corrosive vs corrode else if (pMatPXS->Corrosive && pMatLS->Corrode) pReaction = &DefReactCorrode; - // otherwise, when hitting same or higher density: Material insertion - else + // liquid hitting liquid or solid: Material insertion + else if (DensityLiquid(MatDensity(iMatPXS)) && DensitySemiSolid(MatDensity(iMatLS))) + pReaction = &DefReactInsert; + // solid hitting solid: Material insertion + else if (DensitySolid(MatDensity(iMatPXS)) && DensitySolid(MatDensity(iMatLS))) pReaction = &DefReactInsert; } // assign the function; or NULL for no reaction @@ -675,10 +672,11 @@ bool C4MaterialMap::CrossMapMaterials() // Called after load if (ppReactionMap[(cnt2+1)*(Num+1) + cnt+1]) printf("%s -> %s: %p\n", Map[cnt].Name, Map[cnt2].Name, ppReactionMap[(cnt2+1)*(Num+1) + cnt+1]->pFunc); #endif + // Get hardcoded system material indices - const C4TexMapEntry* earth_entry = ::TextureMap.GetEntry(::TextureMap.GetIndexMatTex(Game.C4S.Landscape.Material)); + const C4TexMapEntry* earth_entry = ::TextureMap.GetEntry(::TextureMap.GetIndexMatTex(szEarthMaterial)); if(!earth_entry) - { LogFatal(FormatString("Earth material \"%s\" not found!", Game.C4S.Landscape.Material).getData()); return false; } + { LogFatal(FormatString("Earth material \"%s\" not found!", szEarthMaterial).getData()); return false; } MVehic = Get("Vehicle"); MCVehic = Mat2PixColDefault(MVehic); MTunnel = Get("Tunnel"); @@ -687,6 +685,7 @@ bool C4MaterialMap::CrossMapMaterials() // Called after load if ((MVehic==MNone) || (MTunnel==MNone)) { LogFatal(LoadResStr("IDS_PRC_NOSYSMATS")); return false; } + return true; } @@ -804,11 +803,14 @@ bool mrfInsertCheck(int32_t &iX, int32_t &iY, C4Real &fXDir, C4Real &fYDir, int3 // Incindiary mats smoke on contact even before doing their slide if (::MaterialMap.Map[iPxsMat].Incindiary) - if (!Random(25)) Smoke(iX, iY, 4+Random(3) ); + if (!Random(25)) + { + Smoke(iX, iY, 4 + Random(3)); + } // Move by mat path/slide int32_t iSlideX = iX, iSlideY = iY; - if (::Landscape.FindMatSlide(iSlideX,iSlideY,Sign(GravAccel),::MaterialMap.Map[iPxsMat].Density,::MaterialMap.Map[iPxsMat].MaxSlide)) + if (::Landscape.FindMatSlide(iSlideX,iSlideY,Sign(GravAccel),Min(::MaterialMap.Map[iPxsMat].Density, C4M_Solid),::MaterialMap.Map[iPxsMat].MaxSlide)) { if (iPxsMat == iLsMat) { iX = iSlideX; iY = iSlideY; fXDir = 0; return false; } @@ -916,16 +918,19 @@ bool C4MaterialMap::mrfCorrode(C4MaterialReaction *pReaction, int32_t &iX, int32 case meeMassMove: // MassMover-movement { // evaluate corrosion percentage - bool fDoCorrode; + bool fDoCorrode; int d100 = Random(100); if (pReaction->fUserDefined) - fDoCorrode = (Random(100) < pReaction->iCorrosionRate); + fDoCorrode = (d100 < pReaction->iCorrosionRate); else - fDoCorrode = (Random(100) < ::MaterialMap.Map[iPxsMat].Corrosive) && (Random(100) < ::MaterialMap.Map[iLsMat].Corrode); + fDoCorrode = (d100 < ::MaterialMap.Map[iPxsMat].Corrosive) && (d100 < ::MaterialMap.Map[iLsMat].Corrode); if (fDoCorrode) { ClearBackPix(iLSPosX,iLSPosY); //::Landscape.CheckInstabilityRange(iLSPosX,iLSPosY); - more correct, but makes acid too effective as well - if (!Random(5)) Smoke(iX,iY,3+Random(3)); + if (!Random(5)) + { + Smoke(iX, iY, 3 + Random(3)); + } if (!Random(20)) StartSoundEffectAt("Corrode", iX, iY); return true; } @@ -940,21 +945,24 @@ bool C4MaterialMap::mrfCorrode(C4MaterialReaction *pReaction, int32_t &iX, int32 // either splash or slide prevented interaction return false; // evaluate corrosion percentage - bool fDoCorrode; + bool fDoCorrode; int d100 = Random(100); if (pReaction->fUserDefined) - fDoCorrode = (Random(100) < pReaction->iCorrosionRate); + fDoCorrode = (d100 < pReaction->iCorrosionRate); else - fDoCorrode = (Random(100) < ::MaterialMap.Map[iPxsMat].Corrosive) && (Random(100) < ::MaterialMap.Map[iLsMat].Corrode); + fDoCorrode = (d100 < ::MaterialMap.Map[iPxsMat].Corrosive) && (d100 < ::MaterialMap.Map[iLsMat].Corrode); if (fDoCorrode) { ClearBackPix(iLSPosX,iLSPosY); ::Landscape.CheckInstabilityRange(iLSPosX,iLSPosY); - if (!Random(5)) Smoke(iX,iY,3+Random(3)); + if (!Random(5)) + { + Smoke(iX,iY,3+Random(3)); + } if (!Random(20)) StartSoundEffectAt("Corrode", iX, iY); return true; } // Else: dead. Insert material here - ::Landscape.InsertMaterial(iPxsMat,iX,iY); + ::Landscape.InsertMaterial(iPxsMat,&iX,&iY); return true; } } @@ -981,7 +989,7 @@ bool C4MaterialMap::mrfIncinerate(C4MaterialReaction *pReaction, int32_t &iX, in // evaluate inflammation (should always succeed) if (::Landscape.Incinerate(iX, iY)) return true; // Else: dead. Insert material here - ::Landscape.InsertMaterial(iPxsMat,iX,iY); + ::Landscape.InsertMaterial(iPxsMat,&iX,&iY); return true; } // not handled @@ -1004,7 +1012,7 @@ bool C4MaterialMap::mrfInsert(C4MaterialReaction *pReaction, int32_t &iX, int32_ // continue existing return false; // Else: dead. Insert material here - ::Landscape.InsertMaterial(iPxsMat,iX,iY); + ::Landscape.InsertMaterial(iPxsMat,&iX,&iY); return true; } @@ -1061,26 +1069,4 @@ C4MaterialShape *C4MaterialMap::GetShapeByName(const char *name) return &(i->second); } - -int32_t PixCol2MatOld(BYTE pixc) -{ - const int C4M_ColsPerMat = 3; - if (pixc < GBM) return MNone; - pixc &= 63; // Substract GBM, ignore IFT - if (pixc > ::MaterialMap.Num*C4M_ColsPerMat-1) return MNone; - return pixc / C4M_ColsPerMat; -} - -int32_t PixCol2MatOld2(BYTE pixc) -{ - int32_t iMat = ((int32_t) (pixc&0x7f)) -1; - // if above MVehic, don't forget additional vehicle-colors - if (iMat<=MVehic) return iMat; - // equals middle vehicle-color - if (iMat==MVehic+1) return MVehic; - // above: range check - iMat-=2; if (iMat >= ::MaterialMap.Num) return MNone; - return iMat; -} - C4MaterialMap MaterialMap; diff --git a/src/game/landscape/C4Material.h b/src/landscape/C4Material.h similarity index 92% rename from src/game/landscape/C4Material.h rename to src/landscape/C4Material.h index 26200c085..45e60febb 100644 --- a/src/game/landscape/C4Material.h +++ b/src/landscape/C4Material.h @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001-2002, 2005-2007, 2011 Sven Eberhardt - * Copyright (c) 2005, 2007 Peter Wortmann - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2011 Tobias Zwick - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Material definitions used by the landscape */ @@ -32,8 +26,6 @@ #include #include -class C4AulFunc; - #define C4MatOv_Default 0 #define C4MatOv_Exact 1 #define C4MatOv_None 2 @@ -249,7 +241,7 @@ public: } C4MaterialReaction *GetReaction(int32_t iPXSMat, int32_t iLandscapeMat); void UpdateScriptPointers(); // set all material script pointers - bool CrossMapMaterials(); + bool CrossMapMaterials(const char* szEarthMaterial); C4MaterialShape *GetShapeByName(const char *name); protected: void SetMatReaction(int32_t iPXSMat, int32_t iLSMat, C4MaterialReaction *pReact); @@ -308,7 +300,4 @@ inline int32_t MatDigFree(int32_t mat) return ::MaterialMap.Map[mat].DigFree; } -int32_t PixCol2MatOld(BYTE pixc); -int32_t PixCol2MatOld2(BYTE pixc); - #endif diff --git a/src/game/landscape/C4MaterialList.cpp b/src/landscape/C4MaterialList.cpp similarity index 63% rename from src/game/landscape/C4MaterialList.cpp rename to src/landscape/C4MaterialList.cpp index 1edc3632a..e86897c75 100644 --- a/src/game/landscape/C4MaterialList.cpp +++ b/src/landscape/C4MaterialList.cpp @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A primitive list to store one amount value per mapped material */ diff --git a/src/game/landscape/C4MaterialList.h b/src/landscape/C4MaterialList.h similarity index 51% rename from src/game/landscape/C4MaterialList.h rename to src/landscape/C4MaterialList.h index 695580a8d..7775f1312 100644 --- a/src/game/landscape/C4MaterialList.h +++ b/src/landscape/C4MaterialList.h @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A primitive list to store one amount value per mapped material */ diff --git a/src/game/landscape/C4PXS.cpp b/src/landscape/C4PXS.cpp similarity index 90% rename from src/game/landscape/C4PXS.cpp rename to src/landscape/C4PXS.cpp index 6646cdddf..fadab3260 100644 --- a/src/game/landscape/C4PXS.cpp +++ b/src/landscape/C4PXS.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001-2002, 2005, 2007 Peter Wortmann - * Copyright (c) 2002, 2004-2006 Sven Eberhardt - * Copyright (c) 2006-2007, 2009 Günther Brammer - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Pixel Sprite system for tiny bits of moving material */ @@ -38,6 +33,7 @@ static const C4Real WindDrift_Factor = itofix(1, 800); void C4PXS::Execute() { #ifdef DEBUGREC_PXS + if (Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; @@ -127,6 +123,7 @@ void C4PXS::Execute() // No contact? Free movement x=ctcox; y=ctcoy; #ifdef DEBUGREC_PXS + if (Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; @@ -140,10 +137,13 @@ void C4PXS::Execute() void C4PXS::Deactivate() { #ifdef DEBUGREC_PXS - C4RCExecPXS rc; - rc.x=x; rc.y=y; rc.iMat=Mat; - rc.pos = 2; - AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); + if (Config.General.DebugRec) + { + C4RCExecPXS rc; + rc.x=x; rc.y=y; rc.iMat=Mat; + rc.pos = 2; + AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); + } #endif Mat=MNone; ::PXS.Delete(this); @@ -247,12 +247,6 @@ void C4PXSSystem::Draw(C4TargetFacet &cgo) C4Rect VisibleRect(cgo.TargetX, cgo.TargetY, cgo.Wdt, cgo.Hgt); VisibleRect.Enlarge(20); - // Lock primary surface -#ifdef USE_DIRECTX - if (pD3D) - cgo.Surface->Lock(); -#endif - // First pass: draw simple PXS (lines/pixels) float cgox = cgo.X - cgo.TargetX, cgoy = cgo.Y - cgo.TargetY; unsigned int cnt; @@ -284,12 +278,6 @@ void C4PXSSystem::Draw(C4TargetFacet &cgo) } } - // Unlock primary surface -#ifdef USE_DIRECTX - if (pD3D) - cgo.Surface->Unlock(); -#endif - // PXS graphics disabled? if (!Config.Graphics.PXSGfx) return; @@ -325,10 +313,16 @@ void C4PXSSystem::Cast(int32_t mat, int32_t num, int32_t tx, int32_t ty, int32_t { int32_t cnt; for (cnt=0; cnt +#include + +// headers for particle loading +#include +#include +#include + +#ifndef USE_CONSOLE +// headers for particle excution +#include +#include +#include +#include +#include +#include +#include +#include +#endif + + +void C4ParticleDefCore::CompileFunc(StdCompiler * pComp) +{ + pComp->Value(mkNamingAdapt(toC4CStrBuf(Name), "Name", "")); + pComp->Value(mkNamingAdapt(GfxFace, "Face")); +} + +C4ParticleDefCore::C4ParticleDefCore() +{ + GfxFace.Default(); +} + +bool C4ParticleDefCore::Compile(char *particle_source, const char *name) +{ + return CompileFromBuf_LogWarn(mkNamingAdapt(*this, "Particle"), + StdStrBuf(particle_source), name); +} + +C4ParticleDef::C4ParticleDef() : C4ParticleDefCore() +{ + // zero fields + Gfx.Default(); + // link into list + if (!Particles.definitions.first) + { + previous = NULL; + Particles.definitions.first = this; + } + else + { + previous = Particles.definitions.last; + previous->next = this; + } + Particles.definitions.last = this; + next = 0; +} + +C4ParticleDef::~C4ParticleDef() +{ + // clear + Clear(); + // unlink from list + if (previous) previous->next = next; else Particles.definitions.first = next; + if (next) next->previous = previous; else Particles.definitions.last = previous; +} + +void C4ParticleDef::Clear() +{ + Name.Clear(); +} + +bool C4ParticleDef::Load(C4Group &group) +{ + // store file + Filename.Copy(group.GetFullName()); + // load + char *particle_source; + if (group.LoadEntry(C4CFN_ParticleCore,&particle_source,NULL,1)) + { + if (!Compile(particle_source, Filename.getData())) + { + DebugLogF("invalid particle def at '%s'", group.GetFullName().getData()); + delete [] particle_source; return false; + } + delete [] particle_source; + // load graphics + if (!Gfx.Load(group, C4CFN_DefGraphics)) + { + DebugLogF("particle %s has no valid graphics defined", Name.getData()); + return false; + } + // set facet, if assigned - otherwise, assume full surface + if (GfxFace.Wdt) Gfx.Set(Gfx.Surface, GfxFace.x, GfxFace.y, GfxFace.Wdt, GfxFace.Hgt); + // set phase num + int32_t Q; Gfx.GetPhaseNum(PhasesX, Q); + Length = PhasesX * Q; + if (!Length) + { + DebugLogF("invalid facet for particle '%s'", Name.getData()); + return false; + } + // calc aspect + Aspect=(float) Gfx.Hgt/Gfx.Wdt; + + // particle overloading + C4ParticleDef *def_overload; + if ((def_overload = Particles.definitions.GetDef(Name.getData(), this))) + { + if (Config.Graphics.VerboseObjectLoading >= 1) + { char ostr[250]; sprintf(ostr,LoadResStr("IDS_PRC_DEFOVERLOAD"),def_overload->Name.getData(),""); Log(ostr); } + delete def_overload; + } + // success + return true; + } + return false; +} + +bool C4ParticleDef::Reload() +{ + // no file? + if (!Filename[0]) return false; + // open group + C4Group group; + if (!group.Open(Filename.getData())) return false; + // reset class + Clear(); + // load + return Load(group); +} + +#ifndef USE_CONSOLE +const int C4Particle::DrawingData::vertexCountPerParticle(4); + +void C4Particle::DrawingData::SetPosition(float x, float y, float size, float rotation, float stretch) +{ + if (size != originalSize || stretch != currentStretch) + { + currentStretch = stretch; + originalSize = std::max(size, 0.0001f); // a size of zero results in undefined behavior + sizeX = originalSize / aspect; + sizeY = originalSize * currentStretch; + } + + if (rotation == 0.f) + { + vertices[0].x = x - sizeX + offsetX; + vertices[0].y = y + sizeY + offsetY; + vertices[1].x = x - sizeX + offsetX; + vertices[1].y = y - sizeY + offsetY; + vertices[2].x = x + sizeX + offsetX; + vertices[2].y = y + sizeY + offsetY; + vertices[3].x = x + sizeX + offsetX; + vertices[3].y = y - sizeY + offsetY; + } + else + { + float sine = sinf(rotation); + float cosine = cosf(rotation); + + vertices[0].x = x + ((-sizeX) * cosine - (+sizeY) * sine) + offsetX; + vertices[0].y = y + ((-sizeX) * sine + (+sizeY) * cosine) + offsetY; + vertices[1].x = x + ((-sizeX) * cosine - (-sizeY) * sine) + offsetX; + vertices[1].y = y + ((-sizeX) * sine + (-sizeY) * cosine) + offsetY; + vertices[2].x = x + ((+sizeX) * cosine - (+sizeY) * sine) + offsetX; + vertices[2].y = y + ((+sizeX) * sine + (+sizeY) * cosine) + offsetY; + vertices[3].x = x + ((+sizeX) * cosine - (-sizeY) * sine) + offsetX; + vertices[3].y = y + ((+sizeX) * sine + (-sizeY) * cosine) + offsetY; + } +} + +void C4Particle::DrawingData::SetPhase(int phase, C4ParticleDef *sourceDef) +{ + this->phase = phase; + phase = phase % sourceDef->Length; + int offsetY = phase / sourceDef->PhasesX; + int offsetX = phase % sourceDef->PhasesX; + float wdt = 1.0f / (float)sourceDef->PhasesX; + int numOfLines = sourceDef->Length / sourceDef->PhasesX; + float hgt = 1.0f / (float)numOfLines; + + float x = wdt * (float)offsetX; + float y = hgt * (float)offsetY; + float xr = x + wdt; + float yr = y + hgt; + + vertices[0].u = x; vertices[0].v = yr; + vertices[1].u = x; vertices[1].v = y; + vertices[2].u = xr; vertices[2].v = yr; + vertices[3].u = xr; vertices[3].v = y; +} + +C4ParticleValueProvider & C4ParticleValueProvider::operator= (const C4ParticleValueProvider &other) +{ + startValue = other.startValue; + endValue = other.endValue; + currentValue = other.currentValue; + rerollInterval = other.rerollInterval; + smoothing = other.smoothing; + valueFunction = other.valueFunction; + isConstant = other.isConstant; + keyFrameCount = other.keyFrameCount; + + if (keyFrameCount > 0) + { + keyFrames.reserve(2 * keyFrameCount); + keyFrames.assign(other.keyFrames.begin(), other.keyFrames.end()); + } + + typeOfValueToChange = other.typeOfValueToChange; + switch (typeOfValueToChange) + { + case VAL_TYPE_FLOAT: + floatValueToChange = other.floatValueToChange; + break; + case VAL_TYPE_INT: + intValueToChange = other.intValueToChange; + break; + case VAL_TYPE_KEYFRAMES: + keyFrameIndex = other.keyFrameIndex; + break; + default: + assert (false && "Trying to copy C4ParticleValueProvider with invalid value type"); + break; + } + + // copy the other's children, too + for (std::vector::const_iterator iter = other.childrenValueProviders.begin(); iter != other.childrenValueProviders.end(); ++iter) + { + childrenValueProviders.push_back(new C4ParticleValueProvider(**iter)); // custom copy constructor usage + } + return (*this); +} + +void C4ParticleValueProvider::SetParameterValue(int type, const C4Value &value, float C4ParticleValueProvider::*floatVal, int C4ParticleValueProvider::*intVal, size_t keyFrameIndex) +{ + // just an atomic data type + if (value.GetType() == C4V_Int) + { + if (type == VAL_TYPE_FLOAT) + this->*floatVal = (float)value.getInt(); + else if (type == VAL_TYPE_INT) + this->*intVal = value.getInt(); + else if (type == VAL_TYPE_KEYFRAMES) + this->keyFrames[keyFrameIndex] = (float)value.getInt(); + } + else if (value.GetType() == C4V_Array) + { + // might be another value provider! + C4ParticleValueProvider *child = new C4ParticleValueProvider(); + childrenValueProviders.push_back(child); + + child->Set(*value.getArray()); + child->typeOfValueToChange = type; + + if (type == VAL_TYPE_FLOAT) + { + child->floatValueToChange = floatVal; + } + else if (type == VAL_TYPE_INT) + { + child->intValueToChange = intVal; + } + else if (type == VAL_TYPE_KEYFRAMES) + { + child->keyFrameIndex = keyFrameIndex; + } + + } + else // invalid + { + if (type == VAL_TYPE_FLOAT) + this->*floatVal = 0.f; + else if (type == VAL_TYPE_INT) + this->*intVal = 0; + else if (type == VAL_TYPE_KEYFRAMES) + this->keyFrames[keyFrameIndex] = 0.f; + } +} + +void C4ParticleValueProvider::UpdatePointerValue(C4Particle *particle, C4ParticleValueProvider *parent) +{ + switch (typeOfValueToChange) + { + case VAL_TYPE_FLOAT: + parent->*floatValueToChange = GetValue(particle); + break; + case VAL_TYPE_INT: + parent->*intValueToChange = (int) GetValue(particle); + break; + case VAL_TYPE_KEYFRAMES: + parent->keyFrames[keyFrameIndex] = GetValue(particle); + break; + default: + assert (false); + } +} + +void C4ParticleValueProvider::UpdateChildren(C4Particle *particle) +{ + for (std::vector::iterator iter = childrenValueProviders.begin(); iter != childrenValueProviders.end(); ++iter) + { + (*iter)->UpdatePointerValue(particle, this); + } +} + +void C4ParticleValueProvider::FloatifyParameterValue(float C4ParticleValueProvider::*value, float denominator, size_t keyFrameIndex) +{ + if (value == 0) + this->keyFrames[keyFrameIndex] /= denominator; + else + this->*value /= denominator; + + for (std::vector::iterator iter = childrenValueProviders.begin(); iter != childrenValueProviders.end(); ++iter) + { + C4ParticleValueProvider *child = *iter; + if (value == 0) + { + if (child->typeOfValueToChange == VAL_TYPE_KEYFRAMES && child->keyFrameIndex == keyFrameIndex) + child->Floatify(denominator); + } + else + { + if (child->floatValueToChange == value) + child->Floatify(denominator); + } + } + +} + +void C4ParticleValueProvider::Floatify(float denominator) +{ + assert (denominator != 0.f && "Trying to floatify C4ParticleValueProvider with denominator of 0"); + + if (valueFunction == &C4ParticleValueProvider::Direction) + { + FloatifyParameterValue(&C4ParticleValueProvider::startValue, 1000.f); + return; + } + + FloatifyParameterValue(&C4ParticleValueProvider::startValue, denominator); + FloatifyParameterValue(&C4ParticleValueProvider::endValue, denominator); + FloatifyParameterValue(&C4ParticleValueProvider::currentValue, denominator); + + // special treatment for keyframes + if (valueFunction == &C4ParticleValueProvider::KeyFrames) + { + for (size_t i = 0; i < keyFrameCount; ++i) + { + FloatifyParameterValue(0, 1000.f, 2 * i); // even numbers are the time values + FloatifyParameterValue(0, denominator, 2 * i + 1); // odd numbers are the actual values + //LogF("KF is %f @ %f", keyFrames[2 * i + 1], keyFrames[2 * i]); + } + } + else if (valueFunction == &C4ParticleValueProvider::Speed || valueFunction == &C4ParticleValueProvider::Wind || valueFunction == &C4ParticleValueProvider::Gravity) + { + FloatifyParameterValue(&C4ParticleValueProvider::speedFactor, 1000.0f); + } +} + +void C4ParticleValueProvider::RollRandom() +{ + float range = endValue - startValue; + float rnd = (float)(rand()) / (float)(RAND_MAX); + currentValue = startValue + rnd * range; +} + +float C4ParticleValueProvider::GetValue(C4Particle *forParticle) +{ + UpdateChildren(forParticle); + return (this->*valueFunction)(forParticle); +} + +float C4ParticleValueProvider::Linear(C4Particle *forParticle) +{ + return startValue + (endValue - startValue) * forParticle->GetRelativeAge(); +} + +float C4ParticleValueProvider::Const(C4Particle *forParticle) +{ + return startValue; +} + +float C4ParticleValueProvider::Random(C4Particle *forParticle) +{ + if ((rerollInterval != 0 && ((int)forParticle->GetAge() % rerollInterval == 0)) || alreadyRolled == 0) + { + alreadyRolled = 1; + RollRandom(); + } + return currentValue; +} + +float C4ParticleValueProvider::Direction(C4Particle *forParticle) +{ + float distX = forParticle->currentSpeedX; + float distY = forParticle->currentSpeedY; + + if (distX == 0.f) return distY > 0.f ? M_PI : 0.f; + if (distY == 0.f) return distX < 0.f ? 3.0f * M_PI_2 : M_PI_2; + + return startValue * (atan2(distY, distX) + (float)M_PI_2); +} + +float C4ParticleValueProvider::Step(C4Particle *forParticle) +{ + return currentValue + startValue * forParticle->GetAge() / delay; +} + +float C4ParticleValueProvider::KeyFrames(C4Particle *forParticle) +{ + float age = forParticle->GetRelativeAge(); + // todo, implement smoothing + //if (smoothing == 0) // linear + { + for (size_t i = 0; i < keyFrameCount; ++i) + { + if (age > keyFrames[i * 2]) continue; + assert(i >= 1); + + float x1 = keyFrames[(i - 1) * 2]; + float x2 = keyFrames[i * 2]; + float y1 = keyFrames[(i - 1) * 2 + 1]; + float y2 = keyFrames[i * 2 + 1]; + float position = (age - x1) / (x2 - x1); + float totalRange = (y2 - y1); + + float value = position * totalRange + y1; + return value; + } + } + + return startValue; +} + +float C4ParticleValueProvider::Speed(C4Particle *forParticle) +{ + float distX = forParticle->currentSpeedX; + float distY = forParticle->currentSpeedY; + float speed = sqrtf((distX * distX) + (distY * distY)); + + return startValue + speedFactor * speed; +} + +float C4ParticleValueProvider::Wind(C4Particle *forParticle) +{ + return startValue + (0.01f * speedFactor * ::Weather.GetWind((int)forParticle->positionX, (int)forParticle->positionY)); +} + +float C4ParticleValueProvider::Gravity(C4Particle *forParticle) +{ + return startValue + (speedFactor * ::Landscape.Gravity); +} + +void C4ParticleValueProvider::SetType(C4ParticleValueProviderID what) +{ + switch (what) + { + case C4PV_Const: + valueFunction = &C4ParticleValueProvider::Const; + break; + case C4PV_Linear: + valueFunction = &C4ParticleValueProvider::Linear; + break; + case C4PV_Random: + valueFunction = &C4ParticleValueProvider::Random; + break; + case C4PV_Direction: + valueFunction = &C4ParticleValueProvider::Direction; + break; + case C4PV_Step: + valueFunction = &C4ParticleValueProvider::Step; + break; + case C4PV_KeyFrames: + valueFunction = &C4ParticleValueProvider::KeyFrames; + break; + case C4PV_Speed: + valueFunction = &C4ParticleValueProvider::Speed; + break; + case C4PV_Wind: + valueFunction = &C4ParticleValueProvider::Wind; + break; + case C4PV_Gravity: + valueFunction = &C4ParticleValueProvider::Gravity; + break; + default: + assert(false && "Invalid C4ParticleValueProvider ID passed"); + }; + + if (what != C4PV_Const) + { + isConstant = false; + } +} + +void C4ParticleValueProvider::Set(const C4ValueArray &fromArray) +{ + startValue = endValue = 1.0f; + valueFunction = &C4ParticleValueProvider::Const; + + size_t arraySize = (size_t) fromArray.GetSize(); + if (arraySize < 2) return; + + int type = fromArray[0].getInt(); + + switch (type) + { + case C4PV_Const: + if (arraySize >= 2) + { + SetType(C4PV_Const); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue); + } + break; + + case C4PV_Linear: + if (arraySize >= 3) + { + SetType(C4PV_Linear); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::endValue); + } + break; + case C4PV_Random: + if (arraySize >= 3) + { + SetType(C4PV_Random); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::endValue); + if (arraySize >= 4) + SetParameterValue(VAL_TYPE_INT, fromArray[3], 0, &C4ParticleValueProvider::rerollInterval); + alreadyRolled = 0; + } + break; + case C4PV_Direction: + if (arraySize >= 2) + { + SetType(C4PV_Direction); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue); + } + break; + case C4PV_Step: + if (arraySize >= 2) + { + SetType(C4PV_Step); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::currentValue); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[3], &C4ParticleValueProvider::delay); + if (delay == 0.f) delay = 1.f; + } + break; + case C4PV_KeyFrames: + if (arraySize >= 5) + { + SetType(C4PV_KeyFrames); + SetParameterValue(VAL_TYPE_INT, fromArray[1], 0, &C4ParticleValueProvider::smoothing); + keyFrames.resize(arraySize + 4 - 1); // 2*2 additional information floats at the beginning and ending, offset the first array item, though + + keyFrameCount = 0; + const size_t startingOffset = 2; + size_t i = startingOffset; + for (; i < arraySize; ++i) + { + SetParameterValue(VAL_TYPE_KEYFRAMES, fromArray[(int32_t)i], 0, 0, 2 + i - startingOffset); + } + keyFrameCount = (i - startingOffset) / 2 + 2; + + startValue = keyFrames[2 + 1]; + endValue = keyFrames[2 * keyFrameCount - 1]; + + // add two points for easier interpolation at beginning and ending + keyFrames[0] = -500.f; + keyFrames[1] = keyFrames[2 + 1]; + keyFrames[2 * keyFrameCount - 2] = 1500.f; + keyFrames[2 * keyFrameCount - 1] = keyFrames[keyFrameCount - 1 - 2]; + + //for (int i = 0; i < keyFrameCount; ++i) + // LogF("KF is %f @ %d of %d", keyFrames[i * 2 + 1], int(keyFrames[i * 2]), keyFrameCount); + } + break; + case C4PV_Speed: + if (arraySize >= 3) + { + SetType(C4PV_Speed); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue); + } + break; + case C4PV_Wind: + if (arraySize >= 3) + { + SetType(C4PV_Wind); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue); + } + break; + case C4PV_Gravity: + if (arraySize >= 3) + { + SetType(C4PV_Gravity); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor); + SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue); + } + break; + default: + throw new C4AulExecError("invalid particle value provider supplied"); + break; + } +} + +void C4ParticleValueProvider::Set(const C4Value &value) +{ + C4ValueArray *valueArray= value.getArray(); + + if (valueArray != 0) + Set(*valueArray); + else + Set((float)value.getInt()); +} + +void C4ParticleValueProvider::Set(float to) +{ + SetType(C4PV_Const); + startValue = endValue = to; +} + +C4ParticleProperties::C4ParticleProperties() +{ + blitMode = 0; + attachment = C4ATTACH_None; + hasConstantColor = false; + hasCollisionVertex = false; + collisionCallback = 0; + bouncyness = 0.f; + + // all values in pre-floatified range (f.e. 0..255 instead of 0..1) + collisionVertex.Set(0.f); + size.Set(8.f); + stretch.Set(1000.f); + forceX.Set(0.f); + forceY.Set(0.f); + speedDampingX.Set(1000.f); + speedDampingY.Set(1000.f); + colorR.Set(255.f); + colorG.Set(255.f); + colorB.Set(255.f); + colorAlpha.Set(255.f); + rotation.Set(0.f); + phase.Set(0.f); +} + +void C4ParticleProperties::Floatify() +{ + bouncyness /= 1000.f; + + collisionVertex.Floatify(1000.f); + size.Floatify(2.f); + stretch.Floatify(1000.f); + forceX.Floatify(100.f); + forceY.Floatify(100.f); + speedDampingX.Floatify(1000.f); + speedDampingY.Floatify(1000.f); + colorR.Floatify(255.f); + colorG.Floatify(255.f); + colorB.Floatify(255.f); + colorAlpha.Floatify(255.f); + rotation.Floatify(180.0f / (float)M_PI); + phase.Floatify(1.f); + + hasConstantColor = colorR.IsConstant() && colorG.IsConstant() && colorB.IsConstant() && colorAlpha.IsConstant(); +} + +void C4ParticleProperties::Set(C4PropList *dataSource) +{ + if (!dataSource) return; + + C4PropList::Iterator iter = dataSource->begin(), end = dataSource->end(); + + for (;iter != end; ++iter) + { + const C4Property * p = *iter; + C4String *key = p->Key; + assert(key && "PropList returns non-string as key"); + const C4Value &property = p->Value; + + if(&Strings.P[P_R] == key) + { + colorR.Set(property); + } + else if(&Strings.P[P_G] == key) + { + colorG.Set(property); + } + else if(&Strings.P[P_B] == key) + { + colorB.Set(property); + } + else if(&Strings.P[P_Alpha] == key) + { + colorAlpha.Set(property); + } + else if(&Strings.P[P_ForceX] == key) + { + forceX.Set(property); + } + else if(&Strings.P[P_ForceY] == key) + { + forceY.Set(property); + } + else if(&Strings.P[P_DampingX] == key) + { + speedDampingX.Set(property); + } + else if(&Strings.P[P_DampingY] == key) + { + speedDampingY.Set(property); + } + else if(&Strings.P[P_Size] == key) + { + size.Set(property); + } + else if(&Strings.P[P_Stretch] == key) + { + stretch.Set(property); + } + else if(&Strings.P[P_Rotation] == key) + { + rotation.Set(property); + } + else if(&Strings.P[P_BlitMode] == key) + { + // needs to be constant + blitMode = (uint32_t) property.getInt(); + } + else if(&Strings.P[P_Attach] == key) + { + // needs to be constant + attachment = (uint32_t) property.getInt(); + } + else if(&Strings.P[P_Phase] == key) + { + phase.Set(property); + } + else if(&Strings.P[P_CollisionVertex] == key) + { + collisionVertex.Set(property); + if (property.GetType() != C4V_Nil) + hasCollisionVertex = true; + } + else if(&Strings.P[P_OnCollision] == key) + { + SetCollisionFunc(property); + } + } + +} + +void C4ParticleProperties::SetCollisionFunc(const C4Value &source) +{ + C4ValueArray *valueArray; + if (!(valueArray = source.getArray())) return; + + int arraySize = valueArray->GetSize(); + if (arraySize < 1) return; + + int type = (*valueArray)[0].getInt(); + + switch (type) + { + case C4PC_Die: + collisionCallback = &C4ParticleProperties::CollisionDie; + break; + case C4PC_Bounce: + collisionCallback = &C4ParticleProperties::CollisionBounce; + bouncyness = 1.f; + if (arraySize >= 2) + bouncyness = ((float)(*valueArray)[1].getInt()); + break; + case C4PC_Stop: + collisionCallback = &C4ParticleProperties::CollisionStop; + break; + default: + assert(false); + break; + } +} + +bool C4ParticleProperties::CollisionBounce(C4Particle *forParticle) +{ + forParticle->currentSpeedX = -forParticle->currentSpeedX * bouncyness; + forParticle->currentSpeedY = -forParticle->currentSpeedY * bouncyness; + return true; +} + +bool C4ParticleProperties::CollisionStop(C4Particle *forParticle) +{ + forParticle->currentSpeedX = 0.f; + forParticle->currentSpeedY = 0.f; + return true; +} + +void C4Particle::Init() +{ + currentSpeedX = currentSpeedY = 0.f; + positionX = positionY = 0.f; + lifetime = startingLifetime = 5.f * 38.f; +} + +bool C4Particle::Exec(C4Object *obj, float timeDelta, C4ParticleDef *sourceDef) +{ + // die of old age? :< + lifetime -= timeDelta; + // check only if we had a maximum lifetime to begin with (for permanent particles) + if (startingLifetime > 0.f) + { + if (lifetime <= 0.f) return false; + } + + // movement + float currentForceX = properties.forceX.GetValue(this); + float currentForceY = properties.forceY.GetValue(this); + + currentSpeedX += currentForceX; + currentSpeedY += currentForceY; + + if (currentSpeedX != 0.f || currentSpeedY != 0.f) + { + float currentDampingX = properties.speedDampingX.GetValue(this); + float currentDampingY = properties.speedDampingY.GetValue(this); + float size = properties.size.GetValue(this); + + currentSpeedX *= currentDampingX; + currentSpeedY *= currentDampingY; + + // move & collision check + // note: accessing Landscape.GetDensity here is not protected by locks + // it is assumed that the particle system is cleaned up before, f.e., the landscape memory is freed + bool collided = false; + if (properties.hasCollisionVertex) + { + float collisionPoint = properties.collisionVertex.GetValue(this); + float size_x = (currentSpeedX > 0.f ? size : -size) * 0.5f * collisionPoint; + float size_y = (currentSpeedY > 0.f ? size : -size) * 0.5f * collisionPoint; + if (GBackSolid(positionX + size_x + timeDelta * currentSpeedX, positionY + size_y + timeDelta * currentSpeedY)) + { + // exec collision func + if (properties.collisionCallback != 0 && !(properties.*properties.collisionCallback)(this)) return false; + collided = true; + } + } + + if (!collided) + { + positionX += timeDelta * currentSpeedX; + positionY += timeDelta * currentSpeedY; + } + drawingData.SetPosition(positionX, positionY, size, properties.rotation.GetValue(this), properties.stretch.GetValue(this)); + + } + else if(!properties.size.IsConstant() || !properties.rotation.IsConstant() || !properties.stretch.IsConstant()) + { + drawingData.SetPosition(positionX, positionY, properties.size.GetValue(this), properties.rotation.GetValue(this), properties.stretch.GetValue(this)); + } + + // adjust color + if (!properties.hasConstantColor) + { + drawingData.SetColor(properties.colorR.GetValue(this), properties.colorG.GetValue(this), properties.colorB.GetValue(this), properties.colorAlpha.GetValue(this)); + } + + int currentPhase = (int)(properties.phase.GetValue(this) + 0.5f); + if (currentPhase != drawingData.phase) + drawingData.SetPhase(currentPhase, sourceDef); + + return true; +} + +void C4ParticleChunk::Clear() +{ + for (size_t i = 0; i < particleCount; ++i) + { + delete particles[i]; + } + particleCount = 0; + particles.clear(); + vertexCoordinates.clear(); + + if (!Particles.useBufferObjectWorkaround) + ClearBufferObjects(); +} + +void C4ParticleChunk::DeleteAndReplaceParticle(size_t indexToReplace, size_t indexFrom) +{ + C4Particle *oldParticle = particles[indexToReplace]; + + // try to replace the soon-to-be empty slot in the array + if (indexFrom != indexToReplace) // false when "replacing" the last one + { + std::copy(&vertexCoordinates[indexFrom * C4Particle::DrawingData::vertexCountPerParticle], &vertexCoordinates[indexFrom * C4Particle::DrawingData::vertexCountPerParticle] + C4Particle::DrawingData::vertexCountPerParticle, &vertexCoordinates[indexToReplace * C4Particle::DrawingData::vertexCountPerParticle]); + particles[indexToReplace] = particles[indexFrom]; + particles[indexToReplace]->drawingData.SetPointer(&vertexCoordinates[indexToReplace * C4Particle::DrawingData::vertexCountPerParticle]); + } + + delete oldParticle; +} + +bool C4ParticleChunk::Exec(C4Object *obj, float timeDelta) +{ + for (size_t i = 0; i < particleCount; ++i) + { + if (!particles[i]->Exec(obj, timeDelta, sourceDefinition)) + { + DeleteAndReplaceParticle(i, particleCount - 1); + --particleCount; + } + } + return particleCount > 0; +} + +#if defined(__APPLE__) +#undef glGenVertexArrays +#undef glBindVertexArray +#undef glDeleteVertexArrays + +#define glGenVertexArrays glGenVertexArraysAPPLE +#define glBindVertexArray glBindVertexArrayAPPLE +#define glDeleteVertexArrays glDeleteVertexArraysAPPLE +#endif + +void C4ParticleChunk::Draw(C4TargetFacet cgo, C4Object *obj) +{ + if (particleCount == 0) return; + const int stride = sizeof(C4Particle::DrawingData::Vertex); + assert(sourceDefinition && "No source definition assigned to particle chunk."); + C4TexRef *textureRef = (*sourceDefinition->Gfx.GetFace().ppTex); + assert(textureRef != 0 && "Particle definition had no texture assigned."); + + + + // use a relative offset? + bool resetMatrix(false); + if ((attachment & C4ATTACH_MoveRelative) && (obj != 0)) + { + resetMatrix = true; + glPushMatrix(); + glTranslatef((float)obj->GetX(), (float)obj->GetY(), 0.0f); + } + + glBlendFunc(GL_SRC_ALPHA, (blitMode & C4GFXBLIT_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA); + + glActiveTexture(GL_TEXTURE0); + glClientActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureRef->texName); + + if (!Particles.useBufferObjectWorkaround) + { + // generate the buffer as necessary + if (drawingDataVertexBufferObject == 0) + { + // clear up old data + ClearBufferObjects(); + // generate new buffer objects + glGenBuffers(1, &drawingDataVertexBufferObject); + assert (drawingDataVertexBufferObject != 0 && "Could not generate OpenGL buffer object."); + + // generate new vertex arrays object + glGenVertexArrays(1, &drawingDataVertexArraysObject); + assert (drawingDataVertexArraysObject != 0 && "Could not generate OpenGL vertex arrays object."); + + // set up the vertex array structure once + glBindVertexArray(drawingDataVertexArraysObject); + glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FLOAT, stride, reinterpret_cast(offsetof(C4Particle::DrawingData::Vertex, x))); + glTexCoordPointer(2, GL_FLOAT , stride, reinterpret_cast(offsetof(C4Particle::DrawingData::Vertex, u))); + glColorPointer(4, GL_FLOAT , stride, reinterpret_cast(offsetof(C4Particle::DrawingData::Vertex, r))); + glBindVertexArray(0); + } + + assert ((drawingDataVertexArraysObject != 0) && "No vertex arrays object has been created yet."); + assert ((drawingDataVertexBufferObject != 0) && "No buffer object has been created yet."); + + // bind the VBO and push the new vertex data + // this has to be done before binding the vertex arrays object + glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject); + glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(C4Particle::DrawingData::Vertex) * particleCount, &vertexCoordinates[0], GL_DYNAMIC_DRAW); + + // bind VAO and set correct state + glBindVertexArray(drawingDataVertexArraysObject); + } + else + { + glVertexPointer(2, GL_FLOAT, stride, &(vertexCoordinates[0].x)); + glTexCoordPointer(2, GL_FLOAT, stride, &(vertexCoordinates[0].u)); + glColorPointer(4, GL_FLOAT, stride, &(vertexCoordinates[0].r)); + } + + if (!Particles.usePrimitiveRestartIndexWorkaround) + { + glDrawElements(GL_TRIANGLE_STRIP, static_cast (5 * particleCount), GL_UNSIGNED_INT, ::Particles.GetPrimitiveRestartArray()); + } + else + { + glMultiDrawElements(GL_TRIANGLE_STRIP, ::Particles.GetMultiDrawElementsCountArray(), GL_UNSIGNED_INT, const_cast(::Particles.GetMultiDrawElementsIndexArray()), static_cast (particleCount)); + } + if (resetMatrix) + glPopMatrix(); + + // reset buffer data + if (!Particles.useBufferObjectWorkaround) + { + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } +} + +bool C4ParticleChunk::IsOfType(C4ParticleDef *def, uint32_t _blitMode, uint32_t _attachment) const +{ + return def == sourceDefinition && blitMode == _blitMode && attachment == _attachment; +} + +void C4ParticleChunk::ClearBufferObjects() +{ + if (drawingDataVertexBufferObject != 0) // the value 0 as a buffer index is reserved and will never be returned by glGenBuffers + glDeleteBuffers(1, &drawingDataVertexBufferObject); + if (drawingDataVertexArraysObject != 0) + glDeleteVertexArrays(1, &drawingDataVertexArraysObject); + + drawingDataVertexArraysObject = 0; + drawingDataVertexBufferObject = 0; +} + +void C4ParticleChunk::ReserveSpace(uint32_t forAmount) +{ + uint32_t newSize = static_cast(particleCount) + forAmount + 1; + ::Particles.PreparePrimitiveRestartIndices(newSize); + if (particles.capacity() < newSize) + particles.reserve(std::max(newSize, particles.capacity() * 2)); + + // resizing the points vector is relatively costly, hopefully we only do it rarely + while (vertexCoordinates.capacity() <= newSize * C4Particle::DrawingData::vertexCountPerParticle) + { + vertexCoordinates.reserve(std::max(C4Particle::DrawingData::vertexCountPerParticle * newSize, vertexCoordinates.capacity() * 2)); + + // update all existing particles' pointers.. + for (size_t i = 0; i < particleCount; ++i) + particles[i]->drawingData.SetPointer(&vertexCoordinates[i * C4Particle::DrawingData::vertexCountPerParticle]); + } +} + +C4Particle *C4ParticleChunk::AddNewParticle() +{ + size_t currentIndex = particleCount++; + + if (currentIndex < particles.size()) + { + particles[currentIndex] = new C4Particle(); + } + else + { + particles.push_back(new C4Particle()); + vertexCoordinates.resize(vertexCoordinates.size() + C4Particle::DrawingData::vertexCountPerParticle); + } + + C4Particle *newParticle = particles[currentIndex]; + newParticle->drawingData.SetPointer(&vertexCoordinates[currentIndex * C4Particle::DrawingData::vertexCountPerParticle], true); + return newParticle; +} + +void C4ParticleList::Exec(float timeDelta) +{ + if (particleChunks.empty()) return; + + accessMutex.Enter(); + + for (std::list::iterator iter = particleChunks.begin(); iter != particleChunks.end();) + { + C4ParticleChunk *chunk = *iter; + if (chunk->Exec(targetObject, timeDelta)) + { + ++iter; + } + else + { + iter = particleChunks.erase(iter); + lastAccessedChunk = 0; + } + } + + accessMutex.Leave(); +} + +void C4ParticleList::Draw(C4TargetFacet cgo, C4Object *obj) +{ + if (particleChunks.empty()) return; + + //glDisable(GL_DEPTH_TEST); + //if (additiveBlit) + // pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE); + pDraw->DeactivateBlitModulation(); + pDraw->ResetBlitMode(); + + glEnable(GL_TEXTURE_2D); + + if (!Particles.usePrimitiveRestartIndexWorkaround) + { + glPrimitiveRestartIndex(0xffffffff); + glEnable(GL_PRIMITIVE_RESTART); + } + // apply zoom + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glTranslatef(cgo.X, cgo.Y, 0.0f); + glScalef(cgo.Zoom, cgo.Zoom, 1.0f); + glTranslatef(-cgo.TargetX, -cgo.TargetY, 0.0f); + + if (Particles.useBufferObjectWorkaround) + { + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + accessMutex.Enter(); + + for (std::list::iterator iter = particleChunks.begin(); iter != particleChunks.end(); ++iter) + { + (*iter)->Draw(cgo, obj); + } + + accessMutex.Leave(); + + if (Particles.useBufferObjectWorkaround) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glPopMatrix(); + + if (!Particles.usePrimitiveRestartIndexWorkaround) + { + glDisable(GL_PRIMITIVE_RESTART); + } + glDisable(GL_TEXTURE_2D); +} + +void C4ParticleList::Clear() +{ + accessMutex.Enter(); + + for (std::list::iterator iter = particleChunks.begin(); iter != particleChunks.end(); ++iter) + delete *iter; + particleChunks.clear(); + + if (targetObject) + { + if (this == targetObject->FrontParticles) targetObject->FrontParticles = NULL; + else if (this == targetObject->BackParticles) targetObject->BackParticles = NULL; + } + else + if(this == ::Particles.globalParticles) ::Particles.globalParticles = NULL; + + accessMutex.Leave(); +} + +C4ParticleChunk *C4ParticleList::GetFittingParticleChunk(C4ParticleDef *def, uint32_t blitMode, uint32_t attachment, bool alreadyLocked) +{ + if (!alreadyLocked) + accessMutex.Enter(); + + // if not cached, find correct chunk in list + C4ParticleChunk *chunk = 0; + if (lastAccessedChunk && lastAccessedChunk->IsOfType(def, blitMode, attachment)) + chunk = lastAccessedChunk; + else + { + for (std::list::iterator iter = particleChunks.begin(); iter != particleChunks.end(); ++iter) + { + C4ParticleChunk *current = *iter; + if (!current->IsOfType(def, blitMode, attachment)) continue; + chunk = current; + break; + } + } + + // add new chunk? + if (!chunk) + { + particleChunks.push_back(new C4ParticleChunk()); + chunk = particleChunks.back(); + chunk->sourceDefinition = def; + chunk->blitMode = blitMode; + chunk->attachment = attachment; + } + + assert(chunk && "No suitable particle chunk could be found or created."); + lastAccessedChunk = chunk; + + if (!alreadyLocked) + accessMutex.Leave(); + + return chunk; +} + +void C4ParticleSystem::CalculationThread::Execute() +{ + Particles.ExecuteCalculation(); +} + +C4ParticleSystem::C4ParticleSystem() : frameCounterAdvancedEvent(false) +{ + currentSimulationTime = 0; + globalParticles = 0; + usePrimitiveRestartIndexWorkaround = false; + useBufferObjectWorkaround = false; +} + +C4ParticleSystem::~C4ParticleSystem() +{ + Clear(); + + calculationThread.SignalStop(); + CalculateNextStep(); + + for (std::vector::iterator iter = multiDrawElementsIndexArray.begin(); iter != multiDrawElementsIndexArray.end(); ++iter) + delete (*iter); +} + +void C4ParticleSystem::DoInit() +{ + // we use features that are only supported from 3.1 upwards. Check whether the graphics card supports that and - if not - use workarounds + if (!GLEW_VERSION_3_1 || (glPrimitiveRestartIndex == 0)) + { + usePrimitiveRestartIndexWorkaround = true; + LogSilent("WARNING (particle system): Your graphics card does not support glPrimitiveRestartIndex - a (slower) fallback will be used!"); + } + + assert (glGenBuffers != 0 && "Your graphics card does not seem to support buffer objects."); + useBufferObjectWorkaround = false; +} + +void C4ParticleSystem::ExecuteCalculation() +{ + frameCounterAdvancedEvent.WaitFor(INFINITE); + frameCounterAdvancedEvent.Reset(); + + int gameTime = Game.FrameCounter; + if (currentSimulationTime < gameTime) + { + float timeDelta = 1.f; + if (currentSimulationTime != 0) + timeDelta = (float)(gameTime - currentSimulationTime); + currentSimulationTime = gameTime; + + particleListAccessMutex.Enter(); + + for (std::list::iterator iter = particleLists.begin(); iter != particleLists.end(); ++iter) + { + iter->Exec(timeDelta); + } + + particleListAccessMutex.Leave(); + } +} +#endif + +C4ParticleList *C4ParticleSystem::GetNewParticleList(C4Object *forObject) +{ +#ifdef USE_CONSOLE + return 0; +#else + C4ParticleList *newList = 0; + + particleListAccessMutex.Enter(); + particleLists.emplace_back(forObject); + newList = &particleLists.back(); + particleListAccessMutex.Leave(); + + return newList; +#endif +} + +void C4ParticleSystem::ReleaseParticleList(C4ParticleList *first, C4ParticleList *second) +{ +#ifndef USE_CONSOLE + particleListAccessMutex.Enter(); + + for(std::list::iterator iter = particleLists.begin(); iter != particleLists.end();) + { + C4ParticleList *list = &(*iter); + if (list == first || list == second) + { + iter = particleLists.erase(iter); + } + else + { + ++iter; + } + } + + particleListAccessMutex.Leave(); +#endif +} + +#ifndef USE_CONSOLE +void C4ParticleSystem::Create(C4ParticleDef *of_def, C4ParticleValueProvider &x, C4ParticleValueProvider &y, C4ParticleValueProvider &speedX, C4ParticleValueProvider &speedY, C4ParticleValueProvider &lifetime, C4PropList *properties, int amount, C4Object *object) +{ + // todo: check amount etc + + C4ParticleList * pxList(0); + + + // initialize the particle properties + // this is done here, because it would also be the right place to implement caching + C4ParticleProperties particleProperties; + particleProperties.Set(properties); + + speedX.Floatify(10.f); + speedY.Floatify(10.f); + + // position offset that will be added to the particle + float xoff(0.f), yoff(0.f); + + // offset only for the drawing position - this is needed so that particles relative to an object work correctly + float drawingOffsetX(0.f), drawingOffsetY(0.f); + + if (object != 0) + { + // for all types of particles add object's offset (mainly for collision etc.) + xoff = object->GetX(); + yoff = object->GetY(); + + if (particleProperties.attachment & C4ATTACH_MoveRelative) + { + drawingOffsetX = -xoff; + drawingOffsetY = -yoff; + + // move relative implies that the particle needs to be in the object's particle list (back OR front) + // just select the front particles here - will be overwritten below if necessary + if (!(particleProperties.attachment & C4ATTACH_Front) && !(particleProperties.attachment & C4ATTACH_Back)) + particleProperties.attachment |= C4ATTACH_Front; + } + + // figure out particle list to use + if (particleProperties.attachment & C4ATTACH_Front) + { + if (!object->FrontParticles) object->FrontParticles = GetNewParticleList(object); + pxList = object->FrontParticles; + } + else if (particleProperties.attachment & C4ATTACH_Back) + { + if (!object->BackParticles) object->BackParticles = GetNewParticleList(object); + pxList = object->BackParticles; + } + } + + // no assigned list implies that we are going to use the global particles + if (!pxList) + { + if (!globalParticles) globalParticles = GetNewParticleList(); + pxList = globalParticles; + } + + // It is necessary to lock the particle list, because we will have it create a particle first that we are going to modify. + // Inbetween creation of the particle and modification, the particle list's calculations should not be executed + // (this could f.e. lead to the particle being removed before it was fully instantiated). + pxList->Lock(); + + // retrieve the fitting chunk for the particle (note that we tell the particle list, we already locked it) + C4ParticleChunk *chunk = pxList->GetFittingParticleChunk(of_def, particleProperties.blitMode, particleProperties.attachment, true); + + // set up chunk to be able to contain enough particles + chunk->ReserveSpace(static_cast(amount)); + + while (amount--) + { + if (x.IsRandom()) x.RollRandom(); + if (y.IsRandom()) y.RollRandom(); + if (speedX.IsRandom()) speedX.RollRandom(); + if (speedY.IsRandom()) speedY.RollRandom(); + if (lifetime.IsRandom()) lifetime.RollRandom(); + + // create a particle in the fitting chunk (note that we tell the particle list, we already locked it) + C4Particle *particle = chunk->AddNewParticle(); + + // initialize some more properties + particle->properties = particleProperties; + // this will adjust the initial values of the (possibly cached) particle properties + particle->properties.Floatify(); + + // setup some more non-property attributes of the particle + float lifetime_value = lifetime.GetValue(particle); + if (lifetime_value < 0.0f) lifetime_value = 0.0f; // negative values not allowed (would crash later); using a value of 0 is most likely visible to the scripter + particle->lifetime = particle->startingLifetime = lifetime_value; + + particle->currentSpeedX = speedX.GetValue(particle); + particle->currentSpeedY = speedY.GetValue(particle); + particle->drawingData.aspect = of_def->Aspect; + particle->drawingData.SetOffset(drawingOffsetX, drawingOffsetY); + particle->SetPosition(x.GetValue(particle) + xoff, y.GetValue(particle) + yoff); + particle->drawingData.SetColor(particle->properties.colorR.GetValue(particle), particle->properties.colorG.GetValue(particle), particle->properties.colorB.GetValue(particle), particle->properties.colorAlpha.GetValue(particle)); + particle->drawingData.SetPhase((int)(particle->properties.phase.GetValue(particle) + 0.5f), of_def); + } + + pxList->Unlock(); +} + +void C4ParticleSystem::PreparePrimitiveRestartIndices(uint32_t forAmount) +{ + if (!usePrimitiveRestartIndexWorkaround) + { + // prepare array with indices, separated by special primitive restart index + const uint32_t PRI = 0xffffffff; + size_t neededAmount = 5 * forAmount; + + if (primitiveRestartIndices.size() < neededAmount) + { + uint32_t oldValue = 0; + + if (primitiveRestartIndices.size() > 2) + { + oldValue = primitiveRestartIndices[primitiveRestartIndices.size()-1]; + if (oldValue == PRI) + oldValue = primitiveRestartIndices[primitiveRestartIndices.size()-2]; + ++oldValue; + } + size_t oldSize = primitiveRestartIndices.size(); + primitiveRestartIndices.resize(neededAmount); + + for (size_t i = oldSize; i < neededAmount; ++i) + { + if (((i+1) % 5 == 0) && (i != 0)) + { + primitiveRestartIndices[i] = PRI; + } + else + { + primitiveRestartIndices[i] = oldValue++; + } + } + } + } + else + { + // prepare arrays for glMultiDrawElements + if (multiDrawElementsCountArray.size() <= forAmount) + { + multiDrawElementsCountArray.resize(forAmount, 4); + } + + if (multiDrawElementsIndexArray.size() <= forAmount) + { + uint32_t oldSize = multiDrawElementsIndexArray.size(); + multiDrawElementsIndexArray.resize(forAmount); + + for (; oldSize < forAmount; ++oldSize) + { + multiDrawElementsIndexArray[oldSize] = new uint32_t[4]; + for (uint32_t i = 0; i < 4; ++i) + multiDrawElementsIndexArray[oldSize][i] = 4 * oldSize + i; + } + } + } +} +#endif + +void C4ParticleSystem::Clear() +{ +#ifndef USE_CONSOLE + currentSimulationTime = 0; + ClearAllParticles(); +#endif + // clear definitions even in console mode + definitions.Clear(); +} + +void C4ParticleSystem::ClearAllParticles() +{ + particleListAccessMutex.Enter(); + particleLists.clear(); + particleListAccessMutex.Leave(); +} + +C4ParticleDef *C4ParticleSystemDefinitionList::GetDef(const char *name, C4ParticleDef *exclude) +{ +#ifndef USE_CONSOLE + // seek list + for (C4ParticleDef *def = first; def != 0; def=def->next) + if (def != exclude && def->Name == name) + return def; +#endif + // nothing found + return 0; +} + +#ifndef USE_CONSOLE +void C4ParticleSystemDefinitionList::Clear() +{ + // the particle definitions update the list in their destructor + while (first) + delete first; +} +#endif +C4ParticleSystem Particles; diff --git a/src/landscape/C4Particles.h b/src/landscape/C4Particles.h new file mode 100644 index 000000000..8ae18259a --- /dev/null +++ b/src/landscape/C4Particles.h @@ -0,0 +1,523 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 2013, 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. + */ + +#include + +#include +#include + + +#ifndef INC_C4Particles +#define INC_C4Particles + +enum C4ParticleValueProviderID +{ + C4PV_Const, + C4PV_Linear, + C4PV_Random, + C4PV_KeyFrames, + C4PV_Direction, + C4PV_Step, + C4PV_Speed, + C4PV_Wind, + C4PV_Gravity, +}; + +enum C4ParticleAttachmentPropertyID +{ + C4ATTACH_None = 0, + C4ATTACH_Front = 1, + C4ATTACH_Back = 2, + C4ATTACH_MoveRelative = 4 +}; + +enum C4ParticleCollisionFuncID +{ + C4PC_Die, + C4PC_Bounce, + C4PC_Stop, +}; + +class C4ParticleDefCore; +class C4ParticleDef; +class C4ParticleList; +class C4ParticleChunk; +class C4Particle; +class C4ParticleProperties; +class C4ParticleValueProvider; + +// core for particle defs +class C4ParticleDefCore +{ +public: + StdStrBuf Name; // name + C4Rect GfxFace; // rect for graphics + + C4ParticleDefCore(); // ctor + void CompileFunc(StdCompiler * compiler); + + bool Compile(char *particle_source, const char *name); // compile from def file +}; + +// one particle definition +class C4ParticleDef : public C4ParticleDefCore +{ +public: + C4ParticleDef *previous, *next; // linked list members + + StdStrBuf Filename; // path to group this particle was loaded from (for EM reloading) + + C4FacetSurface Gfx; // graphics + int32_t Length; // number of phases in gfx + int32_t PhasesX; // number of phases per line in gfx + float Aspect; // height:width + + C4ParticleDef(); // ctor + ~C4ParticleDef(); // dtor + + void Clear(); // free mem associated with this class + + bool Load(C4Group &group); // load particle from group; assume file to be accessed already + bool Reload(); // reload particle from stored position +}; + +typedef float (C4ParticleValueProvider::*C4ParticleValueProviderFunction) (C4Particle*); +typedef bool (C4ParticleProperties::*C4ParticleCollisionCallback) (C4Particle*); + +#ifndef USE_CONSOLE +// the value providers are used to change the attributes of a particle over the lifetime +class C4ParticleValueProvider +{ +protected: + float startValue, endValue; + + // used by Random + float currentValue; + + union + { + int rerollInterval; // for Random + float delay; // for Step + float speedFactor; // for Speed & Wind & Gravity + }; + + union + { + int alreadyRolled; // for Random + int smoothing; // for KeyFrames + }; + + size_t keyFrameCount; + std::vector keyFrames; + + C4ParticleValueProviderFunction valueFunction; + bool isConstant; + + std::vector childrenValueProviders; + + union + { + float C4ParticleValueProvider::*floatValueToChange; + int C4ParticleValueProvider::*intValueToChange; + size_t keyFrameIndex; + }; + enum + { + VAL_TYPE_INT, + VAL_TYPE_FLOAT, + VAL_TYPE_KEYFRAMES, + }; + int typeOfValueToChange; + +public: + void UpdatePointerValue(C4Particle *particle, C4ParticleValueProvider *parent); + void UpdateChildren(C4Particle *particle); + void FloatifyParameterValue(float C4ParticleValueProvider::*value, float denominator, size_t keyFrameIndex = 0); + void SetParameterValue(int type, const C4Value &value, float C4ParticleValueProvider::*floatVal, int C4ParticleValueProvider::*intVal = 0, size_t keyFrameIndex = 0); + + bool IsConstant() const { return isConstant; } + bool IsRandom() const { return valueFunction == &C4ParticleValueProvider::Random; } + C4ParticleValueProvider() : startValue(0.f), endValue(0.f), currentValue(0.f), rerollInterval(0), smoothing(0), valueFunction(0), keyFrameCount(0), isConstant(true), floatValueToChange(0), typeOfValueToChange(VAL_TYPE_FLOAT) { } + ~C4ParticleValueProvider() + { + for (std::vector::iterator iter = childrenValueProviders.begin(); iter != childrenValueProviders.end(); ++iter) + delete *iter; + } + C4ParticleValueProvider(const C4ParticleValueProvider &other) { *this = other; } + C4ParticleValueProvider & operator= (const C4ParticleValueProvider &other); + void RollRandom(); + + // divides by denominator + void Floatify(float denominator); + + void SetType(C4ParticleValueProviderID what = C4PV_Const); + void Set(const C4Value &value); + void Set(const C4ValueArray &fromArray); + void Set(float to); // constant + float GetValue(C4Particle *forParticle); + + float Linear(C4Particle *forParticle); + float Const(C4Particle *forParticle); + float Random(C4Particle *forParticle); + float KeyFrames(C4Particle *forParticle); + float Direction(C4Particle *forParticle); + float Step(C4Particle *forParticle); + float Speed(C4Particle *forParticle); + float Wind(C4Particle *forParticle); + float Gravity(C4Particle *forParticle); +}; + +// the properties are part of every particle and contain certain changeable attributes +class C4ParticleProperties +{ +public: + bool hasConstantColor; + bool hasCollisionVertex; + + C4ParticleValueProvider size, stretch; + C4ParticleValueProvider forceX, forceY; + C4ParticleValueProvider speedDampingX, speedDampingY; + C4ParticleValueProvider colorR, colorG, colorB, colorAlpha; + C4ParticleValueProvider rotation; + C4ParticleValueProvider phase; + C4ParticleValueProvider collisionVertex; + + float bouncyness; + C4ParticleCollisionCallback collisionCallback; + void SetCollisionFunc(const C4Value &source); + + uint32_t blitMode; + + uint32_t attachment; + + C4ParticleProperties(); + + + void Set(C4PropList *dataSource); + // divides ints in certain properties by 1000f and in the color properties by 255f + void Floatify(); + + + bool CollisionDie(C4Particle *forParticle) { return false; } + bool CollisionBounce(C4Particle *forParticle); + bool CollisionStop(C4Particle *forParticle); +}; + +// one single particle +class C4Particle +{ +public: + + struct DrawingData + { + static const int vertexCountPerParticle; + + struct Vertex + { + float x; + float y; + + float u; + float v; + + float r; + float g; + float b; + float alpha; + }; + Vertex *vertices; + + int phase; + + float currentStretch; + float originalSize; + float sizeX, sizeY; + float aspect; + + float offsetX, offsetY; + + void SetOffset(float x, float y) + { + offsetX = x; + offsetY = y; + } + + void SetPointer(Vertex *startingVertex, bool initial = false) + { + vertices = startingVertex; + + if (initial) + { + vertices[0].u = 0.f; vertices[0].v = 1.f; + vertices[1].u = 0.f; vertices[1].v = 0.f; + vertices[2].u = 1.f; vertices[2].v = 1.f; + vertices[3].u = 1.f; vertices[3].v = 0.f; + + SetColor(1.f, 1.f, 1.f, 1.f); + + phase = -1; + } + } + + void SetColor(float r, float g, float b, float a = 1.0f) + { + for (int vertex = 0; vertex < 4; ++vertex) + { + vertices[vertex].r = r; + vertices[vertex].g = g; + vertices[vertex].b = b; + vertices[vertex].alpha = a; + } + } + + void SetPosition(float x, float y, float size, float rotation = 0.f, float stretch = 1.f); + void SetPhase(int phase, C4ParticleDef *sourceDef); + + DrawingData() : currentStretch(1.f), originalSize(0.0001f), aspect(1.f), offsetX(0.f), offsetY(0.f) + { + } + + } drawingData; +protected: + float currentSpeedX, currentSpeedY; + float positionX, positionY; + float lifetime, startingLifetime; + + C4ParticleProperties properties; + +public: + float GetAge() const { return startingLifetime - lifetime; } + float GetLifetime() const { return lifetime; } + float GetRelativeAge() const { return (startingLifetime != 0.f) ? (1.0f - (lifetime / startingLifetime)) : 0.f; } + + void Init(); + C4Particle() { Init(); } + + void SetPosition(float x, float y) + { + positionX = x; + positionY = y; + drawingData.SetPosition(positionX, positionY, properties.size.GetValue(this), properties.rotation.GetValue(this)); + } + + bool Exec(C4Object *obj, float timeDelta, C4ParticleDef *sourceDef); + + friend class C4ParticleProperties; + friend class C4ParticleValueProvider; + friend class C4ParticleChunk; + friend class C4ParticleSystem; +}; + +// a chunk contains all of the single particles that can be drawn with one draw call (~"have certain similar attributes") +// this is noncopyable to make sure that the OpenGL buffers are never freed multiple times +class C4ParticleChunk : public boost::noncopyable +{ +private: + C4ParticleDef *sourceDefinition; + + uint32_t blitMode; + + // whether the particles are translated according to the object's position + uint32_t attachment; + + std::vector particles; + std::vector vertexCoordinates; + size_t particleCount; + + // OpenGL optimizations + GLuint drawingDataVertexBufferObject; + GLuint drawingDataVertexArraysObject; + void ClearBufferObjects(); + + // delete the particle at indexTo. If possible, replace it with the particle at indexFrom to keep the particles tighly packed + void DeleteAndReplaceParticle(size_t indexToReplace, size_t indexFrom); + +public: + C4ParticleChunk() : sourceDefinition(0), blitMode(0), attachment(C4ATTACH_None), particleCount(0), drawingDataVertexBufferObject(0), drawingDataVertexArraysObject(0) + { + + } + ~C4ParticleChunk() + { + Clear(); + } + // removes all particles + void Clear(); + bool Exec(C4Object *obj, float timeDelta); + void Draw(C4TargetFacet cgo, C4Object *obj); + bool IsOfType(C4ParticleDef *def, uint32_t _blitMode, uint32_t attachment) const; + + // before adding a particle, you should ReserveSpace for it + C4Particle *AddNewParticle(); + // sets up internal data structures to be large enough for the passed amount of ADDITIONAL particles + void ReserveSpace(uint32_t forAmount); + + friend class C4ParticleList; +}; + +// this class must not be copied, because deleting the contained CStdCSec twice would be fatal +// a particle list belongs to a game-world entity (objects or global particles) and contains the chunks associated with that entity +class C4ParticleList : public boost::noncopyable +{ +private: + std::list particleChunks; + + C4Object *targetObject; + + // caching.. + C4ParticleChunk *lastAccessedChunk; + + // for making sure that the list is not drawn and calculated at the same time + CStdCSec accessMutex; + +public: + C4ParticleList(C4Object *obj = 0) : targetObject(obj), lastAccessedChunk(0) + { + + } + + ~C4ParticleList() { Clear(); } + + // this enables third-parties to lock the particle list (for example because a particle in the list is modified from outside) + void Lock() { accessMutex.Enter(); } + void Unlock() { accessMutex.Leave(); } + + // deletes all the particles + void Clear(); + + void Exec(float timeDelta = 1.f); + void Draw(C4TargetFacet cgo, C4Object *obj); + C4ParticleChunk *GetFittingParticleChunk(C4ParticleDef *def, uint32_t blitMode, uint32_t attachment, bool alreadyLocked); + C4Particle *AddNewParticle(C4ParticleDef *def, uint32_t blitMode, uint32_t attachment, bool alreadyLocked, int remaining = 0); +}; +#endif + +// cares for the management of particle definitions +class C4ParticleSystemDefinitionList +{ +#ifndef USE_CONSOLE +private: + // pointers to the last and first element of linked list of particle definitions + C4ParticleDef *first, *last; +public: + C4ParticleSystemDefinitionList() : first(0), last(0) {} + void Clear(); +#endif + C4ParticleDef *GetDef(const char *name, C4ParticleDef *exclude=0); + + friend class C4ParticleDef; +}; + +// the global particle system interface class +class C4ParticleSystem +{ +#ifndef USE_CONSOLE + class CalculationThread : public StdThread + { + protected: + virtual void Execute(); + public: + CalculationThread() { StdThread::Start(); } + }; + friend class CalculationThread; + +private: +#ifndef USE_CONSOLE + // contains an array with indices for vertices, separated by a primitive restart index + std::vector primitiveRestartIndices; + // these are fallbacks for if primitiveRestartIndex is not supported by the graphics card + std::vector multiDrawElementsCountArray; + std::vector multiDrawElementsIndexArray; +#endif + std::list particleLists; + + CalculationThread calculationThread; + CStdCSec particleListAccessMutex; + CStdEvent frameCounterAdvancedEvent; + + int currentSimulationTime; // in game time + + // calculates the physics in all of the existing particle lists + void ExecuteCalculation(); + + C4ParticleList *globalParticles; +#endif + +public: +#ifndef USE_CONSOLE + C4ParticleSystem(); + ~C4ParticleSystem(); +#endif + // called to allow the particle system the simulation of another step + void CalculateNextStep() + { +#ifndef USE_CONSOLE + frameCounterAdvancedEvent.Set(); +#endif + } + void DoInit(); + // resets the internal state of the particle system and unloads all definitions + void Clear(); + void DrawGlobalParticles(C4TargetFacet cgo) + { +#ifndef USE_CONSOLE + if (globalParticles) globalParticles->Draw(cgo, 0); +#endif + } + + C4ParticleList *GetGlobalParticles() + { +#ifndef USE_CONSOLE + return globalParticles; +#else + return 0; +#endif + } + + C4ParticleList *GetNewParticleList(C4Object *forTarget = 0); + // releases up to 2 lists + void ReleaseParticleList(C4ParticleList *first, C4ParticleList *second = 0); + + // interface for particle definitions + C4ParticleSystemDefinitionList definitions; + +#ifndef USE_CONSOLE + // on some graphics card, glPrimitiveRestartIndex might not be supported + bool usePrimitiveRestartIndexWorkaround; + GLsizei *GetMultiDrawElementsCountArray() { return &multiDrawElementsCountArray[0]; } + GLvoid **GetMultiDrawElementsIndexArray() { return reinterpret_cast (&multiDrawElementsIndexArray[0]); } + + // if true, OpenGL buffer objects will not be used (instead the slower direct calls will be made) + bool useBufferObjectWorkaround; + + // usually, the following methods are used for drawing + void PreparePrimitiveRestartIndices(uint32_t forSize); + void *GetPrimitiveRestartArray() { return (void*)&primitiveRestartIndices[0]; } + + // creates a new particle + void Create(C4ParticleDef *of_def, C4ParticleValueProvider &x, C4ParticleValueProvider &y, C4ParticleValueProvider &speedX, C4ParticleValueProvider &speedY, C4ParticleValueProvider &lifetime, C4PropList *properties, int amount = 1, C4Object *object=NULL); + + // removes all of the existing particles (used f.e. for scenario section loading) + void ClearAllParticles(); + + friend class C4ParticleList; + +#endif + +}; + +extern C4ParticleSystem Particles; + +#endif diff --git a/src/game/landscape/C4PathFinder.cpp b/src/landscape/C4PathFinder.cpp similarity index 96% rename from src/game/landscape/C4PathFinder.cpp rename to src/landscape/C4PathFinder.cpp index 67d6340ad..85dda84b0 100644 --- a/src/game/landscape/C4PathFinder.cpp +++ b/src/landscape/C4PathFinder.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2005 Matthes Bender - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2006, 2009-2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Finds the way through the Clonk landscape */ diff --git a/src/game/landscape/C4PathFinder.h b/src/landscape/C4PathFinder.h similarity index 79% rename from src/game/landscape/C4PathFinder.h rename to src/landscape/C4PathFinder.h index 4d73d048f..30ceab347 100644 --- a/src/game/landscape/C4PathFinder.h +++ b/src/landscape/C4PathFinder.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2005 Armin Burgmeier - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Finds the way through the Clonk landscape */ diff --git a/src/game/landscape/C4Scenario.cpp b/src/landscape/C4Scenario.cpp similarity index 77% rename from src/game/landscape/C4Scenario.cpp rename to src/landscape/C4Scenario.cpp index 4ccb81a05..c2418847b 100644 --- a/src/game/landscape/C4Scenario.cpp +++ b/src/landscape/C4Scenario.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2002, 2004-2008 Sven Eberhardt - * Copyright (c) 2004-2005 Peter Wortmann - * Copyright (c) 2006, 2009, 2011 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Core component of a scenario file */ @@ -147,7 +142,7 @@ void C4SHead::Default() Origin.Clear(); Icon=18; *Title = *Loader = *Font = *Engine = *MissionAccess = '\0'; - C4XVer[0] = C4XVer[1] = C4XVer[2] = C4XVer[3] = 0; + C4XVer[0] = C4XVer[1] = C4XVer[2] = 0; Difficulty = StartupPlayerCount = RandomSeed = 0; SaveGame = Replay = NoInitialize = false; Film = 0; @@ -213,8 +208,6 @@ void C4SGame::CompileFunc(StdCompiler *pComp, bool fSection) void C4SPlrStart::Default() { - NativeCrew=C4ID::None; - Crew.Set(1,0,1,10); Wealth.Set(0,0,0,250); Position[0]=Position[1]=-1; EnforcePosition=0; @@ -234,9 +227,7 @@ bool C4SPlrStart::EquipmentEqual(C4SPlrStart &rhs) bool C4SPlrStart::operator==(const C4SPlrStart& rhs) { - return (NativeCrew==rhs.NativeCrew) - && (Crew == rhs.Crew) - && (Wealth == rhs.Wealth) + return (Wealth == rhs.Wealth) && (ReadyCrew == rhs.ReadyCrew) && (ReadyBase == rhs.ReadyBase) && (ReadyVehic == rhs.ReadyVehic) @@ -248,12 +239,12 @@ bool C4SPlrStart::operator==(const C4SPlrStart& rhs) void C4SPlrStart::CompileFunc(StdCompiler *pComp) { - pComp->Value(mkNamingAdapt(NativeCrew, "StandardCrew", C4ID::None)); - pComp->Value(mkNamingAdapt(Crew, "Clonks", C4SVal(1, 0, 1, 10), true)); + C4IDList crewDefault; + crewDefault.SetIDCount(C4ID::Clonk,1,true); pComp->Value(mkNamingAdapt(Wealth, "Wealth", C4SVal(0, 0, 0,250), true)); pComp->Value(mkNamingAdapt(mkArrayAdaptDM(Position,-1), "Position" )); pComp->Value(mkNamingAdapt(EnforcePosition, "EnforcePosition", 0)); - pComp->Value(mkNamingAdapt(ReadyCrew, "Crew", C4IDList())); + pComp->Value(mkNamingAdapt(ReadyCrew, "Crew", crewDefault)); pComp->Value(mkNamingAdapt(ReadyBase, "Buildings", C4IDList())); pComp->Value(mkNamingAdapt(ReadyVehic, "Vehicles", C4IDList())); pComp->Value(mkNamingAdapt(ReadyMaterial, "Material", C4IDList())); @@ -290,8 +281,9 @@ void C4SLandscape::Default() NoScan=0; KeepMapCreator=0; SkyScrollMode=0; - NewStyleLandscape=0; FoWRes=C4FogOfWar::DefResolutionX; + MaterialZoom=4; + FlatChunkShapes=false; } void C4SLandscape::GetMapSize(int32_t &rWdt, int32_t &rHgt, int32_t iPlayerNum) @@ -312,8 +304,8 @@ void C4SLandscape::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(InEarthLevel, "InEarthLevel", C4SVal(50,0,0,100), true)); pComp->Value(mkNamingAdapt(mkStringAdaptMA(SkyDef), "Sky", "")); pComp->Value(mkNamingAdapt(mkArrayAdaptDM(SkyDefFade,0),"SkyFade" )); - pComp->Value(mkNamingAdapt(BottomOpen, "BottomOpen", false)); - pComp->Value(mkNamingAdapt(TopOpen, "TopOpen", true)); + pComp->Value(mkNamingAdapt(BottomOpen, "BottomOpen", 0)); + pComp->Value(mkNamingAdapt(TopOpen, "TopOpen", 1)); pComp->Value(mkNamingAdapt(LeftOpen, "LeftOpen", 0)); pComp->Value(mkNamingAdapt(RightOpen, "RightOpen", 0)); pComp->Value(mkNamingAdapt(AutoScanSideOpen, "AutoScanSideOpen", true)); @@ -333,8 +325,9 @@ void C4SLandscape::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(NoScan, "NoScan", false)); pComp->Value(mkNamingAdapt(KeepMapCreator, "KeepMapCreator", false)); pComp->Value(mkNamingAdapt(SkyScrollMode, "SkyScrollMode", 0)); - pComp->Value(mkNamingAdapt(NewStyleLandscape, "NewStyleLandscape", 0)); pComp->Value(mkNamingAdapt(FoWRes, "FoWRes", static_cast(C4FogOfWar::DefResolutionX))); + pComp->Value(mkNamingAdapt(MaterialZoom, "MaterialZoom", 4)); + pComp->Value(mkNamingAdapt(FlatChunkShapes, "FlatChunkShapes", false)); } void C4SWeather::Default() @@ -486,127 +479,5 @@ void C4SDefinitions::CompileFunc(StdCompiler *pComp) bool C4SGame::IsMelee() { - return (Goals.GetIDCount(C4ID::Melee)); + return !!(Goals.GetIDCount(C4ID::Melee)); } - -// scenario sections - -const char *C4ScenSect_Main = "main"; - -C4ScenarioSection::C4ScenarioSection(char *szName) -{ - // copy name - if (szName && !SEqualNoCase(szName, C4ScenSect_Main) && *szName) - { - this->szName = new char[strlen(szName)+1]; - SCopy(szName, this->szName); - } - else - this->szName = const_cast(C4ScenSect_Main); - // zero fields - szTempFilename = szFilename = 0; - fModified = false; - // link into main list - pNext = Game.pScenarioSections; - Game.pScenarioSections = this; -} - -C4ScenarioSection::~C4ScenarioSection() -{ - // del following scenario sections - while (pNext) - { - C4ScenarioSection *pDel = pNext; - pNext = pNext->pNext; - pDel->pNext = NULL; - delete pDel; - } - // del temp file - if (szTempFilename) - { - EraseItem(szTempFilename); - delete szTempFilename; - } - // del filename if assigned - if (szFilename) delete szFilename; - // del name if owned - if (szName != C4ScenSect_Main) delete szName; -} - -bool C4ScenarioSection::ScenarioLoad(char *szFilename) -{ - // safety - if (this->szFilename || !szFilename) return false; - // store name - this->szFilename = new char[strlen(szFilename)+1]; - SCopy(szFilename, this->szFilename, _MAX_FNAME); - // extract if it's not an open folder - if (Game.ScenarioFile.IsPacked()) if (!EnsureTempStore(true, true)) return false; - // donce, success - return true; -} - -C4Group *C4ScenarioSection::GetGroupfile(C4Group &rGrp) -{ - // check temp filename - if (szTempFilename) - { - if (rGrp.Open(szTempFilename)) return &rGrp; - else return NULL; - } - // check filename within scenario - if (szFilename) - { - if (rGrp.OpenAsChild(&Game.ScenarioFile, szFilename)) return &rGrp; - else return NULL; - } - // unmodified main section: return main group - if (SEqualNoCase(szName, C4ScenSect_Main)) return &Game.ScenarioFile; - // failure - return NULL; -} - -bool C4ScenarioSection::EnsureTempStore(bool fExtractLandscape, bool fExtractObjects) -{ - // if it's temp store already, don't do anything - if (szTempFilename) return true; - // make temp filename - char *szTmp = const_cast(Config.AtTempPath(szFilename ? GetFilename(szFilename) : szName)); - MakeTempFilename(szTmp); - // main section: extract section files from main scenario group (create group as open dir) - if (!szFilename) - { - if (!CreatePath(szTmp)) return false; - C4Group hGroup; - if (!hGroup.Open(szTmp, true)) { EraseItem(szTmp); return false; } - // extract all desired section files - Game.ScenarioFile.ResetSearch(); - char fn[_MAX_FNAME+1]; *fn=0; - while (Game.ScenarioFile.FindNextEntry(C4FLS_Section, fn)) - if (fExtractLandscape || !WildcardMatch(C4FLS_SectionLandscape, fn)) - if (fExtractObjects || !WildcardMatch(C4FLS_SectionObjects, fn)) - Game.ScenarioFile.ExtractEntry(fn, szTmp); - hGroup.Close(); - } - else - { - // subsection: simply extract section from main group - if (!Game.ScenarioFile.ExtractEntry(szFilename, szTmp)) return false; - // delete undesired landscape/object files - if (!fExtractLandscape || !fExtractObjects) - { - C4Group hGroup; - if (hGroup.Open(szFilename)) - { - if (!fExtractLandscape) hGroup.Delete(C4FLS_SectionLandscape); - if (!fExtractObjects) hGroup.Delete(C4FLS_SectionObjects); - } - } - } - // copy temp filename - szTempFilename = new char[strlen(szTmp)+1]; - SCopy(szTmp, szTempFilename, _MAX_PATH); - // done, success - return true; -} - diff --git a/src/game/landscape/C4Scenario.h b/src/landscape/C4Scenario.h similarity index 85% rename from src/game/landscape/C4Scenario.h rename to src/landscape/C4Scenario.h index 59c41f850..bf7c4ffab 100644 --- a/src/game/landscape/C4Scenario.h +++ b/src/landscape/C4Scenario.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001-2002, 2004-2007 Sven Eberhardt - * Copyright (c) 2005, 2010 Peter Wortmann - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Core component of a scenario file */ @@ -28,8 +23,6 @@ #include #include -class C4Group; - class C4SVal { public: @@ -68,7 +61,7 @@ enum C4SFilmMode class C4SHead { public: - int32_t C4XVer[4]; + int32_t C4XVer[3]; char Title[C4MaxTitle+1]; char Loader[C4MaxTitle+1]; char Font[C4MaxTitle+1]; // scenario specific font; may be 0 @@ -145,8 +138,6 @@ const int32_t C4S_MaxMapPlayerExtend = 4; class C4SPlrStart { public: - C4ID NativeCrew; // Obsolete - C4SVal Crew; // Obsolete C4SVal Wealth; int32_t Position[2]; int32_t EnforcePosition; @@ -173,7 +164,7 @@ public: C4IDList Vegetation; C4SVal InEarthLevel; C4IDList InEarth; - bool BottomOpen,TopOpen; + int32_t BottomOpen,TopOpen; int32_t LeftOpen,RightOpen; bool AutoScanSideOpen; char SkyDef[C4MaxDefString+1]; @@ -190,8 +181,9 @@ public: char Liquid[C4M_MaxDefName+1]; bool KeepMapCreator; // set if the mapcreator will be needed in the scenario (for DrawDefMap) int32_t SkyScrollMode; // sky scrolling mode for newgfx - int32_t NewStyleLandscape; // if set to 2, the landscape uses up to 125 mat/texture pairs int32_t FoWRes; // chunk size of FoGOfWar + int32_t MaterialZoom; + bool FlatChunkShapes; // if true, all material chunks are drawn flat public: void Default(); void GetMapSize(int32_t &rWdt, int32_t &rHgt, int32_t iPlayerNum); @@ -252,9 +244,6 @@ public: int32_t GetMinPlayer(); // will try to determine the minimum player count for this scenario }; -class C4ScenarioSection; - - extern const char *C4ScenSect_Main; // ref to one scenario section @@ -269,11 +258,12 @@ public: char *szTempFilename; // filename of data file if in temp dir char *szFilename; // filename of section in scenario file bool fModified; // if set, the file is temp and contains runtime landscape and/or object data + class C4ScenarioObjectsScriptHost *pObjectScripts; // points to loaded script file for section Objects.c C4ScenarioSection *pNext; // next member of linked list public: - bool ScenarioLoad(char *szFilename); // called when scenario is loaded: extract to temp store + bool ScenarioLoad(C4Group &rGrp, char *szFilename); // called when scenario is loaded: extract to temp store C4Group *GetGroupfile(C4Group &rGrp); // get group at section file (returns temp group, scenario subgroup or scenario group itself) bool EnsureTempStore(bool fExtractLandscape, bool fExtractObjects); // make sure that a temp file is created, and nothing is modified within the main scenario file }; diff --git a/src/landscape/C4ScenarioSection.cpp b/src/landscape/C4ScenarioSection.cpp new file mode 100644 index 000000000..dc975d56a --- /dev/null +++ b/src/landscape/C4ScenarioSection.cpp @@ -0,0 +1,164 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, 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. + */ + +#include +#include +#include +#include + +// scenario sections + +const char *C4ScenSect_Main = "main"; + +C4ScenarioSection::C4ScenarioSection(char *szName) +{ + // copy name + if (szName && !SEqualNoCase(szName, C4ScenSect_Main) && *szName) + { + this->szName = new char[strlen(szName)+1]; + SCopy(szName, this->szName); + } + else + this->szName = const_cast(C4ScenSect_Main); + // zero fields + szTempFilename = szFilename = 0; + fModified = false; + pObjectScripts = NULL; + // link into main list + pNext = Game.pScenarioSections; + Game.pScenarioSections = this; +} + +C4ScenarioSection::~C4ScenarioSection() +{ + // del following scenario sections + while (pNext) + { + C4ScenarioSection *pDel = pNext; + pNext = pNext->pNext; + pDel->pNext = NULL; + delete pDel; + } + // del temp file + if (szTempFilename) + { + EraseItem(szTempFilename); + delete szTempFilename; + } + // del filename if assigned + if (szFilename) delete szFilename; + // del name if owned + if (szName != C4ScenSect_Main) delete szName; +} + +bool C4ScenarioSection::ScenarioLoad(C4Group &rGrp, char *szFilename) +{ + // safety + if (this->szFilename || !szFilename) return false; + // store name + this->szFilename = new char[strlen(szFilename)+1]; + SCopy(szFilename, this->szFilename, _MAX_FNAME); + // extract if it's not an open folder + if (Game.ScenarioFile.IsPacked()) if (!EnsureTempStore(true, true)) return false; + // load section object script + if (!SEqualNoCase(szName, C4ScenSect_Main)) + { + C4Group GrpSect, *pGrp; + if ((pGrp = GetGroupfile(GrpSect)) && pGrp->FindEntry(C4CFN_ScenarioObjectsScript)) + { + pObjectScripts = new C4ScenarioObjectsScriptHost(); + pObjectScripts->Reg2List(&::ScriptEngine); + pObjectScripts->Load(*pGrp, C4CFN_ScenarioObjectsScript, Config.General.LanguageEx, &::Game.ScenarioLangStringTable); + } + else + { + pObjectScripts = NULL; + } + } + else + { + // Object script for main section + pObjectScripts = ::Game.pScenarioObjectsScript; + } + // donce, success + return true; +} + +C4Group *C4ScenarioSection::GetGroupfile(C4Group &rGrp) +{ + // check temp filename + if (szTempFilename) + { + if (rGrp.Open(szTempFilename)) return &rGrp; + else return NULL; + } + // check filename within scenario + if (szFilename) + { + if (rGrp.OpenAsChild(&Game.ScenarioFile, szFilename)) return &rGrp; + else return NULL; + } + // unmodified main section: return main group + if (SEqualNoCase(szName, C4ScenSect_Main)) return &Game.ScenarioFile; + // failure + return NULL; +} + +bool C4ScenarioSection::EnsureTempStore(bool fExtractLandscape, bool fExtractObjects) +{ + // if it's temp store already, don't do anything + if (szTempFilename) return true; + // make temp filename + char *szTmp = const_cast(Config.AtTempPath(szFilename ? GetFilename(szFilename) : szName)); + MakeTempFilename(szTmp); + // main section: extract section files from main scenario group (create group as open dir) + if (!szFilename) + { + if (!CreatePath(szTmp)) return false; + C4Group hGroup; + if (!hGroup.Open(szTmp, true)) { EraseItem(szTmp); return false; } + // extract all desired section files + Game.ScenarioFile.ResetSearch(); + char fn[_MAX_FNAME+1]; *fn=0; + while (Game.ScenarioFile.FindNextEntry(C4FLS_Section, fn)) + if (fExtractLandscape || !WildcardMatch(C4FLS_SectionLandscape, fn)) + if (fExtractObjects || !WildcardMatch(C4FLS_SectionObjects, fn)) + Game.ScenarioFile.ExtractEntry(fn, szTmp); + hGroup.Close(); + } + else + { + // subsection: simply extract section from main group + if (!Game.ScenarioFile.ExtractEntry(szFilename, szTmp)) return false; + // delete undesired landscape/object files + if (!fExtractLandscape || !fExtractObjects) + { + C4Group hGroup; + if (hGroup.Open(szFilename)) + { + if (!fExtractLandscape) hGroup.Delete(C4FLS_SectionLandscape); + if (!fExtractObjects) hGroup.Delete(C4FLS_SectionObjects); + } + } + } + // copy temp filename + szTempFilename = new char[strlen(szTmp)+1]; + SCopy(szTmp, szTempFilename, _MAX_PATH); + // done, success + return true; +} + diff --git a/src/game/landscape/C4Sky.cpp b/src/landscape/C4Sky.cpp similarity index 90% rename from src/game/landscape/C4Sky.cpp rename to src/landscape/C4Sky.cpp index e2152af83..3a0e8c063 100644 --- a/src/game/landscape/C4Sky.cpp +++ b/src/landscape/C4Sky.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002, 2005-2006 Sven Eberhardt - * Copyright (c) 2005-2010 Günther Brammer - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Small member of the landscape class to handle the sky background */ diff --git a/src/game/landscape/C4Sky.h b/src/landscape/C4Sky.h similarity index 68% rename from src/game/landscape/C4Sky.h rename to src/landscape/C4Sky.h index 7b5e25c77..0b61ca84f 100644 --- a/src/game/landscape/C4Sky.h +++ b/src/landscape/C4Sky.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2007 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Small member of the landscape class to handle the sky background */ @@ -28,9 +25,6 @@ #define C4SkyPM_Fixed 0 // sky parallax mode: fixed #define C4SkyPM_Wind 1 // sky parallax mode: blown by the wind -class C4Group; -class C4TargetFacet; - class C4Sky { public: diff --git a/src/game/landscape/C4SolidMask.cpp b/src/landscape/C4SolidMask.cpp similarity index 84% rename from src/game/landscape/C4SolidMask.cpp rename to src/landscape/C4SolidMask.cpp index 8e46733cd..ee5ae2a1d 100644 --- a/src/game/landscape/C4SolidMask.cpp +++ b/src/landscape/C4SolidMask.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003, 2005, 2008 Sven Eberhardt - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2007-2010 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Solid areas of objects, put into the landscape */ @@ -29,6 +23,8 @@ #include #include #include +#include +#include void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRestoreAttachment) @@ -37,7 +33,7 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes // storing background pixels in cSolidMask. // No mask - if (!pSolidMask || !pSolidMaskMatBuff) { iAttachingObjectsCount = 0; return; } + if (!pForObject || !pForObject->Def || !pForObject->Def->pSolidMask || !pSolidMaskMatBuff) { iAttachingObjectsCount = 0; return; } // Contained if (pForObject->Contained) { iAttachingObjectsCount = 0; return; } // Mask is put @@ -47,7 +43,7 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes if (!pClipRect) { // Regular Put: Update MaskPutRect and MaskPutRotation - MaskPutRotation = pForObject->r; + MaskPutRotation = pForObject->GetR(); pClipRect = &MaskPutRect; RegularPut = true; } @@ -59,10 +55,10 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes if (!pClipRect->ClipBy(MaskPutRect)) return; RegularPut = false; } - // Lock mask surface - int iPitch = pForObject->SolidMask.Wdt; - int xcnt,ycnt,iTx,iTy; + // Get mask surface + CSurface8 *pSolidMask = pForObject->Def->pSolidMask; // Put mask pixels + int xcnt,ycnt,iTx,iTy; BYTE byPixel; // not rotated? if (!MaskPutRotation) @@ -85,7 +81,7 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes // fill rect with mask for (ycnt=0; ycntHgt; ++ycnt) { - BYTE *pPix=pSolidMask + (ycnt+pClipRect->ty)*pForObject->SolidMask.Wdt + pClipRect->tx; + BYTE *pPix=pSolidMask->Bits + (ycnt+pClipRect->ty+pForObject->SolidMask.y)*pSolidMask->Pitch + pClipRect->tx + pForObject->SolidMask.x; for (xcnt=0; xcntWdt; ++xcnt,++pPix) { if (*pPix) @@ -139,8 +135,10 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes const C4Real y0 = itofix(pClipRect->ty - MatBuffPitch/2); const C4Real x0 = itofix(pClipRect->tx - MatBuffPitch/2); iTy=pClipRect->y; - int w = pForObject->SolidMask.Wdt; - int h = pForObject->SolidMask.Hgt; + int32_t w = pForObject->SolidMask.Wdt; + int32_t h = pForObject->SolidMask.Hgt; + int32_t mx0 = pForObject->SolidMask.x; + int32_t my0 = pForObject->SolidMask.y; C4Real ya = y0 * Ma2; C4Real yb = y0 * Mb2; for (ycnt = 0; ycnt < pClipRect->Hgt; ycnt++) @@ -152,10 +150,10 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes for (xcnt = 0; xcnt < pClipRect->Wdt; xcnt++) { // calc position in solidmask buffer - int iMx = fixtoi(xa + ya) + w / 2; - int iMy = fixtoi(xb + yb) + h / 2; + int32_t iMx = fixtoi(xa + ya) + w / 2; + int32_t iMy = fixtoi(xb + yb) + h / 2; // in bounds? and solidmask? - if (iMx >= 0 && iMy >= 0 && iMx < w && iMy < h && pSolidMask[iMy*iPitch+iMx]) + if (iMx >= 0 && iMy >= 0 && iMx < w && iMy < h && pSolidMask->_GetPix(iMx+mx0, iMy+my0)) { // is background mat to be stored? if (!MaskPut) @@ -192,7 +190,7 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes { C4Object *pObj = ppAttachingObjects[i]; if (pObj->IsMoveableBySolidMask(pForObject->GetPlane())) - if (!pObj->Shape.ContactCheck(pObj->GetFixedX()+dx, pObj->GetFixedY()+dy)) + if (!pObj->Shape.ContactCheck(fixtoi(pObj->GetFixedX()+dx), fixtoi(pObj->GetFixedY()+dy))) if (pObj->iLastAttachMovementFrame != Game.FrameCounter) { pObj->iLastAttachMovementFrame = Game.FrameCounter; @@ -214,11 +212,14 @@ int32_t C4SolidMask::DensityProvider::GetDensity(int32_t x, int32_t y) const || !Inside(y, 0, rSolidMaskData.MaskPutRect.Hgt-1)) return 0; // check put mask. Easy for unrotated - BYTE *pPix; + BYTE pix; if (!rSolidMaskData.MaskPutRotation) { - pPix=rSolidMaskData.pSolidMask+(y+rSolidMaskData.MaskPutRect.ty)*rSolidMaskData.pForObject->SolidMask.Wdt+rSolidMaskData.MaskPutRect.tx+x; - if (*pPix == 0xff) + CSurface8 *pSolidMask = rSolidMaskData.pForObject->Def->pSolidMask; + if (!pSolidMask) return 0; // can't really happen + pix=pSolidMask->_GetPix(x+rSolidMaskData.pForObject->SolidMask.x+rSolidMaskData.MaskPutRect.tx, + y+rSolidMaskData.pForObject->SolidMask.y+rSolidMaskData.MaskPutRect.ty); + if (pix == 0xff) return C4M_Solid; else return 0; @@ -227,8 +228,8 @@ int32_t C4SolidMask::DensityProvider::GetDensity(int32_t x, int32_t y) const { // Using put-buffer for rotated masks // for SolidMask-pixels not put because there was another SolidMask already, this will not return solid - pPix=rSolidMaskData.pSolidMaskMatBuff+(y+rSolidMaskData.MaskPutRect.ty)*rSolidMaskData.MatBuffPitch+rSolidMaskData.MaskPutRect.tx+x; - if (*pPix == MCVehic) + pix=*(rSolidMaskData.pSolidMaskMatBuff+(y+rSolidMaskData.MaskPutRect.ty)*rSolidMaskData.MatBuffPitch+rSolidMaskData.MaskPutRect.tx+x); + if (pix == MCVehic) return 0; else return C4M_Solid; @@ -240,7 +241,7 @@ void C4SolidMask::Remove(bool fBackupAttachment) // If put, restore background pixels from buffer // Not put - if (!MaskPut || !pSolidMask || !pSolidMaskMatBuff) return; + if (!MaskPut || !pSolidMaskMatBuff) return; CheckConsistency(); @@ -295,8 +296,7 @@ void C4SolidMask::Remove(bool fBackupAttachment) int iVtx = 0; for (; iVtx < pObj->Shape.VtxNum; ++iVtx) if (pObj->Shape.GetVertexContact(iVtx, pObj->Action.t_attach | CNAT_Bottom, pObj->GetX(), pObj->GetY(), DensityProvider(pForObject, *this))) - if (pObj->Shape.GetVertexContact(iVtx, pObj->Action.t_attach | CNAT_Bottom, pObj->GetX(), pObj->GetY(), DensityProvider(pForObject, *this))) - break; + break; if (iVtx == pObj->Shape.VtxNum) continue; // no contact // contact: Add object to list if (iAttachingObjectsCapacity == iAttachingObjectsCount) @@ -330,7 +330,7 @@ void C4SolidMask::Draw(C4TargetFacet &cgo) void C4SolidMask::RemoveTemporary(C4Rect where) { - if (!MaskPut || !pSolidMask || !pSolidMaskMatBuff) return; + if (!MaskPut || !pSolidMaskMatBuff) return; where.Intersect(MaskPutRect); // reput background pixels for (int y = where.y; y < where.y + where.Hgt; ++y) @@ -351,7 +351,7 @@ void C4SolidMask::RemoveTemporary(C4Rect where) void C4SolidMask::PutTemporary(C4Rect where) { - if (!MaskPut || !pSolidMask || !pSolidMaskMatBuff) return; + if (!MaskPut || !pSolidMaskMatBuff) return; where.Intersect(MaskPutRect); // reput vehicle pixels for (int y = where.y; y < where.y + where.Hgt; ++y) @@ -372,7 +372,7 @@ void C4SolidMask::PutTemporary(C4Rect where) void C4SolidMask::Repair(C4Rect where) { - if (!MaskPut || !pSolidMask || !pSolidMaskMatBuff) return; + if (!MaskPut || !pSolidMaskMatBuff) return; where.Intersect(MaskPutRect); // reput vehicle pixels for (int y = where.y; y < where.y + where.Hgt; ++y) @@ -406,25 +406,11 @@ C4SolidMask::C4SolidMask(C4Object *pForObject) : pForObject(pForObject) Last = this; if (Prev) Prev->Next = this; else First = this; - // copy solid mask from bitmap - int iNeededBufSize = pForObject->SolidMask.Wdt * pForObject->SolidMask.Hgt; - if (!(pSolidMask = new BYTE [iNeededBufSize])) return; - C4Surface * sfcBitmap = pForObject->GetGraphics()->GetBitmap(); - if (!sfcBitmap->Lock()) return; - for (int ycnt=0; ycntSolidMask.Hgt; ycnt++) - for (int xcnt=0; xcntSolidMask.Wdt; xcnt++) - { - // Solid mask target x/y is relative to def bitmap top-left, not object center - int dx = sfcBitmap->Scale*(pForObject->SolidMask.x+xcnt); - int dy = sfcBitmap->Scale*(pForObject->SolidMask.y+ycnt); - pSolidMask[xcnt+ycnt*pForObject->SolidMask.Wdt] = sfcBitmap->IsPixTransparent(dx,dy) ? 0x00 : 0xff; - } // create mat buff to store the material replaced by the solid mask // the upper left corner is here the [objpos]+rot([shapexy]+[targetxy]+[realWH]/2)-maxWH/2 MatBuffPitch = (int) sqrt(double(pForObject->SolidMask.Wdt * pForObject->SolidMask.Wdt + pForObject->SolidMask.Hgt * pForObject->SolidMask.Hgt))+1; if (!(pSolidMaskMatBuff= new BYTE [MatBuffPitch * MatBuffPitch] )) return; memset(pSolidMaskMatBuff, 0, MatBuffPitch * MatBuffPitch); - sfcBitmap->Unlock(); } C4SolidMask::~C4SolidMask() @@ -435,7 +421,6 @@ C4SolidMask::~C4SolidMask() if (Prev) Prev->Next = Next; if (First == this) First = Next; if (Last == this) Last = Prev; - delete [] pSolidMask; delete [] pSolidMaskMatBuff; delete [] ppAttachingObjects; } @@ -485,3 +470,19 @@ bool C4SolidMask::CheckConsistency() } #endif + +CSurface8 *C4SolidMask::LoadMaskFromFile(class C4Group &hGroup, const char *szFilename) +{ + // Construct SolidMask surface from PNG bitmap: + // All pixels that are more than 50% transparent are not solid + CPNGFile png; + StdBuf png_buf; + if (!hGroup.LoadEntry(szFilename, &png_buf)) return NULL; // error messages done by caller + if (!png.Load((BYTE*)png_buf.getData(), png_buf.getSize())) return NULL; + CSurface8 *result = new CSurface8(png.iWdt, png.iHgt); + for (size_t y=0u; ySetPix(x,y,((png.GetPix(x,y)>>24)<128) ? 0x00 : 0xff); + return result; +} + diff --git a/src/game/landscape/C4SolidMask.h b/src/landscape/C4SolidMask.h similarity index 78% rename from src/game/landscape/C4SolidMask.h rename to src/landscape/C4SolidMask.h index 6e4af7d76..45bd62174 100644 --- a/src/game/landscape/C4SolidMask.h +++ b/src/landscape/C4SolidMask.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003, 2005, 2008 Sven Eberhardt - * Copyright (c) 2007-2008 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Solid areas of objects, put into the landscape */ @@ -38,7 +35,6 @@ protected: C4TargetRect MaskPutRect; // absolute bounding screen rect at which the mask is put - tx and ty are offsets within pSolidMask (for rects outside the landscape) - BYTE *pSolidMask; // solid mask data: 0x00 if not solid at this position; 0xff if solid BYTE *pSolidMaskMatBuff; // material replaced by this solidmask. MCVehic if no solid mask data at this position OR another solidmask was already present during put C4Object *pForObject; @@ -59,12 +55,10 @@ protected: // Remove the solidmask temporarily void RemoveTemporary(C4Rect where); void PutTemporary(C4Rect where); - static void RemoveSolidMasks(); - static void PutSolidMasks(); // Reput and update Matbuf after landscape change underneath void Repair(C4Rect where); - friend class C4Landscape; + friend class C4Landscape; friend class DensityProvider; public: @@ -87,6 +81,11 @@ public: #else static bool CheckConsistency() { return true; } #endif + + static void RemoveSolidMasks(); + static void PutSolidMasks(); + + static CSurface8 *LoadMaskFromFile(class C4Group &hGroup, const char *szFilename); }; #endif diff --git a/src/game/landscape/C4Texture.cpp b/src/landscape/C4Texture.cpp similarity index 82% rename from src/game/landscape/C4Texture.cpp rename to src/landscape/C4Texture.cpp index 9f7cbd277..a2031f454 100644 --- a/src/game/landscape/C4Texture.cpp +++ b/src/landscape/C4Texture.cpp @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001-2003, 2005, 2007 Sven Eberhardt - * Copyright (c) 2002, 2004, 2007-2008, 2011 Peter Wortmann - * Copyright (c) 2006-2007, 2009 Günther Brammer - * Copyright (c) 2008, 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Textures used by the landscape */ @@ -140,27 +135,35 @@ bool C4TextureMap::AddTexture(const char *szTexture, C4Surface * sfcSurface) FirstTexture=pTexture; // Compute average texture color - sfcSurface->Lock(); - uint32_t avg_c[4] = { 0, 0, 0, 0 }; - for(int32_t y = 0; y < sfcSurface->Hgt; ++y) + if(sfcSurface) { - for(int32_t x = 0; x < sfcSurface->Wdt; ++x) + sfcSurface->Lock(); + uint32_t avg_c[4] = { 0, 0, 0, 0 }; + for(int32_t y = 0; y < sfcSurface->Hgt; ++y) { - DWORD c = sfcSurface->GetPixDw(x, y, false); - avg_c[0] += c & 0xff; - avg_c[1] += (c >> 8) & 0xff; - avg_c[2] += (c >> 16) & 0xff; - avg_c[3] += (c >> 24) & 0xff; + for(int32_t x = 0; x < sfcSurface->Wdt; ++x) + { + DWORD c = sfcSurface->GetPixDw(x, y, false); + avg_c[0] += c & 0xff; + avg_c[1] += (c >> 8) & 0xff; + avg_c[2] += (c >> 16) & 0xff; + avg_c[3] += (c >> 24) & 0xff; + } } - } - sfcSurface->Unlock(); + sfcSurface->Unlock(); + + double Size = sfcSurface->Wdt * sfcSurface->Hgt; + avg_c[0] = static_cast(avg_c[0] / Size + 0.5); + avg_c[1] = static_cast(avg_c[1] / Size + 0.5); + avg_c[2] = static_cast(avg_c[2] / Size + 0.5); + avg_c[3] = static_cast(avg_c[3] / Size + 0.5); + pTexture->SetAverageColor(avg_c[0] | (avg_c[1] << 8) | (avg_c[2] << 16) | (avg_c[3] << 24)); + } + else + { + pTexture->SetAverageColor(0x00000000); + } - double Size = sfcSurface->Wdt * sfcSurface->Hgt; - avg_c[0] = static_cast(avg_c[0] / Size + 0.5); - avg_c[1] = static_cast(avg_c[1] / Size + 0.5); - avg_c[2] = static_cast(avg_c[2] / Size + 0.5); - avg_c[3] = static_cast(avg_c[3] / Size + 0.5); - pTexture->AvgColor = avg_c[0] | (avg_c[1] << 8) | (avg_c[2] << 16) | (avg_c[3] << 24); return true; } @@ -422,14 +425,10 @@ void C4TextureMap::Default() fInitialized = false; } -void C4TextureMap::StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterial) +void C4TextureMap::StoreMapPalette(CStdPalette *Palette, C4MaterialMap &rMaterial) { - // Zero palette - ZeroMem(bypPalette,256*3); // Sky color - bypPalette[0]=192; - bypPalette[1]=196; - bypPalette[2]=252; + Palette->Colors[0] = C4RGB(192, 196, 252); // Material colors by texture map entries bool fSet[256]; ZeroMem(&fSet, sizeof (fSet)); @@ -438,12 +437,8 @@ void C4TextureMap::StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterial) { // Find material DWORD dwPix = Entry[i].GetPattern().PatternClr(0, 0); - bypPalette[3*i+0]=dwPix >> 16; - bypPalette[3*i+1]=dwPix >> 8; - bypPalette[3*i+2]=dwPix; - bypPalette[3*(i+IFT)+0]=dwPix >> 16; - bypPalette[3*(i+IFT)+1]=dwPix >> 8; - bypPalette[3*(i+IFT)+2]=dwPix | 0x0F; // IFT arbitrarily gets more blue + Palette->Colors[i] = dwPix; + Palette->Colors[i + IFT] = dwPix | 0x0F; // IFT arbitrarily gets more blue fSet[i] = fSet[i + IFT] = true; } // Crosscheck colors, change equal palette entries @@ -452,17 +447,16 @@ void C4TextureMap::StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterial) { // search equal entry int32_t j = 0; - for (; j < i; j++) if (fSet[j]) - if (bypPalette[3*i+0] == bypPalette[3*j+0] && - bypPalette[3*i+1] == bypPalette[3*j+1] && - bypPalette[3*i+2] == bypPalette[3*j+2]) + for (; j < i; j++) + if (fSet[j] && Palette->Colors[i] == Palette->Colors[j]) break; // not found? ok then if (j >= i) break; // change randomly - if (rand() < RAND_MAX / 2) bypPalette[3*i+0] += 3; else bypPalette[3*i+0] -= 3; - if (rand() < RAND_MAX / 2) bypPalette[3*i+1] += 3; else bypPalette[3*i+1] -= 3; - if (rand() < RAND_MAX / 2) bypPalette[3*i+2] += 3; else bypPalette[3*i+2] -= 3; + Palette->Colors[i] = C4RGB( + (rand() < RAND_MAX / 2) ? GetRedValue(Palette->Colors[i]) + 3 : GetRedValue(Palette->Colors[i]) - 3, + (rand() < RAND_MAX / 2) ? GetGreenValue(Palette->Colors[i]) + 3 : GetGreenValue(Palette->Colors[i]) - 3, + (rand() < RAND_MAX / 2) ? GetBlueValue(Palette->Colors[i]) + 3 : GetBlueValue(Palette->Colors[i]) - 3); } } diff --git a/src/game/landscape/C4Texture.h b/src/landscape/C4Texture.h similarity index 80% rename from src/game/landscape/C4Texture.h rename to src/landscape/C4Texture.h index e534a9367..667881150 100644 --- a/src/game/landscape/C4Texture.h +++ b/src/landscape/C4Texture.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001-2002, 2007 Sven Eberhardt - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Textures used by the landscape */ @@ -36,6 +32,7 @@ public: ~C4Texture(); C4Surface * Surface32; + void SetAverageColor(uint32_t Color) { AvgColor = Color; } uint32_t GetAverageColor() const { return AvgColor; } protected: char Name[C4M_MaxName+1]; @@ -83,7 +80,7 @@ public: void RemoveEntry(int32_t iIndex) { if (Inside(iIndex, 1, C4M_MaxTexIndex-1)) Entry[iIndex].Clear(); } void Default(); void Clear(); - void StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterials); + void StoreMapPalette(CStdPalette *, C4MaterialMap &rMaterials); static bool LoadFlags(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures); int32_t LoadMap(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures); int32_t Init(); @@ -97,9 +94,9 @@ public: C4Texture * GetTexture(const char *szTexture); bool CheckTexture(const char *szTexture); // return whether texture exists bool AddEntry(BYTE byIndex, const char *szMaterial, const char *szTexture); + bool AddTexture(const char *szTexture, C4Surface * sfcSurface); int32_t GetTextureIndex(const char *pTexName); protected: - bool AddTexture(const char *szTexture, C4Surface * sfcSurface); }; extern C4TextureMap TextureMap; diff --git a/src/game/landscape/C4Weather.cpp b/src/landscape/C4Weather.cpp similarity index 88% rename from src/game/landscape/C4Weather.cpp rename to src/landscape/C4Weather.cpp index eaf563fb7..ee67169d9 100644 --- a/src/game/landscape/C4Weather.cpp +++ b/src/landscape/C4Weather.cpp @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002, 2005, 2007 Sven Eberhardt - * Copyright (c) 2004-2005, 2007 Peter Wortmann - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Controls temperature, wind, and natural disasters */ diff --git a/src/game/landscape/C4Weather.h b/src/landscape/C4Weather.h similarity index 62% rename from src/game/landscape/C4Weather.h rename to src/landscape/C4Weather.h index 753e7f3ff..7b0db2ee7 100644 --- a/src/game/landscape/C4Weather.h +++ b/src/landscape/C4Weather.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Controls temperature, wind, and natural disasters */ diff --git a/src/lib/C4InputValidation.cpp b/src/lib/C4InputValidation.cpp index 2ece3f2f7..06e0037dc 100644 --- a/src/lib/C4InputValidation.cpp +++ b/src/lib/C4InputValidation.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007-2008 Sven Eberhardt - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2011 Julius Michaelis - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // user input validation functions diff --git a/src/lib/C4InputValidation.h b/src/lib/C4InputValidation.h index a0dca2a73..fffc1facc 100644 --- a/src/lib/C4InputValidation.h +++ b/src/lib/C4InputValidation.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2007-2008 Sven Eberhardt - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // user input validation functions diff --git a/src/lib/C4Log.cpp b/src/lib/C4Log.cpp index 9aaaa1505..fa1f35458 100644 --- a/src/lib/C4Log.cpp +++ b/src/lib/C4Log.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2008 Matthes Bender - * Copyright (c) 2004-2008 Peter Wortmann - * Copyright (c) 2004-2006 Sven Eberhardt - * Copyright (c) 2005-2007, 2009 Günther Brammer - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2010-2011 Julius Michaelis - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Log file handling */ diff --git a/src/lib/C4Log.h b/src/lib/C4Log.h index 1fafce8aa..dc271608a 100644 --- a/src/lib/C4Log.h +++ b/src/lib/C4Log.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006 Sven Eberhardt - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Log file handling */ diff --git a/src/lib/C4LogBuf.cpp b/src/lib/C4LogBuf.cpp index 939955b13..2bc2f38a5 100644 --- a/src/lib/C4LogBuf.cpp +++ b/src/lib/C4LogBuf.cpp @@ -1,25 +1,25 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2005, 2007 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a buffer holding a log history #include "C4Include.h" #include "C4LogBuf.h" +#include + C4LogBuffer::C4LogBuffer(int iSize, int iMaxLines, int iLBWidth, const char *szIndentChars, bool fDynamicGrow, bool fMarkup) : iBufSize(iSize), iFirstLinePos(0), iAfterLastLinePos(0), iLineDataPos(0), iNextLineDataPos(0), iMaxLineCount(iMaxLines), iLineCount(0), iLineBreakWidth(iLBWidth), fDynamicGrow(fDynamicGrow), fMarkup(fMarkup) diff --git a/src/lib/C4LogBuf.h b/src/lib/C4LogBuf.h index 921e2fa49..976db923c 100644 --- a/src/lib/C4LogBuf.h +++ b/src/lib/C4LogBuf.h @@ -1,27 +1,23 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2004-2005 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // a buffer holding a log history #ifndef INC_C4LogBuf #define INC_C4LogBuf -#include - // circular log buffer to holding line-wise log data class C4LogBuffer { diff --git a/src/lib/C4Markup.cpp b/src/lib/C4Markup.cpp index 147992553..79cd99110 100644 --- a/src/lib/C4Markup.cpp +++ b/src/lib/C4Markup.cpp @@ -1,25 +1,23 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002-2003, 2006-2007 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // markup tags for fonts #include "C4Include.h" #include -#include +#include void C4MarkupTagItalic::Apply(C4BltTransform &rBltTrf, bool fDoClr, DWORD &dwClr) { diff --git a/src/lib/C4Markup.h b/src/lib/C4Markup.h index d7bdb5a3d..4f674ad8b 100644 --- a/src/lib/C4Markup.h +++ b/src/lib/C4Markup.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002-2003 Sven Eberhardt - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // markup tags for fonts diff --git a/src/lib/C4NameList.cpp b/src/lib/C4NameList.cpp index c54e50bd8..c5314d3ba 100644 --- a/src/lib/C4NameList.cpp +++ b/src/lib/C4NameList.cpp @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A static list of strings and integer values, i.e. for material amounts */ diff --git a/src/lib/C4NameList.h b/src/lib/C4NameList.h index fd69cdca4..4efb96120 100644 --- a/src/lib/C4NameList.h +++ b/src/lib/C4NameList.h @@ -1,21 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001, 2005 Sven Eberhardt - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* A static list of strings and integer values, i.e. for material amounts */ diff --git a/src/lib/C4RTF.cpp b/src/lib/C4RTF.cpp index e0ec960ad..6ab302bde 100644 --- a/src/lib/C4RTF.cpp +++ b/src/lib/C4RTF.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2008 Günther Brammer - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // RTF file parsing functionality diff --git a/src/lib/C4RTF.h b/src/lib/C4RTF.h index ab0f37ad0..3e10d9b44 100644 --- a/src/lib/C4RTF.h +++ b/src/lib/C4RTF.h @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Sven Eberhardt - * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, 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. + */ // RTF file parsing functionality diff --git a/src/lib/C4Random.cpp b/src/lib/C4Random.cpp index 216c16738..da0643611 100644 --- a/src/lib/C4Random.cpp +++ b/src/lib/C4Random.cpp @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2005, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Network-safe random number generator */ @@ -26,23 +24,30 @@ int RandomCount = 0; unsigned int RandomHold = 0; -#ifdef DEBUGREC int Random(int iRange) { - // next pseudorandom value - RandomCount++; - C4RCRandom rc; - rc.Cnt=RandomCount; - rc.Range=iRange; - if (iRange==0) - rc.Val=0; + if (Config.General.DebugRec) + { + // next pseudorandom value + RandomCount++; + C4RCRandom rc; + rc.Cnt=RandomCount; + rc.Range=iRange; + if (iRange<=0) + rc.Val=0; + else + { + RandomHold = ((uint64_t)RandomHold * 16807) % 2147483647; + rc.Val = RandomHold % iRange; + } + AddDbgRec(RCT_Random, &rc, sizeof(rc)); + return rc.Val; + } else { - RandomHold = RandomHold * 214013L + 2531011L; - rc.Val=(RandomHold >> 16) % iRange; + RandomCount++; + if (iRange<=0) return 0; + RandomHold = ((uint64_t)RandomHold * 16807) % 2147483647; + return RandomHold % iRange; } - AddDbgRec(RCT_Random, &rc, sizeof(rc)); - return rc.Val; } -#endif - diff --git a/src/lib/C4Random.h b/src/lib/C4Random.h index 50dceae57..d6ecb2388 100644 --- a/src/lib/C4Random.h +++ b/src/lib/C4Random.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001-2002 Sven Eberhardt - * Copyright (c) 2005 Günther Brammer - * Copyright (c) 2007 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Network-safe random number generator */ @@ -33,21 +29,11 @@ inline void FixedRandom(DWORD dwSeed) { // for SafeRandom srand((unsigned)time(NULL)); - RandomHold=dwSeed; // srand(dwSeed); + RandomHold=dwSeed; RandomCount=0; } -#ifdef DEBUGREC int Random(int iRange); -#else -inline int Random(int iRange) -{ - RandomCount++; - if (iRange==0) return 0; - RandomHold = RandomHold * 214013L + 2531011L; - return (RandomHold >> 16) % iRange; -} -#endif inline unsigned int SeededRandom(unsigned int iSeed, unsigned int iRange) { diff --git a/src/lib/C4Real.cpp b/src/lib/C4Real.cpp index 41a0756ab..ca01e7bc1 100644 --- a/src/lib/C4Real.cpp +++ b/src/lib/C4Real.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2010 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // fixed numbers - sine functions diff --git a/src/lib/C4Real.h b/src/lib/C4Real.h index aae05748f..51dc06785 100644 --- a/src/lib/C4Real.h +++ b/src/lib/C4Real.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2002, 2005 Sven Eberhardt - * Copyright (c) 2002, 2004-2005, 2007, 2009 Peter Wortmann - * Copyright (c) 2005, 2007 Günther Brammer - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Fixed point math extracted from ALLEGRO by Shawn Hargreaves */ @@ -42,7 +37,12 @@ // activate to switch to classic fixed-point math #define C4REAL_USE_FIXNUM 1 #define inline ALWAYS_INLINE -#define FIXED_EMULATE_64BIT + +// gcc 4.6 generates better code for FIXED_EMULATE_64BIT disablen for both +// 32 and 64 bit. It properly recognizes that the 32,32->64 multiplication +// instruction of the x86 is the right choice for the job whereas the more +// complicated FIXED_EMULATE_64BIT version requires multiple multiplications +//#define FIXED_EMULATE_64BIT // note: C4Fixed has to be defined even though it isn't used // any more. It is used to convert old-format fixed values @@ -99,13 +99,10 @@ private: int32_t to_int() const { int32_t r = val; - // be careful not to overflow - r += (val <= 0x7fffffff - FIXED_FPF / 2) * FIXED_FPF / 2; - // ensure that -x.50 is rounded to -(x+1) - r -= (val < 0); - r >>= FIXED_SHIFT; - // round 32767.5 to 32768 (not that anybody cares) - r += (val > 0x7fffffff - FIXED_FPF / 2); + // round towards positive infinity + r >>= (FIXED_SHIFT - 1); + r += 1; + r >>= 1; return r; } int32_t to_int(int32_t prec) const @@ -113,7 +110,6 @@ private: int64_t r = val; r *= prec; r += FIXED_FPF / 2; - r -= (val < 0); r >>= FIXED_SHIFT; return int32_t(r); } @@ -148,11 +144,11 @@ public: #ifndef FIXED_EMULATE_64BIT val = int32_t( (int64_t(val) * fVal2.val) / FIXED_FPF ); #else - int32_t x0 = val & (FIXED_FPF - 1), - x1 = val >> FIXED_SHIFT; - int32_t y0 = fVal2.val & (FIXED_FPF - 1), - y1 = fVal2.val >> FIXED_SHIFT; - val = x0*y0/FIXED_FPF + x0*y1 + x1*y0 + x1*y1*FIXED_FPF; + uint32_t x0 = val & (FIXED_FPF - 1); + int32_t x1 = val >> FIXED_SHIFT; + uint32_t y0 = fVal2.val & (FIXED_FPF - 1); + int32_t y1 = fVal2.val >> FIXED_SHIFT; + val = int32_t(x0*y0/FIXED_FPF) + int32_t(x0)*y1 + x1*int32_t(y0) + x1*y1*FIXED_FPF; #endif return *this; } @@ -333,6 +329,7 @@ inline C4Real C4REAL10(int x) { return float(x) / 10; } #endif // define 0 const C4Real Fix0 = itofix(0); +const C4Real Fix1 = itofix(1); // conversion... // note: keep out! really dirty casts! diff --git a/src/lib/C4Rect.cpp b/src/lib/C4Rect.cpp index ecc7312e4..c65fbdfea 100644 --- a/src/lib/C4Rect.cpp +++ b/src/lib/C4Rect.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2005, 2007 Matthes Bender - * Copyright (c) 2001-2007 Sven Eberhardt - * Copyright (c) 2003, 2005-2007 Peter Wortmann - * Copyright (c) 2006-2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Basic classes for rectangles and vertex outlines */ diff --git a/src/lib/C4Rect.h b/src/lib/C4Rect.h index 54a40e3de..794c01ba8 100644 --- a/src/lib/C4Rect.h +++ b/src/lib/C4Rect.h @@ -1,22 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2001, 2003-2006 Sven Eberhardt - * Copyright (c) 2005-2006 Peter Wortmann - * Copyright (c) 2006, 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Basic classes for rectangles and vertex outlines */ @@ -28,10 +24,7 @@ #include -class StdCompiler; - struct FLOAT_RECT { float left,right,top,bottom; }; -class C4TargetFacet; class C4Rect { @@ -43,14 +36,14 @@ public: bool Overlap(C4Rect &rTarget); void Intersect(const C4Rect &r2); void Add(const C4Rect &r2); - bool operator ==(const C4Rect &r2) { return !((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); } - bool operator !=(const C4Rect &r2) { return 0 != ((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); } + bool operator ==(const C4Rect &r2) const { return !((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); } + bool operator !=(const C4Rect &r2) const { return 0 != ((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); } - bool Contains(int32_t iX, int32_t iY) + bool Contains(int32_t iX, int32_t iY) const { return iX>=x && iX=y && iY=x && iX+iWdt=y && iY+iHgtiCount) - LogSilentF("%s: n = %d, t = %d, td = %.2f", - pAkt->strName, pAkt->iCount, pAkt->iTimeSum, - double(pAkt->iTimeSum) / /*Max(1,*/ pAkt->iCount /*- 100)*/ * 1000); + LogSilentF("%s: n = %u, t = %u, td = %.2f", + pAkt->strName, pAkt->iCount, pAkt->tTimeSum, + double(pAkt->tTimeSum) / /*Max(1,*/ pAkt->iCount /*- 100)*/ * 1000); } @@ -162,7 +159,7 @@ void C4MainStat::ShowPart(int FrameCounter) // insert all stats for (pAkt = pFirst; pAkt; pAkt = pAkt->pNext) - LogSilentF("%s: n=%d, t=%d", pAkt->strName, pAkt->iCountPart, pAkt->iTimeSumPart); + LogSilentF("%s: n=%u, t=%u", pAkt->strName, pAkt->iCountPart, pAkt->tTimeSumPart); // insert part stat end idtf LogSilentF("** PartStat end\n"); @@ -186,7 +183,7 @@ void C4Stat::Reset() { iStartCalled = 0; - iTimeSum = 0; + tTimeSum = 0; iCount = 0; ResetPart(); @@ -194,7 +191,7 @@ void C4Stat::Reset() void C4Stat::ResetPart() { - iTimeSumPart = 0; + tTimeSumPart = 0; iCountPart = 0; } diff --git a/src/lib/C4Stat.h b/src/lib/C4Stat.h index 94aa57f5b..3acdce9f1 100644 --- a/src/lib/C4Stat.h +++ b/src/lib/C4Stat.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2001, 2007 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // statistics #ifndef INC_C4Stat @@ -59,7 +57,7 @@ public: inline void Start() { if (!iStartCalled) - iStartTick = GetTime(); + tStartTime = C4TimeMilliseconds::Now(); iCount ++; iCountPart ++; iStartCalled ++; @@ -71,10 +69,10 @@ public: iStartCalled --; if (!iStartCalled && iCount >= 100) { - unsigned int iTime = GetTime() - iStartTick; + uint32_t tTime = C4TimeMilliseconds::Now() - tStartTime; - iTimeSum += iTime; - iTimeSumPart += iTime; + tTimeSum += tTime; + tTimeSumPart += tTime; } } @@ -89,9 +87,7 @@ protected: C4Stat* pNext; C4Stat* pPrev; - - // start tick - unsigned int iStartTick; + C4TimeMilliseconds tStartTime; // start-call depth unsigned int iStartCalled; @@ -100,7 +96,7 @@ protected: // ** statistic data // sum of times - unsigned int iTimeSum; + uint32_t tTimeSum; // number of starts called unsigned int iCount; @@ -108,7 +104,7 @@ protected: // ** statistic data (partial stat) // sum of times - unsigned int iTimeSumPart; + uint32_t tTimeSumPart; // number of starts called unsigned int iCountPart; diff --git a/src/lib/PathFinder.cpp b/src/lib/PathFinder.cpp index d81309cc2..d90001c3e 100644 --- a/src/lib/PathFinder.cpp +++ b/src/lib/PathFinder.cpp @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Finds the shortest free path through any pixel environment */ diff --git a/src/lib/PathFinder.h b/src/lib/PathFinder.h index efdcc4b21..5d04e2418 100644 --- a/src/lib/PathFinder.h +++ b/src/lib/PathFinder.h @@ -1,20 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Finds the shortest free path through any pixel environment */ diff --git a/src/lib/Standard.cpp b/src/lib/Standard.cpp index 63016d610..f1c1aa460 100644 --- a/src/lib/Standard.cpp +++ b/src/lib/Standard.cpp @@ -1,24 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2003-2004, 2007 Matthes Bender - * Copyright (c) 2002, 2004, 2007-2008 Sven Eberhardt - * Copyright (c) 2004-2005 Peter Wortmann - * Copyright (c) 2005, 2007, 2009, 2011 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010-2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* All kinds of valuable helpers */ @@ -554,7 +548,7 @@ void SNewSegment(char *szStr, const char *szSepa) int SGetLine(const char *szText, const char *cpPosition) { if (!szText || !cpPosition) return 0; - int iLines = 0; + int iLines = 1; while (*szText && (szText127); if (c>191 && c<224) { unsigned char c2 = *szString++; - if ((c2 & 192) != 128) { *pszString = szString; return '?'; } + if ((c2 & 192) != 128) { *pszString = szString; return REPLACEMENT_CHARACTER; } dwResult = (int(c&31)<<6) | (c2&63); // two char code } else if (c >= 224 && c <= 239) { unsigned char c2 = *szString++; - if ((c2 & 192) != 128) { *pszString = szString; return '?'; } + if ((c2 & 192) != 128) { *pszString = szString; return REPLACEMENT_CHARACTER; } unsigned char c3 = *szString++; - if ((c3 & 192) != 128) { *pszString = szString; return '?'; } + if ((c3 & 192) != 128) { *pszString = szString; return REPLACEMENT_CHARACTER; } dwResult = (int(c&15)<<12) | (int(c2&63)<<6) | int(c3&63); // three char code } else if (c >= 240 && c <= 247) { unsigned char c2 = *szString++; - if ((c2 & 192) != 128) { *pszString = szString; return '?'; } + if ((c2 & 192) != 128) { *pszString = szString; return REPLACEMENT_CHARACTER; } unsigned char c3 = *szString++; - if ((c3 & 192) != 128) { *pszString = szString; return '?'; } + if ((c3 & 192) != 128) { *pszString = szString; return REPLACEMENT_CHARACTER; } unsigned char c4 = *szString++; - if ((c4 & 192) != 128) { *pszString = szString; return '?'; } + if ((c4 & 192) != 128) { *pszString = szString; return REPLACEMENT_CHARACTER; } dwResult = (int(c&7)<<18) | (int(c2&63)<<12) | (int(c3&63)<<6) | int(c4&63); // four char code } *pszString = szString; diff --git a/src/lib/Standard.h b/src/lib/Standard.h index 559ce2a65..ad6016c41 100644 --- a/src/lib/Standard.h +++ b/src/lib/Standard.h @@ -1,23 +1,18 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 1998-2000, 2007 Matthes Bender - * Copyright (c) 2002, 2004-2005, 2007 Sven Eberhardt - * Copyright (c) 2005, 2007, 2009 Peter Wortmann - * Copyright (c) 2005-2009, 2011 Günther Brammer - * Copyright (c) 2009-2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 1998-2000, Matthes Bender + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* All kinds of valuable helpers */ diff --git a/src/lib/StdAdaptors.h b/src/lib/StdAdaptors.h index 702b45edf..f6d1439f9 100644 --- a/src/lib/StdAdaptors.h +++ b/src/lib/StdAdaptors.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2008 Peter Wortmann - * Copyright (c) 2005-2008, 2011 Günther Brammer - * Copyright (c) 2005-2007 Sven Eberhardt - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef STDADAPTORS_H #define STDADAPTORS_H @@ -382,6 +377,56 @@ template inline StdArrayDefaultAdapt mkArrayAdaptMap(T *pArray, size_t iSize, const D &rDefault, M map) { return StdArrayDefaultAdapt(pArray, iSize, rDefault, map); } #define mkArrayAdaptMapDM(A, D, M) mkArrayAdaptMap(A, sizeof(A) / sizeof(*(A)), D, M) +// * Array Adaptor (defaulting to another array) +// Stores a separated list, sets defaults if a value or separator is missing. +template > +struct StdArrayDefaultArrayAdapt +{ + StdArrayDefaultArrayAdapt(T *pArray, size_t iSize, const D &rDefault, const M &map = M()) + : pArray(pArray), iSize(iSize), rDefault(rDefault), map(map) + { } + T *pArray; size_t iSize; const D &rDefault; const M map; + inline void CompileFunc(StdCompiler *pComp) const + { + size_t i, iWrite = iSize; + bool fCompiler = pComp->isCompiler(); + // Decompiling: Omit defaults + if (!fCompiler && pComp->hasNaming()) + while (iWrite > 0 && pArray[iWrite - 1] == rDefault[iWrite - 1]) + iWrite--; + // Read/write values + for (i = 0; i < iWrite; i++) + { + // Separator? + if (i) if (!pComp->Separator(StdCompiler::SEP_SEP)) break; + // Expect a value. Default if not found. + pComp->Value(mkDefaultAdapt(map(pArray[i]), rDefault[i])); + } + // Fill rest of array + if (fCompiler) + for (; i < iSize; i++) + pArray[i] = rDefault[i]; + } + // Additional defaulting (whole array) + inline bool operator == (const T *pDefaults) const + { + for (size_t i = 0; i < iSize; i++) + if (pArray[i] != pDefaults[i]) + return false; + return true; + } + inline StdArrayDefaultArrayAdapt &operator = (const T *pDefaults) + { + for (size_t i = 0; i < iSize; i++) + pArray[i] = pDefaults[i]; + return *this; + } + ALLOW_TEMP_TO_REF(StdArrayDefaultArrayAdapt) +}; +template +inline StdArrayDefaultArrayAdapt mkArrayAdaptDefArr(T *pArray, size_t iSize, const D &rDefault) { return StdArrayDefaultArrayAdapt(pArray, iSize, rDefault); } +#define mkArrayAdaptDMA(A, D) mkArrayAdaptDefArr(A, sizeof(A) / sizeof(*(A)), D) + // * Insertion Adaptor // Compile a value before / after another template diff --git a/src/lib/StdBase64.cpp b/src/lib/StdBase64.cpp deleted file mode 100644 index ee7cc467c..000000000 --- a/src/lib/StdBase64.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2003-2004 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ -/* Base64 encoding / decoding */ - -#include "C4Include.h" -#include "StdBase64.h" - -// Peter's B64Encode implementation would yield incorrect results in Release build -// so I replaced it with some other implementation which does the job... - -// base 64 table -const char Base64Tbl [] = - { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', - 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - -// reversed base 64 table -const unsigned char Base64RTbl[] = -{ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff -}; - -// base 64 padding char -const char Base64Pad = '='; - -char *B64Encode(const void *pData, int iSize) -{ - // ensure b64 table has correct size - if (sizeof(Base64Tbl) != 64) return NULL; - // calc output size - int ioSize = (iSize / 3) * 4; - if (iSize % 3) ioSize += 4; // end padding - ioSize += (ioSize / 76) * 2; // line breaks - ioSize++; // null char - // alloc output mem - char *poData = new char [ioSize]; - // start encoding - const unsigned char *pPos = (const unsigned char *)pData; char *poPos = poData; - for (int i = 0; i < iSize / 3; i++) - { - unsigned char c1 = *pPos++, c2 = *pPos++, c3 = *pPos++; - // char 1 - *(poPos++) = Base64Tbl[ (c1 >> 2)]; - // char 2 - *(poPos++) = Base64Tbl[((c1 & 0x3) << 4) | (c2 >> 4)]; - // char 3 - *(poPos++) = Base64Tbl[((c2 & 0xf) << 2) | (c3 >> 6)]; - // char 4 - *(poPos++) = Base64Tbl[ c3 & 0x3f]; - // line break (every 76 characters) - if (!((i + 1) % 19)) { *(poPos++) = '\r'; *(poPos++) = '\n'; } - } - // encode last bytes - switch (iSize % 3) - { - case 0: // nothign left - break; // no padding - case 1: // one byte left - { - unsigned char c = *pPos++; - // char 1 - *(poPos++) = Base64Tbl[ (c >> 2)]; - // char 2 - *(poPos++) = Base64Tbl[((c & 0x3) << 4) ]; - // char 3 - *(poPos++) = Base64Pad; - // char 4 - *(poPos++) = Base64Pad; - } - break; - case 2: // two bytes left - { - unsigned char c1 = *pPos++, c2 = *pPos++; - // char 1 - *(poPos++) = Base64Tbl[ (c1 >> 2)]; - // char 2 - *(poPos++) = Base64Tbl[((c1 & 0x3) << 4) | (c2 >> 4)]; - // char 3 - *(poPos++) = Base64Tbl[((c2 & 0xf) << 2) ]; - // char 4 - *(poPos++) = Base64Pad; - } - break; - } - // append zero - *(poPos++) = '\0'; - // check size - if (poPos - poData != ioSize) { delete [] poData; return NULL; } - // return data - return poData; -} - -const char x = '\x01'; - -inline unsigned char B64DecodeChar(const unsigned char c) -{ - return( c == Base64Pad ? 0 : - c & 128 ? 0xff : - Base64RTbl[c] ); -} - -char *B64Decode(const char *pData, int &ioSize) -{ - // first: count the characters - const char *pPos; int iCount = 0; - for (pPos = pData; *pPos; pPos++) - if (B64DecodeChar(*pPos) != 0xff) - iCount++; - // if(iCount % 4) return NULL; - // alloc output buffer - char *poData = new char [ioSize = (iCount / 4) * 3]; - // begin decode - pPos = pData; char *poPos = poData; - for (int i = 0; i < iCount / 4; i++) - { - // read & decode 4 bytes - unsigned char c[4]; - for (; *pPos;) if ((c[0] = B64DecodeChar(*(pPos++))) != 0xff) break; if (!*pPos) c[0] = 0; - for (; *pPos;) if ((c[1] = B64DecodeChar(*(pPos++))) != 0xff) break; if (!*pPos) c[1] = 0; - for (; *pPos;) if ((c[2] = B64DecodeChar(*(pPos++))) != 0xff) break; if (!*pPos) c[2] = 0; - for (; *pPos;) if ((c[3] = B64DecodeChar(*(pPos++))) != 0xff) break; if (!*pPos) c[3] = 0; - // write 3 bytes - *(poPos++) = (c[0] << 2) | (c[1] >> 4); - *(poPos++) = (c[1] << 4) | (c[2] >> 2); - *(poPos++) = (c[2] << 6) | c[3] ; - } - // truncate length - if (*(--pPos) == Base64Pad) ioSize--; - if (*(--pPos) == Base64Pad) ioSize--; - // ok - return poData; -} diff --git a/src/lib/StdBase64.h b/src/lib/StdBase64.h deleted file mode 100644 index 1f926b98c..000000000 --- a/src/lib/StdBase64.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2003 Peter Wortmann - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ -/* Base64 encoding / decoding */ - - -char *B64Encode(const void *pData, int iSize); -char *B64Decode(const char *pData, int &ioSize); diff --git a/src/lib/StdBuf.cpp b/src/lib/StdBuf.cpp index 7b66fdfc3..4c807ed92 100644 --- a/src/lib/StdBuf.cpp +++ b/src/lib/StdBuf.cpp @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005, 2007-2008, 2010-2011 Günther Brammer - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2009, 2011 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" #include @@ -238,7 +233,16 @@ void StdStrBuf::AppendFormatV(const char *szFmt, va_list args) // Grow Grow(512); // Try output - iBytes = vsnprintf(getMPtr(iStart), getLength() - iStart, szFmt, args); + va_list args_copy; + #ifdef va_copy + va_copy(args_copy, args); + #else + args_copy = args; + #endif + iBytes = vsnprintf(getMPtr(iStart), getLength() - iStart, szFmt, args_copy); + #ifdef va_copy + va_end(args_copy); + #endif } while (iBytes < 0 || (unsigned int)(iBytes) >= getLength() - iStart); // Calculate real length, if vsnprintf didn't return anything of value diff --git a/src/lib/StdBuf.h b/src/lib/StdBuf.h index eded53e7e..5b18435fd 100644 --- a/src/lib/StdBuf.h +++ b/src/lib/StdBuf.h @@ -1,25 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2005, 2007 Sven Eberhardt - * Copyright (c) 2005, 2008-2011 Günther Brammer - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2009 Nicolas Hake - * Copyright (c) 2009 mizipzor - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // Standard buffer classes diff --git a/src/lib/StdColors.h b/src/lib/StdColors.h index 7bea4d44c..bf0bfa735 100644 --- a/src/lib/StdColors.h +++ b/src/lib/StdColors.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2002, 2004-2006 Sven Eberhardt - * Copyright (c) 2005 Peter Wortmann - * Copyright (c) 2008, 2011 Günther Brammer - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // color calculation routines @@ -297,16 +292,10 @@ inline bool RGB2rgb(int R, int G, int B, double *pr, double *pg, double *pb, dou // a standard pal struct CStdPalette { - BYTE Colors[3*256]; - BYTE Alpha[3*256]; // TODO: alphapal: Why 3*? Isn't Alpha[256] enough? + DWORD Colors[256]; DWORD GetClr(BYTE byCol) - { return C4RGB(Colors[byCol*3], Colors[byCol*3+1], Colors[byCol*3+2])+(Alpha[byCol]<<24); } - - void EnforceC0Transparency() - { - Colors[0]=Colors[1]=Colors[2]=0; Alpha[0]=0; - } + { return Colors[byCol]; } }; // clrmod-add-map to cover a drawing range in which all draws shall be adjusted by the map diff --git a/src/lib/StdCompiler.cpp b/src/lib/StdCompiler.cpp index 2730f3b61..1e438f9fb 100644 --- a/src/lib/StdCompiler.cpp +++ b/src/lib/StdCompiler.cpp @@ -1,23 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006 Sven Eberhardt - * Copyright (c) 2005 Günther Brammer - * Copyright (c) 2005-2007 Peter Wortmann - * Copyright (c) 2008 Matthes Bender - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" #include "StdCompiler.h" diff --git a/src/lib/StdCompiler.h b/src/lib/StdCompiler.h index 4127f01cf..e102da627 100644 --- a/src/lib/StdCompiler.h +++ b/src/lib/StdCompiler.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2005-2006 Peter Wortmann - * Copyright (c) 2005, 2009 Günther Brammer - * Copyright (c) 2006 Sven Eberhardt - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef STDCOMPILER_H #define STDCOMPILER_H @@ -331,7 +326,7 @@ void CompileNewFunc(T *&pStruct, StdCompiler *pComp) // a) Define a standard constructor for T // b) Specialize this function to do whatever the correct // behaviour is to construct the object from compiler data - std::auto_ptr temp(new T); // exception-safety + std::unique_ptr temp(new T); // exception-safety // Compile pComp->Value(*temp); pStruct = temp.release(); @@ -345,7 +340,7 @@ void CompileNewFunc(T *&pStruct, StdCompiler *pComp, const P& rPar) // a) Define a standard constructor for T // b) Specialize this function to do whatever the correct // behaviour is to construct the object from compiler data - std::auto_ptr temp(new T); // exception-safety + std::unique_ptr temp(new T); // exception-safety // Compile //temp->CompileFunc(pComp, rPar); pComp->Value(mkParAdapt(*temp, rPar)); @@ -361,7 +356,7 @@ void CompileNewFuncCtx(T *&pStruct, StdCompiler *pComp, const ContextT& rCtx) // b) Specialize this function to do whatever the correct // behaviour is to construct the object from compiler data // and context - std::auto_ptr temp(new T(rCtx)); // exception-safety + std::unique_ptr temp(new T(rCtx)); // exception-safety // Compile pComp->Value(*temp); pStruct = temp.release(); @@ -376,7 +371,7 @@ void CompileNewFuncCtx(T *&pStruct, StdCompiler *pComp, const ContextT& rCtx, co // b) Specialize this function to do whatever the correct // behaviour is to construct the object from compiler data // and context - std::auto_ptr temp(new T(rCtx)); // exception-safety + std::unique_ptr temp(new T(rCtx)); // exception-safety // Compile //temp->CompileFunc(pComp, rPar); pComp->Value(mkParAdapt(*temp, rPar)); diff --git a/src/lib/StdMesh.cpp b/src/lib/StdMesh.cpp index 9cf7663e4..bce4523fe 100644 --- a/src/lib/StdMesh.cpp +++ b/src/lib/StdMesh.cpp @@ -1,31 +1,41 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Armin Burgmeier - * Copyright (c) 2009 Mark Haßelbusch - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" #include #include -static int StdMeshFaceCmp(const StdMeshFace& face1, const StdMeshFace& face2); +namespace +{ + struct StdMeshFaceOrderHelper + { + float z; + unsigned int i; + }; +} + +static int StdMeshFaceCmp(const StdMeshFaceOrderHelper& h1, const StdMeshFaceOrderHelper& h2) +{ + if(h1.z < h2.z) return -1; + else if(h1.z > h2.z) return +1; + return 0; +} #define SORT_NAME StdMesh -#define SORT_TYPE StdMeshFace +#define SORT_TYPE StdMeshFaceOrderHelper #define SORT_CMP StdMeshFaceCmp #include "timsort/sort.h" @@ -42,71 +52,80 @@ namespace } }; - // Helper to sort faces for FaceOrdering - struct StdMeshInstanceFaceOrderingCmpPred + float StdMeshFaceOrderGetVertexZ(const StdMeshVertex& vtx, const StdMeshMatrix& trans) { - const StdMeshVertex* m_vertices; - StdSubMeshInstance::FaceOrdering m_face_ordering; - const StdMeshMatrix& m_global_trans; + // TODO: Need to apply attach matrix in case of attached meshes - StdMeshInstanceFaceOrderingCmpPred(const StdMeshInstance& mesh_inst, const StdSubMeshInstance& sub_inst, - StdSubMeshInstance::FaceOrdering face_ordering, const StdMeshMatrix& global_trans): - m_face_ordering(face_ordering), m_global_trans(global_trans) + // We need to evaluate the Z coordinate of the transformed vertex + // (for all three vertices of the two faces), something like + // float z11 = (trans*m_vertices[face1.Vertices[0]]).z; + // However we don't do the full matrix multiplication as we are + // only interested in the Z coordinate of the result, also we are + // not interested in the resulting normals. + return trans(2,0)*vtx.x + trans(2,1)*vtx.y + trans(2,2)*vtx.z + trans(2,3); + } + + float StdMeshFaceOrderGetFaceZ(const StdMeshVertex* vertices, const StdMeshFace& face, const StdMeshMatrix& trans) + { + const float z1 = StdMeshFaceOrderGetVertexZ(vertices[face.Vertices[0]], trans); + const float z2 = StdMeshFaceOrderGetVertexZ(vertices[face.Vertices[1]], trans); + const float z3 = StdMeshFaceOrderGetVertexZ(vertices[face.Vertices[2]], trans); + return std::max(std::max(z1, z2), z3); + } + + void SortFacesArray(const StdMeshVertex* vertices, std::vector& faces, StdSubMeshInstance::FaceOrdering face_ordering, const StdMeshMatrix& trans) + { + if(faces.empty()) return; + + std::vector helpers(faces.size()); + for(unsigned int i = 0; i < faces.size(); ++i) { - if(sub_inst.GetNumVertices() > 0) - m_vertices = &sub_inst.GetVertices()[0]; - else - m_vertices = &mesh_inst.GetSharedVertices()[0]; + helpers[i].i = i; + helpers[i].z = StdMeshFaceOrderGetFaceZ(vertices, faces[i], trans); } - inline float get_z(const StdMeshVertex& vtx) const + // The reason to use timsort here instead of std::sort is for performance + // reasons. This is performance critical code, with this function being + // called at least once per frame for each semi-transparent object. I have + // measured a factor 7 difference between the two sorting algorithms on my + // system. + + // We also pre-compute the Z values that we use for sorting, and sort the + // array of Z values, then use the resorted indices to sort the original + // faces array. The reason for this is twofold: + // 1. We don't need to compute the Z value every time the comparison function + // is called. Even though the computation is not very expensive, we have + // to do many comparisons, and small things add up. I have measured a + // 5-10% performance benefit. + // 2. More importantly, due to floating point rounding errors we cannot guarantee + // that Z values computed in the sorting function always yield the exact same + // number, and the same sorting result for the same faces. This can lead to + // a crash, because the f(a1, a2) = -f(a2, a1) property for the sorting function + // would no longer be met, resulting in undefined behaviour in the sort call. + // See http://bugs.openclonk.org/view.php?id=984. + StdMesh_tim_sort(&helpers[0], helpers.size()); + + std::vector new_faces(faces.size()); + switch(face_ordering) { - // We need to evaluate the Z coordinate of the transformed vertex - // (for all three vertices of the two faces), something like - // float z11 = (m_global_trans*m_vertices[face1.Vertices[0]]).z; - // However we don't do the full matrix multiplication as we are - // only interested in the Z coordinate of the result, also we are - // not interested in the resulting normals. - return m_global_trans(2,0)*vtx.x + m_global_trans(2,1)*vtx.y + m_global_trans(2,2)*vtx.z + m_global_trans(2,3); + case StdSubMeshInstance::FO_Fixed: + assert(false); + break; + case StdSubMeshInstance::FO_FarthestToNearest: + for(unsigned int i = 0; i < faces.size(); ++i) + new_faces[i] = faces[helpers[i].i]; + break; + case StdSubMeshInstance::FO_NearestToFarthest: + for(unsigned int i = 0; i < faces.size(); ++i) + new_faces[i] = faces[helpers[faces.size() - i - 1].i]; + break; + default: + assert(false); + break; } - bool operator()(const StdMeshFace& face1, const StdMeshFace& face2) const - { - return compare(face1, face2) < 0; - } - - int compare(const StdMeshFace& face1, const StdMeshFace& face2) const - { - // TODO: Need to apply attach matrix in case of attached meshes - switch (m_face_ordering) - { - case StdSubMeshInstance::FO_Fixed: - assert(false); - return 0; - case StdSubMeshInstance::FO_FarthestToNearest: - case StdSubMeshInstance::FO_NearestToFarthest: - { - float z11 = get_z(m_vertices[face1.Vertices[0]]); - float z12 = get_z(m_vertices[face1.Vertices[1]]); - float z13 = get_z(m_vertices[face1.Vertices[2]]); - float z21 = get_z(m_vertices[face2.Vertices[0]]); - float z22 = get_z(m_vertices[face2.Vertices[1]]); - float z23 = get_z(m_vertices[face2.Vertices[2]]); - - float z1 = std::max(std::max(z11, z12), z13); - float z2 = std::max(std::max(z21, z22), z23); - - if (m_face_ordering == StdSubMeshInstance::FO_FarthestToNearest) - return (z1 < z2 ? -1 : (z1 > z2 ? +1 : 0)); - else - return (z2 < z1 ? -1 : (z2 > z1 ? +1 : 0)); - } - default: - assert(false); - return 0; - } - } - }; + faces.swap(new_faces); + } // Serialize a ValueProvider with StdCompiler struct ValueProviderAdapt @@ -153,11 +172,27 @@ namespace ValueProviderAdapt mkValueProviderAdapt(StdMeshInstance::ValueProvider** ValueProvider) { return ValueProviderAdapt(ValueProvider); } - // Serialize a bone index by name with StdCompiler - struct TransformAdapt + void CompileFloat(StdCompiler* pComp, float& f) + { + // TODO: Teach StdCompiler how to handle float + if(pComp->isCompiler()) + { + C4Real r; + pComp->Value(r); + f = fixtof(r); + } + else + { + C4Real r = ftofix(f); + pComp->Value(r); + } + } + + // Serialize a transformation matrix by name with StdCompiler + struct MatrixAdapt { StdMeshMatrix& Matrix; - TransformAdapt(StdMeshMatrix& matrix): Matrix(matrix) {} + MatrixAdapt(StdMeshMatrix& matrix): Matrix(matrix) {} void CompileFunc(StdCompiler* pComp) { @@ -167,30 +202,42 @@ namespace for(unsigned int j = 0; j < 4; ++j) { if(i != 0 || j != 0) pComp->Separator(); - // TODO: Teach StdCompiler how to handle float -// pComp->Value(Matrix(i, j)); - - if(pComp->isCompiler()) - { - C4Real f; - pComp->Value(f); - Matrix(i,j) = fixtof(f); - } - else - { - C4Real f = ftofix(Matrix(i,j)); - pComp->Value(f); - } + CompileFloat(pComp, Matrix(i, j)); } } pComp->Separator(StdCompiler::SEP_END); } - ALLOW_TEMP_TO_REF(TransformAdapt) + ALLOW_TEMP_TO_REF(MatrixAdapt) }; - - TransformAdapt mkTransformAdapt(StdMeshMatrix& Matrix) { return TransformAdapt(Matrix); } + + struct TransformAdapt + { + StdMeshTransformation& Trans; + TransformAdapt(StdMeshTransformation& trans): Trans(trans) {} + + void CompileFunc(StdCompiler* pComp) + { + pComp->Separator(StdCompiler::SEP_START); + CompileFloat(pComp, Trans.translate.x); + CompileFloat(pComp, Trans.translate.y); + CompileFloat(pComp, Trans.translate.z); + CompileFloat(pComp, Trans.rotate.w); + CompileFloat(pComp, Trans.rotate.x); + CompileFloat(pComp, Trans.rotate.y); + CompileFloat(pComp, Trans.rotate.z); + CompileFloat(pComp, Trans.scale.x); + CompileFloat(pComp, Trans.scale.y); + CompileFloat(pComp, Trans.scale.z); + pComp->Separator(StdCompiler::SEP_END); + } + + ALLOW_TEMP_TO_REF(TransformAdapt); + }; + + MatrixAdapt mkMatrixAdapt(StdMeshMatrix& Matrix) { return MatrixAdapt(Matrix); } + TransformAdapt mkTransformAdapt(StdMeshTransformation& Trans) { return TransformAdapt(Trans); } // Reset all animation list entries corresponding to node or its children void ClearAnimationListRecursively(std::vector& list, StdMeshInstance::AnimationNode* node) @@ -231,13 +278,6 @@ namespace return true; } - - StdMeshInstanceFaceOrderingCmpPred* g_pred = NULL; -} - -static int StdMeshFaceCmp(const StdMeshFace& face1, const StdMeshFace& face2) -{ - return g_pred->compare(face1, face2); } StdMeshTransformation StdMeshTrack::GetTransformAt(float time) const @@ -447,13 +487,16 @@ void StdSubMeshInstance::LoadFacesForCompletion(StdMeshInstance& instance, const // however we can simply give an appropriate transformation matrix to the face ordering. // At this point, all vertices are in the OGRE coordinate frame, and Z in OGRE equals // Y in Clonk, so we are fine without additional transformation. - StdMeshInstanceFaceOrderingCmpPred pred(instance, *this, FO_FarthestToNearest, StdMeshMatrix::Identity()); - g_pred = &pred; - StdMesh_tim_sort(&Faces[0], Faces.size()); - g_pred = NULL; + const StdMeshVertex* vertices; + if(GetNumVertices() > 0) + vertices = &GetVertices()[0]; + else + vertices = &instance.GetSharedVertices()[0]; + SortFacesArray(vertices, Faces, FO_FarthestToNearest, StdMeshMatrix::Identity()); // Third: Only use the first few ones - Faces.resize(static_cast(completion * submesh.GetNumFaces() + 0.5)); + assert(submesh.GetNumFaces() >= 1); + Faces.resize(BoundBy(static_cast(completion * submesh.GetNumFaces() + 0.5), 1, submesh.GetNumFaces())); } } @@ -530,6 +573,13 @@ StdMeshInstance::AnimationNode::AnimationNode(const StdMeshAnimation* animation, Leaf.Position = position; } +StdMeshInstance::AnimationNode::AnimationNode(const StdMeshBone* bone, const StdMeshTransformation& trans): + Type(CustomNode), Parent(NULL) +{ + Custom.BoneIndex = bone->Index; + Custom.Transformation = new StdMeshTransformation(trans); +} + StdMeshInstance::AnimationNode::AnimationNode(AnimationNode* child_left, AnimationNode* child_right, ValueProvider* weight): Type(LinearInterpolationNode), Parent(NULL) { @@ -545,6 +595,9 @@ StdMeshInstance::AnimationNode::~AnimationNode() case LeafNode: delete Leaf.Position; break; + case CustomNode: + delete Custom.Transformation; + break; case LinearInterpolationNode: delete LinearInterpolation.ChildLeft; delete LinearInterpolation.ChildRight; @@ -566,6 +619,12 @@ bool StdMeshInstance::AnimationNode::GetBoneTransform(unsigned int bone, StdMesh if (!track) return false; transformation = track->GetTransformAt(fixtof(Leaf.Position->Value)); return true; + case CustomNode: + if(bone == Custom.BoneIndex) + transformation = *Custom.Transformation; + else + return false; + return true; case LinearInterpolationNode: if (!LinearInterpolation.ChildLeft->GetBoneTransform(bone, transformation)) return LinearInterpolation.ChildRight->GetBoneTransform(bone, transformation); @@ -585,6 +644,7 @@ void StdMeshInstance::AnimationNode::CompileFunc(StdCompiler* pComp, const StdMe static const StdEnumEntry NodeTypes[] = { { "Leaf", LeafNode }, + { "Custom", CustomNode }, { "LinearInterpolation", LinearInterpolationNode }, { NULL, static_cast(0) } @@ -611,6 +671,22 @@ void StdMeshInstance::AnimationNode::CompileFunc(StdCompiler* pComp, const StdMe pComp->Value(mkNamingAdapt(mkValueProviderAdapt(&Leaf.Position), "Position")); break; + case CustomNode: + if(pComp->isCompiler()) + { + StdCopyStrBuf bone_name; + pComp->Value(mkNamingAdapt(toC4CStrBuf(bone_name), "Bone")); + const StdMeshBone* bone = Mesh->GetBoneByName(bone_name); + if(!bone) pComp->excCorrupt("No such bone: \"%s\"", bone_name.getData()); + Custom.BoneIndex = bone->Index; + } + else + { + pComp->Value(mkNamingAdapt(mkParAdapt(mkDecompileAdapt(Mesh->GetBone(Custom.BoneIndex).Name), StdCompiler::RCT_All), "Bone")); + } + + pComp->Value(mkNamingAdapt(mkTransformAdapt(*Custom.Transformation), "Transformation")); + break; case LinearInterpolationNode: pComp->Value(mkParAdapt(mkNamingPtrAdapt(LinearInterpolation.ChildLeft, "ChildLeft"), Mesh)); pComp->Value(mkParAdapt(mkNamingPtrAdapt(LinearInterpolation.ChildRight, "ChildRight"), Mesh)); @@ -621,7 +697,7 @@ void StdMeshInstance::AnimationNode::CompileFunc(StdCompiler* pComp, const StdMe pComp->excCorrupt("Slot of left child does not match parent slot"); if(LinearInterpolation.ChildRight->Slot != Slot) pComp->excCorrupt("Slof of right child does not match parent slot"); - LinearInterpolation.ChildRight->Parent = this; + LinearInterpolation.ChildLeft->Parent = this; LinearInterpolation.ChildRight->Parent = this; } break; @@ -639,14 +715,38 @@ void StdMeshInstance::AnimationNode::DenumeratePointers() case LeafNode: value_provider = dynamic_cast(Leaf.Position); break; + case CustomNode: + value_provider = NULL; + break; case LinearInterpolationNode: value_provider = dynamic_cast(LinearInterpolation.Weight); + // non-recursive, StdMeshInstance::DenumeratePointers walks over all nodes break; } if(value_provider) value_provider->DenumeratePointers(); } +void StdMeshInstance::AnimationNode::ClearPointers(class C4Object* pObj) +{ + SerializableValueProvider* value_provider = NULL; + switch(Type) + { + case LeafNode: + value_provider = dynamic_cast(Leaf.Position); + break; + case CustomNode: + value_provider = NULL; + break; + case LinearInterpolationNode: + value_provider = dynamic_cast(LinearInterpolation.Weight); + // non-recursive, StdMeshInstance::ClearPointers walks over all nodes + break; + } + + if(value_provider) value_provider->ClearPointers(pObj); +} + StdMeshInstance::AttachedMesh::AttachedMesh(): Number(0), Parent(NULL), Child(NULL), OwnChild(true), ChildDenumerator(NULL), ParentBone(0), ChildBone(0), FinalTransformDirty(false) { @@ -711,8 +811,8 @@ void StdMeshInstance::AttachedMesh::CompileFunc(StdCompiler* pComp, DenumeratorF pComp->Value(mkNamingAdapt(Number, "Number")); pComp->Value(mkNamingAdapt(ParentBone, "ParentBone")); // TODO: Save as string pComp->Value(mkNamingAdapt(ChildBone, "ChildBone")); // TODO: Save as string (note we can only resolve this in DenumeratePointers then!) - pComp->Value(mkNamingAdapt(mkTransformAdapt(AttachTrans), "AttachTransformation")); - + pComp->Value(mkNamingAdapt(mkMatrixAdapt(AttachTrans), "AttachTransformation")); + uint8_t dwSyncFlags = static_cast(Flags); pComp->Value(mkNamingAdapt(mkBitfieldAdapt(dwSyncFlags, AM_Entries), "Flags", 0u)); if(pComp->isCompiler()) Flags = dwSyncFlags; @@ -725,6 +825,11 @@ void StdMeshInstance::AttachedMesh::DenumeratePointers() ChildDenumerator->DenumeratePointers(this); } +bool StdMeshInstance::AttachedMesh::ClearPointers(class C4Object* pObj) +{ + return ChildDenumerator->ClearPointers(pObj); +} + StdMeshInstance::StdMeshInstance(const StdMesh& mesh, float completion): Mesh(&mesh), SharedVertices(mesh.GetSharedVertices().size()), Completion(completion), BoneTransforms(Mesh->GetNumBones(), StdMeshMatrix::Identity()), @@ -806,70 +911,16 @@ StdMeshInstance::AnimationNode* StdMeshInstance::PlayAnimation(const StdStrBuf& StdMeshInstance::AnimationNode* StdMeshInstance::PlayAnimation(const StdMeshAnimation& animation, int slot, AnimationNode* sibling, ValueProvider* position, ValueProvider* weight) { - // Default - if (!sibling) sibling = GetRootAnimationForSlot(slot); - assert(!sibling || sibling->Slot == slot); - - // Find two subsequent numbers in case we need to create two nodes, so - // script can deduce the second node. - unsigned int Number1, Number2; - for (Number1 = 0; Number1 < AnimationNodes.size(); ++Number1) - if (AnimationNodes[Number1] == NULL && (!sibling || Number1+1 == AnimationNodes.size() || AnimationNodes[Number1+1] == NULL)) - break; - /* for(Number2 = Number1+1; Number2 < AnimationNodes.size(); ++Number2) - if(AnimationNodes[Number2] == NULL) - break;*/ - Number2 = Number1 + 1; - position->Value = BoundBy(position->Value, Fix0, ftofix(animation.Length)); - weight->Value = BoundBy(weight->Value, Fix0, itofix(1)); - - if (Number1 == AnimationNodes.size()) AnimationNodes.push_back( (StdMeshInstance::AnimationNode*) NULL); - if (sibling && Number2 == AnimationNodes.size()) AnimationNodes.push_back( (StdMeshInstance::AnimationNode*) NULL); - AnimationNode* child = new AnimationNode(&animation, position); - AnimationNodes[Number1] = child; - child->Number = Number1; - child->Slot = slot; + InsertAnimationNode(child, slot, sibling, weight); + return child; +} - if (sibling) - { - AnimationNode* parent = new AnimationNode(child, sibling, weight); - AnimationNodes[Number2] = parent; - parent->Number = Number2; - parent->Slot = slot; - - child->Parent = parent; - parent->Parent = sibling->Parent; - parent->LinearInterpolation.ChildLeft = sibling; - parent->LinearInterpolation.ChildRight = child; - if (sibling->Parent) - { - if (sibling->Parent->LinearInterpolation.ChildLeft == sibling) - sibling->Parent->LinearInterpolation.ChildLeft = parent; - else - sibling->Parent->LinearInterpolation.ChildRight = parent; - } - else - { - // set new parent - AnimationNodeList::iterator iter = GetStackIterForSlot(slot, false); - // slot must not be empty, since sibling uses same slot - assert(iter != AnimationStack.end() && *iter != NULL); - *iter = parent; - } - - sibling->Parent = parent; - } - else - { - delete weight; - AnimationNodeList::iterator iter = GetStackIterForSlot(slot, true); - assert(!*iter); // we have a sibling if slot is not empty - *iter = child; - } - - BoneTransformsDirty = true; +StdMeshInstance::AnimationNode* StdMeshInstance::PlayAnimation(const StdMeshBone* bone, const StdMeshTransformation& trans, int slot, AnimationNode* sibling, ValueProvider* weight) +{ + AnimationNode* child = new AnimationNode(bone, trans); + InsertAnimationNode(child, slot, sibling, weight); return child; } @@ -954,6 +1005,13 @@ void StdMeshInstance::SetAnimationPosition(AnimationNode* node, ValueProvider* p BoneTransformsDirty = true; } +void StdMeshInstance::SetAnimationBoneTransform(AnimationNode* node, const StdMeshTransformation& trans) +{ + assert(node->GetType() == AnimationNode::CustomNode); + *node->Custom.Transformation = trans; + BoneTransformsDirty = true; +} + void StdMeshInstance::SetAnimationWeight(AnimationNode* node, ValueProvider* weight) { assert(node->GetType() == AnimationNode::LinearInterpolationNode); @@ -1011,13 +1069,13 @@ StdMeshInstance::AttachedMesh* StdMeshInstance::AttachMesh(const StdMesh& mesh, { StdMeshInstance* instance = new StdMeshInstance(mesh, 1.0f); AttachedMesh* attach = AttachMesh(*instance, denumerator, parent_bone, child_bone, transformation, flags, true); - if (!attach) { delete instance; delete denumerator; return NULL; } + if (!attach) { delete instance; return NULL; } return attach; } StdMeshInstance::AttachedMesh* StdMeshInstance::AttachMesh(StdMeshInstance& instance, AttachedMesh::Denumerator* denumerator, const StdStrBuf& parent_bone, const StdStrBuf& child_bone, const StdMeshMatrix& transformation, uint32_t flags, bool own_child) { - std::auto_ptr auto_denumerator(denumerator); + std::unique_ptr auto_denumerator(denumerator); // We don't allow an instance to be attached to multiple parent instances for now if (instance.AttachParent) return NULL; @@ -1125,7 +1183,7 @@ bool StdMeshInstance::UpdateBoneTransforms() // Compute transformation for each vertex. We could later think about // doing this on the GPU using a vertex shader. This would then probably - // need to go to CStdGL::PerformMesh and CStdD3D::PerformMesh. + // need to go to CStdGL::PerformMesh. // But first, we need to move vertex data to the GPU. if(!Mesh->GetSharedVertices().empty()) ApplyBoneTransformToVertices(Mesh->GetSharedVertices(), SharedVertices); @@ -1178,26 +1236,16 @@ void StdMeshInstance::ReorderFaces(StdMeshMatrix* global_trans) for (unsigned int i = 0; i < SubMeshInstances.size(); ++i) { StdSubMeshInstance& inst = *SubMeshInstances[i]; - if(inst.CurrentFaceOrdering != StdSubMeshInstance::FO_Fixed) + assert((inst.Faces.size() > 0) && "StdMeshInstance sub-mesh instance has zero faces"); + + if(inst.Faces.size() > 0 && inst.CurrentFaceOrdering != StdSubMeshInstance::FO_Fixed) { - StdMeshInstanceFaceOrderingCmpPred pred(*this, inst, inst.CurrentFaceOrdering, global_trans ? *global_trans : StdMeshMatrix::Identity()); - - // The usage of timsort instead of std::sort at this point is twofold. - // First, it's faster in our case where the array is already sorted in - // many cases (remember this is called at least once a frame). - // And it's not just a bit faster either but a lot. I have measured - // a factor of 7 on my system. - // Second, in our Windows autobuilds there is a crash within std::sort - // which is very hard to debug because it's hardly reproducible with - // anything other than the autobuilds (I tried hard). If the crash goes - // away with timsort then great, if not then maybe it's easier to debug - // since the code is in our tree. - - //std::sort(inst.Faces.begin(), inst.Faces.end(), pred); - - g_pred = &pred; - StdMesh_tim_sort(&inst.Faces[0], inst.Faces.size()); - g_pred = NULL; + const StdMeshVertex* vertices; + if(inst.GetNumVertices() > 0) + vertices = &inst.GetVertices()[0]; + else + vertices = &GetSharedVertices()[0]; + SortFacesArray(vertices, inst.Faces, inst.CurrentFaceOrdering, global_trans ? *global_trans : StdMeshMatrix::Identity()); } } @@ -1294,6 +1342,21 @@ void StdMeshInstance::DenumeratePointers() AttachChildren[i]->DenumeratePointers(); } +void StdMeshInstance::ClearPointers(class C4Object* pObj) +{ + for(unsigned int i = 0; i < AnimationNodes.size(); ++i) + if(AnimationNodes[i]) + AnimationNodes[i]->ClearPointers(pObj); + + std::vector Removal; + for(unsigned int i = 0; i < AttachChildren.size(); ++i) + if(!AttachChildren[i]->ClearPointers(pObj)) + Removal.push_back(AttachChildren[i]->Number); + + for(unsigned int i = 0; i < Removal.size(); ++i) + DetachMesh(Removal[i]); +} + StdMeshInstance::AnimationNodeList::iterator StdMeshInstance::GetStackIterForSlot(int slot, bool create) { // TODO: bsearch @@ -1318,6 +1381,72 @@ StdMeshInstance::AnimationNodeList::iterator StdMeshInstance::GetStackIterForSlo return AnimationStack.insert(AnimationStack.end(), NULL); } +void StdMeshInstance::InsertAnimationNode(AnimationNode* node, int slot, AnimationNode* sibling, ValueProvider* weight) +{ + // Default + if (!sibling) sibling = GetRootAnimationForSlot(slot); + assert(!sibling || sibling->Slot == slot); + + // Find two subsequent numbers in case we need to create two nodes, so + // script can deduce the second node. + unsigned int Number1, Number2; + for (Number1 = 0; Number1 < AnimationNodes.size(); ++Number1) + if (AnimationNodes[Number1] == NULL && (!sibling || Number1+1 == AnimationNodes.size() || AnimationNodes[Number1+1] == NULL)) + break; + /* for(Number2 = Number1+1; Number2 < AnimationNodes.size(); ++Number2) + if(AnimationNodes[Number2] == NULL) + break;*/ + Number2 = Number1 + 1; + + weight->Value = BoundBy(weight->Value, Fix0, itofix(1)); + + if (Number1 == AnimationNodes.size()) AnimationNodes.push_back( (StdMeshInstance::AnimationNode*) NULL); + if (sibling && Number2 == AnimationNodes.size()) AnimationNodes.push_back( (StdMeshInstance::AnimationNode*) NULL); + + AnimationNodes[Number1] = node; + node->Number = Number1; + node->Slot = slot; + + if (sibling) + { + AnimationNode* parent = new AnimationNode(node, sibling, weight); + AnimationNodes[Number2] = parent; + parent->Number = Number2; + parent->Slot = slot; + + node->Parent = parent; + parent->Parent = sibling->Parent; + parent->LinearInterpolation.ChildLeft = sibling; + parent->LinearInterpolation.ChildRight = node; + if (sibling->Parent) + { + if (sibling->Parent->LinearInterpolation.ChildLeft == sibling) + sibling->Parent->LinearInterpolation.ChildLeft = parent; + else + sibling->Parent->LinearInterpolation.ChildRight = parent; + } + else + { + // set new parent + AnimationNodeList::iterator iter = GetStackIterForSlot(slot, false); + // slot must not be empty, since sibling uses same slot + assert(iter != AnimationStack.end() && *iter != NULL); + *iter = parent; + } + + sibling->Parent = parent; + } + else + { + delete weight; + AnimationNodeList::iterator iter = GetStackIterForSlot(slot, true); + assert(!*iter); // we have a sibling if slot is not empty + *iter = node; + } + + BoneTransformsDirty = true; +} + bool StdMeshInstance::ExecuteAnimationNode(AnimationNode* node) { ValueProvider* provider = NULL; @@ -1331,6 +1460,9 @@ bool StdMeshInstance::ExecuteAnimationNode(AnimationNode* node) min = Fix0; max = ftofix(node->GetAnimation()->Length); break; + case AnimationNode::CustomNode: + // No execution necessary + return true; case AnimationNode::LinearInterpolationNode: provider = node->GetWeightProvider(); min = Fix0; @@ -1340,6 +1472,8 @@ bool StdMeshInstance::ExecuteAnimationNode(AnimationNode* node) assert(false); break; } + + assert(provider); const C4Real old_value = provider->Value; if (!provider->Execute()) diff --git a/src/lib/StdMesh.h b/src/lib/StdMesh.h index 9de6b382e..a76cd1c64 100644 --- a/src/lib/StdMesh.h +++ b/src/lib/StdMesh.h @@ -1,22 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2006, 2010 Sven Eberhardt - * Copyright (c) 2009-2011 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_StdMesh @@ -25,8 +20,6 @@ #include #include -class StdCompiler; - class StdMeshBone { friend class StdMesh; @@ -216,7 +209,7 @@ public: // Get face of instance. The instance faces are the same as the mesh faces, // with the exception that they are differently ordered, depending on the // current FaceOrdering. See FaceOrdering in StdMeshInstance. - const StdMeshFace* GetFaces() const { return &Faces[0]; } + const StdMeshFace* GetFaces() const { return Faces.size() > 0 ? &Faces[0] : 0; } size_t GetNumFaces() const { return Faces.size(); } unsigned int GetTexturePhase(size_t pass, size_t texunit) const { return PassData[pass].TexUnits[texunit].Phase; } @@ -363,6 +356,7 @@ public: virtual void CompileFunc(StdCompiler* pComp); virtual void DenumeratePointers() {} + virtual void ClearPointers(class C4Object* pObj) {} }; // A node in the animation tree @@ -372,10 +366,11 @@ public: friend class StdMeshInstance; friend class StdMeshUpdate; public: - enum NodeType { LeafNode, LinearInterpolationNode }; + enum NodeType { LeafNode, CustomNode, LinearInterpolationNode }; AnimationNode(); AnimationNode(const StdMeshAnimation* animation, ValueProvider* position); + AnimationNode(const StdMeshBone* bone, const StdMeshTransformation& trans); AnimationNode(AnimationNode* child_left, AnimationNode* child_right, ValueProvider* weight); ~AnimationNode(); @@ -397,6 +392,7 @@ public: void CompileFunc(StdCompiler* pComp, const StdMesh* Mesh); void DenumeratePointers(); + void ClearPointers(class C4Object* pObj); protected: int Slot; @@ -412,6 +408,12 @@ public: ValueProvider* Position; } Leaf; + struct + { + unsigned int BoneIndex; + StdMeshTransformation* Transformation; + } Custom; + struct { AnimationNode* ChildLeft; @@ -434,6 +436,7 @@ public: virtual void CompileFunc(StdCompiler* pComp, AttachedMesh* attach) = 0; virtual void DenumeratePointers(AttachedMesh* attach) {} + virtual bool ClearPointers(class C4Object* pObj) { return true; } }; typedef Denumerator*(*DenumeratorFactoryFunc)(); @@ -460,6 +463,7 @@ public: void CompileFunc(StdCompiler* pComp, DenumeratorFactoryFunc Factory); void DenumeratePointers(); + bool ClearPointers(class C4Object* pObj); private: unsigned int ParentBone; @@ -488,6 +492,7 @@ public: AnimationNode* PlayAnimation(const StdStrBuf& animation_name, int slot, AnimationNode* sibling, ValueProvider* position, ValueProvider* weight); AnimationNode* PlayAnimation(const StdMeshAnimation& animation, int slot, AnimationNode* sibling, ValueProvider* position, ValueProvider* weight); + AnimationNode* PlayAnimation(const StdMeshBone* bone, const StdMeshTransformation& trans, int slot, AnimationNode* sibling, ValueProvider* weight); void StopAnimation(AnimationNode* node); AnimationNode* GetAnimationNodeByNumber(unsigned int number); @@ -496,6 +501,7 @@ public: // Set new value providers for a node's position or weight - cannot be in // class AnimationNode since we need to mark BoneTransforms dirty. void SetAnimationPosition(AnimationNode* node, ValueProvider* position); + void SetAnimationBoneTransform(AnimationNode* node, const StdMeshTransformation& trans); void SetAnimationWeight(AnimationNode* node, ValueProvider* weight); // Update animations; call once a frame @@ -543,6 +549,7 @@ public: void CompileFunc(StdCompiler* pComp, AttachedMesh::DenumeratorFactoryFunc Factory); void DenumeratePointers(); + void ClearPointers(class C4Object* pObj); const StdMesh& GetMesh() const { assert(Mesh != NULL); return *Mesh; } @@ -550,6 +557,7 @@ protected: typedef std::vector AnimationNodeList; AnimationNodeList::iterator GetStackIterForSlot(int slot, bool create); + void InsertAnimationNode(AnimationNode* node, int slot, AnimationNode* sibling, ValueProvider* weight); bool ExecuteAnimationNode(AnimationNode* node); void ApplyBoneTransformToVertices(const std::vector& mesh_vertices, std::vector& instance_vertices); @@ -578,7 +586,7 @@ private: inline void CompileNewFuncCtx(StdMeshInstance::SerializableValueProvider *&pStruct, StdCompiler *pComp, const StdMeshInstance::SerializableValueProvider::IDBase& rID) { - std::auto_ptr temp(rID.newfunc()); + std::unique_ptr temp(rID.newfunc()); pComp->Value(*temp); pStruct = temp.release(); } diff --git a/src/lib/StdMeshLoader.h b/src/lib/StdMeshLoader.h index 6385f3b51..d5a9a63f8 100644 --- a/src/lib/StdMeshLoader.h +++ b/src/lib/StdMeshLoader.h @@ -1,19 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009 Armin Burgmeier - * Copyright (c) 2010 Nicolas Hake + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // A loader for the OGRE .mesh binary file format @@ -22,9 +19,6 @@ #define INC_StdMeshLoader #include -class StdMesh; -class StdMeshMatManager; - // Interface to load skeleton files. Given a filename occuring in the // mesh file, this should load the skeleton file from wherever the mesh file // was loaded from, for example from a C4Group. Return default-construted diff --git a/src/lib/StdMeshLoaderBinary.cpp b/src/lib/StdMeshLoaderBinary.cpp index fbf2befff..8692c28c4 100644 --- a/src/lib/StdMeshLoaderBinary.cpp +++ b/src/lib/StdMeshLoaderBinary.cpp @@ -1,20 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2010 Armin Burgmeier - * Copyright (c) 2010 Nicolas Hake + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // A loader for the OGRE .mesh binary file format @@ -206,7 +202,7 @@ StdMesh *StdMeshLoader::LoadMeshBinary(const char *src, size_t length, const Std // Generate mesh from data Ogre::Mesh::ChunkMesh &cmesh = *static_cast(root.get()); - std::auto_ptr mesh(new StdMesh); + std::unique_ptr mesh(new StdMesh); mesh->BoundingBox = cmesh.bounds; mesh->BoundingRadius = cmesh.radius; @@ -294,13 +290,21 @@ void StdMeshLoader::LoadSkeletonBinary(StdMesh *mesh, const char *src, size_t si boost::ptr_map bones; boost::ptr_vector animations; for (Ogre::Skeleton::ChunkID id = Ogre::Skeleton::Chunk::Peek(&stream); - id == Ogre::Skeleton::CID_Bone || id == Ogre::Skeleton::CID_Bone_Parent || id == Ogre::Skeleton::CID_Animation; + id == Ogre::Skeleton::CID_BlendMode || id == Ogre::Skeleton::CID_Bone || id == Ogre::Skeleton::CID_Bone_Parent || id == Ogre::Skeleton::CID_Animation; id = Ogre::Skeleton::Chunk::Peek(&stream) ) { - std::auto_ptr chunk(Ogre::Skeleton::Chunk::Read(&stream)); + std::unique_ptr chunk(Ogre::Skeleton::Chunk::Read(&stream)); switch (chunk->GetType()) { + case Ogre::Skeleton::CID_BlendMode: + { + Ogre::Skeleton::ChunkBlendMode& cblend = *static_cast(chunk.get()); + // TODO: Handle it + if(cblend.blend_mode != 0) // 0 is average, 1 is cumulative. I'm actually not sure what the difference really is... anyway we implement only one method yet. I think it's average, but not 100% sure. + LogF("StdMeshLoader: CID_BlendMode not implemented."); + } + break; case Ogre::Skeleton::CID_Bone: { Ogre::Skeleton::ChunkBone &cbone = *static_cast(chunk.get()); diff --git a/src/lib/StdMeshLoaderBinaryChunks.cpp b/src/lib/StdMeshLoaderBinaryChunks.cpp index d94c70f12..2dde151f6 100644 --- a/src/lib/StdMeshLoaderBinaryChunks.cpp +++ b/src/lib/StdMeshLoaderBinaryChunks.cpp @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2010-2011 Nicolas Hake + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" @@ -27,10 +25,12 @@ namespace Ogre { namespace Mesh { - const uint32_t ChunkFileHeader::CurrentVersion = 1041; // Major * 1000 + Minor + const uint32_t ChunkFileHeader::CurrentVersion = 1080; // Major * 1000 + Minor const std::map ChunkFileHeader::VersionTable = boost::assign::map_list_of - // 1.41: Current version - ("[MeshSerializer_v1.41]", CurrentVersion) + // 1.8: Current version + ("[MeshSerializer_v1.8]", CurrentVersion) + // 1.41: Changes to morph keyframes and poses. We don't use either, so no special handling needed + ("[MeshSerializer_v1.41]", 1041) // 1.40: Changes to CID_Mesh_LOD chunks, we ignore those, so no special handling needed ("[MeshSerializer_v1.40]", 1040); @@ -52,7 +52,7 @@ namespace Ogre } // Create chunk - std::auto_ptr chunk; + std::unique_ptr chunk; switch (id) { case CID_Header: chunk.reset(new ChunkFileHeader()); break; @@ -334,7 +334,12 @@ namespace Ogre namespace Skeleton { - const std::string ChunkFileHeader::ExpectedVersion("[Serializer_v1.10]"); + const uint32_t ChunkFileHeader::CurrentVersion = 1080; // Major * 1000 + Minor + const std::map ChunkFileHeader::VersionTable = boost::assign::map_list_of + // 1.80: Current version + ("[Serializer_v1.80]", CurrentVersion) + // 1.10: adds SKELETON_BLENDMODE and SKELETON_ANIMATION_BASEINFO chunks. The chunks have been added to the loader, but we ignore them for now. + ("[Serializer_v1.10]", 1010); Chunk *Chunk::Read(DataStream *stream) { @@ -353,13 +358,15 @@ namespace Ogre } // Create chunk - std::auto_ptr chunk; + std::unique_ptr chunk; switch (id) { case CID_Header: chunk.reset(new ChunkFileHeader()); break; + case CID_BlendMode: chunk.reset(new ChunkBlendMode()); break; case CID_Bone: chunk.reset(new ChunkBone()); break; case CID_Bone_Parent: chunk.reset(new ChunkBoneParent()); break; case CID_Animation: chunk.reset(new ChunkAnimation()); break; + case CID_Animation_BaseInfo: chunk.reset(new ChunkAnimationBaseInfo()); break; case CID_Animation_Track: chunk.reset(new ChunkAnimationTrack()); break; case CID_Animation_Track_KF: chunk.reset(new ChunkAnimationTrackKF()); break; case CID_Animation_Link: chunk.reset(new ChunkAnimationLink()); break; @@ -378,11 +385,16 @@ namespace Ogre void ChunkFileHeader::ReadImpl(DataStream *stream) { // Simple version check - version = stream->Read(); - if (version != ExpectedVersion) + VersionTable_t::const_iterator it = VersionTable.find(stream->Read()); + if (it == VersionTable.end()) throw InvalidVersion(); } + void ChunkBlendMode::ReadImpl(DataStream* stream) + { + blend_mode = stream->Read(); + } + void ChunkBone::ReadImpl(DataStream *stream) { name = stream->Read(); @@ -417,6 +429,15 @@ namespace Ogre { name = stream->Read(); duration = stream->Read(); + + if(!stream->AtEof() && Chunk::Peek(stream) == CID_Animation_BaseInfo) + { + Chunk* chunk = Chunk::Read(stream); + assert(chunk->GetType() == CID_Animation_BaseInfo); + // TODO: Handle it + LogF("StdMeshLoader: CID_Animation_BaseInfo not implemented. Skeleton might not be imported properly."); + } + while (!stream->AtEof() && Chunk::Peek(stream) == CID_Animation_Track) { Chunk *chunk = Chunk::Read(stream); @@ -425,6 +446,12 @@ namespace Ogre } } + void ChunkAnimationBaseInfo::ReadImpl(DataStream* stream) + { + base_animation_name = stream->Read(); + base_key_frame_time = stream->Read(); + } + void ChunkAnimationTrack::ReadImpl(DataStream *stream) { bone = stream->Read(); diff --git a/src/lib/StdMeshLoaderBinaryChunks.h b/src/lib/StdMeshLoaderBinaryChunks.h index 3fa6d2a3d..3d084ee8e 100644 --- a/src/lib/StdMeshLoaderBinaryChunks.h +++ b/src/lib/StdMeshLoaderBinaryChunks.h @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2010 Nicolas Hake + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_StdMeshLoaderChunks @@ -353,7 +351,8 @@ namespace Ogre static Chunk *Read(DataStream *stream); }; - class ChunkUnknown; class ChunkFileHeader; + class ChunkUnknown; class + ChunkFileHeader; class ChunkMesh; class ChunkMeshSkeletonLink; class ChunkMeshBoneAssignments; class ChunkMeshBounds; class ChunkSubmesh; class ChunkSubmeshOp; class ChunkGeometry; class ChunkGeometryVertexDecl; class ChunkGeometryVertexDeclElement; class ChunkGeometryVertexBuffer; class ChunkGeometryVertexData; @@ -538,9 +537,11 @@ namespace Ogre { CID_Invalid = 0, CID_Header = 0x1000, + CID_BlendMode= 0x1010, CID_Bone = 0x2000, CID_Bone_Parent = 0x3000, CID_Animation = 0x4000, + CID_Animation_BaseInfo = 0x4010, CID_Animation_Track = 0x4100, CID_Animation_Track_KF = 0x4110, CID_Animation_Link = 0x5000 @@ -564,7 +565,9 @@ namespace Ogre class ChunkFileHeader : public Chunk { - static const std::string ExpectedVersion; + typedef std::map VersionTable_t; + static const VersionTable_t VersionTable; + static const uint32_t CurrentVersion; public: std::string version; @@ -572,6 +575,14 @@ namespace Ogre virtual void ReadImpl(DataStream *stream); }; + class ChunkBlendMode : public Chunk + { + public: + uint16_t blend_mode; + protected: + virtual void ReadImpl(DataStream* stream); + }; + class ChunkBone : public Chunk { public: @@ -604,6 +615,15 @@ namespace Ogre virtual void ReadImpl(DataStream *stream); }; + class ChunkAnimationBaseInfo : public Chunk + { + public: + std::string base_animation_name; + float base_key_frame_time; + protected: + virtual void ReadImpl(DataStream* stream); + }; + class ChunkAnimationTrack : public Chunk { public: diff --git a/src/lib/StdMeshLoaderDataStream.h b/src/lib/StdMeshLoaderDataStream.h index 05282aa40..de66c8de4 100644 --- a/src/lib/StdMeshLoaderDataStream.h +++ b/src/lib/StdMeshLoaderDataStream.h @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2010 Nicolas Hake + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_StdMeshLoaderDataStream diff --git a/src/lib/StdMeshLoaderXml.cpp b/src/lib/StdMeshLoaderXml.cpp index b17f34781..2013a94a0 100644 --- a/src/lib/StdMeshLoaderXml.cpp +++ b/src/lib/StdMeshLoaderXml.cpp @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2010 Armin Burgmeier - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ // A loader for the OGRE .mesh XML file format @@ -244,7 +241,7 @@ StdMesh *StdMeshLoader::LoadMeshXml(const char* xml_data, size_t size, const Std { StdMeshXML xml(filename ? filename : "", xml_data); - std::auto_ptr mesh(new StdMesh); + std::unique_ptr mesh(new StdMesh); TiXmlElement* mesh_elem = xml.RequireFirstChild(NULL, "mesh"); diff --git a/src/lib/StdMeshMaterial.cpp b/src/lib/StdMeshMaterial.cpp index 04333fef9..0c14c71b0 100644 --- a/src/lib/StdMeshMaterial.cpp +++ b/src/lib/StdMeshMaterial.cpp @@ -1,28 +1,23 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009 Mark Haßelbusch - * Copyright (c) 2009-2011 Armin Burgmeier - * Copyright (c) 2009 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" #include #include -#include +#include #include #include @@ -649,7 +644,7 @@ StdMeshMaterialTextureUnit::StdMeshMaterialTextureUnit(): void StdMeshMaterialTextureUnit::LoadTexture(StdMeshMaterialParserCtx& ctx, const char* texname) { - std::auto_ptr surface(ctx.TextureLoader.LoadTexture(texname)); // be exception-safe + std::unique_ptr surface(ctx.TextureLoader.LoadTexture(texname)); // be exception-safe if (!surface.get()) ctx.Error(StdCopyStrBuf("Could not load texture '") + texname + "'"); @@ -831,7 +826,7 @@ void StdMeshMaterialTextureUnit::Load(StdMeshMaterialParserCtx& ctx) } StdMeshMaterialPass::StdMeshMaterialPass(): - DepthWrite(true), CullHardware(CH_Clockwise) + DepthCheck(true), DepthWrite(true), CullHardware(CH_Clockwise) { Ambient[0] = Ambient[1] = Ambient[2] = 1.0f; Ambient[3] = 1.0f; Diffuse[0] = Diffuse[1] = Diffuse[2] = 1.0f; Diffuse[3] = 1.0f; @@ -885,6 +880,10 @@ void StdMeshMaterialPass::Load(StdMeshMaterialParserCtx& ctx) { ctx.AdvanceColor(true, Emissive); } + else if (token_name == "depth_check") + { + DepthCheck = ctx.AdvanceBoolean(); + } else if (token_name == "depth_write") { DepthWrite = ctx.AdvanceBoolean(); @@ -912,11 +911,6 @@ void StdMeshMaterialPass::Load(StdMeshMaterialParserCtx& ctx) ctx.AdvanceBoolean(); ctx.WarningNotSupported("colour_write"); } - else if (token_name == "depth_check") - { - ctx.AdvanceBoolean(); - ctx.WarningNotSupported(token_name.getData()); - } else if (token_name == "depth_func") { StdStrBuf func; @@ -1090,11 +1084,14 @@ void StdMeshMatManager::Parse(const char* mat_script, const char* filename, StdM mat.Load(ctx); + Materials[material_name] = mat; + // To Gfxspecific setup of the material; choose working techniques - if (pDraw->PrepareMaterial(mat) && mat.BestTechniqueIndex != -1) - Materials[material_name] = mat; - else + if (!pDraw->PrepareMaterial(Materials[material_name])) + { + Materials.erase(material_name); ctx.Error(StdCopyStrBuf("No working technique for material '") + material_name + "'"); + } } else ctx.ErrorUnexpectedIdentifier(token_name); diff --git a/src/lib/StdMeshMaterial.h b/src/lib/StdMeshMaterial.h index 715d48583..79711fbf8 100644 --- a/src/lib/StdMeshMaterial.h +++ b/src/lib/StdMeshMaterial.h @@ -1,20 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Armin Burgmeier - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_StdMeshMaterial @@ -269,10 +266,40 @@ public: float Emissive[4]; float Shininess; + bool DepthCheck; bool DepthWrite; + CullHardwareType CullHardware; SceneBlendType SceneBlendFactors[2]; bool AlphaToCoverage; + + // An abstract shader class. This is supposed to be implemented by the + // GFX implementation, such as C4DrawGL. + class Shader { public: virtual ~Shader() {} }; + + // This is a simple reference to a shader. It is allowed to be copied as long + // as the shader is not set. + class ShaderRef + { + public: + ShaderRef(): Program(NULL) {} + ShaderRef(const ShaderRef& other) { Program = NULL; /* don't copy the program pointer */ } + ~ShaderRef() { delete Program; } + + ShaderRef& operator=(Shader* NewProgram) { assert(Program == NULL); Program = NewProgram; return *this; } + ShaderRef& operator=(const ShaderRef& other) { assert(Program == NULL); assert(other.Program == NULL); Program = NULL; return *this; } + + const Shader* operator->() const { return Program; } + const Shader& operator*() const { return *Program; } + operator const Shader*() const { return Program; } + + Shader* Program; + }; + + // A compiled shader which applies the blending between the texture units, + // and also applies color modulation and MOD2. + // The actual compilation is being done in PrepareMaterial() of the C4Draw. + ShaderRef Program; }; class StdMeshMaterialTechnique diff --git a/src/lib/StdMeshMath.cpp b/src/lib/StdMeshMath.cpp index da402c647..28880d33b 100644 --- a/src/lib/StdMeshMath.cpp +++ b/src/lib/StdMeshMath.cpp @@ -1,21 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Armin Burgmeier - * Copyright (c) 2009 Mark Haßelbusch - * Copyright (c) 2010 Nicolas Hake - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include @@ -348,6 +344,53 @@ float StdMeshMatrix::Determinant() const - a[0][0]*a[1][2]*a[2][1] - a[0][1]*a[1][0]*a[2][2] - a[0][2]*a[1][1]*a[2][0]; } +StdMeshTransformation StdMeshMatrix::Decompose() const +{ + // Extract the scale part of the matrix + const float sx = sqrt(a[0][0]*a[0][0] + a[1][0]*a[1][0] + a[2][0]*a[2][0]); + const float sy = sqrt(a[0][1]*a[0][1] + a[1][1]*a[1][1] + a[2][1]*a[2][1]); + const float sz = sqrt(a[0][2]*a[0][2] + a[1][2]*a[1][2] + a[2][2]*a[2][2]); + + // What remains is the rotation part + // TODO: This can be optimized by not doing the full matrix multiplication + StdMeshMatrix rot = Scale(1.0f/sx, 1.0f/sy, 1.0f/sz) * *this; + + // Note that this does not work for skew matrices -- we cannot + // represent skews in StdMeshTransformation + const float cos_angle = 0.5f * (rot.a[0][0] + rot.a[1][1] + rot.a[2][2] - 1.0f); + + const float rdx = rot.a[2][1] - rot.a[1][2]; + const float rdy = rot.a[0][2] - rot.a[2][0]; + const float rdz = rot.a[1][0] - rot.a[0][1]; + const float det = sqrt(rdx*rdx + rdy*rdy + rdz*rdz); + + const float rx = (rot.a[2][1] - rot.a[1][2]) / det; + const float ry = (rot.a[0][2] - rot.a[2][0]) / det; + const float rz = (rot.a[1][0] - rot.a[0][1]) / det; + + const float angle = acos(cos_angle); + + StdMeshTransformation trans; + trans.scale.x = sx; + trans.scale.y = sy; + trans.scale.z = sz; + trans.rotate = StdMeshQuaternion::AngleAxis(acos(cos_angle), StdMeshVector::Translate(rx, ry, rz)); + trans.translate.x = a[0][3]; + trans.translate.y = a[1][3]; + trans.translate.z = a[2][3]; + +#if 0 + // Double check that the result is correct. This check will fail if + // the original matrix has skew components. + StdMeshMatrix mat2 = StdMeshMatrix::Transform(trans); + for(unsigned int i = 0; i < 3; ++i) + for(unsigned int j = 0; j < 4; ++j) + assert( fabs(mat2.a[i][j] - a[i][j]) < 1e-3); +#endif + + return trans; +} + StdMeshMatrix operator*(const StdMeshMatrix& lhs, const StdMeshMatrix& rhs) { StdMeshMatrix m; diff --git a/src/lib/StdMeshMath.h b/src/lib/StdMeshMath.h index 145d9f214..e320d9a93 100644 --- a/src/lib/StdMeshMath.h +++ b/src/lib/StdMeshMath.h @@ -1,19 +1,17 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2011 Armin Burgmeier - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2011-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_StdMeshMath @@ -95,6 +93,7 @@ public: float operator()(int i, int j) const { return a[i][j]; } float Determinant() const; + StdMeshTransformation Decompose() const; private: // 3x3 orthogonal + translation in last column diff --git a/src/lib/StdMeshUpdate.cpp b/src/lib/StdMeshUpdate.cpp index b9cbec202..8e6db30c7 100644 --- a/src/lib/StdMeshUpdate.cpp +++ b/src/lib/StdMeshUpdate.cpp @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Armin Burgmeier + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #include "C4Include.h" @@ -82,13 +80,13 @@ void StdMeshMaterialUpdate::Add(const StdMeshMaterial* material) } StdMeshUpdate::StdMeshUpdate(const StdMesh& old_mesh): - OldMesh(&old_mesh), BoneNames(OldMesh->GetNumBones()) + OldMesh(&old_mesh), BoneNamesByIndex(OldMesh->GetNumBones()) { for(std::map::const_iterator iter = OldMesh->Animations.begin(); iter != OldMesh->Animations.end(); ++iter) AnimationNames[&iter->second] = iter->first; for(unsigned int i = 0; i < OldMesh->GetNumBones(); ++i) - BoneNames[i] = OldMesh->GetBone(i).Name; + BoneNamesByIndex[i] = OldMesh->GetBone(i).Name; } void StdMeshUpdate::Update(StdMeshInstance* instance, const StdMesh& new_mesh) const @@ -110,7 +108,7 @@ void StdMeshUpdate::Update(StdMeshInstance* instance, const StdMesh& new_mesh) c // in the updated mesh, then detach the mesh from its parent if(instance->AttachParent) { - if(!instance->AttachParent->SetChildBone(BoneNames[instance->AttachParent->ChildBone])) + if(!instance->AttachParent->SetChildBone(BoneNamesByIndex[instance->AttachParent->ChildBone])) { bool OwnChild = instance->AttachParent->OwnChild; instance->AttachParent->Parent->DetachMesh(instance->AttachParent->Number); @@ -127,7 +125,7 @@ void StdMeshUpdate::Update(StdMeshInstance* instance, const StdMesh& new_mesh) c std::vector Removal; for(StdMeshInstance::AttachedMeshIter iter = instance->AttachedMeshesBegin(); iter != instance->AttachedMeshesEnd(); ++iter) { - if(!(*iter)->SetParentBone(BoneNames[(*iter)->ParentBone])) + if(!(*iter)->SetParentBone(BoneNamesByIndex[(*iter)->ParentBone])) { // Do not detach the mesh right here so we can finish iterating over // all attached meshes first. @@ -166,6 +164,15 @@ bool StdMeshUpdate::UpdateAnimationNode(StdMeshInstance* instance, const StdMesh provider->Value = BoundBy(provider->Value, min, max); return true; } + case StdMeshInstance::AnimationNode::CustomNode: + { + // Update bone index by bone name + StdCopyStrBuf bone_name = BoneNamesByIndex[node->Custom.BoneIndex]; + const StdMeshBone* bone = new_mesh.GetBoneByName(bone_name); + if(!bone) return false; + node->Custom.BoneIndex = bone->Index; + return true; + } case StdMeshInstance::AnimationNode::LinearInterpolationNode: { const bool left_result = UpdateAnimationNode(instance, new_mesh, node->GetLeftChild()); diff --git a/src/lib/StdMeshUpdate.h b/src/lib/StdMeshUpdate.h index 64c5905ea..486ebd313 100644 --- a/src/lib/StdMeshUpdate.h +++ b/src/lib/StdMeshUpdate.h @@ -1,18 +1,16 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2009-2011 Armin Burgmeier + * Copyright (c) 2009-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ #ifndef INC_StdMeshUpdate @@ -64,7 +62,7 @@ private: const StdMesh* OldMesh; std::map AnimationNames; - std::vector BoneNames; + std::vector BoneNamesByIndex; }; #endif diff --git a/src/lib/StdResStr.h b/src/lib/StdResStr.h deleted file mode 100644 index 14dd34c61..000000000 --- a/src/lib/StdResStr.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 1998-2000 Matthes Bender - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Load multi-language strings from the resource string table */ - -char *LoadResStr(WORD id); -#ifdef _WIN32 -void SetStringResource(HINSTANCE hResInst, int iExtended); -#endif -void SetResourceStringUnscramble(void (*pResourceStringUnscramble)(char*)); diff --git a/src/lib/StdResStr2.cpp b/src/lib/StdResStr2.cpp index 4212cd5eb..7c57784eb 100644 --- a/src/lib/StdResStr2.cpp +++ b/src/lib/StdResStr2.cpp @@ -1,157 +1,27 @@ /* * OpenClonk, http://www.openclonk.org * - * Copyright (c) 2003, 2005-2006 Matthes Bender - * Copyright (c) 2005-2007 Günther Brammer - * Copyright (c) 2010 Benjamin Herr - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de + * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ + * Copyright (c) 2010-2013, The OpenClonk Team and contributors * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. + * Distributed under the terms of the ISC license; see accompanying file + * "COPYING" for details. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. + * "Clonk" is a registered trademark of Matthes Bender, used with permission. + * See accompanying file "TRADEMARK" for details. * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. + * To redistribute this file separately, substitute the full license texts + * for the above references. */ /* Load strings from a primitive memory string table */ #include "C4Include.h" -#include -#include - -#include - -class ResTable -{ -public: - ResTable(const char * table): Capacity(int(1.10 * SCharCount('\n', table))), Count(0), Entries(new Entry[Capacity]) - { - // reduce the capacity so that there is always an empty entry to mark the end of the search for an nonexistant key - --Capacity; - while (Count < Capacity) - { - // search '=' - const char * pos = table; - const char * equalpos = 0; - while (*pos && *pos != '\n' && *pos != '\r') - { - if (*pos == '=') equalpos = pos; - ++pos; - } - if (equalpos) - { - unsigned int h = Hash(table); - // Get a pointer to the bucket - Entry * e = &(Entries[h % Capacity]); - // Search an empty spot - int i = 0; - while (*e) - { -#ifdef _DEBUG - if (e->Hash == h) printf("Hash Collision: %d (\"%.50s\")\nSTRINGTABLE WILL BREAK\n", h, table); -#endif - e = &(Entries[(h + ++i) % Capacity]); - } - // Fill - e->Hash = h; - e->Data.CopyUntil(equalpos + 1, *pos); - // Compile line feeds ("\n" -> 0D0A) - for (i = 0; i < pos - equalpos; ++i) - if (e->Data.getMData()[i] == '\\' && e->Data.getMData()[i + 1] == 'n') - { e->Data.getMData()[i] = 0x0D; e->Data.getMData()[i + 1] = 0x0A; } - // Count! - ++Count; - } - while (*pos == '\n' || *pos == '\r') ++pos; - table = pos; - if (!*table) break; - } - } - - ~ResTable() - { - delete[] Entries; - } - - const char * GetEntry(const char * Key) - { - if (!Key) return NULL; - unsigned int h = Hash(Key); - Entry * e = &(Entries[h % Capacity]); - int i = 0; - while (e->Hash != h && *e) e = &(Entries[(h + ++i) % Capacity]); - return e->Data.getData(); - } - -private: - struct Entry - { - StdCopyStrBuf Data; - unsigned int Hash; - Entry(): Data(), Hash(0) { } - Entry(const StdStrBuf & Data, int32_t Hash): Data(Data), Hash(Hash) { } - operator const void * () { return Data; } - }; - int Capacity; - int Count; - Entry * Entries; - static unsigned int Hash(const char * Key) - { - // Fowler/Noll/Vo hash - unsigned int h = 2166136261u; - while (*Key && *Key != '=') - h = (h ^ *(Key++)) * 16777619; - return h; - } -}; - -static ResTable * Table = 0; - -void SetResStrTable(char *pTable) -{ - // Clear any old table - ClearResStrTable(); - // Create new Table - Table = new ResTable(pTable); - delete[] pTable; -} - -void ClearResStrTable() -{ - delete Table; - Table = 0; -} - -bool IsResStrTableLoaded() { return Table != 0; } - -const char *GetResStr(const char *id, ResTable * Table) -{ - if (!Table) return "Language string table not loaded."; - const char * r = Table->GetEntry(id); - if (!r) - { - static char strResult[1024]; - // Default - sprintf(strResult, "[Undefined:%s]", id); - return strResult; - } - // Return string - return r; -} - -const char *LoadResStr(const char *id) -{ - return GetResStr(id, Table); -} +#include "C4Language.h" const int ResStrMaxLen = 4096; static char strResult[ResStrMaxLen + 1]; -char *LoadResStrNoAmp(const char *id) +const char *LoadResStrNoAmp(const char *id) { const char * str = LoadResStr(id); char * cpd = strResult; @@ -164,21 +34,4 @@ char *LoadResStrNoAmp(const char *id) } *cpd = 0; return strResult; -} - -char *GetResStr(const char *id, const char *strTable) -{ - const char *pos; - // Default - sprintf(strResult, "[Undefined:%s]", id); - // Compose identifier with operator - char idExt[256 + 1 + 1]; SCopy(id, idExt, 256); SAppendChar('=', idExt); - // String table present and id not empty - if (strTable && id && id[0]) - // Search for identifier with operator - if ((pos = SSearch(strTable, idExt))) - // Get string until end of line - SCopyUntil(pos, strResult, "\r\n", ResStrMaxLen); - // Return string - return strResult; -} +} \ No newline at end of file diff --git a/src/lib/StdResStr2.h b/src/lib/StdResStr2.h deleted file mode 100644 index 79160da60..000000000 --- a/src/lib/StdResStr2.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * OpenClonk, http://www.openclonk.org - * - * Copyright (c) 2003 Matthes Bender - * Copyright (c) 2007 Günther Brammer - * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de - * - * Portions might be copyrighted by other authors who have contributed - * to OpenClonk. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * See isc_license.txt for full license and disclaimer. - * - * "Clonk" is a registered trademark of Matthes Bender. - * See clonk_trademark_license.txt for full license. - */ - -/* Load strings from a primitive memory string table */ - -#ifndef INC_STD_RES_STR_2_H -#define INC_STD_RES_STR_2_H -const char *LoadResStr(const char *id); -char *LoadResStrNoAmp(const char *id); -char *GetResStr(const char *id, const char *strTable); - -void SetResStrTable(char *pTable); -void ClearResStrTable(); -bool IsResStrTableLoaded(); - -#endif // INC_STD_RES_STR_2_H diff --git a/src/mape/configfile.c b/src/mape/configfile.c new file mode 100644 index 000000000..6b9d0db90 --- /dev/null +++ b/src/mape/configfile.c @@ -0,0 +1,177 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include +#include +#include +#include "mape/configfile.h" + +MapeConfigFile* mape_config_file_new(const gchar* filename) +{ + /* If filename does not exist, we return an empty config file. */ + MapeConfigFile* file; + gchar* contents; + gchar** lines; + gchar** cur_line; + gchar* sep; + gsize length; + + file = malloc(sizeof(MapeConfigFile) ); + file->file_path = g_strdup(filename); + file->entries = NULL; + file->entry_count = 0; + + if(g_file_get_contents(filename, &contents, &length, NULL) == FALSE) + return file; + + lines = g_strsplit(contents, "\n", 0); + g_free(contents); + + for(cur_line = lines; *cur_line != NULL; ++ cur_line) + { + sep = strchr(*cur_line, '='); + if(sep == NULL) continue; + + *sep = '\0'; + mape_config_file_set_entry(file, *cur_line, sep + 1); + *sep = '='; + } + + g_strfreev(lines); + return file; +} + +void mape_config_file_destroy(MapeConfigFile* file) +{ + gsize i; + for(i = 0; i < file->entry_count; ++ i) + { + g_free(file->entries[i].key); + g_free(file->entries[i].value); + } + + g_free(file->entries); + g_free(file->file_path); + free(file); +} + +gboolean mape_config_file_serialise(MapeConfigFile* file, + GError** error) +{ + gchar* dir; + gchar* content; + gchar* temp; + gsize i; + + int dir_result; + gboolean cont_result; + + dir = g_dirname(file->file_path); + dir_result = g_mkdir_with_parents(dir, 0755); + + g_free(dir); + if(dir_result == -1) + { + g_set_error( + error, + g_quark_from_static_string("MAPE_CONFIG_FILE_ERROR"), + errno, + "%s", + g_strerror(errno) + ); + + return FALSE; + } + + content = g_strdup(""); + for(i = 0; i < file->entry_count; ++ i) + { + temp = g_strconcat( + content, + file->entries[i].key, + "=", + file->entries[i].value, + "\n", + NULL + ); + + g_free(content); + content = temp; + } + + cont_result = g_file_set_contents(file->file_path, content, -1, error); + g_free(content); + + return(cont_result); +} + +gsize mape_config_file_get_entry_count(MapeConfigFile* file) +{ + return file->entry_count; +} + +MapeConfigFileEntry* mape_config_file_get_entry(MapeConfigFile* file, + gsize index) +{ + g_assert(index < file->entry_count); + return &file->entries[index]; +} + +MapeConfigFileEntry* mape_config_file_get_entry_by_key(MapeConfigFile* file, + const gchar* key) +{ + gsize i; + for(i = 0; i < file->entry_count; ++ i) + if(g_strcasecmp(file->entries[i].key, key) == 0) + return &file->entries[i]; + + return NULL; +} + +void mape_config_file_set_entry(MapeConfigFile* file, + const gchar* key, + const gchar* value) +{ + MapeConfigFileEntry* entry; + entry = mape_config_file_get_entry_by_key(file, key); + + if(entry != NULL) + { + g_free(entry->value); + entry->value = g_strdup(value); + } + else + { + ++ file->entry_count; + file->entries = realloc( + file->entries, + sizeof(MapeConfigFileEntry) * file->entry_count + ); + + entry = &file->entries[file->entry_count - 1]; + entry->key = g_strdup(key); + entry->value = g_strdup(value); + } +} + +const gchar* mape_config_file_entry_get_key(MapeConfigFileEntry* entry) +{ + return entry->key; +} + +const gchar* mape_config_file_entry_get_value(MapeConfigFileEntry* entry) +{ + return entry->value; +} diff --git a/src/mape/configfile.h b/src/mape/configfile.h new file mode 100644 index 000000000..48ee45361 --- /dev/null +++ b/src/mape/configfile.h @@ -0,0 +1,53 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_CONFIGFILE_H +#define INC_MAPE_CONFIGFILE_H + +#include +#include "mape/forward.h" + +struct MapeConfigFileEntry_ { + gchar* key; + gchar* value; +}; + +struct MapeConfigFile_ { + gchar* file_path; + + MapeConfigFileEntry* entries; + gsize entry_count; +}; + +MapeConfigFile* mape_config_file_new(const gchar* filename); +void mape_config_file_destroy(MapeConfigFile* file); + +gboolean mape_config_file_serialise(MapeConfigFile* file, + GError** error); + +gsize mape_config_file_get_entry_count(MapeConfigFile* file); +MapeConfigFileEntry* mape_config_file_get_entry(MapeConfigFile* file, + gsize index); +MapeConfigFileEntry* mape_config_file_get_entry_by_key(MapeConfigFile* file, + const gchar* key); + +void mape_config_file_set_entry(MapeConfigFile* file, + const gchar* key, + const gchar* value); + +const gchar* mape_config_file_entry_get_key(MapeConfigFileEntry* entry); +const gchar* mape_config_file_entry_get_value(MapeConfigFileEntry* entry); + +#endif /* INC_MAPE_CONFIGFILE_H */ diff --git a/src/mape/cpp-handles/group-handle.cpp b/src/mape/cpp-handles/group-handle.cpp new file mode 100644 index 000000000..ef494f289 --- /dev/null +++ b/src/mape/cpp-handles/group-handle.cpp @@ -0,0 +1,106 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Include.h" +#include "C4Group.h" +#include "mape/cpp-handles/group-handle.h" + +#define GROUP_TO_HANDLE(group) (reinterpret_cast(group)) +#define HANDLE_TO_GROUP(handle) (reinterpret_cast(handle)) + +extern "C" { + +C4GroupHandle* c4_group_handle_new(void) +{ + return GROUP_TO_HANDLE(new C4Group); +} + +void c4_group_handle_free(C4GroupHandle* handle) +{ + delete HANDLE_TO_GROUP(handle); +} + +const gchar* c4_group_handle_get_error(C4GroupHandle* handle) +{ + return HANDLE_TO_GROUP(handle)->GetError(); +} + +gboolean c4_group_handle_open(C4GroupHandle* handle, const gchar* path, gboolean create) +{ + return HANDLE_TO_GROUP(handle)->Open(path, create); +} + +gboolean c4_group_handle_open_as_child(C4GroupHandle* handle, C4GroupHandle* mother, const gchar* name, gboolean exclusive, gboolean create) +{ + return HANDLE_TO_GROUP(handle)->OpenAsChild(HANDLE_TO_GROUP(mother), + name, exclusive, create); +} + +const gchar* c4_group_handle_get_name(C4GroupHandle* handle) +{ + return HANDLE_TO_GROUP(handle)->GetName(); +} + +gchar* c4_group_handle_get_full_name(C4GroupHandle* handle) +{ + StdStrBuf buf(HANDLE_TO_GROUP(handle)->GetFullName()); + gchar* res = static_cast(g_malloc(buf.getSize()*sizeof(gchar))); + memcpy(res, buf.getData(), buf.getSize()); + return res; +} + +void c4_group_handle_reset_search(C4GroupHandle* handle) +{ + HANDLE_TO_GROUP(handle)->ResetSearch(); +} + +gboolean c4_group_handle_find_next_entry(C4GroupHandle* handle, const gchar* wildcard, gsize* size, gchar* filename, gboolean start_at_filename) +{ + return HANDLE_TO_GROUP(handle)->FindNextEntry(wildcard, filename, size, start_at_filename); +} + +gboolean c4_group_handle_access_next_entry(C4GroupHandle* handle, const gchar* wildcard, gsize* size, gchar* filename, gboolean start_at_filename) +{ + return HANDLE_TO_GROUP(handle)->AccessNextEntry(wildcard, size, filename, start_at_filename); +} + +gboolean c4_group_handle_access_entry(C4GroupHandle* handle, const gchar* wildcard, gsize* size, gchar* filename, gboolean needs_to_be_a_group) +{ + return HANDLE_TO_GROUP(handle)->AccessEntry(wildcard, size, filename, needs_to_be_a_group); +} + +gsize c4_group_handle_accessed_entry_size(C4GroupHandle* handle) +{ + return HANDLE_TO_GROUP(handle)->AccessedEntrySize(); +} + +gboolean c4_group_handle_read(C4GroupHandle* handle, gpointer buffer, gsize size) +{ + return HANDLE_TO_GROUP(handle)->Read(buffer, size); +} + +C4GroupHandleStatus c4_group_handle_get_status(C4GroupHandle* handle) +{ + int status = HANDLE_TO_GROUP(handle)->GetStatus(); + switch(status) + { + case GRPF_Inactive: return C4_GROUP_HANDLE_INACTIVE; + case GRPF_File: return C4_GROUP_HANDLE_FILE; + case GRPF_Folder: return C4_GROUP_HANDLE_FOLDER; + default: g_assert_not_reached(); return C4_GROUP_HANDLE_INACTIVE; + } +} + +} /* extern "C" */ diff --git a/src/mape/cpp-handles/group-handle.h b/src/mape/cpp-handles/group-handle.h new file mode 100644 index 000000000..6c4d86df6 --- /dev/null +++ b/src/mape/cpp-handles/group-handle.h @@ -0,0 +1,54 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_GROUP_HANDLE_H +#define INC_MAPE_C4_GROUP_HANDLE_H + +#include + +G_BEGIN_DECLS + +typedef struct _C4GroupHandle C4GroupHandle; + +typedef enum _C4GroupHandleStatus { + C4_GROUP_HANDLE_INACTIVE, + C4_GROUP_HANDLE_FILE, + C4_GROUP_HANDLE_FOLDER +} C4GroupHandleStatus; + +C4GroupHandle* c4_group_handle_new(void); +void c4_group_handle_free(C4GroupHandle* handle); + +const gchar* c4_group_handle_get_error(C4GroupHandle* handle); + +gboolean c4_group_handle_open(C4GroupHandle* handle, const gchar* path, gboolean create); +gboolean c4_group_handle_open_as_child(C4GroupHandle* handle, C4GroupHandle* mother, const gchar* name, gboolean exclusive, gboolean create); + +const gchar* c4_group_handle_get_name(C4GroupHandle* handle); +gchar* c4_group_handle_get_full_name(C4GroupHandle* handle); + +void c4_group_handle_reset_search(C4GroupHandle* handle); + +gboolean c4_group_handle_find_next_entry(C4GroupHandle* handle, const gchar* wildcard, gsize* size, gchar* filename, gboolean start_at_filename); +gboolean c4_group_handle_access_next_entry(C4GroupHandle* handle, const gchar* wildcard, gsize* size, gchar* filename, gboolean start_at_filename); +gboolean c4_group_handle_access_entry(C4GroupHandle* handle, const gchar* wildcard, gsize* size, gchar* filename, gboolean needs_to_be_a_group); +gsize c4_group_handle_accessed_entry_size(C4GroupHandle* handle); +gboolean c4_group_handle_read(C4GroupHandle* handle, gpointer buffer, gsize size); + +C4GroupHandleStatus c4_group_handle_get_status(C4GroupHandle* handle); + +G_END_DECLS + +#endif /* INC_MAPE_C4_GROUP_HANDLE_H */ diff --git a/src/mape/cpp-handles/log-handle.cpp b/src/mape/cpp-handles/log-handle.cpp new file mode 100644 index 000000000..e00fa3c33 --- /dev/null +++ b/src/mape/cpp-handles/log-handle.cpp @@ -0,0 +1,57 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include +#include + +// This implements the Log engine function such that the first log message +// is stored and can be retrieved later by the C API. +std::string first_log; +bool Log(const char *msg) +{ + if(first_log.empty()) + first_log = msg; + return true; +} +bool DebugLog(const char *strMessage) { return Log(strMessage); } +bool LogFatal(const char *strMessage) { return Log(strMessage); } + +#define IMPLEMENT_LOGF(func) \ + bool func(const char *msg, ...) { \ + va_list args; va_start(args, msg); \ + StdStrBuf Buf; \ + Buf.FormatV(msg, args); \ + return Log(Buf.getData()); \ + } + +IMPLEMENT_LOGF(DebugLogF) +IMPLEMENT_LOGF(LogF) +IMPLEMENT_LOGF(LogSilentF) + +// C API follows here +extern "C" { + +void c4_log_handle_clear() +{ + first_log.clear(); +} + +const char* c4_log_handle_get_first_log_message() +{ + if(first_log.empty()) return NULL; + return first_log.c_str(); +} + +} // extern "C" diff --git a/src/mape/cpp-handles/log-handle.h b/src/mape/cpp-handles/log-handle.h new file mode 100644 index 000000000..508677d7e --- /dev/null +++ b/src/mape/cpp-handles/log-handle.h @@ -0,0 +1,30 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_LOG_HANDLE_H +#define INC_MAPE_C4_LOG_HANDLE_H + +#include + +G_BEGIN_DECLS + +typedef struct _C4MapgenHandle C4MapgenHandle; + +void c4_log_handle_clear(); +const char* c4_log_handle_get_first_log_message(); + +G_END_DECLS + +#endif /* INC_MAPE_C4_LOG_HANDLE_H */ diff --git a/src/mape/cpp-handles/mapgen-handle.cpp b/src/mape/cpp-handles/mapgen-handle.cpp new file mode 100644 index 000000000..4a88a3a96 --- /dev/null +++ b/src/mape/cpp-handles/mapgen-handle.cpp @@ -0,0 +1,207 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Include.h" +#include +#include +#include +#include + +#include "mape/cpp-handles/material-handle.h" +#include "mape/cpp-handles/texture-handle.h" +#include "mape/cpp-handles/log-handle.h" +#include "mape/cpp-handles/mapgen-handle.h" + +#define HANDLE_TO_MATERIAL_MAP(handle) (reinterpret_cast(handle)) +#define HANDLE_TO_TEXTURE_MAP(handle) (reinterpret_cast(handle)) + +namespace +{ + +bool HasAlgoScript(C4MCNode* node) +{ + if(node->Type() == MCN_Overlay && static_cast(node)->Algorithm == static_cast(node)->GetAlgo("script")) + return true; + + if(node->Child0) return HasAlgoScript(node->Child0); + if(node->Next) return HasAlgoScript(node->Next); + return false; +} + +} + +extern "C" { + +struct _C4MapgenHandle { + unsigned int width; + unsigned int height; + unsigned int rowstride; + StdCopyStrBuf error_message; + BYTE* data; +}; + +C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, const char* script_path, C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map, unsigned int map_width, unsigned int map_height) +{ + try + { + C4SLandscape landscape; + landscape.Default(); + + landscape.MapWdt.Set(map_width, 0, map_width, map_width); + landscape.MapHgt.Set(map_height, 0, map_height, map_height); + landscape.MapPlayerExtend = 0; + + C4MapCreatorS2 mapgen( + &landscape, + HANDLE_TO_TEXTURE_MAP(texture_map), + HANDLE_TO_MATERIAL_MAP(material_map), + 1 + ); + + C4MCParser parser(&mapgen); + parser.ParseMemFile(source, filename); + + C4MCMap* map = mapgen.GetMap(NULL); + if(!map) throw std::runtime_error("No map definition in source file"); + + // Setup the script engine if there is an algo=script overlay in the + // Landscape.txt file + if(HasAlgoScript(mapgen.GetMap(NULL))) + { + if(script_path == NULL) + throw std::runtime_error("For algo=script overlays to work, save the file first at the location of the Script.c file"); + + gchar* dirname = g_path_get_dirname(script_path); + gchar* basename = g_path_get_basename(script_path); + + C4Group File; + if(!File.Open(dirname)) + { + StdStrBuf error_msg = FormatString("Failed to open directory '%s': %s", dirname, File.GetError()); + g_free(dirname); + g_free(basename); + throw std::runtime_error(error_msg.getData()); + } + + // get scripts + File.ResetSearch(); + if(!File.FindNextEntry(basename, (char*)NULL)) + { + g_free(dirname); + g_free(basename); + StdStrBuf error_msg = FormatString("Failed to load '%s': No such file", script_path); + throw std::runtime_error(error_msg.getData()); + } + + // load core functions into script engine + InitCoreFunctionMap(&ScriptEngine); + + c4_log_handle_clear(); + GameScript.Load(File, basename, NULL, NULL); + g_free(dirname); + g_free(basename); + + const char* parse_error = c4_log_handle_get_first_log_message(); + if(parse_error) + throw std::runtime_error(parse_error); + + // Link script engine (resolve includes/appends, generate code) + c4_log_handle_clear(); + ScriptEngine.Link(&::Definitions); + if(ScriptEngine.warnCnt > 0 || ScriptEngine.errCnt > 0) + throw std::runtime_error(c4_log_handle_get_first_log_message()); + // Set name list for globals + ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames); + } + + c4_log_handle_clear(); + int32_t out_width, out_height; + BYTE* array = mapgen.RenderBuf(NULL, out_width, out_height); + GameScript.Clear(); + ScriptEngine.Clear(); + + // Don't show any map if there was a script runtime error + const char* runtime_error = c4_log_handle_get_first_log_message(); + if(runtime_error) + { + delete[] array; + throw std::runtime_error(runtime_error); + } + + C4MapgenHandle* handle = new C4MapgenHandle; + handle->width = map_width; + handle->height = map_height; + handle->rowstride = out_width; + handle->error_message = NULL; + handle->data = array; + return handle; + } + catch(const C4MCParserErr& err) + { + C4MapgenHandle* handle = new C4MapgenHandle; + handle->width = 0; + handle->height = 0; + handle->error_message.Copy(err.Msg); + handle->data = NULL; + return handle; + } + catch(const std::exception& ex) + { + C4MapgenHandle* handle = new C4MapgenHandle; + handle->width = 0; + handle->height = 0; + handle->error_message.Copy(ex.what()); + handle->data = NULL; + return handle; + } +} + +void c4_mapgen_handle_free(C4MapgenHandle* mapgen) +{ + delete[] mapgen->data; + delete mapgen; +} + +const unsigned char* c4_mapgen_handle_get_map(C4MapgenHandle* mapgen) +{ + return reinterpret_cast(mapgen->data); +} + +unsigned int c4_mapgen_handle_get_width(C4MapgenHandle* mapgen) +{ + assert(mapgen->data != NULL); + return mapgen->width; +} + +unsigned int c4_mapgen_handle_get_height(C4MapgenHandle* mapgen) +{ + assert(mapgen->data != NULL); + return mapgen->height; +} + +unsigned int c4_mapgen_handle_get_rowstride(C4MapgenHandle* mapgen) +{ + assert(mapgen->data != NULL); + return mapgen->rowstride; +} + +const char* c4_mapgen_handle_get_error(C4MapgenHandle* mapgen) +{ + if(mapgen->data != NULL) + return NULL; + return mapgen->error_message.getData(); +} + +} // extern "C" diff --git a/src/mape/cpp-handles/mapgen-handle.h b/src/mape/cpp-handles/mapgen-handle.h new file mode 100644 index 000000000..31164e53d --- /dev/null +++ b/src/mape/cpp-handles/mapgen-handle.h @@ -0,0 +1,39 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_MAPGEN_HANDLE_H +#define INC_MAPE_C4_MAPGEN_HANDLE_H + +#include + +#include "mape/cpp-handles/material-handle.h" +#include "mape/cpp-handles/texture-handle.h" + +G_BEGIN_DECLS + +typedef struct _C4MapgenHandle C4MapgenHandle; + +C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, const char* script_path, C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map, unsigned int map_width, unsigned int map_height); +void c4_mapgen_handle_free(C4MapgenHandle* mapgen); + +const unsigned char* c4_mapgen_handle_get_map(C4MapgenHandle* mapgen); +unsigned int c4_mapgen_handle_get_width(C4MapgenHandle* mapgen); +unsigned int c4_mapgen_handle_get_height(C4MapgenHandle* mapgen); +unsigned int c4_mapgen_handle_get_rowstride(C4MapgenHandle* mapgen); +const char* c4_mapgen_handle_get_error(C4MapgenHandle* mapgen); + +G_END_DECLS + +#endif /* INC_MAPE_C4_MAPGEN_HANDLE_H */ diff --git a/src/mape/cpp-handles/material-handle.cpp b/src/mape/cpp-handles/material-handle.cpp new file mode 100644 index 000000000..efaea4e80 --- /dev/null +++ b/src/mape/cpp-handles/material-handle.cpp @@ -0,0 +1,94 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Include.h" +#include "C4Material.h" +#include "C4Texture.h" +#include "mape/cpp-handles/material-handle.h" + +#define MATERIAL_MAP_TO_HANDLE(material_map) (reinterpret_cast(material_map)) +#define HANDLE_TO_MATERIAL_MAP(handle) (reinterpret_cast(handle)) + +#define MATERIAL_TO_HANDLE(material) (reinterpret_cast(material)) +#define HANDLE_TO_MATERIAL(handle) (reinterpret_cast(handle)) + +#define HANDLE_TO_TEXTURE_MAP(handle) (reinterpret_cast(handle)) + +#define GROUP_TO_HANDLE(group) (reinterpret_cast(group)) +#define HANDLE_TO_GROUP(handle) (reinterpret_cast(handle)) + +extern "C" { + +C4MaterialMapHandle* c4_material_map_handle_new(void) +{ + // Simply return a pointer to the global material map. This is a bit stupid, + // but when looking up a material-texture combination, C4TextureMap uses the + // global material map for the material lookup when the default texture is + // requested. This should be changed to get rid of the global variable, but yeah... + C4MaterialMap* map = &::MaterialMap; + map->Clear(); + return MATERIAL_MAP_TO_HANDLE(map); //new C4MaterialMap); +} + +void c4_material_map_handle_free(C4MaterialMapHandle* material_map) +{ + //delete HANDLE_TO_MATERIAL_MAP(material_map); +} + +guint c4_material_map_handle_load(C4MaterialMapHandle* material_map, C4GroupHandle* group) +{ + return HANDLE_TO_MATERIAL_MAP(material_map)->Load(*HANDLE_TO_GROUP(group)); +} + +void c4_material_map_crossmap_materials(C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map) +{ + // Don't call the official crossmap function since it tries to load some surfaces. + // All we need is the default texture. + for(int i = 0; i < HANDLE_TO_MATERIAL_MAP(material_map)->Num; ++i) + { + C4Material* mat = &HANDLE_TO_MATERIAL_MAP(material_map)->Map[i]; + const char* overlay = mat->sTextureOverlay.getData(); + if(!overlay || *overlay == '\0') + { + int first_tex_map_entry = HANDLE_TO_TEXTURE_MAP(texture_map)->GetIndex(mat->Name, NULL, false); + overlay = HANDLE_TO_TEXTURE_MAP(texture_map)->GetEntry(first_tex_map_entry)->GetTextureName(); + } + + if(overlay) + mat->DefaultMatTex = HANDLE_TO_TEXTURE_MAP(texture_map)->GetIndex(mat->Name, overlay, true); + } +} + +guint c4_material_map_handle_get_num(C4MaterialMapHandle* material_map) +{ + return HANDLE_TO_MATERIAL_MAP(material_map)->Num; +} + +C4MaterialHandle* c4_material_map_handle_get_material(C4MaterialMapHandle* material_map, guint index) +{ + g_assert(index < (guint)(HANDLE_TO_MATERIAL_MAP(material_map)->Num)); + return MATERIAL_TO_HANDLE(&HANDLE_TO_MATERIAL_MAP(material_map)->Map[index]); +} + +const gchar* c4_material_handle_get_name(C4MaterialHandle* material) +{ + return HANDLE_TO_MATERIAL(material)->Name; +} +const gchar* c4_material_handle_get_texture_overlay(C4MaterialHandle* material) +{ + return HANDLE_TO_MATERIAL(material)->sTextureOverlay.getData(); +} + +} /* extern "C" */ diff --git a/src/mape/cpp-handles/material-handle.h b/src/mape/cpp-handles/material-handle.h new file mode 100644 index 000000000..773cbe8ff --- /dev/null +++ b/src/mape/cpp-handles/material-handle.h @@ -0,0 +1,43 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_MATERIAL_HANDLE_H +#define INC_MAPE_C4_MATERIAL_HANDLE_H + +#include + +#include "mape/cpp-handles/group-handle.h" +#include "mape/cpp-handles/texture-handle.h" + +G_BEGIN_DECLS + +typedef struct _C4MaterialHandle C4MaterialHandle; +typedef struct _C4MaterialMapHandle C4MaterialMapHandle; + +C4MaterialMapHandle* c4_material_map_handle_new(void); +void c4_material_map_handle_free(C4MaterialMapHandle* material_map); + +guint c4_material_map_handle_load(C4MaterialMapHandle* material_map, C4GroupHandle* group); +void c4_material_map_crossmap_materials(C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map); + +guint c4_material_map_handle_get_num(C4MaterialMapHandle* material_map); +C4MaterialHandle* c4_material_map_handle_get_material(C4MaterialMapHandle* material_map, guint index); + +const gchar* c4_material_handle_get_name(C4MaterialHandle* material); +const gchar* c4_material_handle_get_texture_overlay(C4MaterialHandle* material); + +G_END_DECLS + +#endif /* INC_MAPE_C4_MATERIAL_HANDLE_H */ diff --git a/src/mape/cpp-handles/random-handle.cpp b/src/mape/cpp-handles/random-handle.cpp new file mode 100644 index 000000000..af7b6597d --- /dev/null +++ b/src/mape/cpp-handles/random-handle.cpp @@ -0,0 +1,27 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Include.h" +#include "C4Random.h" +#include "mape/cpp-handles/random-handle.h" + +extern "C" { + +void c4_random_handle_seed(unsigned int seed) +{ + FixedRandom(seed); +} + +} // extern "C" diff --git a/src/mape/cpp-handles/random-handle.h b/src/mape/cpp-handles/random-handle.h new file mode 100644 index 000000000..67d41ad54 --- /dev/null +++ b/src/mape/cpp-handles/random-handle.h @@ -0,0 +1,27 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_RANDOM_HANDLE_H +#define INC_MAPE_C4_RANDOM_HANDLE_H + +#include + +G_BEGIN_DECLS + +void c4_random_handle_seed(unsigned int seed); + +G_END_DECLS + +#endif /* INC_MAPE_C4_RANDOM_HANDLE_H */ diff --git a/src/mape/cpp-handles/stub-handle.cpp b/src/mape/cpp-handles/stub-handle.cpp new file mode 100644 index 000000000..15514faa2 --- /dev/null +++ b/src/mape/cpp-handles/stub-handle.cpp @@ -0,0 +1,208 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Include.h" + +#include "C4Aul.h" +#include "C4AulDebug.h" +#include "C4GameControl.h" +#include "C4Def.h" +#include "C4DefList.h" +#include "C4Facet.h" +#include "C4GameObjects.h" +#include "C4GameParameters.h" +#include "C4GraphicsResource.h" +#include "C4Landscape.h" +#include "C4PXS.h" +#include "C4Record.h" +#include "C4RoundResults.h" +#include "CSurface8.h" +#include "C4MapScript.h" + +/* This file implements stubs for the parts of the engine that are not used + * by mape. It also instantiates global variables required by mape that are + * not instantiated elsewhere. In particular, we avoid C4Globals.cpp. */ + +/* These are actually used by mape: */ +#ifdef _DEBUG +C4Set C4PropList::PropLists; +#endif +C4Set C4PropListNumbered::PropLists; +std::vector C4PropListNumbered::ShelvedPropLists; +int32_t C4PropListNumbered::EnumerationIndex = 0; +C4StringTable Strings; +C4AulScriptEngine ScriptEngine; +C4DefList Definitions; + +/* These are just stubs used by dead code: */ +C4Landscape Landscape; +C4PXSSystem PXS; +C4Config Config; +C4GameObjects Objects; +C4Reloc Reloc; +class C4Draw *pDraw = NULL; + +bool EraseItemSafe(const char *szFilename) {return false;} +void Smoke(int32_t tx, int32_t ty, int32_t level, DWORD dwClr) {} +class C4SoundInstance *StartSoundEffectAt(const char *, int32_t, int32_t, int32_t, int32_t) { return NULL; } + +C4Config::C4Config() {} +C4Config::~C4Config() {} +const char* C4Config::AtTempPath(const char *) { return NULL; } +const char* C4Config::AtRelativePath(char const* s) {return s;} +bool C4Reloc::Open(C4Group&, char const*) const {return false;} + +bool C4Draw::TextOut(const char *, CStdFont &, float, C4Surface *, float, float, DWORD, BYTE, bool) { return false; } + +CSurface8::CSurface8(int, int) {} + +C4Facet::C4Facet() {} +void C4Facet::Set(C4Surface*, float, float, float, float) {} +int32_t C4Facet::GetSectionCount() { return 0; } +C4Facet C4Facet::TruncateSection(int32_t) { return *this; } + +C4Surface::C4Surface() {} +C4Surface::~C4Surface() {} +bool C4Surface::Read(CStdStream &, const char *) { return false; } +bool C4Surface::Lock() { return false; } +bool C4Surface::Unlock() { return false; } +DWORD C4Surface::GetPixDw(int iX, int iY, bool fApplyModulation) { return 0; } + +C4Pattern::C4Pattern() {} +void C4Pattern::Clear() {} +bool C4Pattern::Set(C4Surface *, int) { return false; } +DWORD C4Pattern::PatternClr(unsigned int, unsigned int) const { return 0; } +C4Pattern& C4Pattern::operator=(C4Pattern const&) { return *this; } + +C4IDList::C4IDList() {} +C4IDList::~C4IDList() {} +void C4IDList::Default() {} +void C4IDList::Clear() {} +C4IDList& C4IDList::operator=(C4IDList const&) { return *this; } +bool C4IDList::operator==(const C4IDList&) const { return false; } +int32_t C4IDList::GetIDCount(C4ID, int32_t) const { return 0; } +bool C4IDList::SetIDCount(C4ID, int32_t, bool) { return false; } +void C4IDList::CompileFunc(StdCompiler *, bool) {} +C4IDListChunk::C4IDListChunk() {} +C4IDListChunk::~C4IDListChunk() {} + +void C4Def::IncludeDefinition(C4Def*) {} + +C4DefList::C4DefList() {} +C4DefList::~C4DefList() {} +C4Def* C4DefList::ID2Def(C4ID) {return NULL;} +void C4DefList::Draw(C4ID, C4Facet &, bool, int32_t) {} +C4Def * C4DefList::GetDef(int) {return 0;} +int C4DefList::GetDefCount() {return 0;} +void C4DefList::CallEveryDefinition() {} +void C4DefList::ResetIncludeDependencies() {} +bool C4DefList::DrawFontImage(const char* szImageTag, C4Facet& rTarget, C4DrawTransform* pTransform) { return false; } +float C4DefList::GetFontImageAspect(const char* szImageTag) { return -1.0f; } + +C4Landscape::C4Landscape() {} +C4Landscape::~C4Landscape() {} +bool C4Landscape::FindMatSlide(int&, int&, int, int, int) { return false; } +int32_t C4Landscape::ExtractMaterial(int32_t, int32_t) { return 0; } +bool C4Landscape::InsertMaterial(int32_t, int32_t *, int32_t *, int32_t, int32_t, bool) { return false; } +bool C4Landscape::Incinerate(int32_t, int32_t) { return false; } +bool C4Landscape::ClearPix(int32_t, int32_t) { return false; } +void C4Landscape::CheckInstabilityRange(int32_t, int32_t) {} +void C4Landscape::HandleTexMapUpdate() {} + +void C4Sky::Default() {} +C4Sky::~C4Sky() {} + +void C4LSector::Clear() {} + +C4ObjectList::C4ObjectList() {} +C4ObjectList::~C4ObjectList() {} +void C4ObjectList::Default() {} +void C4ObjectList::Clear() {} +void C4ObjectList::InsertLinkBefore(C4ObjectLink*, C4ObjectLink*) {} +void C4ObjectList::InsertLink(C4ObjectLink*, C4ObjectLink*) {} +void C4ObjectList::RemoveLink(C4ObjectLink*) {} +bool C4ObjectList::Add(C4Object*, C4ObjectList::SortType, C4ObjectList*) {return 0;} +bool C4ObjectList::Remove(C4Object*) {return 0;} +bool C4ObjectList::AssignInfo() {return 0;} +bool C4ObjectList::ValidateOwners() {return 0;} + +void C4NotifyingObjectList::InsertLinkBefore(C4ObjectLink *pLink, C4ObjectLink *pBefore) {} +void C4NotifyingObjectList::InsertLink(C4ObjectLink*, C4ObjectLink*) {} +void C4NotifyingObjectList::RemoveLink(C4ObjectLink*) {} + +C4GameObjects::C4GameObjects() {} +C4GameObjects::~C4GameObjects() {} +void C4GameObjects::Clear(bool) {} +void C4GameObjects::Default() {} +bool C4GameObjects::Remove(C4Object*) {return 0;} +bool C4GameObjects::AssignInfo() {return 0;} +bool C4GameObjects::ValidateOwners() {return 0;} +C4Object * C4GameObjects::ObjectPointer(int) {return 0;} +void C4GameObjects::UpdateScriptPointers() {} +C4Value C4GameObjects::GRBroadcast(char const*, C4AulParSet*, bool, bool) {return C4Value();} + +C4PXSSystem::C4PXSSystem() {} +C4PXSSystem::~C4PXSSystem() {} +bool C4PXSSystem::Create(int, C4Real, C4Real, C4Real, C4Real) { return false; } + +void AddDbgRec(C4RecordChunkType, const void *, int) {} + +#if 0 +/* Pulled in by C4Game... */ +CStdFont::CStdFont() {} +C4PathFinder::C4PathFinder() {} +C4PathFinder::~C4PathFinder() {} +C4TransferZones::C4TransferZones() {} +C4TransferZones::~C4TransferZones() {} +C4PacketBase::C4PacketBase() {} +C4PacketList::C4PacketList() {} +C4PacketBase::~C4PacketBase() {} +C4PacketList::~C4PacketList() {} +C4Control::C4Control() {} +C4Control::~C4Control() {} +C4GameControl::C4GameControl(): Network(this) {} +C4GameControl::~C4GameControl() {} +C4GameControlNetwork::C4GameControlNetwork(C4GameControl*): pParent(NULL) {} +C4GameControlNetwork::~C4GameControlNetwork() {} +C4GraphicsResource::C4GraphicsResource(): CaptionFont(FontCaption), TitleFont(FontTitle), TextFont(FontRegular), MiniFont(FontTiny), TooltipFont(FontTooltip) {} +C4GraphicsResource::~C4GraphicsResource() {} +C4GameParameters::C4GameParameters() {} +C4GameParameters::~C4GameParameters() {} + +//C4Extra::C4Extra() {} +//C4Extra::~C4Extra() {} +void C4Extra::Clear() {} + +static C4KeyboardInput KeyboardInput; +void C4KeyboardInput::Clear() {} +bool C4KeyboardInput::IsValid = false; +C4KeyboardInput &C4KeyboardInput_Init() { return KeyboardInput; } + +static C4GameParameters GameParameters; +static C4RoundResults GameRoundResults; +C4Game::C4Game(): Parameters(GameParameters), Clients(Parameters.Clients), Teams(Parameters.Teams), PlayerInfos(Parameters.PlayerInfos), RestorePlayerInfos(Parameters.RestorePlayerInfos), RoundResults(GameRoundResults), Input(Control.Input), KeyboardInput(C4KeyboardInput_Init()) {} +C4Game::~C4Game() {} +#endif + +C4AulDebug *C4AulDebug::pDebug; +void C4AulDebug::DebugStep(C4AulBCC*, C4Value*) {} + +C4MapScriptHost MapScript; +C4MapScriptHost::C4MapScriptHost() {} +C4MapScriptHost::~C4MapScriptHost() {} +void C4MapScriptHost::Clear() {} +C4PropListStatic *C4MapScriptHost::GetPropList() {return NULL;} +bool C4MapScriptHost::Load(C4Group &, const char *, const char *, C4LangStringTable *) { return false; } +void C4MapScriptHost::AddEngineFunctions() {} diff --git a/src/mape/cpp-handles/texture-handle.cpp b/src/mape/cpp-handles/texture-handle.cpp new file mode 100644 index 000000000..8e825fd27 --- /dev/null +++ b/src/mape/cpp-handles/texture-handle.cpp @@ -0,0 +1,81 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Include.h" +#include "C4Texture.h" +#include "mape/cpp-handles/texture-handle.h" + +#define TEXTURE_MAP_TO_HANDLE(texture_map) (reinterpret_cast(texture_map)) +#define HANDLE_TO_TEXTURE_MAP(handle) (reinterpret_cast(handle)) + +#define GROUP_TO_HANDLE(group) (reinterpret_cast(group)) +#define HANDLE_TO_GROUP(handle) (reinterpret_cast(handle)) + +extern "C" { + +C4TextureMapHandle* c4_texture_map_handle_new(void) +{ + return TEXTURE_MAP_TO_HANDLE(new C4TextureMap); +} + +void c4_texture_map_handle_free(C4TextureMapHandle* texture_map) +{ + delete HANDLE_TO_TEXTURE_MAP(texture_map); +} + + +guint c4_texture_map_handle_load_map(C4TextureMapHandle* texture_map, C4GroupHandle* group, const char* entry_name, gboolean* overload_materials, gboolean* overload_textures) +{ + bool fOverloadMaterials = false; + bool fOverloadTextures = false; + guint32 retval = HANDLE_TO_TEXTURE_MAP(texture_map)->LoadMap(*HANDLE_TO_GROUP(group), entry_name, &fOverloadMaterials, &fOverloadTextures); + if(overload_materials) *overload_materials = fOverloadMaterials; + if(overload_textures) *overload_textures = fOverloadTextures; + return retval; +} + +gboolean c4_texture_map_handle_add_texture(C4TextureMapHandle* texture_map, const char* texture, guint32 avg_color) +{ + gboolean result = HANDLE_TO_TEXTURE_MAP(texture_map)->AddTexture(texture, NULL); + if(!result) return FALSE; + HANDLE_TO_TEXTURE_MAP(texture_map)->GetTexture(texture)->SetAverageColor(avg_color); + return TRUE; +} + +const char* c4_texture_map_handle_get_texture(C4TextureMapHandle* texture_map, guint index) +{ + return HANDLE_TO_TEXTURE_MAP(texture_map)->GetTexture(index); +} + +guint32 c4_texture_handle_get_average_texture_color(C4TextureMapHandle* texture_map, const char* name) +{ + return HANDLE_TO_TEXTURE_MAP(texture_map)->GetTexture(name)->GetAverageColor(); +} + +const char* c4_texture_handle_get_entry_material_name(C4TextureMapHandle* texture_map, guint index) +{ + const C4TexMapEntry* entry = HANDLE_TO_TEXTURE_MAP(texture_map)->GetEntry(index); + if(!entry) return NULL; + return entry->GetMaterialName(); +} + +const char* c4_texture_handle_get_entry_texture_name(C4TextureMapHandle* texture_map, guint index) +{ + const C4TexMapEntry* entry = HANDLE_TO_TEXTURE_MAP(texture_map)->GetEntry(index); + if(!entry) return NULL; + return entry->GetTextureName(); +} + +} /* extern "C" */ diff --git a/src/mape/cpp-handles/texture-handle.h b/src/mape/cpp-handles/texture-handle.h new file mode 100644 index 000000000..f3e5a1b93 --- /dev/null +++ b/src/mape/cpp-handles/texture-handle.h @@ -0,0 +1,41 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_TEXTURE_HANDLE_H +#define INC_MAPE_C4_TEXTURE_HANDLE_H + +#include + +#include "mape/cpp-handles/group-handle.h" + +G_BEGIN_DECLS + +typedef struct _C4TextureMapHandle C4TextureMapHandle; + +C4TextureMapHandle* c4_texture_map_handle_new(void); +void c4_texture_map_handle_free(C4TextureMapHandle* texture_map); + +guint c4_texture_map_handle_load_map(C4TextureMapHandle* texture_map, C4GroupHandle* group, const char* entry_name, gboolean* overload_materials, gboolean* overload_textures); +gboolean c4_texture_map_handle_add_texture(C4TextureMapHandle* texture_map, const char* texture, guint32 avg_color); +const char* c4_texture_map_handle_get_texture(C4TextureMapHandle* texture_map, guint index); + +const char* c4_texture_handle_get_entry_material_name(C4TextureMapHandle* texture_map, guint index); +const char* c4_texture_handle_get_entry_texture_name(C4TextureMapHandle* texture_map, guint index); + +guint32 c4_texture_handle_get_average_texture_color(C4TextureMapHandle* texture_map, const char* name); + +G_END_DECLS + +#endif /* INC_MAPE_C4_TEXTURE_HANDLE_H */ diff --git a/src/mape/cpp-handles/version-handle.cpp b/src/mape/cpp-handles/version-handle.cpp new file mode 100644 index 000000000..ad7ba74a8 --- /dev/null +++ b/src/mape/cpp-handles/version-handle.cpp @@ -0,0 +1,26 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include "C4Version.h" +#include "mape/cpp-handles/version-handle.h" + +extern "C" { + +const char* c4_version_get() +{ + return C4VERSION; +} + +} /* extern "C" */ diff --git a/src/mape/cpp-handles/version-handle.h b/src/mape/cpp-handles/version-handle.h new file mode 100644 index 000000000..d40937559 --- /dev/null +++ b/src/mape/cpp-handles/version-handle.h @@ -0,0 +1,27 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_C4_VERSION_HANDLE_H +#define INC_MAPE_C4_VERSION_HANDLE_H + +#include + +G_BEGIN_DECLS + +const char* c4_version_get(); + +G_END_DECLS + +#endif /* INC_MAPE_C4_TEXTURE_HANDLE_H */ diff --git a/src/mape/diskview.c b/src/mape/diskview.c new file mode 100644 index 000000000..61a6918ac --- /dev/null +++ b/src/mape/diskview.c @@ -0,0 +1,1132 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include +#include + +#include + +#include "mape/group.h" +#include "mape/fileicon.h" +#include "mape/configfile.h" +#include "mape/mattexview.h" +#include "mape/editview.h" +#include "mape/diskview.h" + +static gboolean mape_disk_view_find_iter(MapeDiskView* disk_view, + GtkTreeIter* child, + GtkTreeIter* parent, + const gchar* file) +{ + gboolean result; + gchar* filename; + + result = gtk_tree_model_iter_children( + disk_view->tree_store, + child, + parent + ); + + while(result == TRUE) + { + gtk_tree_model_get( + disk_view->tree_store, + child, + MAPE_DISK_VIEW_COLUMN_FILE, + &filename, + -1 + ); + + if(g_strcasecmp(filename, file) == 0) + { + g_free(filename); + return TRUE; + } + + g_free(filename); + result = gtk_tree_model_iter_next(disk_view->tree_store, child); + } + + return FALSE; +} + +static gchar* mape_disk_view_get_file_path(MapeDiskView* disk_view, + GtkTreeIter* file) +{ + gboolean result; + GtkTreeIter parent; + GtkTreeIter child; + gchar* cur_path; + gchar* component; + gchar* temp_path; + + child = *file; + + gtk_tree_model_get( + disk_view->tree_store, + file, + MAPE_DISK_VIEW_COLUMN_FILE, + &cur_path, + -1 + ); + + for(;;) + { + result = gtk_tree_model_iter_parent( + disk_view->tree_store, + &parent, + &child + ); + + if(result == FALSE) + break; + + gtk_tree_model_get( + disk_view->tree_store, + &parent, + MAPE_DISK_VIEW_COLUMN_FILE, + &component, + -1 + ); + +#ifdef G_OS_WIN32 + temp_path = g_build_filename(component, cur_path, NULL); +#else + /* Add leading "/" to filename for absolute path */ + temp_path = g_build_filename("/", component, cur_path, NULL); +#endif + g_free(component); g_free(cur_path); + cur_path = temp_path; + + child = parent; + } + + return cur_path; +} + +static gboolean mape_disk_view_load_materials(MapeDiskView* disk_view, + GtkTreeIter* material_iter, + GError** error) +{ + GtkTreeIter parent_iter; + GtkTreeIter new_parent; + gboolean has_parent; + gboolean result; + gchar* mat_path; + + MapeGroup* group; + MapeGroup* parent_group; + MapeGroup* overloaded_group; + + MapeTextureMap* texture_map; + gboolean overload_materials; + gboolean overload_textures; + + /* Open Material.ocg group */ + gtk_tree_model_get( + disk_view->tree_store, + material_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &group, + -1 + ); + + if(group == NULL) + { + has_parent = gtk_tree_model_iter_parent( + disk_view->tree_store, + &parent_iter, + material_iter + ); + + if(has_parent == TRUE) + { + gtk_tree_model_get( + disk_view->tree_store, + &parent_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &parent_group, + -1 + ); + + g_assert(parent_group != NULL); + } + else + { + parent_group = disk_view->group_top; + } + + group = mape_group_open_child( + parent_group, + "Material.ocg", + error + ); + + if(group == NULL) return FALSE; + + gtk_tree_store_set( + GTK_TREE_STORE(disk_view->tree_store), + material_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + group, + -1 + ); + } + + texture_map = mape_texture_map_new(); + if(mape_texture_map_load_map(texture_map, group, error) == FALSE) + { + g_object_unref(texture_map); + return FALSE; + } + + overload_materials = mape_texture_map_get_overload_materials(texture_map); + overload_textures = mape_texture_map_get_overload_textures(texture_map); + + if(overload_materials || overload_textures) + { + /* Look for overloaded Material.ocg */ + has_parent = gtk_tree_model_iter_parent( + disk_view->tree_store, + &parent_iter, + material_iter + ); + + for(;;) + { + overloaded_group = NULL; + + has_parent = gtk_tree_model_iter_parent( + disk_view->tree_store, + &new_parent, + &parent_iter + ); + + if(has_parent == FALSE) + break; + + parent_iter = new_parent; + + gtk_tree_model_get( + disk_view->tree_store, + &parent_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &overloaded_group, + -1 + ); + + if(mape_group_has_entry(overloaded_group, "Material.ocg") == + TRUE) + { + /* TODO: Check if the group is already open! + (mape_disk_view_find_iter). */ + overloaded_group = mape_group_open_child( + overloaded_group, + "Material.ocg", + error + ); + + if(overloaded_group == NULL) + { + g_object_unref(texture_map); + return FALSE; + } + + break; + } + } + } + + mat_path = mape_disk_view_get_file_path(disk_view, material_iter); + mape_config_file_set_entry( + disk_view->config, + "material_path", + mat_path + ); + g_free(mat_path); + + result = mape_mat_tex_view_reload( + disk_view->mat_tex, + texture_map, + group, + overload_materials, + overload_textures, + overloaded_group, + error + ); + + g_object_unref(texture_map); + +#if 0 + if(overloaded_group != NULL) + mape_group_destroy(overloaded_group); +#endif + + mape_edit_view_reload(disk_view->edit_view); + + return result; +} + +static gboolean mape_disk_view_load(MapeDiskView* disk_view, + GtkTreeIter* parent_iter, + GError** error) +{ + GtkTreeIter child_iter; + GtkTreeIter group_iter; + GtkTreeIter temp_iter; + + MapeGroup* child_group; + MapeGroup* parent_group; + + MapeFileIcon* icon; + MapeFileIconType icon_type; + const char* fileext; + char* filename; + char* utf8_file; + gboolean deplevel; + + if(parent_iter != NULL) + { + gtk_tree_model_get( + disk_view->tree_store, + parent_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &parent_group, + -1 + ); + + /* Group is already open */ + if(parent_group != NULL) + return TRUE; + + /* Get parent group */ + deplevel = gtk_tree_model_iter_parent( + disk_view->tree_store, + &group_iter, + parent_iter + ); + + if(deplevel == TRUE) + { + gtk_tree_model_get( + disk_view->tree_store, + &group_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &parent_group, + -1 + ); + + g_assert(parent_group != NULL); + } + else + { + /* Parent is at top-level */ + parent_group = disk_view->group_top; + } + } + else + { + parent_group = NULL; + } + + if(parent_group != NULL) + { + gtk_tree_model_get( + disk_view->tree_store, + parent_iter, + MAPE_DISK_VIEW_COLUMN_FILE, + &utf8_file, + -1 + ); + +#ifdef G_OS_WIN32 + filename = g_convert( + utf8_file, + -1, + "LATIN1", + "UTF-8", + NULL, + NULL, + NULL + ); +#else + filename = g_filename_from_utf8( + utf8_file, + -1, + NULL, + NULL, + NULL + ); +#endif + + g_free(utf8_file); + + child_group = mape_group_open_child( + parent_group, + filename, + error + ); + + g_free(filename); + + if(child_group == NULL) + return FALSE; + + /* Store child group in parent */ + gtk_tree_store_set( + GTK_TREE_STORE(disk_view->tree_store), + parent_iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + (gpointer)child_group, + -1 + ); + } + else + { + /* Group is already open */ + if(disk_view->group_top != NULL) + return TRUE; + + disk_view->group_top = mape_group_new(); + if(!mape_group_open(disk_view->group_top, "/", error)) + { + g_object_unref(disk_view->group_top); + disk_view->group_top = NULL; + return FALSE; + } + + child_group = disk_view->group_top; + } + + while( (filename = mape_group_get_next_entry(child_group)) != NULL) + { + /* Check if this entry is a directory (we are hiding files). */ + if(mape_group_is_child_folder(child_group, filename) == FALSE) + { + free(filename); + continue; + } + +#ifdef G_OS_WIN32 + utf8_file = g_convert( + filename, + -1, + "UTF-8", + "LATIN1", + NULL, + NULL, + NULL + ); +#else + utf8_file = g_filename_to_utf8( + filename, + -1, + NULL, + NULL, + NULL + ); +#endif + + g_free(filename); + filename = utf8_file; + + /* Invalid file name */ + if(filename == NULL) + continue; + + gtk_tree_store_append( + GTK_TREE_STORE(disk_view->tree_store), + &child_iter, + parent_iter + ); + + /* Create temporary entry to show the expander arrow */ + if(g_strcasecmp(filename, "Material.ocg") != 0) + { + gtk_tree_store_append( + GTK_TREE_STORE(disk_view->tree_store), + &temp_iter, + &child_iter + ); + } + + fileext = strrchr(filename, '.'); + icon_type = MAPE_FILE_ICON_FOLDER; + + if(fileext != NULL) + { + if(g_strcasecmp(fileext, ".ocd") == 0) + icon_type = MAPE_FILE_ICON_C4OBJECT; + else if(g_strcasecmp(fileext, ".ocf") == 0) + icon_type = MAPE_FILE_ICON_C4FOLDER; + else if(g_strcasecmp(fileext, ".ocg") == 0) + icon_type = MAPE_FILE_ICON_C4GROUP; + else if(g_strcasecmp(fileext, ".ocs") == 0) + icon_type = MAPE_FILE_ICON_C4SCENARIO; + } + + if(mape_group_is_drive_container(child_group)) + icon_type = MAPE_FILE_ICON_DRIVE; + + icon = mape_file_icon_set_lookup( + disk_view->icon_set, + icon_type + ); + + gtk_tree_store_set( + GTK_TREE_STORE(disk_view->tree_store), + &child_iter, + MAPE_DISK_VIEW_COLUMN_ICON, + mape_file_icon_get(icon), + MAPE_DISK_VIEW_COLUMN_FILE, + filename, + MAPE_DISK_VIEW_COLUMN_GROUP, + NULL,/*(gpointer)child_group,*/ + -1 + ); + + gtk_tree_model_ref_node( + disk_view->tree_store, + &child_iter + ); + + free(filename); + /*free(utf8_file);*/ + } + + /* TODO: Close group if no content */ + + return TRUE; +} + +static gboolean mape_disk_view_cb_key_press_event(GtkWidget* widget, + GdkEventKey* event, + gpointer user_data) +{ + MapeDiskView* disk_view; + GtkTreePath* path; + gboolean result; + + disk_view = (MapeDiskView*)user_data; + +#if GTK_CHECK_VERSION(2,21,8) + if(event->keyval != GDK_KEY_Left && event->keyval != GDK_KEY_Right) +#else + if(event->keyval != GDK_Left && event->keyval != GDK_Right) +#endif + return FALSE; + + gtk_tree_view_get_cursor( + GTK_TREE_VIEW(disk_view->view), + &path, + NULL + ); + + if(path == NULL) return FALSE; + + switch(event->keyval) + { +#if GTK_CHECK_VERSION(2,21,8) + case GDK_KEY_Left: +#else + case GDK_Left: +#endif + result = gtk_tree_view_row_expanded( + GTK_TREE_VIEW(disk_view->view), + path + ); + + if(result == TRUE) + { + gtk_tree_view_collapse_row( + GTK_TREE_VIEW(disk_view->view), + path + ); + } + else + { + if(gtk_tree_path_get_depth(path) > 1) + { + result = gtk_tree_path_up(path); + g_assert(result == TRUE); + + gtk_tree_view_set_cursor( + GTK_TREE_VIEW(disk_view->view), + path, + NULL, + FALSE + ); + } + } + + break; +#if GTK_CHECK_VERSION(2,21,8) + case GDK_KEY_Right: +#else + case GDK_Right: +#endif + result = gtk_tree_view_row_expanded( + GTK_TREE_VIEW(disk_view->view), + path + ); + + if(result == TRUE) + { + gtk_tree_path_down(path); + + gtk_tree_view_set_cursor( + GTK_TREE_VIEW(disk_view->view), + path, + NULL, + FALSE + ); + } + else + { + gtk_tree_view_expand_row( + GTK_TREE_VIEW(disk_view->view), + path, + FALSE + ); + } + + break; + default: + g_assert_not_reached(); + break; + } + + gtk_tree_path_free(path); + return TRUE; +} + +static gboolean mape_disk_view_cb_button_press_event(GtkWidget* widget, + GdkEventButton* event, + gpointer user_data) +{ + MapeDiskView* disk_view; + GtkTreePath* path; + GtkTreeIter iter; + gboolean result; + gchar* filename; + GError* error = NULL; + GtkWidget* error_dialog; + + disk_view = (MapeDiskView*)user_data; + + if(event->type == GDK_2BUTTON_PRESS) + { + gtk_tree_view_get_cursor( + GTK_TREE_VIEW(disk_view->view), + &path, + NULL + ); + + if(path == NULL) return FALSE; + + gtk_tree_model_get_iter( + disk_view->tree_store, + &iter, + path + ); + + gtk_tree_model_get( + disk_view->tree_store, + &iter, + MAPE_DISK_VIEW_COLUMN_FILE, + &filename, + -1 + ); + + /* Load Material.ocg */ + if(g_strcasecmp(filename, "Material.ocg") == 0) + { + result = mape_disk_view_load_materials( + disk_view, + &iter, + &error + ); + + if(result == FALSE) + { + error_dialog = gtk_message_dialog_new( + NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", + error->message + ); + + g_error_free(error); + gtk_dialog_run(GTK_DIALOG(error_dialog) ); + gtk_widget_destroy(error_dialog); + } + } + else + { + result = gtk_tree_view_row_expanded( + GTK_TREE_VIEW(disk_view->view), + path + ); + + if(result == TRUE) + { + gtk_tree_view_collapse_row( + GTK_TREE_VIEW(disk_view->view), + path + ); + } + else + { + gtk_tree_view_expand_row( + GTK_TREE_VIEW(disk_view->view), + path, + FALSE + ); + } + } + + g_free(filename); + gtk_tree_path_free(path); + return TRUE; + } + + return FALSE; +} + +static void mape_disk_view_cb_row_expanded(GtkTreeView* treeview, + GtkTreeIter* row, + GtkTreePath* path, + gpointer user_data) +{ + MapeDiskView* disk_view; + MapeGroup* group; + GtkTreeIter iter; + GtkTreeIter temp_iter; + gboolean result; + GError* error = NULL; + GtkWidget* error_dialog; + + disk_view = (MapeDiskView*)user_data; + result = gtk_tree_model_get_iter( + disk_view->tree_store, + &iter, + path + ); + + g_assert(result == TRUE); + + /* Remove temporary entry if group is not already loaded */ + gtk_tree_model_get( + disk_view->tree_store, + &iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &group, + -1 + ); + + if(group == NULL) + { + g_assert( + gtk_tree_model_iter_n_children( + disk_view->tree_store, + &iter + ) == 1 + ); + + result = gtk_tree_model_iter_children( + disk_view->tree_store, + &temp_iter, + &iter + ); + + g_assert(result == TRUE); + + result = gtk_tree_store_remove( + GTK_TREE_STORE(disk_view->tree_store), + &temp_iter + ); + + g_assert(result == FALSE); + } + + if(mape_disk_view_load(disk_view, &iter, &error) == FALSE) + { + error_dialog = gtk_message_dialog_new( + NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", + error->message + ); + + g_error_free(error); + gtk_dialog_run(GTK_DIALOG(error_dialog) ); + gtk_widget_destroy(error_dialog); + + return; + } + + if(group == NULL) + { + gtk_tree_view_expand_row( + GTK_TREE_VIEW(disk_view->view), + path, + FALSE + ); + } +} + +static void mape_disk_view_close_groups(MapeDiskView* disk_view, + GtkTreeIter* iter) +{ + MapeGroup* group; + GtkTreeIter child; + gboolean has_child, has_next; + + gtk_tree_model_get( + disk_view->tree_store, + iter, + MAPE_DISK_VIEW_COLUMN_GROUP, + &group, + -1 + ); + + has_child = gtk_tree_model_iter_children( + disk_view->tree_store, + &child, + iter + ); + + has_next = gtk_tree_model_iter_next( + disk_view->tree_store, + iter + ); + + if(has_child == TRUE) + mape_disk_view_close_groups(disk_view, &child); + + if(group != NULL) + g_object_unref(group); + + if(has_next == TRUE) + mape_disk_view_close_groups(disk_view, iter); +} + + +MapeDiskView* mape_disk_view_new(MapeFileIconSet* icon_set, + MapeMatTexView* mat_tex, + MapeEditView* edit_view, + MapeConfigFile* config, + GError** error) +{ + MapeDiskView* view; + + view = malloc(sizeof(MapeDiskView) ); + + view->group_top = NULL; + view->icon_set = icon_set; + view->mat_tex = mat_tex; + view->edit_view = edit_view; + view->config = config; + + view->tree_store = GTK_TREE_MODEL( + gtk_tree_store_new( + MAPE_DISK_VIEW_COLUMN_COUNT, + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_POINTER + ) + ); + + view->renderer_icon = gtk_cell_renderer_pixbuf_new(); + view->renderer_file = gtk_cell_renderer_text_new(); + + /*view->col_icon = gtk_tree_view_column_new_with_attributes( + "Icon", + view->renderer_icon, + "pixbuf", MAPE_DISK_VIEW_COLUMN_ICON, + NULL + );*/ + + view->col_file = gtk_tree_view_column_new(); + +/* view->col_file = gtk_tree_view_column_new_with_attributes( + "Filename", + view->renderer_file, + "text", MAPE_DISK_VIEW_COLUMN_FILE, + "pixbuf", MAPE_DISK_VIEW_COLUMN_ICON, + NULL + );*/ + + gtk_tree_view_column_pack_start( + view->col_file, + view->renderer_icon, + FALSE + ); + + gtk_tree_view_column_pack_start( + view->col_file, + view->renderer_file, + TRUE + ); + + gtk_tree_view_column_set_attributes( + view->col_file, + view->renderer_icon, + "pixbuf", MAPE_DISK_VIEW_COLUMN_ICON, + NULL + ); + + gtk_tree_view_column_set_attributes( + view->col_file, + view->renderer_file, + "text", MAPE_DISK_VIEW_COLUMN_FILE, + NULL + ); + + gtk_tree_view_column_set_spacing( + view->col_file, + 5 + ); + + view->view = gtk_tree_view_new_with_model( + GTK_TREE_MODEL(view->tree_store) + ); + + gtk_widget_add_events( + view->view, + GDK_BUTTON_PRESS_MASK | + GDK_KEY_PRESS_MASK + ); + + gtk_tree_view_append_column(GTK_TREE_VIEW(view->view), view->col_file); + + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view->view), FALSE); + gtk_tree_sortable_set_sort_column_id( + GTK_TREE_SORTABLE(view->tree_store), + MAPE_DISK_VIEW_COLUMN_FILE, + GTK_SORT_ASCENDING + ); + + g_signal_connect( + G_OBJECT(view->view), + "row-expanded", + G_CALLBACK(mape_disk_view_cb_row_expanded), + view + ); + + g_signal_connect( + G_OBJECT(view->view), + "button-press-event", + G_CALLBACK(mape_disk_view_cb_button_press_event), + view + ); + + g_signal_connect( + G_OBJECT(view->view), + "key-press-event", + G_CALLBACK(mape_disk_view_cb_key_press_event), + view + ); + + if(mape_disk_view_load(view, NULL, error) == FALSE) + { + /* TODO: Free cell renderers? */ + gtk_widget_destroy(view->view); + g_object_unref(G_OBJECT(view->tree_store) ); + + free(view); + return NULL; + } + + gtk_widget_show(view->view); + + view->window = gtk_scrolled_window_new(NULL, NULL); + gtk_container_add( + GTK_CONTAINER(view->window), + view->view + ); + + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(view->window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC + ); + + gtk_scrolled_window_set_shadow_type( + GTK_SCROLLED_WINDOW(view->window), + GTK_SHADOW_IN + ); + + gtk_widget_set_size_request(view->window, 150, -1); + gtk_widget_show(view->window); + + return view; +} + +void mape_disk_view_destroy(MapeDiskView* disk_view) +{ + /* Close open groups */ + GtkTreeIter iter; + if(gtk_tree_model_get_iter_first(disk_view->tree_store, &iter)) + mape_disk_view_close_groups(disk_view, &iter); + + /* TODO: unref cell renderers? */ + /*mape_file_icon_set_destroy(disk_view->icon_set);*/ + g_object_unref(disk_view->group_top); + + g_object_unref(G_OBJECT(disk_view->tree_store) ); + free(disk_view); +} + +gboolean mape_disk_view_extend_to_path(MapeDiskView* disk_view, + const gchar* filepath, + GError** error) +{ + gchar** path_components; + gchar** cur_component; + gchar* file; + GtkTreeIter parent; + GtkTreeIter child; + gboolean result; + GtkTreePath* path; + gboolean got_parent; + + path_components = g_strsplit_set(filepath, "/\\", 0); + + /* Begin at top-level: no parent */ + got_parent = FALSE; + + for(cur_component = path_components; + *cur_component != NULL; + ++ cur_component) + { + file = *cur_component; + if(*file == '\0') continue; + if(strcmp(file, ".") == 0) continue; + + if(strcmp(file, "..") == 0) + { + if(got_parent == FALSE) + { + g_set_error( + error, + g_quark_from_static_string( + "MAPE_DISK_VIEW_ERROR" + ), + MAPE_DISK_VIEW_ERROR_NOENT, + "%s: Invalid path", + filepath + ); + + g_strfreev(path_components); + return FALSE; + } + else + { + child = parent; + + got_parent = gtk_tree_model_iter_parent( + GTK_TREE_MODEL(disk_view->tree_store), + &parent, + &child + ); + } + } + else + { + if(got_parent == FALSE) + { + result = mape_disk_view_find_iter( + disk_view, + &child, + NULL, + file + ); + } + else + { + result = mape_disk_view_find_iter( + disk_view, + &child, + &parent, + file + ); + } + + /* File is not reachable in file system */ + if(result == FALSE) + { + g_set_error( + error, + g_quark_from_static_string( + "MAPE_DISK_VIEW_ERROR" + ), + MAPE_DISK_VIEW_ERROR_NOENT, + "%s: No such file or directory", + filepath + ); + + g_strfreev(path_components); + return FALSE; + } + + if(g_ascii_strcasecmp(file, "Material.ocg") == 0) + { + /* Assume end of path */ + result = mape_disk_view_load_materials( + disk_view, + &child, + error + ); + + g_strfreev(path_components); + return result; + } + else + { + /* Convert child to path to preserve + position while expanding */ + path = gtk_tree_model_get_path( + disk_view->tree_store, + &child + ); + + gtk_tree_view_expand_row( + GTK_TREE_VIEW(disk_view->view), + path, + FALSE + ); + + /* Child is new parent for next iteration */ + gtk_tree_model_get_iter( + disk_view->tree_store, + &parent, + path + ); + got_parent = TRUE; + + gtk_tree_path_free(path); + } + } + } + + /* All nodes expanded without opening Material.ocg */ + g_strfreev(path_components); + return TRUE; +} diff --git a/src/mape/diskview.h b/src/mape/diskview.h new file mode 100644 index 000000000..e1d06678c --- /dev/null +++ b/src/mape/diskview.h @@ -0,0 +1,68 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_DISKVIEW_H +#define INC_MAPE_DISKVIEW_H + +#include + +#include "mape/forward.h" +#include "mape/group.h" + +typedef enum MapeDiskViewColumns_ { + MAPE_DISK_VIEW_COLUMN_ICON, + MAPE_DISK_VIEW_COLUMN_FILE, + MAPE_DISK_VIEW_COLUMN_GROUP, + + MAPE_DISK_VIEW_COLUMN_COUNT +} MapeDiskViewColumns; + +typedef enum MapeDiskViewError_ { + MAPE_DISK_VIEW_ERROR_NOENT, + + MAPE_DISK_VIEW_ERROR_FAILED +} MapeDiskViewError; + +struct MapeDiskView_ { + GtkWidget* window; + GtkWidget* view; + + GtkTreeModel* tree_store; + + GtkCellRenderer* renderer_icon; + GtkCellRenderer* renderer_file; + + GtkTreeViewColumn* col_file; + + MapeMatTexView* mat_tex; + MapeEditView* edit_view; + + MapeFileIconSet* icon_set; + MapeGroup* group_top; + MapeConfigFile* config; +}; + +MapeDiskView* mape_disk_view_new(MapeFileIconSet* icon_set, + MapeMatTexView* mat_tex, + MapeEditView* edit_view, + MapeConfigFile* config, + GError** error); +void mape_disk_view_destroy(MapeDiskView* disk_view); + +gboolean mape_disk_view_extend_to_path(MapeDiskView* disk_view, + const gchar* filepath, + GError** error); + +#endif /* INC_MAPE_DISKVIEW_H */ diff --git a/src/mape/editview.c b/src/mape/editview.c new file mode 100644 index 000000000..a27cbc4a5 --- /dev/null +++ b/src/mape/editview.c @@ -0,0 +1,674 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include +#include +#include +#include "mape/mapgen.h" +#include "mape/random.h" +#include "mape/preferences.h" +#include "mape/mattexview.h" +#include "mape/editview.h" +#include "mape/statusbar.h" +#include "mape/preview.h" + +typedef struct _ThreadData ThreadData; +struct _ThreadData { + MapeEditView* view; + gchar* source; + gchar* file_path; + MapeMaterialMap* mat_map; + MapeTextureMap* tex_map; + guint map_width; + guint map_height; +}; + +typedef struct _ThreadResult ThreadResult; +struct _ThreadResult { + MapeEditView* view; + GdkPixbuf* pixbuf; + GError* error; + guint idle_id; +}; + +static void +mape_edit_view_thread_result_destroy_func(gpointer data) +{ + ThreadResult* result = (ThreadResult*)data; + if(result->pixbuf != NULL) g_object_unref(G_OBJECT(result->pixbuf)); + if(result->error != NULL) g_error_free(result->error); + /* Don't need to g_source_remove(result->idle_id) since this is + * only called when the idle handler is removed anyway. */ +} + +static void mape_edit_view_cb_changed(GtkTextBuffer* buffer, + gpointer user_data) +{ + mape_edit_view_reload((MapeEditView*)user_data); +} + +static void mape_edit_view_cb_update(GtkWidget* widget, + GdkEvent* event, + gpointer user_data) +{ + mape_edit_view_reload((MapeEditView*)user_data); +} + +static GdkPixbuf* mape_edit_view_render_map(const gchar* source, + const gchar* file_path, + MapeMaterialMap* mat_map, + MapeTextureMap* tex_map, + guint map_width, + guint map_height, + GError** error) +{ + GdkPixbuf* pixbuf; + gchar* basename; + gchar* dirname; + gchar* scriptname; + const gchar* filename; + + if(mat_map == NULL || tex_map == NULL) + { + g_set_error( + error, + g_quark_from_static_string("MAPE_EDIT_VIEW_ERROR"), + MAPE_EDIT_VIEW_ERROR_MISSING_MAPS, + "Material.ocg is not loaded" + ); + + return NULL; + } + + if(file_path != NULL) + { + basename = g_path_get_basename(file_path); + filename = basename; + + dirname = g_path_get_dirname(file_path); + scriptname = g_build_filename(dirname, "Script.c", NULL); + g_free(dirname); + } + else + { + basename = NULL; + filename = "Landscape.txt"; + scriptname = NULL; + } + + pixbuf = mape_mapgen_render( + filename, + source, + scriptname, + mat_map, + tex_map, + map_width, + map_height, + error + ); + + g_free(basename); + return pixbuf; +} + +static gboolean +mape_edit_view_thread_result(gpointer data_) +{ + ThreadResult* result; + MapeEditView* view; + + result = (ThreadResult*)data_; + view = result->view; + + if(result->pixbuf == NULL) + { + g_assert(result->error != NULL); + + mape_statusbar_set_compile( + view->statusbar, + result->error->message + ); + } + else + { + mape_statusbar_set_compile( + view->statusbar, + "Landscape rendered successfully" + ); + } + + mape_pre_view_update(view->pre_view, result->pixbuf); + + /* Finish thread */ + g_thread_join(view->render_thread); + view->render_thread = NULL; + + /* Do we have to render again (someone changed + the source while rendering)? */ + if(view->rerender == TRUE) + mape_edit_view_reload(view); + + return FALSE; +} + +static gpointer mape_edit_view_thread_entry(gpointer data_) +{ + ThreadData* data; + ThreadResult* result; + GError* error = NULL; + GdkPixbuf* res_buf; + + data = (ThreadData*)data_; + + res_buf = mape_edit_view_render_map( + data->source, + data->file_path, + data->mat_map, + data->tex_map, + data->map_width, + data->map_height, + &error + ); + + result = g_slice_new(ThreadResult); + result->view = data->view; + result->pixbuf = res_buf; + result->error = error; + + g_free(data->source); + g_free(data->file_path); + g_slice_free(ThreadData, data); + + result->idle_id = g_idle_add_full( + G_PRIORITY_DEFAULT_IDLE, + mape_edit_view_thread_result, + result, + mape_edit_view_thread_result_destroy_func + ); + + /* Note that you can only use this securly with g_thread_join, + * otherwise the idle handler might already have been run */ + return result; +} + +MapeEditView* mape_edit_view_new(MapePreView* pre_view, + MapeStatusbar* statusbar, + GError** error) +{ + MapeEditView* view; + GtkSourceBuffer* buf; + GtkSourceLanguage* lang; + GtkSourceStyleScheme* style; + GtkWidget* error_dialog; + GPtrArray* search_dirs; + const gchar* const* data_dirs; + const gchar* const* dir; + + view = malloc(sizeof(MapeEditView) ); + view->pre_view = pre_view; + view->statusbar = statusbar; + view->file_path = NULL; + view->encoding = "UTF-8"; + view->render_thread = NULL; + view->rerender = FALSE; + view->fixed_seed = FALSE; + + view->view = gtk_source_view_new(); + buf = GTK_SOURCE_BUFFER( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view) ) + ); + + g_signal_connect_after( + G_OBJECT(buf), + "changed", + G_CALLBACK(mape_edit_view_cb_changed), + view + ); + + g_signal_connect( + G_OBJECT(pre_view->event_box), + "button-press-event", + G_CALLBACK(mape_edit_view_cb_update), + view + ); + + view->font_desc = pango_font_description_new(); + pango_font_description_set_family(view->font_desc, "monospace"); + gtk_widget_modify_font(view->view, view->font_desc); + + search_dirs = g_ptr_array_new(); +#ifdef G_OS_WIN32 + g_ptr_array_add( + search_dirs, + g_win32_get_package_installation_subdirectory(NULL, NULL, "mape-syntax") + ); +#endif + + g_ptr_array_add( + search_dirs, + g_build_filename(g_get_home_dir(), ".mape-syntax", NULL) + ); + + data_dirs = g_get_system_data_dirs(); + for(dir = data_dirs; *dir != NULL; ++ dir) + g_ptr_array_add(search_dirs, g_build_filename(*dir, "mape", NULL)); + g_ptr_array_add(search_dirs, NULL); + + view->lang_manager = gtk_source_language_manager_new(); + gtk_source_language_manager_set_search_path( + view->lang_manager, + (gchar**)search_dirs->pdata + ); + + view->style_manager = gtk_source_style_scheme_manager_new(); + gtk_source_style_scheme_manager_set_search_path( + view->style_manager, + (gchar**)search_dirs->pdata + ); + + g_ptr_array_foreach(search_dirs, (GFunc)g_free, NULL); + g_ptr_array_free(search_dirs, TRUE); + + lang = gtk_source_language_manager_get_language( + view->lang_manager, + "c4landscape" + ); + + style = gtk_source_style_scheme_manager_get_scheme( + view->style_manager, + "c4landscape" + ); + + if(lang == NULL || style == NULL) + { + /* TODO: Show location where we search in */ + error_dialog = gtk_message_dialog_new( + NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "The syntax highlighting file for Landscape.txt files " + "could not be located. Perhaps mape has not been " + "properly installed. Syntax highlighting is disabled." + ); + + gtk_window_set_title(GTK_WINDOW(error_dialog), "Mape"); + + gtk_dialog_run(GTK_DIALOG(error_dialog) ); + gtk_widget_destroy(error_dialog); + } + else + { + gtk_source_buffer_set_language(buf, lang); + gtk_source_buffer_set_style_scheme(buf, style); + } + + gtk_widget_show(view->view); + + view->window = gtk_scrolled_window_new(NULL, NULL); + + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(view->window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC + ); + + gtk_scrolled_window_set_shadow_type( + GTK_SCROLLED_WINDOW(view->window), + GTK_SHADOW_IN + ); + + gtk_container_add( + GTK_CONTAINER(view->window), + view->view + ); + + gtk_widget_show(view->window); + return view; +} + +void mape_edit_view_destroy(MapeEditView* view) +{ + gpointer data; + + /* Wait for render thread to finish */ + if(view->render_thread != NULL) + { + data = g_thread_join(view->render_thread); + view->render_thread = NULL; + + /* Don't let idle handler run since edit_view is about to be destroyed */ + g_assert(((ThreadResult*)data)->idle_id != 0); + g_source_remove(((ThreadResult*)data)->idle_id); + } + + g_object_unref(G_OBJECT(view->lang_manager) ); + g_object_unref(G_OBJECT(view->style_manager)); + g_free(view->file_path); + free(view); +} + +void mape_edit_view_clear(MapeEditView* view) +{ + g_free(view->file_path); + view->file_path = NULL; + + /* TODO: Undoable action dingsen */ + /* (statische mape_edit_view_set_contents-Call?) */ + gtk_text_buffer_set_text( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)), + "", + 0 + ); + + gtk_text_buffer_set_modified( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)), + FALSE + ); +} + +gboolean mape_edit_view_open(MapeEditView* view, + const gchar* filename, + GError** error) +{ + gboolean result; + gchar* contents; + gchar* conv; + gchar* utf8_file; + gchar* new_path; + gsize length; + + result = g_file_get_contents(filename, &contents, &length, error); + if(result == FALSE) return FALSE; + + /* Assume UTF-8 */ + result = g_utf8_validate(contents, length, NULL); + + if(result == FALSE) + { + /* No UTF-8, try LATIN1 */ + conv = g_convert( + contents, + -1, + "UTF-8", + "LATIN1", + NULL, + NULL, + NULL + ); + + g_free(contents); + if(conv == NULL) + { + utf8_file = g_filename_to_utf8( + filename, + -1, + NULL, + NULL, + NULL + ); + + if(utf8_file == NULL) + utf8_file = g_strdup(""); + + g_set_error( + error, + g_quark_from_static_string( + "MAPE_EDIT_VIEW_ERROR" + ), + MAPE_EDIT_VIEW_ERROR_UNKNOWN_ENCODING, + "Could not read file %s: Either the encoding " + "is unknown or it is a binary file", + utf8_file + ); + + g_free(utf8_file); + return FALSE; + } + + /* Conversion succeeded */ + contents = conv; + view->encoding = "LATIN1"; + } + else + { + view->encoding = "UTF-8"; + } + + /* TODO: Verify that filename is absolute and make it absolute if + it is not */ + new_path = g_strdup(filename); + g_free(view->file_path); + view->file_path = new_path; + + /* TODO: Undoable action dingsen */ + /* (statische mape_edit_view_set_contents-Call?) */ + gtk_text_buffer_set_text( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)), + contents, + length + ); + + g_free(contents); + + gtk_text_buffer_set_modified( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)), + FALSE + ); + + return TRUE; +} + +gboolean mape_edit_view_save(MapeEditView* view, + const gchar* filename, + GError** error) +{ + GtkTextBuffer* buffer; + GtkTextIter begin; + GtkTextIter end; + gchar* new_path; + gchar* source; + gchar* conv; + gboolean result; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view) ); + gtk_text_buffer_get_start_iter(buffer, &begin); + gtk_text_buffer_get_end_iter(buffer, &end); + source = gtk_text_buffer_get_text(buffer, &begin, &end, TRUE); + + conv = g_convert( + source, + -1, + view->encoding, + "UTF-8", + NULL, + NULL, + error + ); + + g_free(source); + if(conv == NULL) return FALSE; + + result = g_file_set_contents(filename, conv, -1, error); + g_free(conv); + if(result == FALSE) return FALSE; + + gtk_text_buffer_set_modified( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)), + FALSE + ); + + new_path = g_strdup(filename); + g_free(view->file_path); + view->file_path = new_path; + + /* Rerender with new file path -- + * different Script.c lookup for algo=script overlays */ + mape_edit_view_reload(view); + + return TRUE; +} + +gboolean mape_edit_view_get_modified(MapeEditView* view) +{ + return gtk_text_buffer_get_modified( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)) + ); +} + +void mape_edit_view_undo(MapeEditView* edit_view) +{ + gtk_source_buffer_undo( + GTK_SOURCE_BUFFER( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit_view->view)) + ) + ); +} + +void mape_edit_view_redo(MapeEditView* edit_view) +{ + gtk_source_buffer_redo( + GTK_SOURCE_BUFFER( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit_view->view)) + ) + ); +} + +void mape_edit_view_apply_preferences(MapeEditView* edit_view, + MapePreferences* preferences) +{ + GtkSourceView* view; + GtkSourceBuffer* buffer; + GtkWrapMode wrap_mode; + + view = GTK_SOURCE_VIEW(edit_view->view); + buffer = GTK_SOURCE_BUFFER( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)) + ); + + gtk_source_view_set_tab_width( + view, + preferences->tab_width + ); + + gtk_source_view_set_insert_spaces_instead_of_tabs( + view, + preferences->tab_to_spaces + ); + + gtk_source_view_set_auto_indent( + view, + preferences->auto_indentation + ); + + wrap_mode = GTK_WRAP_CHAR; + if(preferences->text_wrapping == FALSE) + wrap_mode = GTK_WRAP_NONE; + gtk_text_view_set_wrap_mode( + GTK_TEXT_VIEW(view), + wrap_mode + ); + + gtk_source_view_set_show_line_numbers( + view, + preferences->line_numbers + ); + + gtk_source_view_set_highlight_current_line( + view, + preferences->highlight_line + ); + + gtk_source_buffer_set_highlight_matching_brackets( + buffer, + preferences->bracket_matching + ); + + edit_view->fixed_seed = preferences->fixed_seed; + edit_view->random_seed = preferences->random_seed; + edit_view->map_width = preferences->map_width; + edit_view->map_height = preferences->map_height; + + /* Rerender with new random settings */ + mape_edit_view_reload(edit_view); +} + +void mape_edit_view_reload(MapeEditView* edit_view) +{ + GError* error = NULL; + ThreadData* data; + GtkTextBuffer* buffer; + GtkTextIter begin; + GtkTextIter end; + + if(edit_view->render_thread == NULL) + { + data = g_slice_new(ThreadData); + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit_view->view) ); + gtk_text_buffer_get_start_iter(buffer, &begin); + gtk_text_buffer_get_end_iter(buffer, &end); + + /* TODO: We need to ref view so that it is guaranteed to be alive in the + * thread result handler */ + data->view = edit_view; + data->source = gtk_text_buffer_get_text(buffer, &begin, &end, TRUE); + data->file_path = g_strdup(edit_view->file_path); + + /* TODO: We need to ref these so noone can delete them while the thread + * uses them. */ + data->mat_map = edit_view->pre_view->mat_tex->mat_map, + data->tex_map = edit_view->pre_view->mat_tex->tex_map, + + data->map_width = edit_view->map_width; + data->map_height = edit_view->map_height; + + if(edit_view->fixed_seed == TRUE) + mape_random_seed(edit_view->random_seed); + + mape_statusbar_set_compile( + edit_view->statusbar, + "Rendering map..." + ); + + edit_view->rerender = FALSE; + + edit_view->render_thread = g_thread_create( + mape_edit_view_thread_entry, + data, + TRUE, + &error + ); + + if(edit_view->render_thread == NULL) + { + mape_statusbar_set_compile( + edit_view->statusbar, + error->message + ); + + g_free(data->source); + g_slice_free(ThreadData, data); + + g_error_free(error); + } + } + else + { + /* Rerender when thread finished */ + edit_view->rerender = TRUE; + } +} + diff --git a/src/mape/editview.h b/src/mape/editview.h new file mode 100644 index 000000000..66175fcab --- /dev/null +++ b/src/mape/editview.h @@ -0,0 +1,75 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_EDITVIEW_H +#define INC_MAPE_EDITVIEW_H + +#include +#include +#include +#include "mape/forward.h" + +typedef enum MapeEditViewError_ { + MAPE_EDIT_VIEW_ERROR_MISSING_MAPS, + MAPE_EDIT_VIEW_ERROR_UNKNOWN_ENCODING, + MAPE_EDIT_VIEW_ERROR_FAILED +} MapeEditViewError; + +struct MapeEditView_ { + GtkWidget* window; + GtkWidget* view; + gchar* file_path; + const gchar* encoding; + + GtkSourceLanguageManager* lang_manager; + GtkSourceStyleSchemeManager* style_manager; + PangoFontDescription* font_desc; + + MapePreView* pre_view; + MapeStatusbar* statusbar; + + gboolean fixed_seed; + unsigned int random_seed; + + unsigned int map_width; + unsigned int map_height; + + GThread* render_thread; + gboolean rerender; +}; + +MapeEditView* mape_edit_view_new(MapePreView* pre_view, + MapeStatusbar* statusbar, + GError** error); +void mape_edit_view_destroy(MapeEditView* view); + +void mape_edit_view_clear(MapeEditView* view); +gboolean mape_edit_view_open(MapeEditView* view, + const gchar* filename, + GError** error); +gboolean mape_edit_view_save(MapeEditView* view, + const gchar* filename, + GError** error); + +gboolean mape_edit_view_get_modified(MapeEditView* view); +void mape_edit_view_undo(MapeEditView* edit_view); +void mape_edit_view_redo(MapeEditView* edit_view); + +void mape_edit_view_apply_preferences(MapeEditView* edit_view, + MapePreferences* preferences); +void mape_edit_view_reload(MapeEditView* edit_view); + + +#endif /* INC_MAPE_EDITVIEW_H */ diff --git a/src/mape/fileicon.c b/src/mape/fileicon.c new file mode 100644 index 000000000..07fc9bc6a --- /dev/null +++ b/src/mape/fileicon.c @@ -0,0 +1,160 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include +#include + +#include "mape/fileicon.h" +#include "mape-icons.h" // Generated file + +static MapeFileIcon* mape_file_icon_new(GtkWidget* widget, + MapeFileIconType type) +{ + MapeFileIcon* icon; + GdkPixbuf* pixbuf; + gint width, height; + GdkPixbuf* scaled_pixbuf; + + switch(type) + { + case MAPE_FILE_ICON_DRIVE: + pixbuf = gtk_widget_render_icon( + widget, + GTK_STOCK_HARDDISK, + GTK_ICON_SIZE_BUTTON, + NULL + ); + break; + case MAPE_FILE_ICON_FOLDER: + pixbuf = gtk_widget_render_icon( + widget, + GTK_STOCK_DIRECTORY, + GTK_ICON_SIZE_BUTTON, + NULL + ); + break; + case MAPE_FILE_ICON_C4OBJECT: + pixbuf = gdk_pixbuf_new_from_inline( + -1, + mape_icon_ocd, + FALSE, + NULL + ); + break; + case MAPE_FILE_ICON_C4FOLDER: + pixbuf = gdk_pixbuf_new_from_inline( + -1, + mape_icon_ocf, + FALSE, + NULL + ); + break; + case MAPE_FILE_ICON_C4GROUP: + pixbuf = gdk_pixbuf_new_from_inline( + -1, + mape_icon_ocg, + FALSE, + NULL + ); + break; + case MAPE_FILE_ICON_C4SCENARIO: + pixbuf = gdk_pixbuf_new_from_inline( + -1, + mape_icon_ocs, + FALSE, + NULL + ); + break; + case MAPE_FILE_ICON_C4MATERIAL: + pixbuf = gdk_pixbuf_new_from_inline( + -1, + mape_icon_ocm, + FALSE, + NULL + ); + break; + default: + g_assert_not_reached(); + break; + } + + if(pixbuf == NULL) + return NULL; + + gtk_icon_size_lookup(GTK_ICON_SIZE_BUTTON, &width, &height); + + /* Scale pixbuf to size of GTK_ICON_SIZE_BUTTON */ + if(gdk_pixbuf_get_width(pixbuf) != width || + gdk_pixbuf_get_height(pixbuf) != height) + { + scaled_pixbuf = gdk_pixbuf_scale_simple( + pixbuf, + width, + height, + GDK_INTERP_HYPER + ); + + g_object_unref(pixbuf); + pixbuf = scaled_pixbuf; + + if(pixbuf == NULL) + return NULL; + } + + icon = malloc(sizeof(MapeFileIcon) ); + icon->type = type; + icon->pixbuf = pixbuf; + + return icon; +} + +static void mape_file_icon_destroy(MapeFileIcon* icon) +{ + g_object_unref(G_OBJECT(icon->pixbuf) ); + free(icon); +} + +MapeFileIconSet* mape_file_icon_set_new(GtkWidget* widget) +{ + MapeFileIconSet* set; + unsigned int i; + + set = malloc(sizeof(MapeFileIconSet) ); + + for(i = 0; i < MAPE_FILE_ICON_COUNT; ++ i) + set->icons[i] = mape_file_icon_new(widget, (MapeFileIconType)i); + + return set; +} + +void mape_file_icon_set_destroy(MapeFileIconSet* set) +{ + unsigned int i; + for(i = 0; i < MAPE_FILE_ICON_COUNT; ++ i) + mape_file_icon_destroy(set->icons[i]); +} + +MapeFileIcon* mape_file_icon_set_lookup(MapeFileIconSet* set, + MapeFileIconType type) +{ + g_assert(type < MAPE_FILE_ICON_COUNT); + + return set->icons[type]; +} + +GdkPixbuf* mape_file_icon_get(MapeFileIcon* icon) +{ + return icon->pixbuf; +} diff --git a/src/mape/fileicon.h b/src/mape/fileicon.h new file mode 100644 index 000000000..b1a91f746 --- /dev/null +++ b/src/mape/fileicon.h @@ -0,0 +1,53 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_FILEICON_H +#define INC_MAPE_FILEICON_H + +#include +#include + +#include "mape/forward.h" + +typedef enum MapeFileIconType_ { + MAPE_FILE_ICON_DRIVE, + MAPE_FILE_ICON_FOLDER, + MAPE_FILE_ICON_C4GROUP, + MAPE_FILE_ICON_C4SCENARIO, + MAPE_FILE_ICON_C4OBJECT, + MAPE_FILE_ICON_C4FOLDER, + MAPE_FILE_ICON_C4MATERIAL, + + MAPE_FILE_ICON_COUNT +} MapeFileIconType; + +struct MapeFileIcon_ { + MapeFileIconType type; + GdkPixbuf* pixbuf; +}; + +struct MapeFileIconSet_ { + MapeFileIcon* icons[MAPE_FILE_ICON_COUNT]; +}; + +MapeFileIconSet* mape_file_icon_set_new(GtkWidget* widget); +void mape_file_icon_set_destroy(MapeFileIconSet* set); + +MapeFileIcon* mape_file_icon_set_lookup(MapeFileIconSet* set, + MapeFileIconType type); + +GdkPixbuf* mape_file_icon_get(MapeFileIcon* icon); + +#endif /* INC_MAPE_FILEICON_H */ diff --git a/src/mape/forward.h b/src/mape/forward.h new file mode 100644 index 000000000..8cc669b38 --- /dev/null +++ b/src/mape/forward.h @@ -0,0 +1,37 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_FORWARD_H +#define INC_MAPE_FORWARD_H + +/*typedef struct MapeGroup_ MapeGroup;*/ +/*typedef struct MapeMaterialMap_ MapeMaterialMap;*/ +/*typedef struct MapeTextureMap_ MapeTextureMap;*/ +typedef struct MapeFileIcon_ MapeFileIcon; +typedef struct MapeFileIconSet_ MapeFileIconSet; +typedef struct MapeConfigFileEntry_ MapeConfigFileEntry; +typedef struct MapeConfigFile_ MapeConfigFile; +typedef struct MapePreferences_ MapePreferences; +typedef struct MapePreferencesDialog_ MapePreferencesDialog; +typedef struct MapeHeader_ MapeHeader; +typedef struct MapeStatusbar_ MapeStatusbar; +typedef struct MapeDiskView_ MapeDiskView; +typedef struct MapeIconView_ MapeIconView; +typedef struct MapeMatTexView_ MapeMatTexView; +typedef struct MapeEditView_ MapeEditView; +typedef struct MapePreView_ MapePreView; +typedef struct MapeWindow_ MapeWindow; + +#endif /* INC_MAPE_FORWARD_H */ diff --git a/src/mape/group.c b/src/mape/group.c new file mode 100644 index 000000000..0ac725e84 --- /dev/null +++ b/src/mape/group.c @@ -0,0 +1,717 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +/** + * SECTION:mape-group + * @title: MapeGroup + * @short_description: C4Group interface + * @include: mape/group.h + * @stability: Unstable + * + * #MapeGroup is a simple GObject-based interface to C4Group. It currntly + * only supports a subset of the C4Group operations, it does not support + * writing groups for example. It is just enough for what Mape requires. + **/ + +#include /* for strrchr */ + +#include "mape/cpp-handles/group-handle.h" +#include "mape/group.h" + +#ifdef G_OS_WIN32 +#include +#endif + +/* Declare private API */ +C4GroupHandle* +_mape_group_get_handle(MapeGroup* group); /* shut up gcc */ + +typedef struct _MapeGroupPrivate MapeGroupPrivate; +struct _MapeGroupPrivate { + C4GroupHandle* handle; + + /* On Windows, the root directory "/" is interpreted as a directory + * containing the local drives (C:\, D:\, etc.). handle is set to NULL for + * a group representing the "/" directory. */ +#ifdef G_OS_WIN32 + /* This is 0 if the group is closed, otherwise the currently accessed drive + * index (as returned by GetLogicalDrives()) minus one. */ + guint drive; +#endif +}; + +enum { + PROP_0, + + /* read only */ + PROP_NAME, + PROP_FULL_NAME +}; + +#define MAPE_GROUP_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), MAPE_TYPE_GROUP, MapeGroupPrivate)) + +static GQuark mape_group_error_quark; + +G_DEFINE_TYPE(MapeGroup, mape_group, G_TYPE_OBJECT) + +/* + * GObject overrides. + */ + +static void +mape_group_init(MapeGroup* group) +{ + MapeGroupPrivate* priv; + priv = MAPE_GROUP_PRIVATE(group); + + priv->handle = NULL; + +#ifdef G_OS_WIN32 + priv->drive = 0; +#endif +} + +static void +mape_group_finalize(GObject* object) +{ + MapeGroup* group; + MapeGroupPrivate* priv; + + group = MAPE_GROUP(object); + priv = MAPE_GROUP_PRIVATE(group); + + if(priv->handle != NULL) + c4_group_handle_free(priv->handle); + + G_OBJECT_CLASS(mape_group_parent_class)->finalize(object); +} + +static void +mape_group_set_property(GObject* object, + guint prop_id, + const GValue* value, + GParamSpec* pspec) +{ + MapeGroup* group; + MapeGroupPrivate* priv; + + group = MAPE_GROUP(object); + priv = MAPE_GROUP_PRIVATE(group); + + switch(prop_id) + { + /* we have only readonly properties */ + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(value, prop_id, pspec); + break; + } +} + +static void +mape_group_get_property(GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec) +{ + MapeGroup* group; + MapeGroupPrivate* priv; + + group = MAPE_GROUP(object); + priv = MAPE_GROUP_PRIVATE(group); + + switch(prop_id) + { + case PROP_NAME: + g_value_set_string(value, mape_group_get_name(group)); + break; + case PROP_FULL_NAME: + g_value_take_string(value, mape_group_get_full_name(group)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/* + * Gype registration. + */ + +static void +mape_group_class_init(MapeGroupClass *class) +{ + GObjectClass* object_class; + + object_class = G_OBJECT_CLASS(class); + mape_group_parent_class = G_OBJECT_CLASS(g_type_class_peek_parent(class)); + g_type_class_add_private(class, sizeof(MapeGroupPrivate)); + + object_class->finalize = mape_group_finalize; + object_class->set_property = mape_group_set_property; + object_class->get_property = mape_group_get_property; + + mape_group_error_quark = g_quark_from_static_string("MAPE_GROUP_ERROR"); + + g_object_class_install_property( + object_class, + PROP_NAME, + g_param_spec_string( + "name", + "Name", + "The name of the group", + NULL, + G_PARAM_READABLE + ) + ); + + g_object_class_install_property( + object_class, + PROP_FULL_NAME, + g_param_spec_string( + "full-name", + "Full Name", + "The full path to the group", + NULL, + G_PARAM_READABLE + ) + ); +} + +/* + * Public API. + */ + +/** + * mape_group_new: + * + * Creates a new group object. The group object is initially closed. Open it + * with mape_group_open(). To open a child group from an existing group, use + * mape_group_open_child() instead of this function. + * + * Return Value: A new #MapeGroup. Free with g_object_unref(). + **/ +MapeGroup* +mape_group_new(void) +{ + return MAPE_GROUP(g_object_new(MAPE_TYPE_GROUP, NULL)); +} + +/** + * mape_group_is_open: + * @group: A #MapeGroup. + * + * Returns whether @group is open or not. + * + * Returns: Whether @group is open. + */ +gboolean +mape_group_is_open(MapeGroup* group) +{ + MapeGroupPrivate* priv; + + g_return_val_if_fail(MAPE_IS_GROUP(group), FALSE); + + priv = MAPE_GROUP_PRIVATE(group); + + if(priv->handle != NULL) return TRUE; +#ifdef G_OS_WIN32 + if(priv->drive != 0) return TRUE; +#endif + return FALSE; +} + +/** + * mape_group_open: + * @group: A #MapeGroup. + * @path: A path leading to a non-packed C4Group file or a directory on disk. + * @error: Location to store error information, if any. + * + * @group must not be open yet. Upon success, @group has been opened and its + * content can be read via mape_group_get_next_entry() and + * mape_group_load_entry(). On error, the function returns %FALSE and @error + * will be set. + * + * Return Value: %TRUE on success, and %FALSE on error. + **/ +gboolean +mape_group_open(MapeGroup* group, + const gchar* path, + GError** error) +{ + MapeGroupPrivate* priv; + + g_return_val_if_fail(MAPE_IS_GROUP(group), FALSE); + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + g_return_val_if_fail(mape_group_is_open(group) == FALSE, FALSE); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + if(strcmp(path, "/") == 0) + { + priv->drive = 1; + return TRUE; + } +#endif + + priv->handle = c4_group_handle_new(); + if(c4_group_handle_open(priv->handle, path, FALSE) == FALSE) + { + g_set_error(error, mape_group_error_quark, MAPE_GROUP_ERROR_OPEN, + "Could not open '%s': %s", path, + c4_group_handle_get_error(priv->handle)); + c4_group_handle_free(priv->handle); + priv->handle = NULL; + return FALSE; + } + + g_object_notify(G_OBJECT(group), "name"); + g_object_notify(G_OBJECT(group), "full-name"); + + return TRUE; +} + +/** + * mape_group_open_child: + * @group: A #MapeGroup. + * @entry: A subgroup entry in @group. + * @error: Location to store error information, if any. + * + * This function attempts to open a child group which is contained in @group, + * named @entry. On success the new, opened group is returned. On failure, + * the function returns %NULL and @error is set. + * + * Returns: A new group to be freed with g_object_unref() when no longer + * needed, or %NULL on error. + **/ +MapeGroup* +mape_group_open_child(MapeGroup* group, + const gchar* entry, + GError** error) +{ + MapeGroupPrivate* parent_priv; + MapeGroup* child; + MapeGroupPrivate* child_priv; + C4GroupHandle* child_handle; + + g_return_val_if_fail(MAPE_IS_GROUP(group), NULL); + g_return_val_if_fail(entry != NULL, NULL); + g_return_val_if_fail(error == NULL || *error == NULL, NULL); + g_return_val_if_fail(mape_group_is_open(group) == TRUE, NULL); + + parent_priv = MAPE_GROUP_PRIVATE(group); +#ifdef G_OS_WIN32 + if(parent_priv->handle == NULL) + { + child = mape_group_new(); + if(!mape_group_open(child, entry, error)) + { + g_object_unref(child); + return NULL; + } + + return child; + } +#endif + + child_handle = c4_group_handle_new(); + if(!c4_group_handle_open_as_child(child_handle, parent_priv->handle, + entry, FALSE, FALSE)) + { + g_set_error(error, mape_group_error_quark, MAPE_GROUP_ERROR_OPEN, + "Could not open '%s': %s", entry, + c4_group_handle_get_error(child_handle)); + c4_group_handle_free(child_handle); + return NULL; + } + + child = mape_group_new(); + child_priv = MAPE_GROUP_PRIVATE(child); + child_priv->handle = child_handle; + + return child; +} + +/** + * mape_group_close: + * @group: A #MapeGroup. + * + * Closes an open group. The group can be reopened afterwards. + */ +void +mape_group_close(MapeGroup* group) +{ + MapeGroupPrivate* priv; + + g_return_if_fail(MAPE_IS_GROUP(group)); + g_return_if_fail(mape_group_is_open(group) == FALSE); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + priv->drive = 0; +#endif + + if(priv->handle != NULL) + { + c4_group_handle_free(priv->handle); + priv->handle = NULL; + + /* Don't notify when only drive was reset, as name and full-name are + * not specified for these anyway (yet). */ + g_object_notify(G_OBJECT(group), "name"); + g_object_notify(G_OBJECT(group), "full-name"); + } +} + +/** + * mape_group_get_name: + * @group: An open #MapeGroup. + * + * Returns the name of the group. + * + * Return Value: The group's name. The name is owned by the group and must not + * be freed. + **/ +const gchar* +mape_group_get_name(MapeGroup* group) +{ + g_return_val_if_fail(MAPE_IS_GROUP(group), NULL); + g_return_val_if_fail(mape_group_is_open(group), NULL); + + return c4_group_handle_get_name(MAPE_GROUP_PRIVATE(group)->handle); +} + +/** + * mape_group_get_full_name: + * @group: An open #MapeGroup. + * + * Returns the full path to the group. + * + * Return Value: The group path. Free with g_free() when no longer needed. + **/ +gchar* +mape_group_get_full_name(MapeGroup* group) +{ + g_return_val_if_fail(MAPE_IS_GROUP(group), NULL); + g_return_val_if_fail(mape_group_is_open(group), NULL); + + return c4_group_handle_get_full_name(MAPE_GROUP_PRIVATE(group)->handle); +} + +/** + * mape_group_has_entry: + * @group: An open #MapeGroup. + * @entry: The entry name to check. + * + * Returns %TRUE if @group contains an entry with the given name, and %FALSE + * otherwise. + */ +gboolean +mape_group_has_entry(MapeGroup* group, + const gchar* entry) +{ + MapeGroupPrivate* priv; +#ifdef G_OS_WIN32 + DWORD chk_drv; +#endif + + g_return_val_if_fail(MAPE_IS_GROUP(group), FALSE); + g_return_val_if_fail(mape_group_is_open(group), FALSE); + g_return_val_if_fail(entry != NULL, FALSE); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + if(priv->handle == NULL) + { + if(entry[0] == '\0') return FALSE; + if(entry[1] != ':') return FALSE; + + chk_drv = 1 << (entry[0] - 'A'); + return (GetLogicalDrives() & chk_drv) != 0; + } +#endif + + c4_group_handle_reset_search(priv->handle); + return c4_group_handle_find_next_entry(priv->handle, entry, + NULL, NULL, FALSE); +} + +/** + * mape_group_rewind: + * @group: An open #MapeGroup. + * + * Resets the group's internal iterator. The next call to + * mape_group_get_next_entry() will return the first entry in the group again. + */ +void +mape_group_rewind(MapeGroup* group) +{ + MapeGroupPrivate* priv; + + g_return_if_fail(MAPE_IS_GROUP(group)); + g_return_if_fail(mape_group_is_open(group)); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + if(priv->handle == NULL) + { + priv->drive = 1; + return; + } +#endif + + c4_group_handle_reset_search(priv->handle); +} + +/** + * mape_group_get_next_entry: + * @group: An open #MapeGroup. + * @error: Location to store error information, if any. + * + * Advances the group's internal iterator by one and returns the name of the + * entry it now points to. Use mape_group_load_entry() to load its contents + * into memory, or mape_group_open_child() if you expect the entry to be a + * subgroup. If there are no more entries in the group, the function returns + * %NULL. + * + * Returns: The name of the next entry, or %NULL if there is no next entry. + */ +gchar* +mape_group_get_next_entry(MapeGroup* group) +{ + MapeGroupPrivate* priv; + gchar* buf; +#ifdef G_OS_WIN32 + DWORD drv_c; + guint drive; +#endif + + g_return_val_if_fail(MAPE_IS_GROUP(group), NULL); + g_return_val_if_fail(mape_group_is_open(group), NULL); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + static const guint DRV_C_SUPPORT = 26; + if(priv->handle == NULL) + { + drv_c = GetLogicalDrives(); + + /* Find next available drive or wait for overflow */ + drive = priv->drive - 1; + while( (drive < DRV_C_SUPPORT) && ((~drv_c & (1 << drive)) != 0)) + ++drive; + if(drive >= DRV_C_SUPPORT) return NULL; + + buf = g_malloc(3 * sizeof(gchar)); + buf[0] = 'A' + drive; + buf[1] = ':'; + buf[2] = '\0'; + priv->drive = drive + 2; + + return buf; + } +#endif + + buf = g_malloc(512 * sizeof(gchar)); + if(!c4_group_handle_find_next_entry(priv->handle, "*", NULL, buf, FALSE)) + { + g_free(buf); + buf = NULL; + } + + return buf; +} + +/** + * mape_group_load_entry: + * @group: An open #MapeGroup. + * @entry: The name of the file to open. + * @size: Location to store the size of the entry in, or %NULL. + * @error: Location to store error information, if any. + * + * Attempts to load the entry with the given name + * into memory. If @size is non-%NULL, the size of the + * entry will be stored at the location @size points to. On error, %NULL + * is returned, @error is set and @size is left untouched. + * + * Returns: A pointer pointing to the loaded entry's contents. + */ +guchar* +mape_group_load_entry(MapeGroup* group, + const gchar* entry, + gsize* size, + GError** error) +{ + MapeGroupPrivate* priv; + gsize s; + guchar* res; + + g_return_val_if_fail(MAPE_IS_GROUP(group), NULL); + g_return_val_if_fail(mape_group_is_open(group), NULL); + g_return_val_if_fail(error == NULL || *error == NULL, NULL); + + priv = MAPE_GROUP_PRIVATE(group); + if(!c4_group_handle_access_entry(priv->handle, entry, &s, NULL, FALSE)) + { + g_set_error(error, mape_group_error_quark, MAPE_GROUP_ERROR_ACCESS, + "%s", c4_group_handle_get_error(priv->handle)); + return NULL; + } + + res = g_malloc(s); + if(!c4_group_handle_read(priv->handle, (char*)res, s)) + { + g_set_error(error, mape_group_error_quark, MAPE_GROUP_ERROR_READ, + "%s", c4_group_handle_get_error(priv->handle)); + g_free(res); + return NULL; + } + + if(size != NULL) *size = s; + return res; +} + +/** + * mape_group_is_folder: + * @group: An open #MapeGroup. + * + * Returns whether this group is a directory or a packed file. + * + * Returns: %TRUE if the group is a directory or %FALSE if it is a file. + */ +gboolean +mape_group_is_folder(MapeGroup* group) +{ + MapeGroupPrivate* priv; + C4GroupHandleStatus status; + + g_return_val_if_fail(MAPE_IS_GROUP(group), FALSE); + g_return_val_if_fail(mape_group_is_open(group), FALSE); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + if(priv->handle == NULL) + return TRUE; +#endif + + status = c4_group_handle_get_status(priv->handle); + if(status == C4_GROUP_HANDLE_FOLDER) return TRUE; + return FALSE; +} + +/* + * mape_group_is_drive_container: + * @group: An open #MapeGroup. + * + * Returns whether @group is a proxy folder which contains the available + * drives on Windows (C:\, D:\, etc.) as subfolders. This is what one gets + * when opening the root folder "/" on Windows. On Unix, the function always + * returns %FALSE. + * + * Returns: Whether @group contains the available drives. + */ +gboolean +mape_group_is_drive_container(MapeGroup* group) +{ + g_return_val_if_fail(MAPE_IS_GROUP(group), FALSE); + g_return_val_if_fail(mape_group_is_open(group), FALSE); + +#ifdef G_OS_WIN32 + { + MapeGroupPrivate* priv = MAPE_GROUP_PRIVATE(group); + if(priv->handle == NULL) + return TRUE; + } +#endif + + return FALSE; +} + +/* + * mape_group_is_child_folder: + * @group: An open #MapeGroup. + * @child: A child entry. + * + * Returns whether the given entry is a subgroup or not. The current + * implementation only works exactly for directories, not for packed groups. + * For the latter it makes only a guess upon the extension of the entry. + * + * Returns: %TRUE if @child is a subgroup of @group, %FALSE otherwise. + */ +gboolean +mape_group_is_child_folder(MapeGroup* group, + const gchar* child) +{ + MapeGroupPrivate* priv; + const gchar* ext; + gchar* fullname; + gchar* filename; + gboolean result; + + g_return_val_if_fail(MAPE_IS_GROUP(group), FALSE); + g_return_val_if_fail(mape_group_is_open(group), FALSE); + g_return_val_if_fail(child != NULL, FALSE); + + priv = MAPE_GROUP_PRIVATE(group); + +#ifdef G_OS_WIN32 + /* Drives are always folders */ + if(priv->handle == NULL) + return TRUE; +#endif + + /* Guess on extension */ + ext = strrchr(child, '.'); + if(ext != NULL) + { + if(g_ascii_strcasecmp(ext, ".ocs") == 0 || + g_ascii_strcasecmp(ext, ".ocd") == 0 || + g_ascii_strcasecmp(ext, ".ocf") == 0 || + g_ascii_strcasecmp(ext, ".ocg") == 0) + { + return TRUE; + } + } + + /* Otherwise assume it's not a subgroup */ + if(c4_group_handle_get_status(priv->handle) != C4_GROUP_HANDLE_FOLDER) + return FALSE; + + /* It is an open directory - check for regular directory */ + fullname = c4_group_handle_get_full_name(priv->handle); + filename = g_build_filename(fullname, child, NULL); + g_free(fullname); + + result = g_file_test(filename, G_FILE_TEST_IS_DIR); + g_free(filename); + + return result; +} + +/* This function is for internal use only */ +C4GroupHandle* +_mape_group_get_handle(MapeGroup* group) +{ + g_return_val_if_fail(MAPE_IS_GROUP(group), NULL); + return MAPE_GROUP_PRIVATE(group)->handle; +} + +/* vim:set et sw=2 ts=2: */ diff --git a/src/mape/group.h b/src/mape/group.h new file mode 100644 index 000000000..ade55e0cc --- /dev/null +++ b/src/mape/group.h @@ -0,0 +1,127 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_GROUP_H +#define INC_MAPE_GROUP_H + +#include + +G_BEGIN_DECLS + +#define MAPE_TYPE_GROUP (mape_group_get_type()) +#define MAPE_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MAPE_TYPE_GROUP, MapeGroup)) +#define MAPE_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MAPE_TYPE_GROUP, MapeGroupClass)) +#define MAPE_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAPE_TYPE_GROUP)) +#define MAPE_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MAPE_TYPE_GROUP)) +#define MAPE_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MAPE_TYPE_GROUP, MapeGroupClass)) + +typedef struct _MapeGroup MapeGroup; +typedef struct _MapeGroupClass MapeGroupClass; + +/** + * MapeGroupError: + * @MAPE_GROUP_ERROR_OPEN: An error occured when attempting to open the group. + * @MAPE_GROUP_ERROR_ACCESS: An error occurred when accessing a group element. + * @MAPE_GROUP_ERROR_READ: An error occured when reading from the group. + * + * These errors are from the MAPE_GROUP_ERROR error domain. They can occur + * when opening, seeking or reading from a group, respectively. + */ +typedef enum _MapeGroupError { + MAPE_GROUP_ERROR_OPEN, + MAPE_GROUP_ERROR_ACCESS, + MAPE_GROUP_ERROR_READ +} MapeGroupError; + +/** + * MapeGroupClass: + * + * This structure does not contain any public fields. + */ +struct _MapeGroupClass { + /*< private >*/ + GObjectClass parent_class; +}; + +/** + * MapeGroup: + * + * #MapeGroup is an opaque data type. You should only access it via the + * public API functions. + */ +struct _MapeGroup { + /*< private >*/ + GObject parent; +}; + +GType +mape_group_get_type(void) G_GNUC_CONST; + +MapeGroup* +mape_group_new(void); + +gboolean +mape_group_is_open(MapeGroup* group); + +gboolean +mape_group_open(MapeGroup* group, + const gchar* path, + GError** error); + +MapeGroup* +mape_group_open_child(MapeGroup* group, + const gchar* entry, + GError** error); + +void +mape_group_close(MapeGroup* group); + +const gchar* +mape_group_get_name(MapeGroup* group); + +gchar* +mape_group_get_full_name(MapeGroup* group); + +gboolean +mape_group_has_entry(MapeGroup* group, + const gchar* entry); + +void +mape_group_rewind(MapeGroup* group); + +gchar* +mape_group_get_next_entry(MapeGroup* group); + +guchar* +mape_group_load_entry(MapeGroup* group, + const gchar* entry, + gsize* size, + GError** error); + +gboolean +mape_group_is_folder(MapeGroup* group); + +gboolean +mape_group_is_drive_container(MapeGroup* group); + +gboolean +mape_group_is_child_folder(MapeGroup* group, + const gchar* child); + +G_END_DECLS + +#endif /* INC_MAPE_GROUP_H */ + +/* vim:set et sw=2 ts=2: */ diff --git a/src/mape/header.c b/src/mape/header.c new file mode 100644 index 000000000..b951e6df7 --- /dev/null +++ b/src/mape/header.c @@ -0,0 +1,278 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include + +#include "mape/header.h" + +static const GtkActionEntry mape_header_file_entries[] = { + { + "File", + NULL, + "_File", + NULL, + NULL, + NULL + }, { + "FileNew", + GTK_STOCK_NEW, + "_New", + "N", + "Opens a new document", + NULL + }, { + "FileOpen", + GTK_STOCK_OPEN, + "_Open", + "O", + "Opens an already existing document from disk", + NULL + }, { + "FileSave", + GTK_STOCK_SAVE, + "_Save", + "S", + "Saves the current document to disk", + NULL + }, { + "FileSaveAs", + GTK_STOCK_SAVE_AS, + "Save as", + "S", + "Save the current map to another path on disk", + NULL + }, { + "FileQuit", + GTK_STOCK_QUIT, + "_Quit", + "Q", + "Exit the program", + NULL + } +}; + +static const GtkActionEntry mape_header_edit_entries[] = { + { + "Edit", + NULL, + "_Edit", + NULL, + NULL, + NULL + }, { + "EditUndo", + GTK_STOCK_UNDO, + "_Undo", + "Z", + "Undo the last action", + NULL + }, { + "EditRedo", + GTK_STOCK_REDO, + "_Redo", + "Y", + "Redo the last action", + NULL + }, { + "EditPreferences", + GTK_STOCK_PREFERENCES, + "Pr_eferences", + NULL, + "Configure the application", + NULL + } +}; + +static const GtkActionEntry mape_header_help_entries[] = { + { + "Help", + NULL, + "_Help", + NULL, + NULL, + NULL + }, { + "HelpAbout", + GTK_STOCK_ABOUT, + "_About", + NULL, + "Shows authors and copyright information", + NULL + } +}; + +static const gchar* mape_header_ui_desc = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +MapeHeader* mape_header_new(void) +{ + MapeHeader* header; + gint result; + + header = malloc(sizeof(MapeHeader) ); + + header->group_file = gtk_action_group_new("FileActions"); + gtk_action_group_add_actions( + header->group_file, + mape_header_file_entries, + G_N_ELEMENTS(mape_header_file_entries), + header + ); + + header->group_edit = gtk_action_group_new("EditActions"); + gtk_action_group_add_actions( + header->group_edit, + mape_header_edit_entries, + G_N_ELEMENTS(mape_header_edit_entries), + header + ); + + header->group_help = gtk_action_group_new("HelpActions"); + gtk_action_group_add_actions( + header->group_help, + mape_header_help_entries, + G_N_ELEMENTS(mape_header_help_entries), + header + ); + + header->ui_manager = gtk_ui_manager_new(); + gtk_ui_manager_insert_action_group( + header->ui_manager, + header->group_file, + 0 + ); + + gtk_ui_manager_insert_action_group( + header->ui_manager, + header->group_edit, + 0 + ); + + gtk_ui_manager_insert_action_group( + header->ui_manager, + header->group_help, + 0 + ); + + result = gtk_ui_manager_add_ui_from_string( + header->ui_manager, + mape_header_ui_desc, + -1, + NULL + ); + + g_assert(result != 0); + + header->menubar = gtk_ui_manager_get_widget( + header->ui_manager, + "/MenuBar" + ); + + header->toolbar = gtk_ui_manager_get_widget( + header->ui_manager, + "/ToolBar" + ); + + g_assert(header->menubar != NULL); + g_assert(header->toolbar != NULL); + + header->accel_group = gtk_ui_manager_get_accel_group( + header->ui_manager + ); + + g_assert(header->accel_group != NULL); + + header->file_new = gtk_action_group_get_action( + header->group_file, + "FileNew" + ); + + header->file_open = gtk_action_group_get_action( + header->group_file, + "FileOpen" + ); + + header->file_save = gtk_action_group_get_action( + header->group_file, + "FileSave" + ); + + header->file_save_as = gtk_action_group_get_action( + header->group_file, + "FileSaveAs" + ); + + header->file_quit = gtk_action_group_get_action( + header->group_file, + "FileQuit" + ); + + header->edit_undo = gtk_action_group_get_action( + header->group_edit, + "EditUndo" + ); + + header->edit_redo = gtk_action_group_get_action( + header->group_edit, + "EditRedo" + ); + + header->edit_preferences = gtk_action_group_get_action( + header->group_edit, + "EditPreferences" + ); + + header->help_about = gtk_action_group_get_action( + header->group_help, + "HelpAbout" + ); + + return header; +} + +void mape_header_destroy(MapeHeader* header) +{ + g_object_unref(G_OBJECT(header->ui_manager) ); + free(header); +} diff --git a/src/mape/header.h b/src/mape/header.h new file mode 100644 index 000000000..e9417c091 --- /dev/null +++ b/src/mape/header.h @@ -0,0 +1,48 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_HEADER_H +#define INC_MAPE_HEADER_H + +#include +#include "mape/forward.h" + +struct MapeHeader_ { + GtkUIManager* ui_manager; + GtkAccelGroup* accel_group; + + GtkWidget* menubar; + GtkWidget* toolbar; + + GtkActionGroup* group_file; + GtkAction* file_new; + GtkAction* file_open; + GtkAction* file_save; + GtkAction* file_save_as; + GtkAction* file_quit; + + GtkActionGroup* group_edit; + GtkAction* edit_undo; + GtkAction* edit_redo; + GtkAction* edit_preferences; + + GtkActionGroup* group_help; + GtkAction* help_about; +}; + +MapeHeader* mape_header_new(void); +void mape_header_destroy(MapeHeader* header); + +#endif /* INC_MAPE_HEADER_H */ diff --git a/src/mape/iconview.c b/src/mape/iconview.c new file mode 100644 index 000000000..1be62def8 --- /dev/null +++ b/src/mape/iconview.c @@ -0,0 +1,138 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#include +#include "mape/iconview.h" + +MapeIconView* mape_icon_view_new(GError** error) +{ + MapeIconView* view; + view = malloc(sizeof(MapeIconView) ); + + view->list_store = GTK_TREE_MODEL( + gtk_list_store_new( + MAPE_ICON_VIEW_COLUMN_COUNT, + GDK_TYPE_PIXBUF, + G_TYPE_STRING + ) + ); + + view->view = gtk_icon_view_new_with_model(view->list_store); + g_object_unref(view->list_store); + +#if GTK_CHECK_VERSION(2,22,0) + gtk_icon_view_set_item_orientation( +#else + gtk_icon_view_set_orientation( +#endif + GTK_ICON_VIEW(view->view), + GTK_ORIENTATION_HORIZONTAL + ); + + view->renderer_icon = gtk_cell_renderer_pixbuf_new(); + gtk_cell_layout_pack_start( + GTK_CELL_LAYOUT(view->view), + view->renderer_icon, + FALSE + ); + + gtk_cell_layout_set_attributes( + GTK_CELL_LAYOUT(view->view), + view->renderer_icon, + "pixbuf", MAPE_ICON_VIEW_COLUMN_ICON, + NULL + ); + + view->renderer_name = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start( + GTK_CELL_LAYOUT(view->view), + view->renderer_name, + TRUE + ); + + gtk_cell_layout_set_attributes( + GTK_CELL_LAYOUT(view->view), + view->renderer_name, + "text", MAPE_ICON_VIEW_COLUMN_NAME, + NULL + ); + + gtk_icon_view_set_selection_mode( + GTK_ICON_VIEW(view->view), + GTK_SELECTION_NONE + ); + + gtk_tree_sortable_set_sort_column_id( + GTK_TREE_SORTABLE(view->list_store), + MAPE_ICON_VIEW_COLUMN_NAME, + GTK_SORT_ASCENDING + ); + + gtk_widget_show(view->view); + + view->window = gtk_scrolled_window_new(NULL, NULL); + gtk_container_add( + GTK_CONTAINER(view->window), + view->view + ); + + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(view->window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC + ); + + gtk_scrolled_window_set_shadow_type( + GTK_SCROLLED_WINDOW(view->window), + GTK_SHADOW_IN + ); + + gtk_widget_show(view->window); + return view; +} + +void mape_icon_view_destroy(MapeIconView* view) +{ + /* TODO: unref cell renderers? */ + free(view); +} + +void mape_icon_view_clear(MapeIconView* view) +{ + gtk_list_store_clear(GTK_LIST_STORE(view->list_store) ); +} + +void mape_icon_view_add(MapeIconView* view, + GdkPixbuf* icon, + const char* name) +{ + GtkTreeIter iter; + + gtk_list_store_append( + GTK_LIST_STORE(view->list_store), + &iter + ); + + gtk_list_store_set( + GTK_LIST_STORE(view->list_store), + &iter, + MAPE_ICON_VIEW_COLUMN_ICON, + icon, + MAPE_ICON_VIEW_COLUMN_NAME, + name, + -1 + ); +} + diff --git a/src/mape/iconview.h b/src/mape/iconview.h new file mode 100644 index 000000000..b74c1e842 --- /dev/null +++ b/src/mape/iconview.h @@ -0,0 +1,47 @@ +/* + * mape - C4 Landscape.txt editor + * + * Copyright (c) 2005-2009, Armin Burgmeier + * + * 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. + */ + +#ifndef INC_MAPE_ICONVIEW_H +#define INC_MAPE_ICONVIEW_H + +#include +#include "mape/forward.h" + +typedef enum MapeIconViewColumns_ { + MAPE_ICON_VIEW_COLUMN_ICON, + MAPE_ICON_VIEW_COLUMN_NAME, + + MAPE_ICON_VIEW_COLUMN_COUNT +} MapeIconViewColumns; + +struct MapeIconView_ { + GtkWidget* window; + GtkWidget* view; + + GtkTreeModel* list_store; + + GtkCellRenderer* renderer_icon; + GtkCellRenderer* renderer_name; +}; + +MapeIconView* mape_icon_view_new(GError** error); +void mape_icon_view_destroy(MapeIconView* view); + +void mape_icon_view_clear(MapeIconView* view); +void mape_icon_view_add(MapeIconView* view, + GdkPixbuf* icon, + const char* name); + +#endif /* INC_MAPE_ICONVIEW_H */ diff --git a/src/mape/mape-syntax/c4landscape.lang b/src/mape/mape-syntax/c4landscape.lang new file mode 100644 index 000000000..237b81656 --- /dev/null +++ b/src/mape/mape-syntax/c4landscape.lang @@ -0,0 +1,95 @@ + + + + text/plain + Landscape.txt + // + /* + */ + + + +