Get rid of Lua modding (#28572)

* Get rid of Lua modding
This commit is contained in:
ZhilkinSerg 2019-03-14 06:36:17 +03:00 committed by Kevin Granade
parent 46e2ec79da
commit cf9dee953d
98 changed files with 218 additions and 7941 deletions

View File

@ -19,11 +19,7 @@ cache:
- 'c:\tools\vcpkg\installed'
install:
# Install dependency packages
- cmd: vcpkg --triplet %PLATFORM%-windows-static install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext lua
# Add LUA binary folder to PATH
- cmd: set PATH=c:\tools\vcpkg\installed\%PLATFORM%-windows-static\tools\lua;%PATH%
# Report LUA binary version
- cmd: lua.exe -v
- cmd: vcpkg --triplet %PLATFORM%-windows-static install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext
build:
parallel: true
project: /msvc-full-features/Cataclysm-vcpkg-static.sln

1
.gitattributes vendored
View File

@ -9,7 +9,6 @@
*.cpp text
*.h text
*.json text
*.lua text
*.md text
*.py text
*.rc text

1
.gitignore vendored
View File

@ -24,7 +24,6 @@
/obj/
/objwin/
/save/
/src/lua/catabindings.cpp
/src/version.h
/sound/
/templates/

View File

@ -73,7 +73,7 @@ jobs:
sources: [*apt_sources, llvm-toolchain-trusty-6.0]
# macOS Tiles
- env: CLANG=clang++ NATIVE=osx OSX_MIN=10.13 TILES=1 SOUND=1 LUA=1
- env: CLANG=clang++ NATIVE=osx OSX_MIN=10.13 TILES=1 SOUND=1
os: osx
osx_image: xcode10.1
compiler: clang

View File

@ -9,7 +9,6 @@ SET(CMAKE_MODULE_PATH
)
# Build options
option(LUA "Lua support (required for some mods)." "OFF")
option(TILES "Build graphical tileset version." "OFF")
option(CURSES "Build curses version." "ON" )
option(SOUND "Support for in-game sounds & music." "OFF")
@ -18,9 +17,8 @@ option(USE_HOME_DIR "Use user's home directory for save files." "ON" )
option(LOCALIZE "Support for language localizations. Also enable UTF support." "ON" )
option(LANGUAGES "Compile localization files for specified languages." "" )
option(DYNAMIC_LINKING "Use dynamic linking. Or use static to remove MinGW dependency instead." "ON")
option(LUA_BINARY "Lua binary name or path. You can try to use luajit for extra speed." "")
option(GIT_BINARY "Git binary name or path." "")
OPTION(PREFIX "Location of Data,GFX, & Lua directories" "")
OPTION(PREFIX "Location of Data & GFX directories" "")
include(CTest)
@ -140,10 +138,6 @@ ENDIF (${CMAKE_SYSTEM_NAME} MATCHES Windows)
MESSAGE(STATUS "${PROJECT_NAME} build options --\n")
# Preset variables
IF (NOT LUA_BINARY)
SET (LUA_BINARY "lua")
ENDIF (NOT LUA_BINARY)
IF(NOT LANGUAGES)
SET (LANGUAGES de es_AR es_ES fr it_IT ja ko pt_BR ru zh_CN zh_TW)
ENDIF(NOT LANGUAGES)
@ -192,16 +186,12 @@ ELSE (CMAKE_BUILD_TYPE STREQUAL Debug)
MESSAGE(STATUS "PIXMAPS_UNITY_ENTRY_PATH : ${PIXMAPS_UNITY_ENTRY_PATH}")
MESSAGE(STATUS "MANPAGE_ENTRY_PATH : ${MANPAGE_ENTRY_PATH}\n")
ADD_DEFINITIONS(-DRELEASE)
# Use PREFIX as storage of data,gfx,lua etc.. Usefull only on *nix OS.
# Use PREFIX as storage of data,gfx, etc.. Usefull only on *nix OS.
IF (PREFIX AND NOT WIN32)
ADD_DEFINITIONS(-DDATA_DIR_PREFIX)
ENDIF (PREFIX AND NOT WIN32)
ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug)
MESSAGE(STATUS "LUA : ${LUA}")
IF (LUA)
MESSAGE(STATUS "LUA_BINARY : ${LUA_BINARY}")
ENDIF (LUA)
MESSAGE(STATUS "GIT_BINARY : ${GIT_EXECUTABLE}")
MESSAGE(STATUS "DYNAMIC_LINKING : ${DYNAMIC_LINKING}")
MESSAGE(STATUS "TILES : ${TILES}")
@ -309,16 +299,6 @@ IF(SOUND)
ENDIF(NOT SDL2_MIXER_FOUND)
ENDIF(SOUND)
IF(LUA)
FIND_PACKAGE(Lua)
IF(NOT LUA_FOUND)
MESSAGE(FATAL_ERROR
"You need the Lua development library to be able to compile with Lua support.\nSee INSTALL file for details and more info\n"
)
ENDIF(NOT LUA_FOUND)
ADD_DEFINITIONS(-DLUA)
ENDIF(LUA)
IF(BACKTRACE)
ADD_DEFINITIONS(-DBACKTRACE)
ENDIF(BACKTRACE)
@ -347,11 +327,6 @@ IF(USE_HOME_DIR)
ADD_DEFINITIONS(-DUSE_HOME_DIR)
ENDIF(USE_HOME_DIR)
IF(LUA)
add_subdirectory(lua)
add_subdirectory(src/lua)
ENDIF(LUA)
add_subdirectory(src)
add_subdirectory(data)
if (NOT MSVC)

View File

@ -1,117 +0,0 @@
# Locate Lua library
# This module defines
# LUA_EXECUTABLE, if found
# LUA_FOUND, if false, do not try to link to Lua
# LUA_LIBRARIES
# LUA_INCLUDE_DIR, where to find lua.h
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
#
# Note that the expected include convention is
# #include "lua.h"
# and not
# #include <lua/lua.h>
# This is because, the lua location is not standardized and may exist
# in locations other than lua/
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
# Modified to support Lua 5.2 by LuaDist 2012
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
#
# The required version of Lua can be specified using the
# standard syntax, e.g. FIND_PACKAGE(Lua 5.1)
# Otherwise the module will search for any available Lua implementation
# Always search for non-versioned lua first (recommended)
SET(_POSSIBLE_LUA_INCLUDE include include/lua)
SET(_POSSIBLE_LUA_EXECUTABLE lua)
SET(_POSSIBLE_LUA_LIBRARY lua)
# Determine possible naming suffixes (there is no standard for this)
IF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR)
SET(_POSSIBLE_SUFFIXES "${Lua_FIND_VERSION_MAJOR}${Lua_FIND_VERSION_MINOR}" "${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}" "-${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}")
ELSE(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR)
SET(_POSSIBLE_SUFFIXES "52" "5.2" "-5.2" "51" "5.1" "-5.1")
ENDIF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR)
# Set up possible search names and locations
FOREACH(_SUFFIX ${_POSSIBLE_SUFFIXES})
LIST(APPEND _POSSIBLE_LUA_INCLUDE "include/lua${_SUFFIX}")
LIST(APPEND _POSSIBLE_LUA_EXECUTABLE "lua${_SUFFIX}")
LIST(APPEND _POSSIBLE_LUA_LIBRARY "lua${_SUFFIX}")
ENDFOREACH(_SUFFIX)
# Find the lua executable
FIND_PROGRAM(LUA_EXECUTABLE
NAMES ${_POSSIBLE_LUA_EXECUTABLE}
)
# Find the lua header
FIND_PATH(LUA_INCLUDE_DIR lua.h
HINTS
$ENV{LUA_DIR}
PATH_SUFFIXES ${_POSSIBLE_LUA_INCLUDE}
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
# Find the lua library
FIND_LIBRARY(LUA_LIBRARY
NAMES ${_POSSIBLE_LUA_LIBRARY}
HINTS
$ENV{LUA_DIR}
PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
)
IF(LUA_LIBRARY)
# include the math library for Unix
IF(UNIX AND NOT APPLE)
FIND_LIBRARY(LUA_MATH_LIBRARY m)
SET( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
ELSE(UNIX AND NOT APPLE)
SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
ENDIF(UNIX AND NOT APPLE)
ENDIF(LUA_LIBRARY)
# Determine Lua version
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
UNSET(lua_version_str)
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY LUA_EXECUTABLE)

View File

@ -31,7 +31,6 @@ order to build CataclysmDDA:
* `zlib`
* `bzip2`
* Optional
* `lua51`
* `gettext`
* Curses
* `ncurses`
@ -68,7 +67,6 @@ Obtain packages specified above with your system package manager.
pacman -S mingw-w64-i686-toolchain msys/git \
mingw-w64-i686-cmake \
mingw-w64-i686-SDL2_{image,mixer,ttf} \
mingw-w64-i686-lua51 \
ncurses-devel \
gettext-devel
```
@ -82,7 +80,6 @@ Obtain packages specified above with your system package manager.
pacman -S mingw-w64-x86_64-toolchain msys/git \
mingw-w64-x86_64-cmake \
mingw-w64-x86_64-SDL2_{image,mixer,ttf} \
mingw-w64-x86_64-lua51 \
ncurses-devel \
gettext-devel
```
@ -178,9 +175,6 @@ The above example creates a build directory inside the source directory, but tha
* `libintl-8.dll`
* `libiconv-2.dll`
* LUA deps:
* `lua51.dll`
* TILES deps:
* `SDL2.dll`
* `SDL2_ttf.dll`
@ -216,7 +210,7 @@ The above example creates a build directory inside the source directory, but tha
CMake can generate `.sln` and `.vcxproj` files used either by Visual Studio itself or by MSBuild command line compiler (if you don't want
a full fledged IDE) and have more "native" binaries than what MSYS/Cygwin can provide.
At the moment only a limited combination of options is supported (tiles only, no lua, no localizations, no backtrace).
At the moment only a limited combination of options is supported (tiles only, no localizations, no backtrace).
Get the tools:
* CMake from the official site - https://cmake.org/download/.
@ -229,7 +223,6 @@ Get the required libraries:
* `SDL2_image` - https://www.libsdl.org/projects/SDL_image/
* `SDL2_mixer` (optional, for sound support) - https://www.libsdl.org/projects/SDL_mixer/
* Unsupported (and unused in the following instructions) optional libs:
* `Lua` - http://luabinaries.sourceforge.net/
* `gettext`/`libintl` - http://gnuwin32.sourceforge.net/packages/gettext.htm
* `ncurses` - ???
@ -315,11 +308,6 @@ Run the game. Should work.
Support for in-game sounds & music.
* LUA=`<boolean>`
This enables Lua support. Needed only for full-fledged mods.
* USE_HOME_DIR=`<boolean>`
Use user's home directory for save files.
@ -342,16 +330,11 @@ Run the game. Should work.
-DLANGUAGES="cs;de;el;es_AR;es_ES"
```
* LUA_BINARY=`<str>`
Override default Lua binary name or path. You can try to use `luajit` for extra speed.
* GIT_BINARY=`<str>`
Override default Git binary name or path.
So a CMake command for building Cataclysm-DDA in release mode with tiles, sound and lua support will look as follows, provided it is run in build directory located in the project.
So a CMake command for building Cataclysm-DDA in release mode with tiles and sound support will look as follows, provided it is run in build directory located in the project.
```
cmake ../ -DCMAKE_BUILD_TYPE=Release -DTILES=ON -DSOUND=ON -DLUA=ON
cmake ../ -DCMAKE_BUILD_TYPE=Release -DTILES=ON -DSOUND=ON
```

View File

@ -39,7 +39,7 @@ pacman -Su
4. Install packages required for compilation with:
```bash
pacman -S git git-extras-git make mingw-w64-x86_64-{astyle,ccache,gcc,libmad,libwebp,lua,ncurses,pkg-config,SDL2} mingw-w64-x86_64-SDL2_{image,mixer,ttf}
pacman -S git git-extras-git make mingw-w64-x86_64-{astyle,ccache,gcc,libmad,libwebp,ncurses,pkg-config,SDL2} mingw-w64-x86_64-SDL2_{image,mixer,ttf}
```
5. Update paths in system-wide profile file (e.g. `C:\msys64\etc\profile`) as following:
@ -88,10 +88,10 @@ cd Cataclysm-DDA
2. Compile with following command line:
```bash
make CCACHE=1 RELEASE=1 MSYS2=1 DYNAMIC_LINKING=1 LUA=1 SDL=1 TILES=1 SOUND=1 LOCALIZE=1 LANGUAGES=all LINTJSON=0 ASTYLE=0 RUNTESTS=0
make CCACHE=1 RELEASE=1 MSYS2=1 DYNAMIC_LINKING=1 SDL=1 TILES=1 SOUND=1 LOCALIZE=1 LANGUAGES=all LINTJSON=0 ASTYLE=0 RUNTESTS=0
```
**Note**: This will compile release version with Lua, Sound and Tiles support and all localization languages, skipping checks and tests and using ccache for faster build. You can use other switches, but `MSYS2=1`, `DYNAMIC_LINKING=1` and probably `RELEASE=1` are required to compile without issues.
**Note**: This will compile release version with Sound and Tiles support and all localization languages, skipping checks and tests and using ccache for faster build. You can use other switches, but `MSYS2=1`, `DYNAMIC_LINKING=1` and probably `RELEASE=1` are required to compile without issues.
## Running:

View File

@ -34,26 +34,26 @@ vcpkg integrate install
#### install 64 bit dependencies:
```cmd
vcpkg --triplet x64-windows install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext lua
vcpkg --triplet x64-windows install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext
```
or (if you want to build statically linked executable)
```cmd
vcpkg --triplet x64-windows-static install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext lua
vcpkg --triplet x64-windows-static install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext
```
#### install32 bit dependencies:
```cmd
vcpkg --triplet x86-windows install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext lua
vcpkg --triplet x86-windows install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext
```
or (if you want to build statically linked executable)
```cmd
vcpkg --triplet x86-windows-static install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext lua
vcpkg --triplet x86-windows-static install sdl2 sdl2-image sdl2-mixer sdl2-ttf gettext
```
#### upgrade all dependencies:
@ -75,4 +75,4 @@ cd Cataclysm-DDA
2. Open one of provided solutions (`msvc-full-features\Cataclysm-vcpkg.sln` for dynamically linked executable or `msvc-full-features\Cataclysm-vcpkg-static.sln` for statically linked executable) in `Visual Studio`, select configuration (`Release` or `Debug`) an platform (`x64` or `x86`) and build it.
**Note**: This will compile release version with Lua, Sound, Tiles and Localization support (language files won't be automatically compiled).
**Note**: This will compile release version with Sound, Tiles and Localization support (language files won't be automatically compiled).

View File

@ -63,7 +63,7 @@ There are some general dependencies, optional dependencies and then specific dep
Rough list based on building on Arch:
* General: `gcc-libs`, `glibc`, `zlib`, `bzip2`
* Optional: `lua51`, `gettext`
* Optional: `gettext`
* Curses: `ncurses`
* Tiles: `sdl2`, `sdl2_image`, `sdl2_ttf`, `sdl2_mixer`, `freetype2`
@ -72,7 +72,6 @@ E.g. for curses build on Debian and derivatives you'll also need `libncurses5-de
Note on optional dependencies:
* `gettext` - for localization support; if you plan to only use English you can skip it
* `lua` - for full-fledged mods; you'll probably prefer to have it
You should be able to figure out what you are missing by reading the compilation errors and/or the output of `ldd` for compiled binaries.
@ -86,7 +85,6 @@ Given you're building from source you have a number of choices to make:
* `TILES=1` - with this you'll get the tiles version, without it the curses version
* `SOUND=1` - if you want sound; this requires `TILES=1`
* `LOCALIZE=0` - this disables localizations so `gettext` is not needed
* `LUA=1` - this enables Lua support; needed only for full-fledged mods
* `CLANG=1` - use Clang instead of GCC
* `CCACHE=1` - use ccache
* `USE_LIBCXX=1` - use libc++ instead of libstdc++ with Clang (default on OS X)
@ -137,12 +135,11 @@ Dependencies:
* SDL_ttf
* freetype
* build essentials
* lua5.2 and liblua5.2 - Only necessary if compiling with lua, which some mods like stats through skills use. Versions 5.1, 5.2 and 5.3 are supported.
* libsdl2-mixer-dev - Used if compiling with sound support.
Install:
sudo apt-get install libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-mixer-dev libfreetype6-dev build-essential lua5.2 liblua5.2-dev
sudo apt-get install libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-mixer-dev libfreetype6-dev build-essential
### Building
@ -152,9 +149,9 @@ A simple installation could be done by simply running:
A more comprehensive alternative is:
make -j2 TILES=1 SOUND=1 RELEASE=1 LUA=1 USE_HOME_DIR=1
make -j2 TILES=1 SOUND=1 RELEASE=1 USE_HOME_DIR=1
The -j2 flag means it will compile with two parallel processes. It can be omitted or changed to -j4 in a more modern processor. If there is no desire to use lua, or have sound, those flags can also be omitted. The USE_HOME_DIR flag places the user files, like configurations and saves into the home folder, making It easier for backups, and can also be omitted.
The -j2 flag means it will compile with two parallel processes. It can be omitted or changed to -j4 in a more modern processor. If there is no desire to have sound, those flags can also be omitted. The USE_HOME_DIR flag places the user files, like configurations and saves into the home folder, making It easier for backups, and can also be omitted.
@ -192,7 +189,7 @@ Install:
mkdir -p ~/src/mxe
git clone https://github.com/mxe/mxe.git ~/src/mxe
cd ~/src/mxe
make MXE_TARGETS='x86_64-w64-mingw32.static i686-w64-mingw32.static' sdl2 sdl2_ttf sdl2_image sdl2_mixer gettext lua ncurses
make MXE_TARGETS='x86_64-w64-mingw32.static i686-w64-mingw32.static' sdl2 sdl2_ttf sdl2_image sdl2_mixer gettext ncurses
If you are not on a Debian derivative (Linux Mint, Ubuntu, etc), you will have to use a different command than apt-get to install [the MXE requirements](http://mxe.cc/#requirements). Building all these packages from MXE might take a while even on a fast computer. Be patient. If you are not planning on building for both 32-bit and 64-bit, you might want to adjust your MXE_TARGETS.
@ -201,21 +198,21 @@ If you are not on a Debian derivative (Linux Mint, Ubuntu, etc), you will have t
Run:
PLATFORM="i686-w64-mingw32.static"
make CROSS="~/src/mxe/usr/bin/${PLATFORM}-" TILES=1 SOUND=1 LUA=1 RELEASE=1 LOCALIZE=1
make CROSS="~/src/mxe/usr/bin/${PLATFORM}-" TILES=1 SOUND=1 RELEASE=1 LOCALIZE=1
Change PLATFORM to x86_64-w64-mingw32.static for a 64-bit Windows build.
To create nice zip file with all the required resources for a trouble free copy on Windows use the bindist target like this:
PLATFORM="i686-w64-mingw32.static"
make CROSS="~/src/mxe/usr/bin/${PLATFORM}-" TILES=1 SOUND=1 LUA=1 RELEASE=1 LOCALIZE=1 bindist
make CROSS="~/src/mxe/usr/bin/${PLATFORM}-" TILES=1 SOUND=1 RELEASE=1 LOCALIZE=1 bindist
### Building (ncurses)
Run:
PLATFORM="i686-w64-mingw32.static"
make CROSS="~/src/mxe/usr/bin/${PLATFORM}-" LUA=1 RELEASE=1 LOCALIZE=1
make CROSS="~/src/mxe/usr/bin/${PLATFORM}-" RELEASE=1 LOCALIZE=1
## Cross-compile to Mac OS X from Linux
@ -252,34 +249,31 @@ Your directory tree should look like:
├── gettext
│   ├── include
│   └── lib
├── lua
│   ├── include
│   └── lib
└── ncurses
├── include
└── lib
Populated with respective frameworks, dylibs and headers.
Tested lib versions are libintl.8.dylib for gettext, liblua.5.2.4.dylib for lua, libncurses.5.4.dylib for ncurses.
Tested lib versions are libintl.8.dylib for gettext, libncurses.5.4.dylib for ncurses.
These libs were obtained from `homebrew` binary distribution at OS X 10.11
Frameworks were obtained from SDL official website as described in the next [section](https://github.com/CleverRaven/Cataclysm-DDA/blob/master/COMPILING.md#sdl)
### Building (SDL)
To build full feature tiles and sound enabled version with localizations and lua enabled:
To build full feature tiles and sound enabled version with localizations enabled:
make dmgdist CROSS=x86_64-apple-darwin15- NATIVE=osx OSX_MIN=10.7 USE_HOME_DIR=1 CLANG=1
RELEASE=1 LOCALIZE=1 LANGUAGES=all LUA=1 TILES=1 SOUND=1 FRAMEWORK=1
RELEASE=1 LOCALIZE=1 LANGUAGES=all TILES=1 SOUND=1 FRAMEWORK=1
OSXCROSS=1 LIBSDIR=../libs FRAMEWORKSDIR=../Frameworks
Make sure that `x86_64-apple-darwin15-clang++` is in `PATH` environment variable.
### Building (ncurses)
To build full curses version with localizations and lua enabled:
To build full curses version with localizations enabled:
make dmgdist CROSS=x86_64-apple-darwin15- NATIVE=osx OSX_MIN=10.7 USE_HOME_DIR=1 CLANG=1
RELEASE=1 LOCALIZE=1 LANGUAGES=all LUA=1 OSXCROSS=1 LIBSDIR=../libs FRAMEWORKSDIR=../Frameworks
RELEASE=1 LOCALIZE=1 LANGUAGES=all OSXCROSS=1 LIBSDIR=../libs FRAMEWORKSDIR=../Frameworks
Make sure that `x86_64-apple-darwin15-clang++` is in `PATH` environment variable.
@ -287,7 +281,7 @@ Make sure that `x86_64-apple-darwin15-clang++` is in `PATH` environment variable
The Android build uses [Gradle](https://gradle.org/) to compile the java and native C++ code, and is based heavily off SDL's [Android project template](https://hg.libsdl.org/SDL/file/f1084c419f33/android-project). See the official SDL documentation [README-android.md](https://hg.libsdl.org/SDL/file/f1084c419f33/docs/README-android.md) for further information.
The Gradle project lives in the repository under `android/`. You can build it via the command line or open it in [Android Studio](https://developer.android.com/studio/). For simplicity, it only builds the SDL version with all features enabled, including tiles, sound, localization and lua.
The Gradle project lives in the repository under `android/`. You can build it via the command line or open it in [Android Studio](https://developer.android.com/studio/). For simplicity, it only builds the SDL version with all features enabled, including tiles, sound and localization.
### Dependencies
@ -297,7 +291,6 @@ The Gradle project lives in the repository under `android/`. You can build it vi
* SDL2_mixer (tested with 2.0.2)
* SDL2_image (tested with 2.0.3)
* libintl-lite (tested with a custom fork of libintl-lite 0.5)
* lua (tested with lua 5.1.5)
The Gradle build process automatically installs dependencies from [deps.zip](android/app/deps.zip).
@ -305,7 +298,7 @@ The Gradle build process automatically installs dependencies from [deps.zip](and
Install Linux dependencies. For a desktop Ubuntu installation:
sudo apt-get install lua5.2 openjdk-8-jdk-headless
sudo apt-get install openjdk-8-jdk-headless
Install Android SDK and NDK:
@ -358,7 +351,7 @@ To build Cataclysm on Mac you'll need [Command Line Tools for Xcode](https://dev
## Simple build using Homebrew
Homebrew installation will come with tiles, sound and lua suooprt enabled by default.
Homebrew installation will come with tiles and sound support enabled by default.
Once you have Homebrew installed, open Terminal and run one of the following commands.
@ -564,7 +557,7 @@ Open Terminal's preferences, turn on "Use bright colors for bold text" in "Prefe
## Visual Studio Guide
Visual Studio 2015 (or later) is required to build Cataclysm. If you use a later version of Visual Studio, you will need to [enable the Visual Studio 2015 (v140) platform toolset](https://developercommunity.visualstudio.com/content/problem/48806/cant-find-v140-in-visual-studio-2017.html). We created solution and project files in directory `msvc-full-features`. Because of the complexity and how troublesome defining every combination of build feature options are, in Visual Studio project we added all build features, including tiles, sound, localization and lua.
Visual Studio 2015 (or later) is required to build Cataclysm. If you use a later version of Visual Studio, you will need to [enable the Visual Studio 2015 (v140) platform toolset](https://developercommunity.visualstudio.com/content/problem/48806/cant-find-v140-in-visual-studio-2017.html). We created solution and project files in directory `msvc-full-features`. Because of the complexity and how troublesome defining every combination of build feature options are, in Visual Studio project we added all build features, including tiles, sound and localization.
### Dependencies
@ -572,12 +565,6 @@ We've prepared an archive containing all the headers and libraries required to b
Extract the 'WinDepend' folder and put it in the root folder of Cataclysm project. Run the "copy_dll_to_bin" batch file and then move the dll files from the bin folder into the root folder the Cataclysm project.
### Lua
The next thing you need to do is to install lua. Download the appropriate x86 or x64 lua from [http://lua-users.org/wiki/LuaBinaries](http://lua-users.org/wiki/LuaBinaries) or [http://dev.narc.ro/cataclysm/WinDepend-lua.zip](http://dev.narc.ro/cataclysm/WinDepend-lua.zip), and extract it to `C:\Windows\System32` or somewhere else on your path.
Once you have it installed, go to the project directory, then go to `src/lua`, and run `lua53 generate_bindings.lua catabindings.cpp`. This will generate the `catabindings.cpp` file which is necessary for compilation.
### Building
Building Cataclysm with Visual Studio is very simple. Just build it like a normal Visual C++ project. The process may takes a long period of time, so you'd better prepare a cup of coffee and some books in front of your computer :)
@ -613,7 +600,7 @@ If we want to compile with Tiles (SDL) we have to download a few libraries.
#### Bundled Libraries
The following archives were pre-bundled for convenience and reduction of head-aches, simply download and extract directly to the root directory of the CDDA source:
* `64-bit SDL \ Tiles \ Sound \ Lua \ Localization` http://dev.narc.ro/cataclysm/cdda-win64-codeblocks.7z
* `64-bit SDL \ Tiles \ Sound \ Localization` http://dev.narc.ro/cataclysm/cdda-win64-codeblocks.7z
#### Installing Tiles(SDL) libraries.
For the first 3 (`SDL2`, `SDL_ttf` and `SDL_image`) you want to extract the include and lib folders from the `i686-w64-mingw32` folders into your MinGW installation folder. (Recommended `C:\MinGW`). And the `SDL2_image.dll` and `SDL2_ttf.dll` into your cataclysm root folder.
@ -644,7 +631,7 @@ If you dont want localization you can change `LOCALIZE` to 0.
## Rough guide to building with only MSYS2
This is a tentative step-by-step guide to building your own CDDA with Tiles, Localization and Lua using only MSYS2. You may want to follow it if the MinGW guide above doesn't work for you or you just feel adventurous. Feedback is very much welcome in terms of issues and/or pull-requests.
This is a tentative step-by-step guide to building your own CDDA with Tiles and Localization using only MSYS2. You may want to follow it if the MinGW guide above doesn't work for you or you just feel adventurous. Feedback is very much welcome in terms of issues and/or pull-requests.
This guide assumes you're building on a x86_64 build of Windows. If not adjust the invocations appropriately. It has been tested and proven to work on Windows XP, Windows 7 and Windows 10. Your mileage may vary.
@ -702,7 +689,6 @@ pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image mingw-w64-x86_64-SDL
pacman -S mingw-w64-x86_64-ncurses
pacman -S mingw-w64-x86_64-pkg-config mingw-w64-x86_64-libwebp
pacman -S git make
pacman -S mingw-w64-x86_64-lua
```
#### 8. Close MSYS2 terminal and open MinGW-w64 Win64 Shell from Start menu and run:
@ -717,11 +703,9 @@ cd Cataclysm-DDA
#### 9. Compile your CDDA by running:
```bash
make MSYS2=1 RELEASE=1 TILES=1 LOCALIZE=1 SOUND=1 LUA=1 NATIVE=win64
make MSYS2=1 RELEASE=1 TILES=1 LOCALIZE=1 SOUND=1 NATIVE=win64
```
Note: You cannot naively use `-jX` to speed up your building process with `LUA=1`. You must first run `cd src/lua/ && lua generate_bindings.lua && cd ../..` if you want to use `-jX`. X should be the number of threads/cores your processor has.
That's it. You should get a `cataclysm-tiles.exe` binary in the same folder you've found the `Makefile` in. The make flags are the same as the ones described above. For instance, if you do not want to build with sound support, you can remove `SOUND=1`.
# BSDs

View File

@ -8,11 +8,22 @@
"USE_HOME_DIR=1",
"CLANG=1",
"CCACHE=1",
"RELEASE=1",
"LUA=1"
"RELEASE=1"
],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "make RELEASE LUA",
"name": "make RELEASE",
"working_dir": "${folder:${project_path:${file_path}}}"
},
{
"cmd":
[
"make",
"USE_HOME_DIR=1",
"CLANG=1",
"CCACHE=1"
],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "make",
"working_dir": "${folder:${project_path:${file_path}}}"
},
{
@ -22,24 +33,10 @@
"USE_HOME_DIR=1",
"CLANG=1",
"CCACHE=1",
"LUA=1"
],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "make LUA",
"working_dir": "${folder:${project_path:${file_path}}}"
},
{
"cmd":
[
"make",
"USE_HOME_DIR=1",
"CLANG=1",
"CCACHE=1",
"LUA=1",
"TILES=1"
],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "make TILES LUA",
"name": "make TILES",
"working_dir": "${folder:${project_path:${file_path}}}"
},
{
@ -49,12 +46,11 @@
"USE_HOME_DIR=1",
"CLANG=1",
"CCACHE=1",
"LUA=1",
"TILES=1",
"RELEASE=1"
],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "make RELEASE TILES LUA",
"name": "make RELEASE TILES",
"working_dir": "${folder:${project_path:${file_path}}}"
}
],

View File

@ -54,28 +54,6 @@
<Add directory="WinDepend/lib" />
</Linker>
</Target>
<Target title="Release (Lua)">
<Option output="CataclysmWin" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/ReleaseLua/" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-Os -O2" />
<Add option="-DLUA" />
<Add option="-DRELEASE=1" />
<Add directory="WinDepend/include" />
<Add directory="WinDepend/include/lua5.1" />
</Compiler>
<Linker>
<Add library="liblua5.1.a" />
<Add directory="WinDepend/lib" />
</Linker>
<ExtraCommands>
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 -v || echo &apos;lua5.1&apos; command not found!" />
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 generate_bindings.lua catabindings.cpp" />
<Mode after="always" />
</ExtraCommands>
</Target>
<Target title="Release (SDL, Sound)">
<Option output="Cataclysm-Tiles" prefix_auto="0" extension_auto="1" />
<Option object_output="obj/ReleaseSoundSDL/" />
@ -123,9 +101,9 @@
<Add directory="WinDepend/lib" />
</Linker>
</Target>
<Target title="Release (SDL, Loc, Lua, Sound)">
<Target title="Release (SDL, Loc, Sound)">
<Option output="Cataclysm-Tiles" prefix_auto="0" extension_auto="1" />
<Option object_output="obj/ReleaseLocalizedLuaSoundSDL/" />
<Option object_output="obj/ReleaseLocalizedSoundSDL/" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
@ -134,10 +112,8 @@
<Add option="-DTILES" />
<Add option="-DSDLTILES" />
<Add option="-DSDL_SOUND" />
<Add option="-DLUA" />
<Add option="-DRELEASE=1" />
<Add directory="WinDepend/include" />
<Add directory="WinDepend/include/lua5.1" />
<Add directory="WinDepend/include/SDL2" />
</Compiler>
<Linker>
@ -148,14 +124,8 @@
<Add library="libSDL2_ttf.dll.a" />
<Add library="libSDL2_image.dll.a" />
<Add library="libSDL2_mixer.dll.a" />
<Add library="liblua5.1.a" />
<Add directory="WinDepend/lib" />
</Linker>
<ExtraCommands>
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 -v || echo &apos;lua5.1&apos; command not found!" />
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 generate_bindings.lua catabindings.cpp" />
<Mode after="always" />
</ExtraCommands>
</Target>
<Target title="Debug">
<Option output="CataclysmWin" prefix_auto="1" extension_auto="1" />
@ -208,28 +178,6 @@
<Add directory="WinDepend/lib" />
</Linker>
</Target>
<Target title="Debug (Lua)">
<Option output="CataclysmWin" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/DebugLua/" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-pg -g" />
<Add option="-DLUA" />
<Add directory="WinDepend/include" />
<Add directory="WinDepend/include/lua5.1" />
</Compiler>
<Linker>
<Add option="-pg -lgmon" />
<Add library="liblua5.1.a" />
<Add directory="WinDepend/lib" />
</Linker>
<ExtraCommands>
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 -v || echo &apos;lua5.1&apos; command not found!" />
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 generate_bindings.lua catabindings.cpp" />
<Mode after="always" />
</ExtraCommands>
</Target>
<Target title="Debug (SDL, Sound)">
<Option output="Cataclysm-Tiles" prefix_auto="0" extension_auto="1" />
<Option object_output="obj/DebugSoundSDL/" />
@ -279,9 +227,9 @@
<Add directory="WinDepend/lib" />
</Linker>
</Target>
<Target title="Debug (SDL, Loc, Lua, Sound)">
<Target title="Debug (SDL, Loc, Sound)">
<Option output="Cataclysm-Tiles" prefix_auto="0" extension_auto="1" />
<Option object_output="obj/DebugLocalizedLuaSoundSDL/" />
<Option object_output="obj/DebugLocalizedSoundSDL/" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
@ -291,9 +239,7 @@
<Add option="-DTILES" />
<Add option="-DSDLTILES" />
<Add option="-DSDL_SOUND" />
<Add option="-DLUA" />
<Add directory="WinDepend/include" />
<Add directory="WinDepend/include/lua5.1" />
<Add directory="WinDepend/include/SDL2" />
</Compiler>
<Linker>
@ -305,14 +251,8 @@
<Add library="libSDL2_ttf.dll.a" />
<Add library="libSDL2_image.dll.a" />
<Add library="libSDL2_mixer.dll.a" />
<Add library="liblua5.1.a" />
<Add directory="WinDepend/lib" />
</Linker>
<ExtraCommands>
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 -v || echo &apos;lua5.1&apos; command not found!" />
<Add before="cmd /c cd src/lua &amp;&amp; lua5.1 generate_bindings.lua catabindings.cpp" />
<Mode after="always" />
</ExtraCommands>
</Target>
</Build>
<Compiler>

View File

@ -53,8 +53,6 @@
# make AUTO_BUILD_PREFIX=1
# Install to system directories.
# make install
# Enable lua support. Required only for full-fledged mods.
# make LUA=1
# Use user's XDG base directories for save files and configs.
# make USE_XDG_DIR=1
# Use user's home directory for save files.
@ -134,10 +132,6 @@ CHKJSON_BIN = $(BUILD_PREFIX)chkjson
BINDIST_DIR = $(BUILD_PREFIX)bindist
BUILD_DIR = $(CURDIR)
SRC_DIR = src
LUA_DIR = lua
LUASRC_DIR = $(SRC_DIR)/$(LUA_DIR)
# if you have LUAJIT installed, try make LUA_BINARY=luajit for extra speed
LUA_BINARY = lua
LOCALIZE = 1
ASTYLE_BINARY = astyle
@ -178,7 +172,7 @@ W32ODIR = $(BUILD_PREFIX)objwin
W32ODIRTILES = $(W32ODIR)/tiles
ifdef AUTO_BUILD_PREFIX
BUILD_PREFIX = $(if $(RELEASE),release-)$(if $(DEBUG_SYMBOLS),symbol-)$(if $(TILES),tiles-)$(if $(SOUND),sound-)$(if $(LOCALIZE),local-)$(if $(BACKTRACE),back-)$(if $(SANITIZE),sanitize-)$(if $(MAPSIZE),map-$(MAPSIZE)-)$(if $(LUA),lua-)$(if $(USE_XDG_DIR),xdg-)$(if $(USE_HOME_DIR),home-)$(if $(DYNAMIC_LINKING),dynamic-)$(if $(MSYS2),msys2-)
BUILD_PREFIX = $(if $(RELEASE),release-)$(if $(DEBUG_SYMBOLS),symbol-)$(if $(TILES),tiles-)$(if $(SOUND),sound-)$(if $(LOCALIZE),local-)$(if $(BACKTRACE),back-)$(if $(SANITIZE),sanitize-)$(if $(MAPSIZE),map-$(MAPSIZE)-)$(if $(USE_XDG_DIR),xdg-)$(if $(USE_HOME_DIR),home-)$(if $(DYNAMIC_LINKING),dynamic-)$(if $(MSYS2),msys2-)
export BUILD_PREFIX
endif
@ -499,41 +493,6 @@ ifeq ($(SOUND), 1)
CXXFLAGS += -DSDL_SOUND
endif
ifdef LUA
ifeq ($(TARGETSYSTEM),WINDOWS)
ifeq ($(MSYS2),1)
LUA_USE_PKGCONFIG := 1
else
# Windows expects to have lua unpacked at a specific location
LUA_LIBS := -llua
endif
else
LUA_USE_PKGCONFIG := 1
endif
ifdef OSXCROSS
LUA_LIBS = -L$(LIBSDIR)/lua/lib -llua -lm
LUA_CFLAGS = -I$(LIBSDIR)/lua/include
else
ifdef LUA_USE_PKGCONFIG
# On unix-like systems, use pkg-config to find lua
LUA_CANDIDATES = lua5.3 lua5.2 lua-5.3 lua-5.2 lua5.1 lua-5.1 lua $(LUA_BINARY)
LUA_FOUND = $(firstword $(foreach lua,$(LUA_CANDIDATES),\
$(shell if $(PKG_CONFIG) --silence-errors --exists $(lua); then echo $(lua);fi)))
LUA_PKG = $(if $(LUA_FOUND),$(LUA_FOUND),$(error "Lua not found by $(PKG_CONFIG), install it or make without 'LUA=1'"))
LUA_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs $(LUA_PKG))
LUA_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags $(LUA_PKG))
endif
endif
LDFLAGS += $(LUA_LIBS)
CXXFLAGS += $(LUA_CFLAGS)
CXXFLAGS += -DLUA
LUA_DEPENDENCIES = $(LUASRC_DIR)/catabindings.cpp
BINDIST_EXTRAS += $(LUA_DIR)
endif
ifdef SDL
TILES = 1
endif
@ -794,15 +753,13 @@ endif
$(BUILD_PREFIX)$(TARGET_NAME).a: $(OBJS)
$(AR) rcs $(BUILD_PREFIX)$(TARGET_NAME).a $(filter-out $(ODIR)/main.o $(ODIR)/messages.o,$(OBJS))
.PHONY: version json-verify
.PHONY: version
version:
@( VERSION_STRING=$(VERSION) ; \
[ -e ".git" ] && GITVERSION=$$( git describe --tags --always --dirty --match "[0-9A-Z]*.[0-9A-Z]*" ) && VERSION_STRING=$$GITVERSION ; \
[ -e "$(SRC_DIR)/version.h" ] && OLDVERSION=$$(grep VERSION $(SRC_DIR)/version.h|cut -d '"' -f2) ; \
if [ "x$$VERSION_STRING" != "x$$OLDVERSION" ]; then echo "#define VERSION \"$$VERSION_STRING\"" | tee $(SRC_DIR)/version.h ; fi \
)
json-verify:
$(LUA_BINARY) lua/json_verifier.lua
# Unconditionally create the object dir on every invocation.
$(shell mkdir -p $(ODIR))
@ -817,11 +774,6 @@ src/version.h: version
src/version.cpp: src/version.h
$(LUASRC_DIR)/catabindings.cpp: $(LUA_DIR)/class_definitions.lua $(LUASRC_DIR)/generate_bindings.lua
cd $(LUASRC_DIR) && $(LUA_BINARY) generate_bindings.lua
$(SRC_DIR)/catalua.cpp: $(LUA_DEPENDENCIES)
localization:
lang/compile_mo.sh $(LANGUAGES)
@ -836,7 +788,7 @@ clean: clean-tests
rm -rf *$(TILES_TARGET_NAME).exe *$(TARGET_NAME).exe *$(TARGET_NAME).a
rm -rf *obj *objwin
rm -rf *$(BINDIST_DIR) *cataclysmdda-*.tar.gz *cataclysmdda-*.zip
rm -f $(SRC_DIR)/version.h $(LUASRC_DIR)/catabindings.cpp
rm -f $(SRC_DIR)/version.h
rm -f $(CHKJSON_BIN)
distclean:
@ -872,12 +824,6 @@ ifdef TILES
endif
ifdef SOUND
cp -R --no-preserve=ownership data/sound $(DATA_PREFIX)
endif
ifdef LUA
mkdir -p $(DATA_PREFIX)/lua
install --mode=644 lua/autoexec.lua $(DATA_PREFIX)/lua
install --mode=644 lua/log.lua $(DATA_PREFIX)/lua
install --mode=644 lua/class_definitions.lua $(DATA_PREFIX)/lua
endif
install --mode=644 data/changelog.txt data/cataicon.ico data/fontdata.json \
LICENSE.txt -t $(DATA_PREFIX)
@ -909,12 +855,6 @@ ifdef TILES
endif
ifdef SOUND
cp -R --no-preserve=ownership data/sound $(DATA_PREFIX)
endif
ifdef LUA
mkdir -p $(DATA_PREFIX)/lua
install --mode=644 lua/autoexec.lua $(DATA_PREFIX)/lua
install --mode=644 lua/log.lua $(DATA_PREFIX)/lua
install --mode=644 lua/class_definitions.lua $(DATA_PREFIX)/lua
endif
install --mode=644 data/changelog.txt data/cataicon.ico data/fontdata.json \
LICENSE.txt -t $(DATA_PREFIX)
@ -975,11 +915,6 @@ ifeq ($(LOCALIZE), 1)
LIBINTL=$$($(CROSS)otool -L $(APPTARGET) | grep libintl | sed -n 's/\(.*\.dylib\).*/\1/p') && if [ -f $$LIBINTL ]; then cp $$LIBINTL $(APPRESOURCESDIR)/; fi; \
if [ ! -z "$$OSXCROSS" ]; then LIBINTL=$$(basename $$LIBINTL) && if [ ! -z "$$LIBINTL" ]; then cp $(LIBSDIR)/gettext/lib/$$LIBINTL $(APPRESOURCESDIR)/; fi; fi
endif
ifdef LUA
cp -R lua $(APPRESOURCESDIR)/
LIBLUA=$$($(CROSS)otool -L $(APPTARGET) | grep liblua | sed -n 's/\(.*\.dylib\).*/\1/p') && if [ -f $$LIBLUA ]; then cp $$LIBLUA $(APPRESOURCESDIR)/; fi; \
if [ ! -z "$$OSXCROSS" ]; then LIBLUA=$$(basename $$LIBLUA) && if [ ! -z "$$LIBLUA" ]; then cp $(LIBSDIR)/lua/lib/$$LIBLUA $(APPRESOURCESDIR)/; fi; fi
endif # ifdef LUA
ifdef TILES
ifdef SOUND
cp -R data/sound $(APPDATADIR)

View File

@ -33,7 +33,7 @@ RUN apt-fast -qq install --no-install-recommends gettext
RUN apt-fast -qq install --no-install-recommends libncurses5-dev libncursesw5-dev
# CDDA: libraries for tiles build
RUN apt-fast -qq install --no-install-recommends libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-mixer-dev libfreetype6-dev lua5.2 liblua5.2-dev
RUN apt-fast -qq install --no-install-recommends libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-mixer-dev libfreetype6-dev
# general packages for a much nicer time inside the container (we install psmisc for `killall`)
RUN apt-fast -qq install --no-install-recommends tree watch tmux fish colormake vim emacs git silversearcher-ag lsof psmisc dstat

View File

@ -32,6 +32,6 @@ fi
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew update
brew install sdl2 sdl2_image sdl2_ttf sdl2_mixer gettext ncurses lua
brew install sdl2 sdl2_image sdl2_ttf sdl2_mixer gettext ncurses
brew link --force gettext ncurses
fi

View File

@ -4,7 +4,7 @@
"ident": "StatsThroughSkills",
"name": "StatsThroughSkills",
"authors": [ "Ryan \"DeNarr\" Saige", "Kevin Granade" ],
"description": "Allows stats to raise naturally via skill progression.",
"description": "Allows stats to raise via skill progression.",
"category": "rebalance",
"dependencies": [ "dda" ]
},

View File

@ -1,194 +0,0 @@
File Layout
===========
- `src/catalua.cpp` - Core of the lua mod, glueing lua to the cataclysm C++ engine.
- `src/catalua.h` - Export of some public lua-related functions, do not use these outside #ifdef LUA
- `lua/autoexec.lua` - Lua-side initialization of important data structures(metatables for classes etc.)
- `lua/class_definitions.lua` - Definitions of classes and functions that bindings will be generated from
- `lua/generate_bindings.lua` - Custom binding generator for cataclysm, can generate class and function bindings.
- `lua/catabindings.cpp` - Output of generate_bindings.lua
- `data/main.lua` - Script that will be called on cataclysm startup. You can define functions here and call them in the lua debug interpreter.
Adding new functionality
========================
Generally, adding new functionality to lua is pretty straightforward. You have several options.
Manually defining a new lua function in catalua.cpp
---------------------------------------------------
This is the most straightforward, and also most difficult method. You basically define a new C function that does all the lua stack handling etc. manually, then register it in the lua function table. More information on this can be found at: http://www.lua.org/manual/5.1/manual.html#3
An example of such a function would be:
```c++
// items = game.items_at(x, y)
static int game_items_at(lua_State *L) {
int x = lua_tointeger(L, 1);
int y = lua_tointeger(L, 2);
std::vector<item>& items = g->m.i_at(x, y);
lua_createtable(L, items.size(), 0); // Preallocate enough space for all our items.
// Iterate over the monster list and insert each monster into our returned table.
for(int i=0; i < items.size(); i++) {
// The stack will look like this:
// 1 - t, table containing item
// 2 - k, index at which the next item will be inserted
// 3 - v, next item to insert
//
// lua_rawset then does t[k] = v and pops v and k from the stack
lua_pushnumber(L, i + 1);
item** item_userdata = (item**) lua_newuserdata(L, sizeof(item*));
*item_userdata = &(items[i]);
luah_setmetatable(L, "item_metatable");
lua_rawset(L, -3);
}
return 1; // 1 return values
}
static const struct luaL_Reg global_funcs [] = {
{"register_iuse", game_register_iuse},
{"items_at", game_items_at}, // Don't forget to register your function in here!
{NULL, NULL}
};
```
Defining a global function in catalua.cpp and registering it in lua/class_definitions.lua
---------------------------------------------------------------------------------------------
This method involves a bit more bureaucracy, but is much easier to pull off and less prone to errors. Unless you wish to do something that the binding generator can't handle, this method is recommended for functions.
First, define your function however you like in catalua.cpp
```c++
// game.remove_item(x, y, item)
void game_remove_item(int x, int y, item *it) {
std::vector<item>& items = g->m.i_at(x, y);
for(int i=0; i<items.size(); i++) {
if(&(items[i]) == it) {
items.erase(items.begin() + i);
}
}
}
```
Then register your function as a global function in lua/class_definitions.lua
```lua
global_functions = {
[...]
remove_item = {
cpp_name = "game_remove_item",
args = {"int", "int", "item"},
rval = nil
},
[...]
}
```
`cpp_name` refers to the function that should be called, this can also be something more complex like `g->add_msg`(works because g is a global). `args` is simply a list of the argument types, most common C++ types should work, as well as any classes that are wrapped by lua. `rval` is similarly the type of the return value, and since C++ has no multi-return, rval is not a list.
Of note is the special argument type `game`. If that type is found, the binding generator will not wrap that parameter, but instead always pass `g` to that argument. So say you have a function foo(game* g, int a), then you should set `args = {"game", "int"}`, and from lua you would simply call foo(5), the game parameter being implicitly set to `g`.
Wrapping class member variables
-------------------------------
Wrapping member variables is simply a matter of adding the relevant entries to the class definition in lua/class_definitions.lua.
```lua
classes = {
player = {
attributes = {
posx = {
type = "int",
writable = false
},
```
`type` works the same as for global functions, `writable` specifies whether a setter should be generated for this attribute.
Wrapping class member functions
-------------------------------
This process is nearly identical to wrapping global functions.
```lua
classes = {
player = {
[...]
functions = {
has_disease = {
args = { "string" },
rval = "bool"
},
```
As you can see, the way functions are defined here is identical to global functions. The only difference is that there's an implicit first argument that will always be present, `self`, which enables us to call `player:has_disease("foo")`.
Adding new classes
------------------
To add a new wrapped class, you have to do several things:
- Add a new entry to `classes` in lua/class_definitions.lua
- Add the relevant metatable to lua/autoexec.lua, e.g. `monster_metatable = generate_metatable("monster", classes.monster)`
Eventually, the latter should be automated, but right now it's necessary. Note that the class name should be the exact same in lua as in C++, otherwise the binding generator will fail. That limitation might be removed at some point.
Callbacks
---------
Following Lua-callbacks exist:
*game-related*:
- `on_savegame_loaded` runs when saved game is loaded;
- `on_weather_changed(weather_new, weather_old)` runs when weather is changed.
*calendar-related*:
- `on_turn_passed` runs once each turn (once per 6 seconds or 10 times per minute);
- `on_minute_passed` runs once per minute;
- `on_hour_passed` runs once per hour (at the beginning of the hour);
- `on_day_passed` runs once per day (at midnight);
- `on_year_passed` runs once per year (on first day of the year at midnight).
*player-related*:
- `on_player_skill_increased(player_id, source, skill_id, level)` runs whenever player skill is increased (previously known as `on_skill_increased`);
- `on_player_dodge(player_id, source, difficulty)` runs whenever player have dodged;
- `on_player_hit(player_id, source, body_part)` runs whenever player were hit;
- `on_player_hurt(player_id, source, disturb)` runs whenever player were hurt;
- `on_player_mutation_gain(player_id, mutation_id)` runs whenever player gains mutation;
- `on_player_mutation_loss(player_id, mutation_id)` runs whenever player loses mutation;
- `on_player_stat_change(player_id, stat_id, stat_value)` runs whenever player stats are changed;
- `on_player_effect_int_changes(player_id, effect_id, intensity, bodypart)` runs whenever intensity of effect on player has changed;
- `on_player_item_wear(player_id, item_id)` runs whenever player wears some clothes on;
- `on_player_item_takeoff(player_id, item_id)` runs whenever player takes some clothes off;
- `on_mission_assignment(player_id, mission_id)` runs whenever player is assigned to mission;
- `on_mission_finished(player_id, mission_id)` runs whenever player finishes the mission.
*player activity-related*:
- `on_activity_call_do_turn_started(act_id, player_id)` runs whenever player activity turn started;
- `on_activity_call_do_turn_finished(act_id, player_id)` runs whenever player activity turn ended;
- `on_activity_call_finish_started(act_id, player_id)` runs whenever player activity finish started;
- `on_activity_call_finish_finished(act_id, player_id)` runs whenever player activity finish ended.
__Note for `player_id`:__ Value of -1 (when game is not started) or 1 (when game is started) are used for player character, values bigger than 1 are used for npcs.
*mapgen-related*:
- `on_mapgen_finished(mapgen_generator_type, mapgen_terrain_type_id, mapgen_terrain_coordinates)` runs whenever `builtin`, `json` or `lua` mapgen is finished generating.
Some callbacks provide arguments which can be useful (see example mods).
Example mods
============
See `/doc/sample_mods` folder.

View File

@ -45,30 +45,26 @@
* 2.4.0.1 "amount"
* 2.4.0.2 "chance"
* 2.4.0.3 "repeat"
* 2.5 "lua":
* 2.6 specials:
* 2.6.0 "fields"
* 2.6.1 "npcs"
* 2.6.2 "signs"
* 2.6.3 "vendingmachines"
* 2.6.4 "toilets"
* 2.6.5 "gaspumps"
* 2.6.6 "items"
* 2.6.7 "monsters"
* 2.6.8 "vehicles"
* 2.6.9 "item"
* 2.6.10 "traps"
* 2.6.11 "furniture"
* 2.6.12 "terrain"
* 2.6.13 "monster"
* 2.6.14 "rubble"
* 2.6.15 "place_liquids"
* 2.6.16 "loot"
* 2.6.17 "sealed_item"
* 2.7 "rotation"
* 3 Method: lua
* 3.0 Tested functions
* 3.1 Example script inside overmap_terrain entry
* 2.5 specials:
* 2.5.0 "fields"
* 2.5.1 "npcs"
* 2.5.2 "signs"
* 2.5.3 "vendingmachines"
* 2.5.4 "toilets"
* 2.5.5 "gaspumps"
* 2.5.6 "items"
* 2.5.7 "monsters"
* 2.5.8 "vehicles"
* 2.5.9 "item"
* 2.5.10 "traps"
* 2.5.11 "furniture"
* 2.5.12 "terrain"
* 2.5.13 "monster"
* 2.5.14 "rubble"
* 2.5.15 "place_liquids"
* 2.5.16 "loot"
* 2.5.17 "sealed_item"
* 2.6 "rotation"
# 0 Intro
Note: You may wish to read over JSON_INFO.md beforehand.
@ -89,8 +85,6 @@ One doesn't (and shouldn't) need to create a new overmap_terrain for a new varia
While adding mapgen as a c++ function is one of the fastest (and the most versatile) ways to generate procedural terrain on the fly, this requires recompiling the game. For mods, one can instead define a mapgen function in:
* JSON: A set of json arrays and objects for defining stuff and things. Pros: Fastest to apply, mostly complete, supported by one third party map editor so far. Cons: Not a programming language; no if statements or variables means instances of a particular json mapgen definition will all be similar. Support was added for randomizing things, however.
* LUA: The same scripting language used in Garry's Mod, S.T.A.L.K.E.R, CIV5, etc. Pros: Powerful; as a full scripting language it allows for endless variety and options in theory. Cons: In theory; lua needs bindings for internal game functions, and this is a work in progress. Also, it will apply to the map slower than c++ or json.
## 1.1 Placement
Mapgen definitions can be added in 2 places:
### 1.1.0 Embedded
@ -111,7 +105,7 @@ As "mapgen": { ... } objects inside an existing overmap_terrain object ( see "s_
```
### 1.1.1 Standalone
As standalone { "type": "mapgen", ... } objects in a .json inside data/json. Below is the same fast food restaurant, along with one written lua (as part of unhealthy_dining_expansion_mod.json)
As standalone { "type": "mapgen", ... } objects in a .json inside data/json. Below is the same fast food restaurant.
```C++
[
{
@ -122,15 +116,6 @@ As standalone { "type": "mapgen", ... } objects in a .json inside data/json. Bel
"object": {
(see below)
}
},
{
"type": "mapgen",
"om_terrain": "s_restaurant_fast",
"weight": 500,
"method": "lua",
"script": {
(see below)
}
}
]
```
@ -147,25 +132,6 @@ The above example only illustrate the mapgen entries, not the actual format for
"object": { (more json here) }
```
-or-
> * "lua" - requires
```
"script": "-- string of lua code\n -- for newline use \n -- and escape \"quote\"s"
```
-or-
> "lua" - requires
```
"script": [
" -- array of lines ",
" -- etc ",
]
```
### 1.2.1 "om_terrain":
**required for standalone**
> Values:
@ -209,11 +175,10 @@ Default: 1000
## 1.3 How "overmap_terrain" variables affect mapgen
"id" is used to determine the required "om_terrain" id for standalone, -except- when the following variables are set in "overmap_terrain":
* "extras" - applies rare, random scenes after mapgen; helicopter crashes, etc
* "mondensity" - determines the default 'density' value for *"place_groups": [ { "monster": ...* (json) or *map:place_monster(..)* (lua)
* "mondensity" - determines the default 'density' value for *"place_groups": [ { "monster": ...* (json)
## 1.4 Limitations / TODO
* JSON: adding specific monster spawns are still WIP.
* lua: Just about *everything* is WIP; there are issues passing class pointers back and forth with the game that will be corrected eventually
* The old mapgen.cpp system involved *The Biggest "if / else if / else if / .." Statement Known to Man*(tm), and is only halfway converted to the "builtin" mapgen class. This means that while custom mapgen functions are allowed, the game will cheerfully forget the default if one is added.
* TODO: Add to this list.
@ -467,13 +432,7 @@ Example: "amount": [ 5, 15 ]
Example: [ 1, 3 ] - apply 1-3 times
#### 2.5 "lua"
**optional** lua script to run after all of the above finishes. See below.
> Value: "string"
Example: "lua": "if game.one_in(5000) then\n map:square_ter(\"t_lava\", 3, 3, 20, 20)\n game.add_msg(\"Oh noes micro volcano ;.;\")\n end"
# 2.6 specials
# 2.5 specials
**optional** Special map features that do more than just placing furniture / terrain.
Specials can be defined either via a mapping like the terrain / furniture mapping using the "rows" entry above or through their exact location by its coordinates.
@ -567,46 +526,46 @@ Same as
}
```
### 2.6.0 "fields"
### 2.5.0 "fields"
Places a field (see fields.h). Values:
- "field": (required, string) the field type (e.g. "fd_blood")
- "density": (optional, integer) field density. Defaults to 1. Possible values are 1, 2, or 3.
- "age": (optional, integer) field age. Defaults to 0.
### 2.6.1 "npcs"
### 2.5.1 "npcs"
Places a new NPC. Values:
- "class": (required, string) the npc class id, see data/json/npcs/npc.json or define your own npc class.
### 2.6.2 "signs"
### 2.5.2 "signs"
Places a sign (furniture f_sign) with a message written on it. Either "signage" or "snippet" must be defined. The message may include tags like \<full_name\>, \<given_name\>, and \<family_name\> that will insert a randomly generated name, or \<city\> that will insert the nearest city name. Values:
- "signage": (optional, string) the message that should appear on the sign.
- "snippet": (optional, string) a category of snippets that can appear on the sign.
### 2.6.3 "vendingmachines"
### 2.5.3 "vendingmachines"
Places a vending machine (furniture) and fills it with items. The machine can sometimes spawn as broken one. Values:
- "item_group": (optional, string) the item group that is used to create items inside the machine. It defaults to either "vending_food" or "vending_drink" (randomly chosen).
### 2.6.4 "toilets"
### 2.5.4 "toilets"
Places a toilet (furniture) and adds water to it. Values:
- "amount": (optional, integer or min/max array) the amount of water to be placed in the toilet.
### 2.6.5 "gaspumps"
### 2.5.5 "gaspumps"
Places a gas pump with gasoline (or sometimes diesel) in it. Values:
- "amount": (optional, integer or min/max array) the amount of fuel to be placed in the pump.
- "fuel": (optional, string: "gasoline" or "diesel") the type of fuel to be placed in the pump.
### 2.6.6 "items"
### 2.5.6 "items"
Places items from an item group. Values:
- "item": (required, string) the item group to use.
- "chance": (optional, integer or min/max array) x in 100 chance that a loop will continue to spawn items from the group (which itself may spawn multiple items or not depending on its type, see `ITEM_SPAWN.md`), unless the chance is 100, in which case it will trigger the item group spawn exactly 1 time (see `map::place_items`).
### 2.6.7 "monsters"
### 2.5.7 "monsters"
Places a monster spawn point, the actual monsters are spawned when the map is loaded. Values:
- "monster": (required, string) a monster group id, when the map is loaded, a random monsters from that group are spawned.
- "density": (optional, float) if defined, it overrides the default monster density at the location (monster density is bigger towards the city centers) (see `map::place_spawns`).
- "chance": (optional, integer or min/max array) one in x chance of spawn point being created (see `map::place_spawns`).
### 2.6.8 "vehicles"
### 2.5.8 "vehicles"
Places a vehicle. Values:
- "vehicle": (required, string) type of the vehicle or id of a vehicle group.
- "chance": (optional, integer or min/max array) x in 100 chance of the vehicle spawning at all. The default is 1 (which means 1% probability that the vehicle spawns, you probably want something larger).
@ -614,7 +573,7 @@ Places a vehicle. Values:
- "fuel": (optional, integer) the fuel status. Default is -1 which makes the tanks 1-7% full. Positive values are interpreted as percentage of the vehicles tanks to fill (e.g. 100 means completely full).
- "status": (optional, integer) default is -1 (light damage), a value of 0 means perfect condition, 1 means heavily damaged.
### 2.6.9 "item"
### 2.5.9 "item"
Places a specific item. Values:
- "item": (required, string) the item type id of the new item.
- "chance": (optional, integer or min/max array) one in x chance that the item will spawn. Default is 1, meaning it will always spawn.
@ -630,25 +589,25 @@ To use this type with explicit coordinates use the name "place_item" (this if fo
]
```
### 2.6.10 "traps"
### 2.5.10 "traps"
Places a trap. Values:
- "trap": (required, string) type id of the trap (e.g. tr_beartrap).
### 2.6.11 "furniture"
### 2.5.11 "furniture"
Places furniture. Values:
- "furn": (required, string) type id of the furniture (e.g. f_chair).
### 2.6.12 "terrain"
### 2.5.12 "terrain"
Places terrain. Values:
- "ter": (required, string) type id of the terrain (e.g. t_floor).
### 2.6.13 "monster"
### 2.5.13 "monster"
Places a specific monster. Values:
- "monster": (required, string) type id of the monster (e.g. mon_zombie).
- "friendly": (optional, bool) whether the monster is friendly, default is false.
- "name": (optional, string) a name for that monster, optional, default is to create an unnamed monster.
### 2.6.14 "rubble"
### 2.5.14 "rubble"
Creates rubble and bashes existing terrain (this step is applied last, after other things like furniture/terrain have been set). Creating rubble invokes the bashing function that can destroy terrain and cause structures to collapse.
Values:
- "rubble_type": (optional, furniture id, default: f_rubble) the type of the created rubble.
@ -663,7 +622,7 @@ To use this type with explicit coordinates use the name "place_rubble" (no plura
]
```
### 2.6.15 "place_liquids"
### 2.5.15 "place_liquids"
Creates a liquid item at the specified location. Liquids can't currently be picked up (except for gasoline in tanks or pumps), but can be used to add flavor to mapgen.
Values:
- "liquid": (required, item id) the item (a liquid)
@ -680,7 +639,7 @@ Example for dropping a default amount of gasoline (200 units) on the ground (eit
],
```
### 2.6.16 "loot"
### 2.5.16 "loot"
Places item(s) from an item group, or an individual item. An important distinction between this and `place_item` and `item`/`items` is that `loot` can spawn a single item from a distribution group (without looping). It can also spawn a matching magazine and ammo for guns.
- Either `group` or `item` must be specified, but not both
- "group": (string) the item group to use (see `ITEM_SPAWN.md` for notes on collection vs distribution groups)
@ -689,7 +648,7 @@ Places item(s) from an item group, or an individual item. An important distincti
- "ammo": (optional, integer) x in 100 chance of item(s) spawning with the default amount of ammo. Defaults to 0.
- "magazine": (optional, integer) x in 100 chance of item(s) spawning with the default magazine. Defaults to 0.
### 2.6.17 "sealed_item"
### 2.5.17 "sealed_item"
Places an item or item group inside furniture that has special handling for items.
This is intended for furniture such as `f_plant_harvest` with the `PLANT` flag, because placing items on such furniture via the other means will not work (since they have the `NOITEM` FLAG).
@ -716,49 +675,3 @@ Rotates the generated map after all the other mapgen stuff has been done. The va
"rotation": [ 0, 3 ],
```
Values are 90° steps.
## 3 Method: lua
Lua is very WIP but supports the following map class functions:
# 3.0 Tested functions
```
ter_set(x, y, "ter_id")
furn_set(x, y, "furn_id")
line_ter("ter_id", x, y, x2, y2)
line_furn("furn_id", x, y, x2, y2)
fill_background("ter_id")
square_ter("ter_id", x, y, x2, y2)
square_furn("furn_id", x, y, x2, y2)
rough_circle("ter_id", x, y, radius)
place_items("itype", chance, x, y, x2, y2, bool ongrass, int chance)
```
## 3.1 Example script inside overmap_terrain entry
```
{ "method": "lua", "weight": 500, "comment": "Inlined, easier to edit", "script": [
"-- tertype, turn = ...",
"function g_or_d_or_p()",
" if game.one_in(6) then",
" return \"t_water_sh\"",
" end",
" if game.rng(1,4) == 1 then",
" return \"t_grass\"",
" end",
" return \"t_dirt\"",
"end",
"x = 0",
"while x < 24 do",
" y = 0",
" while y < 24 do",
" map:ter_set(x, y, g_or_d_or_p())",
" y = y + 1",
" end",
" x = x + 1",
"end",
"map:place_items(\"field\", 60, 0, 0, 23, 23, 1, turn)",
"--map:square_furn(\"f_mutpoppy\", 10,10,13,13)",
"--map:line_ter(\"t_paper\", 1, 1, 22, 22)",
"game.add_msg(\"generated oter=\"..tertype..\" turn=\"..turn)"
]
},
```
Ideally there will also be a way to load a .lua file directly from the same directory as its mapgen definition

View File

@ -1,17 +0,0 @@
local milk = game.get_comestible_type("milk")
-- if milk spoils in less than a day, make it last at least a day
if milk.spoils_in < 24 then
milk.spoils_in = 24
end
-- set the volume to half, just to test that inheritance really works
milk.volume = milk.volume / 2
-- access a few other things to test the wrappers
local pipe_rifle = game.get_gun_type("rifle_22")
pipe_rifle.ammo = "battery" -- hell yeah
local welder = game.get_tool_type("welder")
welder.max_charges = 1000 -- why not?
welder.def_charges = 500

View File

@ -1,9 +0,0 @@
{
"type": "MOD_INFO",
"mod-type": "SUPPLEMENTAL",
"ident": "DrinkableMilk",
"name": "Drinkable Milk",
"description": "Makes it so milk doesn't spoil instantly upon arriving in the cataclysm.",
"path": ""
}

View File

@ -1,39 +0,0 @@
[
{
"type" : "MONSTER",
"id" : "mon_elf",
"name": "elf",
"species":"ZOMBIE",
"symbol":"E",
"color":"white",
"size":"MEDIUM",
"material":"flesh",
"diff":0,
"aggression":50,
"morale":100,
"speed":120,
"melee_skill":10,
"melee_dice":4,
"melee_dice_sides":6,
"melee_cut":12,
"dodge":10,
"armor_bash":2,
"armor_cut":2,
"item_chance":0,
"luminance":0,
"hp":50,
"special_freq":0,
"death_function":"NORMAL",
"special_attack":"NONE",
"description":"This is an elf. Nobody knows what an elf is doing in the cataclysm.",
"flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "VIS40"],
"anger_triggers":["PLAYER_CLOSE", "HURT"]
},{
"type":"monstergroup",
"name" : "GROUP_ELF",
"default" : "mon_elf",
"monsters" : [
{ "monster" : "mon_elf", "freq" : 300, "cost_multiplier" : 0 }
]
}
]

View File

@ -1,21 +0,0 @@
local MOD = {}
mods["ElfMod"] = MOD
function MOD.on_day_passed()
game.add_msg("A day has passed! New elves are spawning!")
-- spawn monster group in top left corner
local overmap = g:get_cur_om()
local newgroup = game.create_monster_group(overmap, "GROUP_ELF", 5, 5, 0, 10, 2000)
newgroup.horde = true
-- Elves multiply
for _, mongroup in pairs(game.monstergroups(overmap)) do
if mongroup.type == "GROUP_ELF" then
mongroup.population = mongroup.population + 1
game.add_msg("The elves multiply, oh noes! Current elf count: "..tostring(mongroup.population))
end
end
end

View File

@ -1,9 +0,0 @@
{
"type": "MOD_INFO",
"mod-type": "SUPPLEMENTAL",
"ident": "Elf",
"name": "Elf Mod",
"description": "Elves spawn randomly in the cataclysm.",
"path": ""
}

View File

@ -1,8 +0,0 @@
{
"type": "MOD_INFO",
"mod-type": "SUPPLEMENTAL",
"ident": "Manhack_Lua",
"name": "Manhack Lua",
"description": "Manhack IUSE implemented in lua.",
"path": ""
}

View File

@ -1,31 +0,0 @@
function pick_from_list(list)
local rand = math.random(1, #list)
return list[rand]
end
function iuse_manhack(item, active)
-- find a bunch of locations where we might spawn the manhack
local locs = {}
for delta_x = -1, 1 do
for delta_y = -1, 1 do
local point = player:pos()
point.x = point.x + delta_x
point.y = point.y + delta_y
if g:is_empty(point) then
table.insert(locs, point )
end
end
end
if #locs == 0 then
game.add_msg("You can't use this here!")
return 0 -- 0 charges used
end
-- okay, we got a bunch of locations, pick one and spawn a manhack there
local loc = pick_from_list(locs)
local monster = game.create_monster(mtype_id("mon_manhack"), loc)
return 1 -- 1 charge used
end
game.register_iuse("IUSE_LUA_MANHACK", iuse_manhack)

View File

@ -1,24 +0,0 @@
[
{
"id": "bot_manhack_lua",
"type": "TOOL",
"symbol": ",",
"color": "light_green",
"name": "inactive manhack(lua)",
"description": "This is an inactive manhack. Manhacks are fist-sized robots that fly through the air. They are covered with whirring blades and attack by throwing themselves against their target. Use this item to activate the manhack.",
"price": 60000,
"material": ["aluminum", "plastic"],
"weight": 300,
"volume": 1,
"bashing": 6,
"cutting": 6,
"to_hit": -3,
"max_charges": 0,
"initial_charges": 0,
"charges_per_use": 0,
"turns_per_charge": 0,
"ammo": "NULL",
"revert_to": "null",
"use_action": "IUSE_LUA_MANHACK"
}
]

View File

@ -1,17 +0,0 @@
[
{
"id":"test_ptakeoff",
"type": "TOOL",
"symbol": "?",
"color": "white",
"name": "Test_Takeoff",
"category": "ZZZ",
"description": "Activate this to remove whatever item is just below your wielded item.",
"bashing": 1,
"price": 1,
"material": ["plastic"],
"weight": 1,
"volume": 1,
"use_action": ["PLAYERTAKEOFF"]
}
]

View File

@ -1,8 +0,0 @@
{
"type": "MOD_INFO",
"mod-type": "SUPPLEMENTAL",
"ident": "LuaPlayerTakeoff",
"name": "Lua Test: Player:takeoff",
"description": "This makes an item named Test_Takeoff that calls player:takeoff(player:iat(-2)) and removes a single item just below the wielded weapon. Not using -1 because that is wielded weapon slot, and this won't work for that slot.",
"path": ""
}

View File

@ -1,14 +0,0 @@
local MOD = {}
mods["LUAPlayerTakeoff"] = MOD
function playertakeoff()
if (player:i_at(-2):display_name() ~= "none") then
game.add_msg("Taking off: "..player:i_at(-2):display_name())
player:takeoff(player:i_at(-2))
else
game.add_msg("Nothing in that slot!")
end
end
game.register_iuse("PLAYERTAKEOFF", playertakeoff)

View File

@ -1,16 +0,0 @@
local MOD = {}
mods["lua_test_activity"] = MOD
function message(...)
local s = string.format(...)
game.add_msg(s)
end
function MOD.on_minute_passed()
local act = player.activity
if not act:is_null() then
-- Show your current activity
message("activity_id: %s", act:id():str())
message("moves_left: %d", act.moves_left)
end
end

View File

@ -1,10 +0,0 @@
[
{
"type": "MOD_INFO",
"ident": "lua_test_activity",
"name": "Lua sample code: Player activity",
"description": "Sample code of player activity.",
"category": "content",
"dependencies": ["dda"]
}
]

View File

@ -1,7 +0,0 @@
[
{
"type": "item_action",
"id": "TEST_BIONICS_LIST",
"name": "Show your bionics"
}
]

View File

@ -1,12 +0,0 @@
[
{
"id": "test_bionics_list",
"type": "TOOL",
"symbol": "?",
"color": "white",
"name": "Bionics List(LUA)",
"description": "Show your bionics list.",
"material": ["plastic"],
"use_action": ["TEST_BIONICS_LIST"]
}
]

View File

@ -1,10 +0,0 @@
[
{
"type": "MOD_INFO",
"ident": "lua_test_bionics",
"name": "Lua sample code: Bionics",
"description": "Sample code of bionics related functions.",
"category": "content",
"dependencies": ["dda"]
}
]

View File

@ -1,27 +0,0 @@
function message(...)
local s = string.format(...)
game.add_msg(s)
end
function iuse_test_bionics_list()
local num = player:num_bionics()
if num == 0 then
message("You installed no bionics.")
else
local i = 0
while i < num do
-- Get bionic reference
local bio = player:bionic_at_index(i)
-- Get bionic_data reference (use obj() function of bionic_id class)
local bio_data = bio.id:obj()
local color = "white"
if bio_data.activated then
color = "green"
end
message("bionics[%d]: <color_%s>%s</color>", i, color, bio_data.name)
i = i + 1
end
end
end
game.register_iuse("TEST_BIONICS_LIST", iuse_test_bionics_list)

View File

@ -1,142 +0,0 @@
local MOD = {
id = "lua_test_callback",
version = "2019-01-06"
}
mods[MOD.id] = MOD
MOD.MessageWithLog = function(s)
if log.message then
log.message(s)
end
if game.add_msg then
game.add_msg(s)
end
end
MOD.on_game_loaded = function()
MOD.DisplayCallbackMessages("on_game_loaded")
end
MOD.on_savegame_loaded = function()
MOD.DisplayCallbackMessages("on_savegame_loaded")
end
MOD.on_new_player_created = function(player_id)
MOD.DisplayCallbackMessages("on_new_player_created", player_id)
end
MOD.on_turn_passed = function()
MOD.DisplayCallbackMessages("on_turn_passed")
end
MOD.on_second_passed = function()
MOD.DisplayCallbackMessages("on_second_passed")
end
MOD.on_minute_passed = function()
MOD.DisplayCallbackMessages("on_minute_passed")
end
MOD.on_hour_passed = function()
MOD.DisplayCallbackMessages("on_hour_passed")
end
MOD.on_day_passed = function()
MOD.DisplayCallbackMessages("on_day_passed")
end
MOD.on_year_passed = function()
MOD.DisplayCallbackMessages("on_year_passed")
end
MOD.on_weather_changed = function(weather_new, weather_old)
MOD.DisplayCallbackMessages("on_weather_changed", weather_new, weather_old)
end
MOD.on_player_skill_increased = function(player_id, source, skill_id, level)
MOD.DisplayCallbackMessages("on_player_skill_increased", player_id, source, skill_id, level)
end
MOD.on_player_dodge = function(player_id, source, difficulty)
MOD.DisplayCallbackMessages("on_player_dodge", player_id, source, difficulty)
end
MOD.on_player_hit = function(player_id, source, bodypart) --[[dealt_projectile_attack]]--
MOD.DisplayCallbackMessages("on_player_hit", player_id, source, bodypart)
end
MOD.on_player_hurt = function(player_id, source, disturb)
MOD.DisplayCallbackMessages("on_player_hurt", player_id, source, disturb)
end
MOD.on_player_mutation_gain = function(player_id, mutation_id)
MOD.DisplayCallbackMessages("on_player_mutation_gain", player_id, mutation_id)
end
MOD.on_player_mutation_loss = function(player_id, mutation_id)
MOD.DisplayCallbackMessages("on_player_mutation_loss", player_id, mutation_id)
end
MOD.on_player_stat_change = function(player_id, stat_id, stat_value)
MOD.DisplayCallbackMessages("on_player_stat_change", player_id, stat_id, stat_value)
end
MOD.on_player_item_wear = function(player_id, item_id)
MOD.DisplayCallbackMessages("on_player_item_wear", player_id, item_id)
end
MOD.on_player_item_takeoff = function(player_id, item_id)
MOD.DisplayCallbackMessages("on_player_item_takeoff", player_id, item_id)
end
MOD.on_player_effect_int_changes = function(player_id, effect_id, intensity, bodypart)
MOD.DisplayCallbackMessages("on_player_effect_int_change", player_id, effect_id, intensity, bodypart)
end
MOD.on_player_mission_assignment = function(player_id, mission_id)
MOD.DisplayCallbackMessages("on_player_mission_assignment", player_id, mission_id)
end
MOD.on_player_mission_finished = function(player_id, mission_id)
MOD.DisplayCallbackMessages("on_player_mission_finished", player_id, mission_id)
end
MOD.on_activity_call_do_turn_started = function(act_id, player_id)
MOD.DisplayCallbackMessages("on_activity_call_do_turn_started", act_id, player_id)
end
MOD.on_activity_call_do_turn_finished = function(act_id, player_id)
MOD.DisplayCallbackMessages("on_activity_call_do_turn_finished", act_id, player_id)
end
MOD.on_activity_call_finish_started = function(act_id, player_id)
MOD.DisplayCallbackMessages("on_activity_call_finish_started", act_id, player_id)
end
MOD.on_activity_call_finish_finished = function(act_id, player_id)
MOD.DisplayCallbackMessages("on_activity_call_finish_finished", act_id, player_id)
end
MOD.on_mapgen_finished = function(mapgen_type, mapgen_id, mapgen_coord)
MOD.DisplayCallbackMessages("on_mapgen_finished", mapgen_type, mapgen_id, mapgen_coord)
end
MOD.DisplayCallbackMessages = function(callback_name, ...)
MOD.MessageWithLog ("Callback name is <color_cyan>"..tostring(callback_name).."</color>")
local callback_args = {...}
local callback_args_count = #callback_args
if callback_args_count > 0 then
MOD.MessageWithLog ("Callback data length is <color_blue>"..tostring(callback_args_count).."</color>")
for i = 1, callback_args_count do
local callback_arg_name = "callback_arg_"..i
local callback_arg_data = callback_args[i]
local callback_arg_type = type(callback_arg_data)
MOD.MessageWithLog ("Callback arg <color_yellow>"..tostring(callback_arg_name).."</color> is <color_green>"..tostring(callback_arg_data).."</color> of type <color_pink>"..tostring(callback_arg_type).."</color>")
end
else
MOD.MessageWithLog ("Callback args are <color_red>empty</color>")
end
end
MOD.on_game_loaded()

View File

@ -1,11 +0,0 @@
[
{
"type": "MOD_INFO",
"ident": "lua_test_callback",
"name": "Dark Days Ahead: Lua Test: Callback",
"description": "Test of all callback Lua functions.",
"category": "content",
"dependencies": [ "dda" ],
"//": "Put mod into `./data/mods/lua_test_callback/` folder"
}
]

View File

@ -1,4 +0,0 @@
local MOD = {
id = "lua_test_callback",
version = "2019-01-06"
}

View File

@ -1,7 +0,0 @@
[
{
"type": "item_action",
"id": "TEST_GAIN_MORALE",
"name": "Gain morale! (+100)"
}
]

View File

@ -1,12 +0,0 @@
[
{
"id": "test_gain_morale",
"type": "TOOL",
"symbol": "?",
"color": "white",
"name": "Gain morale(LUA)",
"description": "You gain big morale boost.",
"material": ["plastic"],
"use_action": ["TEST_GAIN_MORALE"]
}
]

View File

@ -1,10 +0,0 @@
[
{
"type": "MOD_INFO",
"ident": "lua_test_morale",
"name": "Lua sample code: Morale",
"description": "Sample code of morale related functions.",
"category": "content",
"dependencies": ["dda"]
}
]

View File

@ -1,7 +0,0 @@
[
{
"id": "morale_test",
"type": "morale_type",
"text": "Gain big morale boost!"
}
]

View File

@ -1,34 +0,0 @@
function message(...)
local s = string.format(...)
game.add_msg(s)
end
function iuse_test_gain_morale()
-- Create select menu
local um = game.create_uimenu()
um.title = "Gain morale menu"
um:addentry("Gain morale")
um:addentry("Remove morale")
um:addentry("Cancel")
-- Wait for player selection
um:query(true)
if um.selected == 0 then
-- "Gain morale" is selected
if player:has_morale(morale_type("morale_test")) == 0 then
-- Add morale boost (+100/10 min.)
player:add_morale(morale_type("morale_test"), 100, 100, MINUTES(10))
message("You gained big morale boost!")
else
message("You already gained morale boost.")
end
elseif um.selected == 1 then
-- "Remove morale" is selected
player:rem_morale(morale_type("morale_test"))
message("Your morale boost is finished.")
end
return 0
end
game.register_iuse("TEST_GAIN_MORALE", iuse_test_gain_morale)

View File

@ -1,7 +0,0 @@
[
{
"type": "item_action",
"id": "TEST_NPC",
"name": "Test NPC function"
}
]

View File

@ -1,12 +0,0 @@
[
{
"id": "test_npc",
"type": "TOOL",
"symbol": "?",
"color": "white",
"name": "NPC test(LUA)",
"description": "You check NPC's opinion.",
"material": ["plastic"],
"use_action": ["TEST_NPC"]
}
]

View File

@ -1,12 +0,0 @@
[
{
"type": "MOD_INFO",
"ident": "lua_test_npc",
"name": "Lua sample code: NPC",
"authors": [ "LISP" ],
"maintainers": [ "LISP" ],
"description": "Sample code of NPC related functions.",
"category": "misc_additions",
"dependencies": [ "dda" ]
}
]

View File

@ -1,76 +0,0 @@
function message(...)
local s = string.format(...)
game.add_msg(s)
end
function iuse_test_npc(item, active)
local um
local feature
-- Create select menu
um = game.create_uimenu()
um.title = "What do you do?"
um:addentry("Check NPC's opinion")
um:addentry("Make NPC angry")
um:addentry("Make NPC your follower")
um:addentry("Cancel")
-- Wait for player selection
um:query(true)
if um.selected == 3 then
-- Canceled
return 0
end
feature = um.selected
local p = player:pos()
local delta_x
local delta_y
local npc_num = 0
local npcs = {}
local npc
-- Create select menu
um = game.create_uimenu()
um.title = "Select NPC"
-- Search NPCs around you
for delta_x = -1, 1 do
for delta_y = -1, 1 do
local tp = tripoint(p.x + delta_x, p.y + delta_y, p.z)
npc = game.get_npc_at(tp)
if npc then
um:addentry(npc:get_name())
table.insert(npcs, npc)
npc_num = npc_num + 1
end
end
end
um:addentry("Cancel")
-- Wait for player selection
um:query(true)
if um.selected == npc_num then
-- Canceled
return 0
end
local target = npcs[um.selected + 1]
if feature == 0 then
local opinion = target.op_of_u
message("Trust: %d", opinion.trust)
message("Fear: %d", opinion.fear)
message("Value: %d", opinion.value)
message("Anger: %d", opinion.anger)
message("Owed: %d", opinion.owed)
elseif feature == 1 then
target:make_angry()
message("%s gets angry!", target:disp_name())
elseif feature == 2 then
target:set_attitude("NPCATT_FOLLOW")
message("%s is your follower now.", target:disp_name())
end
return 0
end
game.register_iuse("TEST_NPC", iuse_test_npc)

View File

@ -1,9 +0,0 @@
[
{
"type": "MOD_INFO",
"ident": "MonsterSpecialAttackTest",
"name": "Lua Test: Monster Special Attack",
"description": "This adds Lua-coded special attack. Zombies say hello.",
"path": ""
}
]

View File

@ -1,45 +0,0 @@
[
{
"id": "mon_zombie_test",
"type": "MONSTER",
"name": "zombie(lua)",
"description": "A human body, swaying as it moves, an unstoppable rage is visible in its oily black eyes.",
"default_faction": "zombie",
"categories": [ "CLASSIC" ],
"species": [ "ZOMBIE", "HUMAN" ],
"diff": 3,
"size": "MEDIUM",
"hp": 80,
"speed": 70,
"material": [ "flesh" ],
"symbol": "Z",
"color": "light_green",
"aggression": 100,
"morale": 100,
"melee_skill": 4,
"melee_dice": 2,
"melee_dice_sides": 3,
"melee_cut": 0,
"vision_night": 3,
"special_attacks": [ [ "SAY_HELLO", 1 ] ],
"death_drops": "default_zombie_death_drops",
"death_function": [ "NORMAL" ],
"burn_into": "mon_zombie_scorched",
"upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_UPGRADE" },
"flags": [
"SEES",
"HEARS",
"SMELLS",
"STUMBLES",
"WARM",
"BASHES",
"GROUP_BASH",
"POISON",
"BLEED",
"NO_BREATHE",
"REVIVES",
"BONES",
"PUSH_MON"
]
}
]

View File

@ -1,10 +0,0 @@
local MOD = {}
mods["MonsterSpecialAttackTest"] = MOD
function say_hello(monster)
game.add_msg(monster:disp_name()..": Hello!")
return true;
end
game.register_monattack("SAY_HELLO", say_hello)

View File

@ -1,15 +0,0 @@
function blacklist_item_from_spawns(id)
local all_groups = game.get_item_groups()
for _, group_id in ipairs(all_groups) do
-- a chance of 0 removes the item
game.add_item_to_group(group_id, id, 0)
end
end
blacklist_item_from_spawns("jam_strawberries")
blacklist_item_from_spawns("jam_blueberries")
-- also remove rocks from spawn, since it's rather hard to test whether
-- jams spawn or not ;) rock recipes should still exist though, leading
-- to hilarity
blacklist_item_from_spawns("rock")

View File

@ -1,9 +0,0 @@
{
"type": "MOD_INFO",
"mod-type": "SUPPLEMENTAL",
"ident": "NoJamSpawn",
"name": "No Jam Spawn",
"description": "Prevents jam from spawning, but you can still make it.",
"path": ""
}

View File

@ -1,24 +0,0 @@
# LUA files + test
cmake_minimum_required(VERSION 2.8.12)
SET(CATACLYSM_DDA_LUA_SOURCES
${CMAKE_SOURCE_DIR}/lua/class_definitions.lua
${CMAKE_SOURCE_DIR}/lua/autoexec.lua
)
# test chain
add_custom_target (
check_lua
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_custom_command (
TARGET check_lua
PRE_BUILD
COMMAND ${LUA_BINARY} lua/json_verifier.lua
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
IF(RELEASE)
install(FILES ${CATACLYSM_DDA_LUA_SOURCES} DESTINATION ${DATA_PREFIX}/lua)
ENDIF(RELEASE)

View File

@ -1,93 +0,0 @@
--dofile("./class_definitions.lua")
package.path = package.path .. ";./lua/?.lua" --Windows/Linux
package.path = package.path .. ";/usr/share/cataclysm-dda/lua/?.lua" --Linux(via make install)
package.path = package.path .. ";/storage/emulated/0/Android/data/com.cleverraven.cataclysmdda/files/lua/?.lua" --Android
package.path = package.path .. ";/storage/sdcard/Android/data/com.cleverraven.cataclysmdda/files/lua/?.lua" --Android (SD Card)
package.path = package.path .. ";/storage/sdcard0/Android/data/com.cleverraven.cataclysmdda/files/lua/?.lua" --Android (SD Card 0)
package.path = package.path .. ";/storage/sdcard1/Android/data/com.cleverraven.cataclysmdda/files/lua/?.lua" --Android (SD Card 1)
log = require("log")
log.init("./config/lua-log.log")
outdated_metatable = {
__index = function(userdata, key)
error("Attempt to access outdated gamedata.")
end,
__newindex = function(table, key, value)
error("Attempt to access outdated gamedata.")
end
}
-- table containing our mods
mods = { }
function mod_callback(callback_name, ...)
rval = nil
for modname, mod_instance in pairs(mods) do
if type(mod_instance[callback_name]) == "function" then
rval = mod_instance[callback_name](...)
end
end
return rval
end
function resolve_name(name)
local a = _G
for key in string.gmatch(name, "([^%.]+)(%.?)") do
if a[key] then
a = a[key]
else
return nil
end
end
return a
end
function function_exists(name)
return type(resolve_name(name)) == 'function'
end
function table_length(name)
local length = 0
if (name ~= nil) then
for _ in pairs(name) do
length = length + 1
end
end
return length
end
-- Constructs `time_duration` with given `int` value (which is number of turns).
function TURNS(turns)
if( function_exists( "game.get_time_duration" ) ) then
return game.get_time_duration( turns )
else
return nil
end
end
function MINUTES(turns)
if( function_exists( "game.get_time_duration" ) ) then
return game.get_time_duration( turns * 10 )
else
return nil
end
end
function HOURS(turns)
if( function_exists( "game.get_time_duration" ) ) then
return game.get_time_duration( turns * 10 * 60 )
else
return nil
end
end
function DAYS(turns)
if( function_exists( "game.get_time_duration" ) ) then
return game.get_time_duration( turns * 10 * 60 * 24 )
else
return nil
end
end

File diff suppressed because it is too large Load Diff

View File

@ -1,843 +0,0 @@
-- Module options:
local always_try_using_lpeg = true
local register_global_module_table = false
local global_module_name = 'json'
--[==[
David Kolf's JSON module for Lua 5.1/5.2
========================================
*Version 2.4*
In the default configuration this module writes no global values, not even
the module table. Import it using
json = require ("dkjson")
In environments where `require` or a similiar function are not available
and you cannot receive the return value of the module, you can set the
option `register_global_module_table` to `true`. The module table will
then be saved in the global variable with the name given by the option
`global_module_name`.
Exported functions and values:
`json.encode (object [, state])`
--------------------------------
Create a string representing the object. `Object` can be a table,
a string, a number, a boolean, `nil`, `json.null` or any object with
a function `__tojson` in its metatable. A table can only use strings
and numbers as keys and its values have to be valid objects as
well. It raises an error for any invalid data types or reference
cycles.
`state` is an optional table with the following fields:
- `indent`
When `indent` (a boolean) is set, the created string will contain
newlines and indentations. Otherwise it will be one long line.
- `keyorder`
`keyorder` is an array to specify the ordering of keys in the
encoded output. If an object has keys which are not in this array
they are written after the sorted keys.
- `level`
This is the initial level of indentation used when `indent` is
set. For each level two spaces are added. When absent it is set
to 0.
- `buffer`
`buffer` is an array to store the strings for the result so they
can be concatenated at once. When it isn't given, the encode
function will create it temporary and will return the
concatenated result.
- `bufferlen`
When `bufferlen` is set, it has to be the index of the last
element of `buffer`.
- `tables`
`tables` is a set to detect reference cycles. It is created
temporary when absent. Every table that is currently processed
is used as key, the value is `true`.
When `state.buffer` was set, the return value will be `true` on
success. Without `state.buffer` the return value will be a string.
`json.decode (string [, position [, null]])`
--------------------------------------------
Decode `string` starting at `position` or at 1 if `position` was
omitted.
`null` is an optional value to be returned for null values. The
default is `nil`, but you could set it to `json.null` or any other
value.
The return values are the object or `nil`, the position of the next
character that doesn't belong to the object, and in case of errors
an error message.
Two metatables are created. Every array or object that is decoded gets
a metatable with the `__jsontype` field set to either `array` or
`object`. If you want to provide your own metatables use the syntax
json.decode (string, position, null, objectmeta, arraymeta)
To prevent the assigning of metatables pass `nil`:
json.decode (string, position, null, nil)
`<metatable>.__jsonorder`
-------------------------
`__jsonorder` can overwrite the `keyorder` for a specific table.
`<metatable>.__jsontype`
------------------------
`__jsontype` can be either `"array"` or `"object"`. This value is only
checked for empty tables. (The default for empty tables is `"array"`).
`<metatable>.__tojson (self, state)`
------------------------------------
You can provide your own `__tojson` function in a metatable. In this
function you can either add directly to the buffer and return true,
or you can return a string. On errors nil and a message should be
returned.
`json.null`
-----------
You can use this value for setting explicit `null` values.
`json.version`
--------------
Set to `"dkjson 2.4"`.
`json.quotestring (string)`
---------------------------
Quote a UTF-8 string and escape critical characters using JSON
escape sequences. This function is only necessary when you build
your own `__tojson` functions.
`json.addnewline (state)`
-------------------------
When `state.indent` is set, add a newline to `state.buffer` and spaces
according to `state.level`.
LPeg support
------------
When the local configuration variable `always_try_using_lpeg` is set,
this module tries to load LPeg to replace the `decode` function. The
speed increase is significant. You can get the LPeg module at
<http://www.inf.puc-rio.br/~roberto/lpeg/>.
When LPeg couldn't be loaded, the pure Lua functions stay active.
In case you don't want this module to require LPeg on its own,
disable the option `always_try_using_lpeg` in the options section at
the top of the module.
In this case you can later load LPeg support using
### `json.use_lpeg ()`
Require the LPeg module and replace the functions `quotestring` and
and `decode` with functions that use LPeg patterns.
This function returns the module table, so you can load the module
using:
json = require "dkjson".use_lpeg()
Alternatively you can use `pcall` so the JSON module still works when
LPeg isn't found.
json = require "dkjson"
pcall (json.use_lpeg)
### `json.using_lpeg`
This variable is set to `true` when LPeg was loaded successfully.
---------------------------------------------------------------------
Contact
-------
You can contact the author by sending an e-mail to 'david' at the
domain 'dkolf.de'.
---------------------------------------------------------------------
*Copyright (C) 2010-2013 David Heiko Kolf*
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<!-- This documentation can be parsed using Markdown to generate HTML.
The source code is enclosed in a HTML comment so it won't be displayed
by browsers, but it should be removed from the final HTML file as
it isn't a valid HTML comment (and wastes space).
-->
<!--]==]
-- global dependencies:
local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
local error, require, pcall, select = error, require, pcall, select
local floor, huge = math.floor, math.huge
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
string.rep, string.gsub, string.sub, string.byte, string.char,
string.find, string.len, string.format
local strmatch = string.match
local concat = table.concat
local json = { version = "dkjson 2.4" }
if register_global_module_table then
_G[global_module_name] = json
end
local _ENV = nil -- blocking globals in Lua 5.2
pcall (function()
-- Enable access to blocked metatables.
-- Don't worry, this module doesn't change anything in them.
local debmeta = require "debug".getmetatable
if debmeta then getmetatable = debmeta end
end)
json.null = setmetatable ({}, {
__tojson = function () return "null" end
})
local function isarray (tbl)
local max, n, arraylen = 0, 0, 0
for k,v in pairs (tbl) do
if k == 'n' and type(v) == 'number' then
arraylen = v
if v > max then
max = v
end
else
if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
return false
end
if k > max then
max = k
end
n = n + 1
end
end
if max > 10 and max > arraylen and max > n * 2 then
return false -- don't create an array with too many holes
end
return true, max
end
local escapecodes = {
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
}
local function escapeutf8 (uchar)
local value = escapecodes[uchar]
if value then
return value
end
local a, b, c, d = strbyte (uchar, 1, 4)
a, b, c, d = a or 0, b or 0, c or 0, d or 0
if a <= 0x7f then
value = a
elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
value = (a - 0xc0) * 0x40 + b - 0x80
elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
else
return ""
end
if value <= 0xffff then
return strformat ("\\u%.4x", value)
elseif value <= 0x10ffff then
-- encode as UTF-16 surrogate pair
value = value - 0x10000
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
else
return ""
end
end
local function fsub (str, pattern, repl)
-- gsub always builds a new string in a buffer, even when no match
-- exists. First using find should be more efficient when most strings
-- don't contain the pattern.
if strfind (str, pattern) then
return gsub (str, pattern, repl)
else
return str
end
end
local function quotestring (value)
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
if strfind (value, "[\194\216\220\225\226\239]") then
value = fsub (value, "\194[\128-\159\173]", escapeutf8)
value = fsub (value, "\216[\128-\132]", escapeutf8)
value = fsub (value, "\220\143", escapeutf8)
value = fsub (value, "\225\158[\180\181]", escapeutf8)
value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8)
value = fsub (value, "\226\129[\160-\175]", escapeutf8)
value = fsub (value, "\239\187\191", escapeutf8)
value = fsub (value, "\239\191[\176-\191]", escapeutf8)
end
return "\"" .. value .. "\""
end
json.quotestring = quotestring
local function replace(str, o, n)
local i, j = strfind (str, o, 1, true)
if i then
return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1)
else
return str
end
end
-- locale independent num2str and str2num functions
local decpoint, numfilter
local function updatedecpoint ()
decpoint = strmatch(tostring(0.5), "([^05+])")
-- build a filter that can be used to remove group separators
numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+"
end
updatedecpoint()
local function num2str (num)
return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
end
local function str2num (str)
local num = tonumber(replace(str, ".", decpoint))
if not num then
updatedecpoint()
num = tonumber(replace(str, ".", decpoint))
end
return num
end
local function addnewline2 (level, buffer, buflen)
buffer[buflen+1] = "\n"
buffer[buflen+2] = strrep (" ", level)
buflen = buflen + 2
return buflen
end
function json.addnewline (state)
if state.indent then
state.bufferlen = addnewline2 (state.level or 0,
state.buffer, state.bufferlen or #(state.buffer))
end
end
local encode2 -- forward declaration
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder)
local kt = type (key)
if kt ~= 'string' and kt ~= 'number' then
return nil, "type '" .. kt .. "' is not supported as a key by JSON."
end
if prev then
buflen = buflen + 1
buffer[buflen] = ","
end
if indent then
buflen = addnewline2 (level, buffer, buflen)
end
buffer[buflen+1] = quotestring (key)
buffer[buflen+2] = ":"
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder)
end
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder)
local valtype = type (value)
local valmeta = getmetatable (value)
valmeta = type (valmeta) == 'table' and valmeta -- only tables
local valtojson = valmeta and valmeta.__tojson
if valtojson then
if tables[value] then
return nil, "reference cycle"
end
tables[value] = true
local state = {
indent = indent, level = level, buffer = buffer,
bufferlen = buflen, tables = tables, keyorder = globalorder
}
local ret, msg = valtojson (value, state)
if not ret then return nil, msg end
tables[value] = nil
buflen = state.bufferlen
if type (ret) == 'string' then
buflen = buflen + 1
buffer[buflen] = ret
end
elseif value == nil then
buflen = buflen + 1
buffer[buflen] = "null"
elseif valtype == 'number' then
local s
if value ~= value or value >= huge or -value >= huge then
-- This is the behaviour of the original JSON implementation.
s = "null"
else
s = num2str (value)
end
buflen = buflen + 1
buffer[buflen] = s
elseif valtype == 'boolean' then
buflen = buflen + 1
buffer[buflen] = value and "true" or "false"
elseif valtype == 'string' then
buflen = buflen + 1
buffer[buflen] = quotestring (value)
elseif valtype == 'table' then
if tables[value] then
return nil, "reference cycle"
end
tables[value] = true
level = level + 1
local isa, n = isarray (value)
if n == 0 and valmeta and valmeta.__jsontype == 'object' then
isa = false
end
local msg
if isa then -- JSON array
buflen = buflen + 1
buffer[buflen] = "["
for i = 1, n do
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder)
if not buflen then return nil, msg end
if i < n then
buflen = buflen + 1
buffer[buflen] = ","
end
end
buflen = buflen + 1
buffer[buflen] = "]"
else -- JSON object
local prev = false
buflen = buflen + 1
buffer[buflen] = "{"
local order = valmeta and valmeta.__jsonorder or globalorder
if order then
local used = {}
n = #order
for i = 1, n do
local k = order[i]
local v = value[k]
if v then
used[k] = true
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
prev = true -- add a seperator before the next element
end
end
for k,v in pairs (value) do
if not used[k] then
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
if not buflen then return nil, msg end
prev = true -- add a seperator before the next element
end
end
else -- unordered
for k,v in pairs (value) do
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
if not buflen then return nil, msg end
prev = true -- add a seperator before the next element
end
end
if indent then
buflen = addnewline2 (level - 1, buffer, buflen)
end
buflen = buflen + 1
buffer[buflen] = "}"
end
tables[value] = nil
else
return nil, "type '" .. valtype .. "' is not supported by JSON."
end
return buflen
end
function json.encode (value, state)
state = state or {}
local oldbuffer = state.buffer
local buffer = oldbuffer or {}
updatedecpoint()
local ret, msg = encode2 (value, state.indent, state.level or 0,
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder)
if not ret then
error (msg, 2)
elseif oldbuffer then
state.bufferlen = ret
return true
else
return concat (buffer)
end
end
local function loc (str, where)
local line, pos, linepos = 1, 1, 0
while true do
pos = strfind (str, "\n", pos, true)
if pos and pos < where then
line = line + 1
linepos = pos
pos = pos + 1
else
break
end
end
return "line " .. line .. ", column " .. (where - linepos)
end
local function unterminated (str, what, where)
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
end
local function scanwhite (str, pos)
while true do
pos = strfind (str, "%S", pos)
if not pos then return nil end
if strsub (str, pos, pos + 2) == "\239\187\191" then
-- UTF-8 Byte Order Mark
pos = pos + 3
else
return pos
end
end
end
local escapechars = {
["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f",
["n"] = "\n", ["r"] = "\r", ["t"] = "\t"
}
local function unichar (value)
if value < 0 then
return nil
elseif value <= 0x007f then
return strchar (value)
elseif value <= 0x07ff then
return strchar (0xc0 + floor(value/0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0xffff then
return strchar (0xe0 + floor(value/0x1000),
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0x10ffff then
return strchar (0xf0 + floor(value/0x40000),
0x80 + (floor(value/0x1000) % 0x40),
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
else
return nil
end
end
local function scanstring (str, pos)
local lastpos = pos + 1
local buffer, n = {}, 0
while true do
local nextpos = strfind (str, "[\"\\]", lastpos)
if not nextpos then
return unterminated (str, "string", pos)
end
if nextpos > lastpos then
n = n + 1
buffer[n] = strsub (str, lastpos, nextpos - 1)
end
if strsub (str, nextpos, nextpos) == "\"" then
lastpos = nextpos + 1
break
else
local escchar = strsub (str, nextpos + 1, nextpos + 1)
local value
if escchar == "u" then
value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16)
if value then
local value2
if 0xD800 <= value and value <= 0xDBff then
-- we have the high surrogate of UTF-16. Check if there is a
-- low surrogate escaped nearby to combine them.
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
else
value2 = nil -- in case it was out of range for a low surrogate
end
end
end
value = value and unichar (value)
if value then
if value2 then
lastpos = nextpos + 12
else
lastpos = nextpos + 6
end
end
end
end
if not value then
value = escapechars[escchar] or escchar
lastpos = nextpos + 2
end
n = n + 1
buffer[n] = value
end
end
if n == 1 then
return buffer[1], lastpos
elseif n > 1 then
return concat (buffer), lastpos
else
return "", lastpos
end
end
local scanvalue -- forward declaration
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
local len = strlen (str)
local tbl, n = {}, 0
local pos = startpos + 1
if what == 'object' then
setmetatable (tbl, objectmeta)
else
setmetatable (tbl, arraymeta)
end
while true do
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
local char = strsub (str, pos, pos)
if char == closechar then
return tbl, pos + 1
end
local val1, err
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
char = strsub (str, pos, pos)
if char == ":" then
if val1 == nil then
return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")"
end
pos = scanwhite (str, pos + 1)
if not pos then return unterminated (str, what, startpos) end
local val2
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end
tbl[val1] = val2
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
char = strsub (str, pos, pos)
else
n = n + 1
tbl[n] = val1
end
if char == "," then
pos = pos + 1
end
end
end
scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
pos = pos or 1
pos = scanwhite (str, pos)
if not pos then
return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
end
local char = strsub (str, pos, pos)
if char == "{" then
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
elseif char == "[" then
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
elseif char == "\"" then
return scanstring (str, pos)
else
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
if pstart then
local number = str2num (strsub (str, pstart, pend))
if number then
return number, pend + 1
end
end
pstart, pend = strfind (str, "^%a%w*", pos)
if pstart then
local name = strsub (str, pstart, pend)
if name == "true" then
return true, pend + 1
elseif name == "false" then
return false, pend + 1
elseif name == "null" then
return nullval, pend + 1
end
end
return nil, pos, "no valid JSON value at " .. loc (str, pos)
end
end
local function optionalmetatables(...)
if select("#", ...) > 0 then
return ...
else
return {__jsontype = 'object'}, {__jsontype = 'array'}
end
end
function json.decode (str, pos, nullval, ...)
local objectmeta, arraymeta = optionalmetatables(...)
return scanvalue (str, pos, nullval, objectmeta, arraymeta)
end
function json.use_lpeg ()
local g = require ("lpeg")
if g.version() == "0.11" then
error "due to a bug in LPeg 0.11, it cannot be used for JSON matching"
end
local pegmatch = g.match
local P, S, R = g.P, g.S, g.R
local function ErrorCall (str, pos, msg, state)
if not state.msg then
state.msg = msg .. " at " .. loc (str, pos)
state.pos = pos
end
return false
end
local function Err (msg)
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
end
local Space = (S" \n\r\t" + P"\239\187\191")^0
local PlainChar = 1 - S"\"\\\n\r"
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
local HexDigit = R("09", "af", "AF")
local function UTF16Surrogate (match, pos, high, low)
high, low = tonumber (high, 16), tonumber (low, 16)
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
else
return false
end
end
local function UTF16BMP (hex)
return unichar (tonumber (hex, 16))
end
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
local Char = UnicodeEscape + EscapeSequence + PlainChar
local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
local Fractal = P"." * R"09"^0
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
local Number = (Integer * Fractal^(-1) * Exponent^(-1))/str2num
local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1)
local SimpleValue = Number + String + Constant
local ArrayContent, ObjectContent
-- The functions parsearray and parseobject parse only a single value/pair
-- at a time and store them directly to avoid hitting the LPeg limits.
local function parsearray (str, pos, nullval, state)
local obj, cont
local npos
local t, nt = {}, 0
repeat
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
if not npos then break end
pos = npos
nt = nt + 1
t[nt] = obj
until cont == 'last'
return pos, setmetatable (t, state.arraymeta)
end
local function parseobject (str, pos, nullval, state)
local obj, key, cont
local npos
local t = {}
repeat
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
if not npos then break end
pos = npos
t[key] = obj
until cont == 'last'
return pos, setmetatable (t, state.objectmeta)
end
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
local Value = Space * (Array + Object + SimpleValue)
local ExpectedValue = Value + Space * Err "value expected"
ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
local DecodeValue = ExpectedValue * g.Cp ()
function json.decode (str, pos, nullval, ...)
local state = {}
state.objectmeta, state.arraymeta = optionalmetatables(...)
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
if state.msg then
return nil, state.pos, state.msg
else
return obj, retpos
end
end
-- use this function only once:
json.use_lpeg = function () return json end
json.using_lpeg = true
return json -- so you can get the module using json = require "dkjson".use_lpeg()
end
if always_try_using_lpeg then
pcall (json.use_lpeg)
end
return json
-->

View File

@ -1,58 +0,0 @@
dofile "class_definitions.lua"
io.write("=== Global Functions ===\n")
function write_function(name, func)
io.write("* ")
io.write("'''"..(func.rval or "void").."'''")
io.write(" ")
io.write(name)
io.write("(")
for key, arg in ipairs(func.args) do
io.write(arg)
if func.argnames then
io.write(" "..func.argnames[key])
end
if next(func.args, key) then
io.write(", ")
end
end
io.write(")\n")
if func.desc then
io.write("** "..func.desc.."\n")
end
end
function write_attribute(name, attribute)
io.write("* ")
io.write("'''"..attribute.type.."'''")
io.write(" ")
io.write(name)
if not attribute.writable then
io.write(" ''read-only''")
end
io.write("\n")
if attribute.desc then
io.write("** "..attribute.desc.."\n")
end
end
for name, func in pairs(global_functions) do
write_function(name, func)
end
for classname, class in pairs(classes) do
io.write("=== "..classname.." ===\n")
io.write("==== Functions ====\n")
for name, func in pairs(class.functions) do
write_function(name, func)
end
io.write("==== Attributes ====\n")
for name, attr in pairs(class.attributes) do
write_attribute(name, attr)
end
end

View File

@ -1,175 +0,0 @@
-- script to verify CDDA JSON(verifies all mods)
-- run this script with: lua lua/json_verifier.lua
--
-- requires luafilesystem to scan for files, installation instructions:
-- arch linux: pacman -S lua-filesystem
-- debian linux: aptitude install liblua5.1-filesystem0
-- other linux distributions: search for "lua file system" in the
-- package manager of your choice
local json = require("lua/dkjson")
local lfs = require("lfs")
local exit_code = 0
-- function to read a file completely into a string
function read_file(filename)
local f = io.open(filename, "r")
local content = f:read("*all")
f:close()
return content
end
decode_cache = {}
-- parse the JSON of an entire cataclysm file
function parse_cata_json(filename, handler)
local root, pos, err
if not decode_cache[filename] then
local content = read_file(filename)
root, pos, err = json.decode(content, 1, nil)
decode_cache[filename] = root
else
root = decode_cache[filename]
end
if err then
print("Error in ", filename ,":", err)
os.exit(1)
else
-- top level should be a json array
if type(root) ~= "table" then
print("Wrong root element to JSON file ", filename, " :", type(root))
end
for _, entry in ipairs(root) do
if not entry.type then
print("Invalid entry type in ", filename, ": ", entry.type)
end
if handler[entry.type] then
handler[entry.type](entry, filename)
end
end
end
end
local definitions = {}
local material_definitions = {}
function load_item_definition(entry, filename)
-- store that this item was defined
definitions[entry.id] = true
end
-- define load_definition handlers
local load_definition = {}
local item_types = { "BOOK", "TOOL", "GUN", "GUNMOD", "TOOL_ARMOR", "ARMOR", "BIONIC_ITEM", "GENERIC", "AMMO", "CONTAINER", "COMESTIBLE", "VAR_VEH_PART" }
for _, item_type in ipairs(item_types) do
load_definition[item_type] = load_item_definition
end
-- load definition handler for materials
function load_material_definition(entry, filename)
-- store that this material was defined
material_definitions[entry.ident] = true
end
load_definition.material = load_material_definition
local verify_handler = {}
function ensure_definition(id, filename, parent_id)
if not definitions[id] then
-- signify that something went wrong
exit_code = 1
print("Trying to access non-existent item id ", id, " in ", filename, "(", parent_id, ")")
end
end
function ensure_material_definition(id, filename, parent_id)
if not material_definitions[id] then
-- signify that something went wrong
exit_code = 1
print("Trying to access non-existent material id ", id, " in ", filename, "(", parent_id, ")")
end
end
verify_handler.recipe = function(entry, filename)
ensure_definition(entry.result, filename, entry.result)
for _, alternatives in ipairs(entry.components) do
for _, item in ipairs(alternatives) do
ensure_definition(item[1], filename, entry.result)
end
end
if entry.tools then
for _, alternatives in ipairs(entry.tools) do
for _, item in ipairs(alternatives) do
ensure_definition(item[1], filename, entry.result)
end
end
end
end
function verify_item_definition(entry, filename)
local materials
if not entry.material or entry.material == "" then
return
elseif type(entry.material) == "string" then
materials = { entry.material }
elseif type(entry.material == "table") then
materials = entry.material
else
exit_code = 1
print("Invalid material for ", entry.id, " in ", filename)
end
for _, material in ipairs(materials) do
ensure_material_definition(material, filename, entry.id)
end
end
for _, item_type in ipairs(item_types) do
verify_handler[item_type] = verify_item_definition
end
function string.endswith(mystr, myend)
return myend=="" or string.sub(mystr,string.len(mystr)-string.len(myend)+1)==myend
end
function load_all_jsons_recursive(path, handler)
for file in lfs.dir(path) do
if file ~= "." and file ~= ".." then
local f = path..'/'..file
local attr = lfs.attributes(f)
if attr.mode == "directory" then
load_all_jsons_recursive(f, handler)
elseif attr.mode == "file" and string.endswith(f, ".json") then
parse_cata_json(f, handler)
end
end
end
end
function load_all_jsons(handler)
load_all_jsons_recursive("data/json", handler)
load_all_jsons_recursive("data/mods", handler)
end
-- first load all item definitions
load_all_jsons(load_definition)
-- some hardcoded item definitions
definitions["cvd_machine"] = true
definitions["corpse"] = true
definitions["apparatus"] = true
definitions["toolset"] = true
definitions["fire"] = true
-- then verify recipes
load_all_jsons(verify_handler)
os.exit(exit_code)

View File

@ -1,43 +0,0 @@
local log = {
output_path = "./config/lua-log.log",
datetime_format= "%Y-%m-%d %H:%M:%S"
}
log.init = function(output_path)
if (output_path ~= nil) then
log.output_path = output_path
end
return log
end
log.clear = function()
local output_file = io.open (log.output_path, "w+")
io.close(output_file)
end
log.message = function(message_text, ...)
local message_text_formatted = ""
if (#{...} > 0) then
message_text_formatted = string.format(message_text, ...)
else
message_text_formatted = tostring(message_text)
end
local output_text = os.date(log.datetime_format).."|"..message_text_formatted.."\n"
local output_file = io.open (log.output_path, "a")
io.output(output_file)
io.write(output_text)
io.close(output_file)
end
return log

View File

@ -102,7 +102,7 @@
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
@ -132,7 +132,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
@ -162,7 +162,7 @@
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
@ -192,7 +192,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>

View File

@ -102,7 +102,7 @@
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
@ -130,7 +130,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
@ -158,7 +158,7 @@
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
@ -186,7 +186,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LUA;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<CompileAsManaged>false</CompileAsManaged>
<MultiProcessorCompilation>false</MultiProcessorCompilation>

View File

@ -116,13 +116,13 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalOptions>/LTCG:OFF %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>prebuild.cmd</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Get version string and generate lua bindings</Message>
<Message>Get version string</Message>
</PreBuildEvent>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -148,9 +148,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalOptions>/LTCG:OFF %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkStatus>true</LinkStatus>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
@ -187,13 +187,13 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalOptions>/LTCG:OFF %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>prebuild.cmd</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Get version string and generate lua bindings</Message>
<Message>Get version string</Message>
</PreBuildEvent>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -222,9 +222,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalOptions>/LTCG:OFF %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkStatus>true</LinkStatus>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>

View File

@ -126,7 +126,7 @@
<Command>prebuild.cmd</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Get version string and generate lua bindings</Message>
<Message>Get version string</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -155,7 +155,7 @@
<Command>prebuild.cmd</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Get version string and generate lua bindings</Message>
<Message>Get version string</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -185,7 +185,7 @@
<Command>prebuild.cmd</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Get version string and generate lua bindings</Message>
<Message>Get version string</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -215,7 +215,7 @@
<Command>prebuild.cmd</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Get version string and generate lua bindings</Message>
<Message>Get version string</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>

View File

@ -107,7 +107,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;$(LUADIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SDL_MAIN_HANDLED;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths>
<SDLCheck>true</SDLCheck>
@ -117,8 +117,8 @@
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -129,7 +129,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;$(LUADIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SDL_MAIN_HANDLED;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths>
<CompileAsManaged>false</CompileAsManaged>
@ -144,8 +144,8 @@
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkStatus>true</LinkStatus>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<IgnoreSpecificDefaultLibraries>
@ -162,7 +162,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;$(LUADIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SDL_MAIN_HANDLED;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths>
<CompileAsManaged>false</CompileAsManaged>
@ -174,8 +174,8 @@
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -188,7 +188,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;$(LUADIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;..\src;$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SDL_MAIN_HANDLED;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths>
<CompileAsManaged>false</CompileAsManaged>
@ -204,8 +204,8 @@
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkStatus>true</LinkStatus>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<IgnoreSpecificDefaultLibraries>

View File

@ -8,19 +8,18 @@
<SDL2MIXER>$(WINDEPEND)SDL2_mixer-2.0.4\</SDL2MIXER>
<SDL2IMAGE>$(WINDEPEND)SDL2_image-2.0.4\</SDL2IMAGE>
<GETTEXT>$(WINDEPEND)gettext\</GETTEXT>
<LUADIR>$(WINDEPEND)lua-5.3.3\</LUADIR>
</PropertyGroup>
<PropertyGroup>
<_PropertySheetDisplayName>WINDEPEND</_PropertySheetDisplayName>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;$(LUADIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SDL_SOUND;TILES;LUA;LOCALIZE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SDL2ROOT)include;$(SDL2TTF)include;$(SDL2MIXER)include;$(SDL2IMAGE)include;$(GETTEXT)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SDL_SOUND;TILES;LOCALIZE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);$(LUADIR)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>SDL2.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;Lua.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SDL2ROOT)lib\$(PlatformTarget);$(SDL2TTF)lib\$(PlatformTarget);$(SDL2MIXER)lib\$(PlatformTarget);$(SDL2IMAGE)lib\$(PlatformTarget);$(GETTEXT)lib\$(PlatformTarget);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>SDL2.lib;SDL2_image.lib;SDL2_mixer.lib;SDL2_ttf.lib;libiconv.lib;libintl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@ -48,9 +47,5 @@
<Value>$(GETTEXT)</Value>
<EnvironmentVariable>true</EnvironmentVariable>
</BuildMacro>
<BuildMacro Include="LUADIR">
<Value>$(LUADIR)</Value>
<EnvironmentVariable>true</EnvironmentVariable>
</BuildMacro>
</ItemGroup>
</Project>

View File

@ -5,7 +5,6 @@ xcopy /s /e /i ..\data distribution\data
xcopy /s /e /i ..\config distribution\config
xcopy /s /e /i ..\gfx distribution\gfx
xcopy /s /e /i ..\lang\mo distribution\lang\mo
xcopy /s /e /i ..\lua distribution\lua
copy ..\Cataclysm.exe distribution\
echo Distribution files has been put into `distribution\' directory.
pause

View File

@ -1,9 +1,6 @@
@echo off
SETLOCAL
cd ..\src\lua
echo Generating lua bindings
lua generate_bindings.lua
cd ..\..\msvc-full-features
echo Done

View File

@ -22,8 +22,7 @@ apps:
parts:
cataclysm:
plugin: make
build-packages: [astyle, ccache, build-essential, libncurses5-dev, libncursesw5-dev, lua5.2, liblua5.2-dev, gettext]
stage-packages: [liblua5.2-0]
override-build: make NATIVE=linux64 RELEASE=1 LTO=1 LUA=1 LOCALIZE=1 CCACHE=1 USE_HOME_DIR=1 && mv * $SNAPCRAFT_PART_INSTALL
stage: [data, lua, cataclysm, cataclysm-launcher, usr]
prime: [data, lua, cataclysm, cataclysm-launcher, usr]
build-packages: [astyle, ccache, build-essential, libncurses5-dev, libncursesw5-dev, gettext]
override-build: make NATIVE=linux64 RELEASE=1 LTO=1 LOCALIZE=1 CCACHE=1 USE_HOME_DIR=1 && mv * $SNAPCRAFT_PART_INSTALL
stage: [data, cataclysm, cataclysm-launcher, usr]
prime: [data, cataclysm, cataclysm-launcher, usr]

View File

@ -14,11 +14,11 @@ LOCAL_CPP_FEATURES := exceptions rtti
FILE_LIST := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_image SDL2_ttf lua libintl-lite mpg123
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_image SDL2_ttf libintl-lite mpg123
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
LOCAL_CFLAGS += -DTILES=1 -DSDL_SOUND=1 -DLUA=1 -DCATA_NO_CPP11_STRING_CONVERSIONS=1 -DLOCALIZE=1 -Wextra -Wall -fsigned-char -ffast-math
LOCAL_CFLAGS += -DTILES=1 -DSDL_SOUND=1 -DCATA_NO_CPP11_STRING_CONVERSIONS=1 -DLOCALIZE=1 -Wextra -Wall -fsigned-char -ffast-math
LOCAL_LDFLAGS += $(LOCAL_CFLAGS)

View File

@ -54,12 +54,6 @@ IF(TILES)
target_link_libraries(cataclysm-tiles libcataclysm-tiles)
target_compile_definitions(libcataclysm-tiles PUBLIC TILES )
IF (LUA)
ADD_DEPENDENCIES(libcataclysm-tiles lua_bindings)
target_include_directories(libcataclysm-tiles PUBLIC ${LUA_INCLUDE_DIR})
target_link_libraries(libcataclysm-tiles ${LUA_LIBRARIES})
ENDIF(LUA)
IF (LOCALIZE)
target_include_directories(libcataclysm-tiles PUBLIC
${LIBINTL_INCLUDE_DIR}
@ -162,12 +156,6 @@ IF(CURSES)
target_link_libraries(cataclysm libcataclysm)
IF (LUA)
ADD_DEPENDENCIES(libcataclysm lua_bindings)
target_include_directories(libcataclysm PUBLIC ${LUA_INCLUDE_DIR})
target_link_libraries(libcataclysm ${LUA_LIBRARIES})
ENDIF(LUA)
IF (LOCALIZE)
target_include_directories(libcataclysm PUBLIC
${LIBINTL_INCLUDE_DIR}
@ -224,11 +212,6 @@ IF(MINGW AND NOT RELEASE)
${RuntimeLib_STDC_PP_6}
${RuntimeLib_WINPTHREAD_1}
)
IF (LUA)
SET(RuntimeLib_LUA
${LUA_LIBRARIES}
)
ENDIF (LUA)
IF (LOCALIZE)
find_library(RuntimeLib_iconv "libiconv-2")
find_library(RuntimeLib_intl "libintl-8")
@ -298,7 +281,6 @@ IF(MINGW AND NOT RELEASE)
ENDIF (TILES)
install(FILES ${RuntimeLib_GCC_ALL}
${RuntimeLib_LOCALIZE}
${RuntimeLib_LUA}
${RuntimeLib_SDL}
${RuntimeLib_SDL_SOUND}
DESTINATION ${BIN_PREFIX}

View File

@ -5,7 +5,6 @@
#include "action.h"
#include "advanced_inv.h"
#include "catalua.h"
#include "clzones.h"
#include "construction.h"
#include "craft_command.h"
@ -1891,14 +1890,6 @@ void activity_handlers::train_finish( player_activity *act, player *p )
pgettext( "memorial_female", "Reached skill level %1$d in %2$s." ),
new_skill_level, skill_name );
}
const std::string skill_increase_source = "training";
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( p->getID() );
lua_callback_args_info.emplace_back( skill_increase_source );
lua_callback_args_info.emplace_back( sk.str() );
lua_callback_args_info.emplace_back( new_skill_level );
lua_callback( "on_player_skill_increased", lua_callback_args_info );
lua_callback( "on_skill_increased" ); // Legacy callback
act->set_to_null();
return;
}

View File

@ -5,7 +5,6 @@
#include "activity_handlers.h"
#include "assign.h"
#include "catalua.h"
#include "debug.h"
#include "json.h"
#include "player.h"
@ -86,12 +85,7 @@ void activity_type::call_do_turn( player_activity *act, player *p ) const
{
const auto &pair = activity_handlers::do_turn_functions.find( id_ );
if( pair != activity_handlers::do_turn_functions.end() ) {
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( act->id().str() );
lua_callback_args_info.emplace_back( p->getID() );
lua_callback( "on_activity_call_do_turn_started", lua_callback_args_info );
pair->second( act, p );
lua_callback( "on_activity_call_do_turn_finished", lua_callback_args_info );
}
}
@ -99,12 +93,7 @@ bool activity_type::call_finish( player_activity *act, player *p ) const
{
const auto &pair = activity_handlers::finish_functions.find( id_ );
if( pair != activity_handlers::finish_functions.end() ) {
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( act->id().str() );
lua_callback_args_info.emplace_back( p->getID() );
lua_callback( "on_activity_call_finish_started", lua_callback_args_info );
pair->second( act, p );
lua_callback( "on_activity_call_finish_finished", lua_callback_args_info );
return true;
}
return false;

View File

@ -153,7 +153,7 @@ class calendar
/**
* Accessor for current turn_number.
*
* @returns Current turn number (`get_turn()` function for `calendar` class in Lua bindings.)
* @returns Current turn number.
*/
operator int() const;

File diff suppressed because it is too large Load Diff

View File

@ -1,113 +0,0 @@
#pragma once
#ifndef CATALUA_H
#define CATALUA_H
#include <list>
#include <sstream>
#include <string>
#include "creature.h"
#include "enums.h"
#include "int_id.h"
#include "item.h"
enum CallbackArgumentType : int {
Integer,
Number,
Double = Number,
Float = Number,
Boolean,
String,
Tripoint,
Item,
Reference_Creature,
Enum_BodyPart,
};
struct CallbackArgument {
CallbackArgumentType type;
int value_integer;
float value_number;
bool value_boolean;
std::string value_string;
tripoint value_tripoint;
item value_item;
Creature *value_creature;
body_part value_body_part;
CallbackArgument( int arg_value ) :
type( CallbackArgumentType::Integer ), value_integer( arg_value ) {
}
CallbackArgument( double arg_value ) :
type( CallbackArgumentType::Number ), value_number( arg_value ) {
}
CallbackArgument( float arg_value ) :
type( CallbackArgumentType::Number ), value_number( arg_value ) {
}
CallbackArgument( bool arg_value ) :
type( CallbackArgumentType::Boolean ), value_boolean( arg_value ) {
}
CallbackArgument( const std::string &arg_value ) :
type( CallbackArgumentType::String ), value_string( arg_value ) {
}
CallbackArgument( const tripoint &arg_value ) :
type( CallbackArgumentType::Tripoint ), value_tripoint( arg_value ) {
}
CallbackArgument( const item &arg_value ) :
type( CallbackArgumentType::Item ), value_item( arg_value ) {
}
CallbackArgument( Creature *&arg_value ) :
type( CallbackArgumentType::Reference_Creature ), value_creature( arg_value ) {
}
CallbackArgument( const body_part &arg_value ) :
type( CallbackArgumentType::Enum_BodyPart ), value_body_part( arg_value ) {
}
#ifdef LUA
void Save();
#endif //LUA
};
typedef std::list<CallbackArgument> CallbackArgumentContainer;
class map;
class monster;
class time_point;
struct mapgendata;
struct oter_t;
using oter_id = int_id<oter_t>;
extern std::stringstream lua_output_stream;
extern std::stringstream lua_error_stream;
/** If this returns 0, no lua function was defined to override behavior.
* If this returns 1, lua behavior was called and regular behavior should be omitted.
*/
int lua_monster_move( monster *m );
/**
* Call the given string as lua code, used for interactive debugging.
*/
int call_lua( const std::string &tocall );
int lua_mapgen( map *m, const oter_id &terrain_type, const mapgendata &md, const time_point &t,
float d, const std::string &scr );
/**
* Execute a callback that can be overridden by all mods with optional accessible arguments.
*/
void lua_callback( const char *callback_name, const CallbackArgumentContainer &callback_args );
void lua_callback( const char *callback_name );
std::string lua_callback_getstring( const char *callback_name,
const CallbackArgumentContainer &callback_args );
/**
* Load the main file of a lua mod.
*
* @param base_path The base path of the mod.
* @param main_file_name The file name of the lua file, usually "main.lua"
*/
void lua_loadmod( const std::string &base_path, const std::string &main_file_name );
#endif

View File

@ -85,10 +85,6 @@ void craft_command::execute()
crafter->assign_activity( activity );
/* legacy support for lua bindings to last_batch and lastrecipe */
crafter->last_batch = batch_size;
crafter->lastrecipe = rec->ident();
const auto iter = std::find( uistate.recent_recipes.begin(), uistate.recent_recipes.end(),
rec->ident() );
if( iter != uistate.recent_recipes.end() ) {

View File

@ -23,7 +23,6 @@
#include "bodypart.h"
#include "cata_utility.h"
#include "catacharset.h"
#include "catalua.h"
#include "clzones.h"
#include "compatibility.h"
#include "computer.h"
@ -57,7 +56,6 @@
#include "line.h"
#include "live_view.h"
#include "loading_ui.h"
#include "lua_console.h"
#include "map.h"
#include "map_item_stack.h"
#include "map_iterator.h"
@ -358,22 +356,12 @@ void game::load_core_data( loading_ui &ui )
// anyway.
DynamicDataLoader::get_instance().unload_data();
init_lua();
load_data_from_dir( FILENAMES[ "jsondir" ], "core", ui );
}
void game::load_data_from_dir( const std::string &path, const std::string &src, loading_ui &ui )
{
// Process a preload file before the .json files,
// so that custom IUSE's can be defined before
// the items that need them are parsed
lua_loadmod( path, "preload.lua" );
DynamicDataLoader::get_instance().load_data_from_path( path, src, ui );
// main.lua will be executed after JSON, allowing to
// work with items defined by mod's JSON
lua_loadmod( path, "main.lua" );
}
game::~game()
@ -970,10 +958,6 @@ bool game::start_game()
u.add_memorial_log( pgettext( "memorial_male", "%s began their journey into the Cataclysm." ),
pgettext( "memorial_female", "%s began their journey into the Cataclysm." ),
u.name.c_str() );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( u.getID() );
lua_callback( "on_new_player_created", lua_callback_args_info );
return true;
}
@ -1505,22 +1489,8 @@ bool game::do_turn()
if( calendar::once_every( 1_days ) ) {
overmap_buffer.process_mongroups();
if( calendar::turn.day_of_year() == 0 ) {
lua_callback( "on_year_passed" );
}
lua_callback( "on_day_passed" );
}
if( calendar::once_every( 1_hours ) ) {
lua_callback( "on_hour_passed" );
}
if( calendar::once_every( 1_minutes ) ) {
lua_callback( "on_minute_passed" );
}
lua_callback( "on_turn_passed" );
// Move hordes every 2.5 min
if( calendar::once_every( time_duration::from_minutes( 2.5 ) ) ) {
overmap_buffer.move_hordes();
@ -1852,12 +1822,6 @@ void game::update_weather()
// Check weather every few turns, instead of every turn.
//@todo: predict when the weather changes and use that time.
nextweather = calendar::turn + 50_turns;
if( weather != old_weather ) {
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( weather_data( weather ).name );
lua_callback_args_info.emplace_back( weather_data( old_weather ).name );
lua_callback( "on_weather_changed", lua_callback_args_info );
}
if( weather != old_weather && weather_data( weather ).dangerous &&
get_levz() >= 0 && m.is_outside( u.pos() )
&& !u.has_activity( activity_id( "ACT_WAIT_WEATHER" ) ) ) {
@ -2778,8 +2742,6 @@ void game::load( const save_t &name )
u.reset();
draw();
lua_callback( "on_savegame_loaded" );
}
void game::load_world_modfiles( loading_ui &ui )
@ -3049,20 +3011,19 @@ void game::debug()
_( "Test Item Group" ), // 22
_( "Damage Self" ), // 23
_( "Show Sound Clustering" ), // 24
_( "Lua Console" ), // 25
_( "Display weather" ), // 26
_( "Display overmap scents" ), // 27
_( "Change time" ), // 28
_( "Set automove route" ), // 29
_( "Show mutation category levels" ), // 30
_( "Overmap editor" ), // 31
_( "Draw benchmark (X seconds)" ), // 32
_( "Teleport - Adjacent overmap" ), // 33
_( "Test trait group" ), // 34
_( "Show debug message" ), // 35
_( "Crash game (test crash handling)" ),// 36
_( "Spawn Map Extra" ), // 37
_( "Quit to Main Menu" ), // 38
_( "Display weather" ), // 25
_( "Display overmap scents" ), // 26
_( "Change time" ), // 27
_( "Set automove route" ), // 28
_( "Show mutation category levels" ), // 29
_( "Overmap editor" ), // 30
_( "Draw benchmark (X seconds)" ), // 31
_( "Teleport - Adjacent overmap" ), // 32
_( "Test trait group" ), // 33
_( "Show debug message" ), // 34
_( "Crash game (test crash handling)" ),// 35
_( "Spawn Map Extra" ), // 36
_( "Quit to Main Menu" ), // 37
} );
refresh_all();
switch( action ) {
@ -3338,18 +3299,13 @@ void game::debug()
}
break;
case 25: {
lua_console console;
console.run();
}
break;
case 26:
case 25:
ui::omap::display_weather();
break;
case 27:
case 26:
ui::omap::display_scents();
break;
case 28: {
case 27: {
auto set_turn = [&]( const int initial, const int factor, const char *const msg ) {
const auto text = string_input_popup()
.title( msg )
@ -3407,7 +3363,7 @@ void game::debug()
} while( smenu.ret != UILIST_CANCEL );
}
break;
case 29: {
case 28: {
const cata::optional<tripoint> dest = look_around();
if( !dest || *dest == u.pos() ) {
break;
@ -3421,17 +3377,17 @@ void game::debug()
}
}
break;
case 30:
case 29:
for( const auto &elem : u.mutation_category_level ) {
add_msg( "%s: %d", elem.first.c_str(), elem.second );
}
break;
case 31:
case 30:
ui::omap::display_editor();
break;
case 32: {
case 31: {
const int ms = string_input_popup()
.title( _( "Enter benchmark length (in milliseconds):" ) )
.width( 20 )
@ -3441,19 +3397,19 @@ void game::debug()
}
break;
case 33:
case 32:
debug_menu::teleport_overmap();
break;
case 34:
case 33:
trait_group::debug_spawn();
break;
case 35:
case 34:
debugmsg( "Test debugmsg" );
break;
case 36:
case 35:
std::raise( SIGSEGV );
break;
case 37: {
case 36: {
oter_id terrain_type = overmap_buffer.ter( g->u.global_omt_location() );
map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
@ -3478,7 +3434,7 @@ void game::debug()
}
break;
}
case 38:
case 37:
if( query_yn(
_( "Quit without saving? This may cause issues such as duplicated or missing items and vehicles!" ) ) ) {
u.moves = 0;

View File

@ -915,7 +915,6 @@ class game
#endif
// Data Initialization
void init_autosave(); // Initializes autosave parameters
void init_lua(); // Initializes lua interpreter.
void create_starting_npcs(); // Creates NPCs that start near you
// V Menu Functions and helpers:

View File

@ -2180,7 +2180,6 @@ void Item_factory::clear()
categories.clear();
// Also clear functions referring to lua
iuse_function_list.clear();
m_templates.clear();

View File

@ -62,13 +62,6 @@ class Item_factory
* This should be called once after all json data has been loaded.
*/
void check_definitions() const;
/**
* Registers a LUA based iuse function.
* @param name The name that is used in the json data to refer to the LUA function.
* It is stored in @ref iuse_function_list
* @param lua_function The LUA id of the LUA function.
*/
void register_iuse_lua( const std::string &name, int lua_function );
/**
* @name Item groups
@ -123,12 +116,10 @@ class Item_factory
Item_spawn_data *get_group( const Group_tag &id );
/**
* Returns the idents of all item groups that are known.
* This is meant to be accessed at startup by lua to do mod-related modifications of groups.
*/
std::vector<Group_tag> get_all_group_names();
/**
* Sets the chance of the specified item in the group.
* This is meant to be accessed at startup by lua to do mod-related modifications of groups.
* @param group_id Group to add item to
* @param item_id Id of item to add to group
* @param weight The relative weight of the item. A value of 0 removes the item from the

View File

@ -7905,3 +7905,42 @@ int iuse::magic_8_ball( player *p, item *it, bool, const tripoint & )
p->add_msg_if_player( color, _( "The %s says: %s" ), it->tname().c_str(), _( tab[rn] ) );
return 0;
}
use_function::use_function( const use_function &other )
: actor( other.actor ? other.actor->clone() : nullptr )
{
}
use_function &use_function::operator=( iuse_actor *const f )
{
return operator=( use_function( f ) );
}
use_function &use_function::operator=( const use_function &other )
{
actor.reset( other.actor ? other.actor->clone() : nullptr );
return *this;
}
void use_function::dump_info( const item &it, std::vector<iteminfo> &dump ) const
{
if( actor != nullptr ) {
actor->info( it, dump );
}
}
ret_val<bool> use_function::can_call( const player &p, const item &it, bool t,
const tripoint &pos ) const
{
if( actor == nullptr ) {
return ret_val<bool>::make_failure( _( "You can't do anything interesting with your %s." ),
it.tname().c_str() );
}
return actor->can_use( p, it, t, pos );
}
long use_function::call( player &p, item &it, bool active, const tripoint &pos ) const
{
return actor->use( p, it, active, pos );
}

View File

@ -1,23 +0,0 @@
# CataclysmDDA Lua bindings
cmake_minimum_required(VERSION 2.8.12)
MESSAGE(STATUS "Searching for Lua library --\n")
SET(CATACLYSM_DDA_LUA_BINDING_SOURCES
${CMAKE_SOURCE_DIR}/lua/class_definitions.lua
${CMAKE_SOURCE_DIR}/src/lua/generate_bindings.lua
)
add_custom_target (
lua_bindings
ALL
DEPENDS ${CMAKE_SOURCE_DIR}/src/lua/catabindings.cpp
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
ADD_CUSTOM_COMMAND (
OUTPUT ${CMAKE_SOURCE_DIR}/src/lua/catabindings.cpp
COMMAND ${LUA_BINARY} generate_bindings.lua
DEPENDS ${CATACLYSM_DDA_LUA_BINDING_SOURCES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/lua
)

View File

@ -1,656 +0,0 @@
-- Tool to automatically generate bindings for lua.
-- The bindings are generated as C++ and lua files, which are
-- then included into the cataclysm source.
-- Conventions:
-- The variable holding the name of a class is named "class_name"
-- The variable holding the data (declarations etc.) of a class is "class"
-- Example code: for class_name, class in pairs(classes) do ...
-- The generated helper C++ functions use this naming system:
-- Getter: "get_" .. class_name .. "_" .. member_name
-- Setter: "set_" .. class_name .. "_" .. member_name
-- Member function: "func_" .. class_name .. "_" .. member_name
-- Operators: "op_" .. class_name .. "_" .. operator_id
-- Constructors: "new_" .. class_name
-- Global functions get a "global_" prefix.
-- This allows a data member "foo", as well as a function member "get_foo(...)".
-- They would get "get_class_foo", "set_class_foo" and "func_class_get_foo" wrappers.
local br = "\n"
local tab = " "
-- Helper function for sorted iteration over tables
local function sorted_pairs(t)
local keys = {}
for key in pairs(t) do
table.insert(keys, key)
end
table.sort(keys)
return function()
local key = table.remove(keys, 1)
return key, t[key]
end
end
-- Generic helpers to generate C++ source code chunks for use in our lua binding.
---------------------------------------------------------------------------------
-- Convert a given type such as "string" to the corresponding C++ wrapper class,
-- e.g. `LuaType<std::string>`. The wrapper class has various static functions:
-- `get` to get a value of that type from Lua stack.
-- `push` to push a value of that type to Lua stack.
-- `check` and `has` to check for a value of that type on the stack.
-- See catalua.h for their implementation.
function member_type_to_cpp_type(member_type)
if member_type == "bool" then return "LuaType<bool>"
elseif member_type == "cstring" then return "LuaType<const char*>"
elseif member_type == "string" then return "LuaType<std::string>"
elseif member_type == "int" then return "LuaType<int>"
elseif member_type == "float" then return "LuaType<float>"
else
for class_name, class in pairs(classes) do
if class_name == member_type then
if class.by_value then
return "LuaValue<" .. member_type .. ">"
elseif class.by_value_and_reference then
return "LuaValueOrReference<" .. member_type .. ">"
else
return "LuaReference<" .. member_type .. ">"
end
end
end
for enum_name, _ in pairs(enums) do
if enum_name == member_type then
return "LuaEnum<" .. member_type .. ">"
end
end
error("'"..member_type.."' is not a build-in type and is not defined in class_definitions.lua")
end
end
-- Loads an instance of class_name (which must be the first thing on the stack) into a local
-- variable, named "instance". Only use for classes (not enums/primitives).
function load_instance(class_name)
if not classes[class_name] then
error("'"..class_name.."' is not defined in class_definitions.lua")
end
return class_name .. "& instance = " .. retrieve_lua_value(class_name, 1) .. ";"
end
-- Returns a full statement that checks whether the given stack item has the given value.
-- The statement does not return if the check fails (long jump back into the Lua error handling).
function check_lua_value(value_type, stack_position)
return member_type_to_cpp_type(value_type).."::check(L, " .. stack_position .. ");"
end
-- Returns an expression that evaluates to `true` if the stack has an object of the given type
-- at the given position.
function has_lua_value(value_type, stack_position)
return member_type_to_cpp_type(value_type) .. "::has(L, " .. stack_position .. ")"
end
-- Returns code to retrieve a lua value from the stack and store it into
-- a C++ variable
function retrieve_lua_value(value_type, stack_position)
return member_type_to_cpp_type(value_type) .. "::get(L, " .. stack_position .. ")"
end
-- Returns code to take a C++ variable of the given type and push a lua version
-- of it onto the stack.
function push_lua_value(in_variable, value_type)
local wrapper
if value_type:sub(-1) == "&" then
-- A reference is to be pushed. Copying the referred to object may not be allowed (it may
-- be a reference to a global game object).
local t = value_type:sub(1, -2)
if classes[t] then
if classes[t].by_value_and_reference then
-- special case becaus member_type_to_cpp_type would return LuaValueOrReference,
-- which does not have a push function.
wrapper = "LuaReference<" .. t .. ">"
else
wrapper = member_type_to_cpp_type(t)
end
else
wrapper = member_type_to_cpp_type(t)
end
elseif classes[value_type] then
-- Not a native Lua type, but it's not a reference, so we *have* to copy it (the value would
-- go out of scope otherwise). Copy semantic means using LuaValue.
wrapper = "LuaValue<" .. value_type .. ">"
else
-- Either an undefined type or a native Lua type, both is handled in member_type_to_cpp_type
wrapper = member_type_to_cpp_type(value_type)
end
return wrapper .. "::push(L, " .. in_variable .. ");"
end
-- Generates a getter function for a specific class and member variable.
function generate_getter(class_name, member_name, member_type, cpp_name)
local function_name = "get_" .. class_name .. "_" .. member_name
local text = "static int "..function_name.."(lua_State *L) {"..br
text = text .. tab .. load_instance(class_name)..br
-- adding the "&" to the type, so push_lua_value knows it's a reference.
text = text .. tab .. push_lua_value("instance."..cpp_name, member_type .. "&")..br
text = text .. tab .. "return 1; // 1 return value"..br
text = text .. "}" .. br
return text
end
-- Generates a setter function for a specific class and member variable.
function generate_setter(class_name, member_name, member_type, cpp_name)
local function_name = "set_" .. class_name .. "_" .. member_name
local text = "static int "..function_name.."(lua_State *L) {"..br
text = text .. tab .. load_instance(class_name)..br
text = text .. tab .. check_lua_value(member_type, 2)..";"..br
text = text .. tab .. "instance."..cpp_name.." = " .. retrieve_lua_value(member_type, 2)..";"..br
text = text .. tab .. "return 0; // 0 return values"..br
text = text .. "}" .. br
return text
end
-- Generates a function wrapper for a global function. "function_to_call" can be any string
-- that works as a "function", including expressions like "g->add_msg"
function generate_global_function_wrapper(function_name, function_to_call, args, rval)
local text = "static int global_"..function_name.."(lua_State *L) {"..br
for i, arg in ipairs(args) do
text = text .. tab .. check_lua_value(arg, i)..br
-- Needs to be auto, can be a proxy object, a real reference, or a POD.
-- This will be resolved when the functin is called. The C++ compiler will convert
-- the auto to the expected parameter type.
text = text .. tab .. "auto && parameter"..i .. " = " .. retrieve_lua_value(arg, i)..";"..br
end
local func_invoc = function_to_call .. "("
for i, arg in ipairs(args) do
func_invoc = func_invoc .. "parameter"..i
if next(args, i) then func_invoc = func_invoc .. ", " end
end
func_invoc = func_invoc .. ")"
if rval then
text = text .. tab .. push_lua_value(func_invoc, rval)..br
text = text .. tab .. "return 1; // 1 return values"..br
else
text = text .. tab .. func_invoc .. ";"..br
text = text .. tab .. "return 0; // 0 return values"..br
end
text = text .. "}"..br
return text
end
--[[
To allow function overloading, we need to create a function that somehow detects the input
types and calls the matching C++ overload.
First step is to restructure the input: instead of
functions = {
{ name = "f", ... },
{ name = "f", ... },
{ name = "f", ... },
}
we want a decision tree. The leafs of the tree are the rval entries (they can be different for
each overload, but they do not affect the overload resolution).
Example: functions = {
r = { rval = "int", cpp_name = "f" }
"string" = {
r = { rval = "int", cpp_name = "f" }
},
"int" = {
r = { rval = "bool", cpp_name = "f" }
"int" = {
r = { rval = "void", cpp_name = "f" }
},
"string" = {
r = { rval = "int", cpp_name = "f" }
}
}
}
Means: `int f()` `int f(string)` `bool f(int)` void f(int, int)` `int f(int, string)`
Leafs are marked by the presence of rval entries.
--]]
function generate_overload_tree(classes)
for class_name, value in pairs(classes) do
local functions_by_name = {}
for _, func in ipairs(value.functions) do
if not func.name then
print("Every function of " .. class_name .. " needs a name, doesn't it?")
end
-- Create the table now. In the next loop below, we can simply assume it already exists
functions_by_name[func.name] = {}
end
-- This creates the mentioned tree: each entry has the key matching the parameter type,
-- and the final table (the leaf) has a `r` entry.
for _, func in ipairs(value.functions) do
local root = functions_by_name[func.name]
for _, arg in pairs(func.args) do
if not root[arg] then
root[arg] = {}
end
root = root[arg]
end
root.r = { rval = func.rval, cpp_name = func.cpp_name or func.name }
end
value.functions = functions_by_name
if value.new then
local new_root = {}
for _, func in ipairs(value.new) do
local root = new_root
for _, arg in pairs(func) do
if not root[arg] then
root[arg] = {}
end
root = root[arg]
end
root.r = { rval = nil, cpp_name = class_name .. "::" .. class_name }
end
value.new = new_root
end
end
end
--[[
This (recursive) function handles function overloading:
- function_name: actual function name (only for showing an error message)
- args: tree of argument (see generate_overload_tree)
- indentation: level of indentation of the source code (only used for nice formatting)
- stack_index: index (1-based, because this is Lua) of the currently handled argument.
- cbc: callback that returns the C++ code that actually calls the C++ function.
Its parameters:
- indentation: level of indentation it should use
- stack_index: number of parameters it can use (C++ variables parameter1, parameter2 and so on)
- rval: type of the object the C++ function returns (can be nil)
- cpp_name: name of the C++ function to call.
--]]
function insert_overload_resolution(function_name, args, cbc, indentation, stack_index)
local ind = string.rep(" ", indentation)
local text = ""
-- Number of choices that can be made for function overloading
local count = 0
for _ in pairs(args) do count = count + 1 end
local more = (count ~= 1)
-- If we can chose several overloads at this point (more=true), we have to add if statements
-- and have to increase the indentation inside of them.
-- Otherwise (no choices), we keep everything at the same indentation level.
-- (e.g. no overload at all, or this parameter is the same for all overloads).
local nsi = stack_index + 1 -- next stack_index
local ni = more and (indentation + 1) or indentation -- next indentation
local mind = more and (ind .. tab) or ind -- more indentation
local valid_types = "" -- list of acceptable types, for the error message
for arg_type, more_args in sorted_pairs(args) do
if arg_type == "r" then
-- handled outside this loop
else
if more then
-- Either check the type here (and continue when it's fine)
text = text..ind.."if("..has_lua_value(arg_type, nsi)..") {"..br
else
-- or check it here and let Lua bail out.
text = text..ind..check_lua_value(arg_type, nsi)..br
end
-- Needs to be auto, can be a proxy object, a real reference, or a POD.
-- This will be resolved when the functin is called. The C++ compiler will convert
-- the auto to the expected parameter type.
text = text..mind.."auto && parameter"..stack_index.." = "..retrieve_lua_value(arg_type, nsi)..";"..br
text = text..insert_overload_resolution(function_name, more_args, cbc, ni, nsi)
if more then
text = text..ind.."}"..br
end
valid_types = valid_types.." or "..arg_type
end
end
-- An overload can be called at this level, all required parameters are already extracted.
if args.r then
if more then
text = text .. ind .. "if(lua_gettop(L) == "..stack_index..") {"..br
end
-- If we're here, any further arguments will ignored, so raise an error if there are any left over
text = text..mind.."if(lua_gettop(L) > "..stack_index..") {"..br
text = text..mind..tab.."return luaL_error(L, \"Too many arguments to "..function_name..", expected only "..stack_index..", got %d\", lua_gettop(L));"..br
text = text..mind.."}"..br
text = text .. cbc(ni, stack_index - 1, args.r.rval, args.r.cpp_name)
if more then
text = text .. ind .. "}"..br
end
valid_types = valid_types .. " or nothing at all"
end
-- If more is false, there was no branching (no `if` statement) generated, but a return
-- statement had already been made, so this error would be unreachable code.
if more then
text = text .. ind .. "return luaL_argerror(L, "..stack_index..", \"Unexpected type, expected are "..valid_types:sub(5).."\");"..br
end
return text
end
-- Generate a wrapper around a class function(method) that allows us to call a method of a specific
-- C++ instance by calling the method on the corresponding lua wrapper, e.g.
-- monster:name() in lua translates to monster.name() in C++
function generate_class_function_wrapper(class_name, function_name, func, cur_class_name)
local text = "static int func_" .. class_name .. "_" .. function_name .. "(lua_State *L) {"..br
-- retrieve the object to call the function on from the stack.
text = text .. tab .. load_instance(class_name)..br
local cbc = function(indentation, stack_index, rval, function_to_call)
local tab = string.rep(" ", indentation)
local func_invoc
if cur_class_name == class_name then
func_invoc = "instance"
else
--[[
If we call a function of the parent class, we need to call it through
a reference to the parent class, otherwise we get into trouble with default parameters:
Example:
class A { void f(int = 0); }
class B : A { void f(int); }
This won't work: B b; b.f();
But this will: B b; static_cast<A&>(b).f()
--]]
func_invoc = "static_cast<"..cur_class_name.."&>(instance)"
end
func_invoc = func_invoc .. "."..function_to_call .. "("
for i = 1,stack_index do
func_invoc = func_invoc .. "parameter"..i
if i < stack_index then func_invoc = func_invoc .. ", " end
end
func_invoc = func_invoc .. ")"
local text
if rval then
text = tab .. push_lua_value(func_invoc, rval)..br
text = text .. tab .. "return 1; // 1 return values"..br
else
text = tab .. func_invoc .. ";"..br
text = text .. tab .. "return 0; // 0 return values"..br
end
return text
end
text = text .. insert_overload_resolution(function_name, func, cbc, 1, 1)
text = text .. "}"..br
return text
end
function generate_constructor(class_name, args)
local text = "static int new_" .. class_name .. "(lua_State *L) {"..br
local cbc = function(indentation, stack_index, rval, function_to_call)
local tab = string.rep(" ", indentation)
-- Push is always done on a value, never on a pointer/reference, therefor don't use
-- `push_lua_value` (which uses member_type_to_cpp_type to get either LuaValue or LuaReference).
local text = tab .. "LuaValue<" .. class_name .. ">::push(L"
for i = 1,stack_index do
text = text .. ", parameter"..i
end
text = text .. ");"..br
text = text .. tab .. "return 1; // 1 return values"..br
return text
end
text = text .. insert_overload_resolution(class_name .. "::" .. class_name, args, cbc, 1, 1)
text = text .. "}"..br
return text
end
function generate_operator(class_name, operator_id, cppname)
local text = "static int op_" .. class_name .. "_" .. operator_id .. "(lua_State *L) {"..br
text = text .. tab .. "const " .. class_name .. " &lhs = " .. retrieve_lua_value(class_name, 1) .. ";"..br
text = text .. tab .. "const " .. class_name .. " &rhs = " .. retrieve_lua_value(class_name, 2) .. ";"..br
text = text .. tab .. "bool rval = "
if classes[class_name].by_value then
text = text .. "lhs " .. cppname .. " rhs";
else
-- Both objects are pointers, they need to point to the same object to be equal.
text = text .. "&lhs " .. cppname .. " &rhs";
end
text = text .. ";"..br
text = text .. tab .. push_lua_value("rval", "bool")..br
text = text .. tab .. "return 1; // 1 return values"..br
text = text .. "}"..br
return text
end
-- Generate our C++ source file with all wrappers for accessing variables and functions from lua.
-------------------------------------------------------------------------------------------------
local cpp_output = "// This file was automatically generated by lua/generate_bindings.lua"..br
local lua_output = ""
dofile "../../lua/class_definitions.lua"
generate_overload_tree(classes)
function generate_accessors(class, class_name)
-- Generate getters and setters for our player attributes.
for key, attribute in sorted_pairs(class) do
cpp_output = cpp_output .. generate_getter(class_name, key, attribute.type, attribute.cpp_name or key)
if attribute.writable then
cpp_output = cpp_output .. generate_setter(class_name, key, attribute.type, attribute.cpp_name or key)
end
end
end
function generate_class_function_wrappers(functions, class_name, cur_class_name)
for index, func in sorted_pairs(functions) do
cpp_output = cpp_output .. generate_class_function_wrapper(class_name, index, func, cur_class_name)
end
end
for class_name, class in sorted_pairs(classes) do
while class do
generate_accessors(class.attributes, class_name)
class = classes[class.parent]
end
end
for class_name, class in sorted_pairs(classes) do
local cur_class_name = class_name
while class do
generate_class_function_wrappers(class.functions, class_name, cur_class_name)
if class.new then
cpp_output = cpp_output .. generate_constructor(class_name, class.new)
end
if class.has_equal then
cpp_output = cpp_output .. generate_operator(class_name, "eq", "==")
end
cur_class_name = class.parent
class = classes[class.parent]
end
end
for name, func in sorted_pairs(global_functions) do
cpp_output = cpp_output .. generate_global_function_wrapper(name, func.cpp_name, func.args, func.rval)
end
-- luaL_Reg is the name of the struct in C which this creates and returns.
function luaL_Reg(cpp_name, lua_name)
return tab .. '{"' .. lua_name .. '", ' .. cpp_name .. '},' .. br
end
-- Creates the LuaValue<T>::FUNCTIONS array, containing all the public functions of the class.
function generate_functions_static(cpp_type, class, class_name)
cpp_output = cpp_output .. "template<>" .. br
cpp_output = cpp_output .. "const luaL_Reg " .. cpp_type .. "::FUNCTIONS[] = {" .. br
while class do
for name, _ in sorted_pairs(class.functions) do
cpp_output = cpp_output .. luaL_Reg("func_" .. class_name .. "_" .. name, name)
end
if class.new then
cpp_output = cpp_output .. luaL_Reg("new_" .. class_name, "__call")
end
if class.has_equal then
cpp_output = cpp_output .. luaL_Reg("op_" .. class_name .. "_eq", "__eq")
end
class = classes[class.parent]
end
cpp_output = cpp_output .. tab .. "{NULL, NULL}" .. br -- sentinel to indicate end of array
cpp_output = cpp_output .. "};" .. br
end
-- Creates the LuaValue<T>::READ_MEMBERS map, containing the getters. Example:
-- const LuaValue<foo>::MRMap LuaValue<foo>::READ_MEMBERS{ { "id", foo_get_id }, ... };
function generate_read_members_static(cpp_type, class, class_name)
cpp_output = cpp_output .. "template<>" .. br
cpp_output = cpp_output .. "const " .. cpp_type .. "::MRMap " .. cpp_type .. "::READ_MEMBERS{" .. br
while class do
for key, attribute in sorted_pairs(class.attributes) do
local function_name = "get_" .. class_name .. "_" .. key
cpp_output = cpp_output .. tab .. "{\"" .. key .. "\", " .. function_name .. "}," .. br
end
class = classes[class.parent]
end
cpp_output = cpp_output .. "};" .. br
end
-- Creates the LuaValue<T>::READ_MEMBERS map, containing the setters. Example:
-- const LuaValue<foo>::MWMap LuaValue<foo>::WRITE_MEMBERS{ { "id", foo_set_id }, ... };
function generate_write_members_static(cpp_type, class, class_name)
cpp_output = cpp_output .. "template<>" .. br
cpp_output = cpp_output .. "const " .. cpp_type .. "::MWMap " .. cpp_type .. "::WRITE_MEMBERS{" .. br
while class do
for key, attribute in sorted_pairs(class.attributes) do
if attribute.writable then
local function_name = "set_" .. class_name .. "_" .. key
cpp_output = cpp_output .. tab .. "{\"" .. key .. "\", " .. function_name .. "}," .. br
end
end
class = classes[class.parent]
end
cpp_output = cpp_output .. "};" .. br
end
-- The static constant is always define in LuaValue (LuaReference gets it via inheritance)
-- But LuaReference inherits from LuaValue<T*>!
function wrapper_base_class(class_name)
-- This must not be LuaReference because it is used for declaring/defining the static members
-- and those should onloy exist for LuaValue.
if classes[class_name].by_value then
return "LuaValue<" .. class_name .. ">"
else
return "LuaValue<" .. class_name .. "*>"
end
end
function generate_LuaValue_constants(class_name, class, by_value_and_reference)
local cpp_name = ""
local metatable_name = ""
if by_value_and_reference then
-- A different metatable name, to allow the C++ wrappers to detect what the
-- object from Lua refers to. The wrappers can thereby be used by both types
-- at the same type. In other words: the created static functions `get_foo_member`
-- can be called on a value that was pushed to Lua via `Lua<foo>::push` (and is a value),
-- and values pushed via `LuaReference<foo>::push` (which is a pointer).
metatable_name = "value_of_" .. class_name .. "_metatable"
cpp_name = "LuaValue<" .. class_name .. ">"
else
metatable_name = class_name .. "_metatable"
cpp_name = wrapper_base_class(class_name)
end
cpp_output = cpp_output .. "template<>" .. br
cpp_output = cpp_output .. "const char * const " .. cpp_name .. "::METATABLE_NAME = \"" .. metatable_name .. "\";" .. br
cpp_output = cpp_output .. "template<>" .. br
cpp_output = cpp_output .. cpp_name.."::Type *"..cpp_name.."::get_subclass( lua_State* const S, const int i) {"..br
for child, class in sorted_pairs(classes) do
-- Note: while the function get_subclass resides in LuaValue<T>, this calls into LuaValue or
-- LuaReference, that way we get a simple pointer. Unconditionally calling LuaValue<T>::get,
-- would result in returning monster** (LuaValue<T>::get returns a T&, applying `&` gives T*).
-- Now consider that T is already a pointer for LuaValue<monster*>, so T* would be monster**
-- And that can not be converted to Creature**!
-- In the end, this function does not return T*. but std::remove_pointer<T>::type* and that
-- is basically T* (if T is not a pointer) or T (if T is already a pointer).
local cpp_child_name = member_type_to_cpp_type(child);
if class.parent == class_name then
cpp_output = cpp_output .. tab .. "if("..cpp_child_name.."::has(S, i)) {" .. br
cpp_output = cpp_output .. tab .. tab .. "return &"..cpp_child_name.."::get( S, i );" .. br
cpp_output = cpp_output .. tab .. "}" .. br
end
end
cpp_output = cpp_output .. tab .. "(void)S; (void)i;" .. br -- just in case to prevent warnings
cpp_output = cpp_output .. tab .. "return nullptr;" .. br
cpp_output = cpp_output .. "}" .. br
generate_functions_static(cpp_name, class, class_name)
generate_read_members_static(cpp_name, class, class_name)
generate_write_members_static(cpp_name, class, class_name)
end
-- Create the static constant members of LuaValue
for class_name, class in sorted_pairs(classes) do
generate_LuaValue_constants(class_name, class, false)
if class.by_value_and_reference then
if class.by_value then
error("by_value_and_reference only works with classes that have `by_value = false`")
end
generate_LuaValue_constants(class_name, class, true)
end
end
-- Create a function that calls load_metatable on all the registered LuaValue's
cpp_output = cpp_output .. "static void load_metatables(lua_State* const L) {" .. br
for class_name, class in sorted_pairs(classes) do
local cpp_name = wrapper_base_class(class_name)
-- If the class has a constructor, it should be exposed via a global name (which is the class name)
if class.new then
cpp_output = cpp_output .. tab .. cpp_name .. "::load_metatable( L, \"" .. class_name .. "\" );" .. br
else
cpp_output = cpp_output .. tab .. cpp_name .. "::load_metatable( L, nullptr );" .. br
end
end
cpp_output = cpp_output .. "}" .. br
-- Create bindings lists for enums
for enum_name, values in sorted_pairs(enums) do
local cpp_name = "LuaEnum<"..enum_name..">"
cpp_output = cpp_output .. "template<>" .. br
cpp_output = cpp_output .. "const "..cpp_name.."::EMap "..cpp_name.."::BINDINGS = {"..br
for _, name in ipairs(values) do
cpp_output = cpp_output .. tab.."{\""..name.."\", "..name.."},"..br
end
cpp_output = cpp_output .. "};" .. br
end
-- Create a lua registry with the global functions
cpp_output = cpp_output .. "static const struct luaL_Reg gamelib [] = {"..br
for name, func in sorted_pairs(global_functions) do
cpp_output = cpp_output .. tab .. '{"'..name..'", global_'..name..'},'..br
end
cpp_output = cpp_output .. tab .. "{NULL, NULL}"..br.."};"..br
-- We generated our binding, now write it to a .cpp file for inclusion in
-- the main source code.
function writeFile(path,data)
local file = io.open(path,"wb")
file:write(data)
file:close()
end
writeFile("catabindings.cpp", cpp_output)

View File

@ -1,115 +0,0 @@
#include "lua_console.h"
#include <map>
#include "catalua.h"
#include "input.h"
#include "string_input_popup.h"
lua_console::lua_console() : cWin( catacurses::newwin( lines, width, 0, 0 ) ),
iWin( catacurses::newwin( 1, width, lines, 0 ) )
{
#ifndef LUA
text_stack.push_back( {_( "This build does not support Lua." ), c_red} );
#else
text_stack.push_back( {_( "Welcome to the Lua console! Here you can enter Lua code." ), c_green} );
#endif
text_stack.push_back( {_( "Press [Esc] to close the Lua console." ), c_blue} );
}
lua_console::~lua_console() = default;
std::string lua_console::get_input()
{
std::map<long, std::function<bool()>> callbacks {
{
KEY_ESCAPE, [this]()
{
this->quit();
return false;
}
},
{
KEY_NPAGE, [this]()
{
this->scroll_up();
return false;
}
},
{
KEY_PPAGE, [this]()
{
this->scroll_down();
return false;
}
} };
string_input_popup popup;
popup.window( iWin, 0, 0, width )
.max_length( width )
.identifier( "LUA" );
popup.callbacks = callbacks;
popup.query();
return popup.text();
}
void lua_console::draw()
{
werase( cWin );
// Some juggling to make sure text is aligned with the bottom of the console.
int stack_size = text_stack.size() - scroll;
for( int i = lines; i > lines - stack_size && i >= 0; i-- ) {
auto line = text_stack[stack_size - 1 - ( lines - i )];
mvwprintz( cWin, i - 1, 0, line.second, line.first );
}
wrefresh( cWin );
}
void lua_console::quit()
{
done = true;
}
void lua_console::scroll_down()
{
scroll = std::min( std::max( ( static_cast<int>( text_stack.size() ) ) - lines, 0 ), scroll + 1 );
draw();
}
void lua_console::scroll_up()
{
scroll = std::max( 0, scroll - 1 );
draw();
}
void lua_console::read_stream( std::stringstream &stream, nc_color text_color )
{
std::string line;
while( std::getline( stream, line ) ) {
for( auto str : foldstring( line, width ) ) {
text_stack.push_back( {str, text_color} );
}
}
stream.str( std::string() ); // empty the buffer
stream.clear();
}
void lua_console::run()
{
while( !done ) {
draw();
std::string input = get_input();
#ifdef LUA
call_lua( input );
read_stream( lua_output_stream, c_white );
read_stream( lua_error_stream, c_red );
#else
text_stack.push_back( {_( "This build does not support Lua." ), c_red} );
text_stack.push_back( {_( "Press [Esc] to close the Lua console." ), c_blue} );
#endif // LUA
}
}

View File

@ -1,42 +0,0 @@
#pragma once
#ifndef LUA_CONSOLE_H
#define LUA_CONSOLE_H
#include <string>
#include <utility>
#include <vector>
#include "cursesdef.h"
#include "output.h"
class nc_color;
class lua_console
{
public:
lua_console();
~lua_console();
void run();
private:
const int width = TERMX;
const int lines = 10;
catacurses::window cWin;
catacurses::window iWin;
std::vector<std::pair<std::string, nc_color>> text_stack;
std::string get_input();
void draw();
bool done = false;
int scroll = 0;
void read_stream( std::stringstream &stream, nc_color text_color );
void quit();
void scroll_up();
void scroll_down();
};
#endif // LUA_CONSOLE_H

View File

@ -844,13 +844,8 @@ bool main_menu::load_character_tab()
color1 = c_light_cyan;
color2 = h_light_cyan;
} else {
if( world_generator->world_need_lua_build( world_name ) ) {
color1 = c_dark_gray;
color2 = h_dark_gray;
} else {
color1 = c_white;
color2 = h_white;
}
color1 = c_white;
color2 = h_white;
}
mvwprintz( w_open, line, 15 + iMenuOffsetX + extra_w / 2,
( sel2 == i ? color2 : color1 ), "%s (%d)",
@ -898,12 +893,7 @@ bool main_menu::load_character_tab()
mvwprintz( w_open, iMenuOffsetY - 2 - sel2, 15 + iMenuOffsetX + extra_w / 2,
h_white, "%s", wn.c_str() );
if( ( wn != "TUTORIAL" && wn != "DEFENSE" ) && world_generator->world_need_lua_build( wn ) ) {
savegames.clear();
mvwprintz( w_open, iMenuOffsetY - 2 - sel2, 40 + iMenuOffsetX + extra_w / 2,
c_red, "%s", _( "This world requires the game to be compiled with Lua." ) );
on_error();
} else if( savegames.empty() ) {
if( savegames.empty() ) {
mvwprintz( w_open, iMenuOffsetY - 2 - sel2, 40 + iMenuOffsetX + extra_w / 2,
c_red, "%s", _( "No save games found!" ) );
on_error();

View File

@ -8,7 +8,6 @@
#include <sstream>
#include "ammo.h"
#include "catalua.h"
#include "computer.h"
#include "coordinate_conversions.h"
#include "coordinates.h"
@ -209,14 +208,6 @@ void mapgen_function_builtin::generate( map *m, const oter_id &terrain_type, con
const time_point &t, float d )
{
( *fptr )( m, terrain_type, mgd, t, d );
const std::string mapgen_generator_type = "builtin";
const tripoint terrain_tripoint = sm_to_omt_copy( m->get_abs_sub() );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( mapgen_generator_type );
lua_callback_args_info.emplace_back( terrain_type.id().str() );
lua_callback_args_info.emplace_back( terrain_tripoint );
lua_callback( "on_mapgen_finished", lua_callback_args_info );
}
/////////////////////////////////////////////////////////////////////////////////
@ -322,29 +313,6 @@ load_mapgen_function( JsonObject &jio, const std::string &id_base,
} else {
debugmsg( "oter_t[%s]: Invalid mapgen function (missing \"name\" value).", id_base.c_str() );
}
} else if( mgtype == "lua" ) { // lua script
if( jio.has_string( "script" ) ) { // minified into one\nline
const std::string mgscript = jio.get_string( "script" );
ret = std::make_shared<mapgen_function_lua>( mgscript, mgweight );
oter_mapgen[id_base].push_back( ret );
} else if( jio.has_array( "script" ) ) { // or 1 line per entry array
std::string mgscript;
JsonArray jascr = jio.get_array( "script" );
while( jascr.has_more() ) {
mgscript += jascr.next_string();
mgscript += "\n";
}
ret = std::make_shared<mapgen_function_lua>( mgscript, mgweight );
oter_mapgen[id_base].push_back( ret );
// @todo: pass dirname current.json, because the latter two are icky
// } else if ( jio.has_string("file" ) { // or "same-dir-as-this/json/something.lua
} else {
debugmsg( "oter_t[%s]: Invalid mapgen function (missing \"script\" or \"file\" value).",
id_base.c_str() );
}
#ifndef LUA
dbg( D_ERROR ) << "oter_t " << id_base << ": mapgen entry requires a build with LUA=1.";
#endif
} else if( mgtype == "json" ) {
if( jio.has_object( "object" ) ) {
JsonObject jo = jio.get_object( "object" );
@ -358,7 +326,7 @@ load_mapgen_function( JsonObject &jio, const std::string &id_base,
debugmsg( "oter_t[%s]: Invalid mapgen function type: %s", id_base.c_str(), mgtype.c_str() );
}
} else {
debugmsg( "oter_t[%s]: Invalid mapgen function (missing \"method\" value, must be \"builtin\", \"lua\", or \"json\").",
debugmsg( "oter_t[%s]: Invalid mapgen function (missing \"method\" value, must be \"builtin\" or \"json\").",
id_base.c_str() );
}
return ret;
@ -1908,17 +1876,6 @@ bool mapgen_function_json::setup_internal( JsonObject &jo )
fill_ter = ter_str_id( jo.get_string( "fill_ter" ) ).id();
}
if( jo.has_string( "lua" ) ) { // minified into one\nline
luascript = jo.get_string( "lua" );
} else if( jo.has_array( "lua" ) ) { // or 1 line per entry array
luascript.clear();
JsonArray jascr = jo.get_array( "lua" );
while( jascr.has_more() ) {
luascript += jascr.next_string();
luascript += "\n";
}
}
if( jo.has_member( "rotation" ) ) {
rotation = jmapgen_int( jo, "rotation" );
}
@ -2263,7 +2220,7 @@ void mapgen_function_json_base::formatted_set_incredibly_simple( map &m, int off
* Apply mapgen as per a derived-from-json recipe; in theory fast, but not very versatile
*/
void mapgen_function_json::generate( map *m, const oter_id &terrain_type, const mapgendata &md,
const time_point &t, float d )
const time_point &, float d )
{
if( fill_ter != t_null ) {
m->draw_fill_background( fill_ter );
@ -2274,9 +2231,6 @@ void mapgen_function_json::generate( map *m, const oter_id &terrain_type, const
for( auto &elem : setmap_points ) {
elem.apply( md, 0, 0 );
}
if( ! luascript.empty() ) {
lua_mapgen( m, terrain_type, md, t, d, luascript );
}
place_stairs( m, terrain_type, md );
@ -2287,14 +2241,6 @@ void mapgen_function_json::generate( map *m, const oter_id &terrain_type, const
if( terrain_type->is_rotatable() ) {
mapgen_rotate( m, terrain_type, false );
}
const std::string mapgen_generator_type = "json";
const tripoint terrain_tripoint = sm_to_omt_copy( m->get_abs_sub() );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( mapgen_generator_type );
lua_callback_args_info.emplace_back( terrain_type.id().str() );
lua_callback_args_info.emplace_back( terrain_tripoint );
lua_callback( "on_mapgen_finished", lua_callback_args_info );
}
void mapgen_function_json_nested::nest( const mapgendata &dat, int offset_x, int offset_y,
@ -2349,47 +2295,6 @@ void jmapgen_objects::apply( const mapgendata &dat, int offset_x, int offset_y,
}
}
/////////////////////////////////////////////////////////////////////////////////
///// lua mapgen functions
// wip: need more bindings. Basic stuff works
#ifndef LUA
int lua_mapgen( map *m, const oter_id &terrain_type, const mapgendata &mgd, const time_point &t,
float d, const std::string & )
{
mapgen_crater( m, terrain_type, mgd, to_turn<int>( t ), d );
mapf::formatted_set_simple( m, 0, 6,
"\
* * ***\n\
** * * *\n\
* * * * *\n\
* ** * *\n\
* * ***\n\
\n\
* * * *\n\
* * * * *\n\
* * * ***\n\
* * * * *\n\
***** *** * *\n\
", mapf::ter_bind( "*", t_paper ), mapf::furn_bind( "*", f_null ) );
return 0;
}
#endif
void mapgen_function_lua::generate( map *m, const oter_id &terrain_type, const mapgendata &mgd,
const time_point &t, float d )
{
lua_mapgen( m, terrain_type, mgd, t, d, scr );
const std::string mapgen_generator_type = "lua";
const tripoint terrain_tripoint = sm_to_omt_copy( m->get_abs_sub() );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( mapgen_generator_type );
lua_callback_args_info.emplace_back( terrain_type.id().str() );
lua_callback_args_info.emplace_back( terrain_tripoint );
lua_callback( "on_mapgen_finished", lua_callback_args_info );
}
/////////////
// TODO: clean up variable shadowing in this function
// unfortunately, due to how absurdly long the function is (over 8000 lines!), it'll be hard to

View File

@ -310,7 +310,6 @@ class mapgen_function_json : public mapgen_function_json_base, public virtual ma
~mapgen_function_json() override = default;
ter_id fill_ter;
std::string luascript;
protected:
bool setup_internal( JsonObject &jo ) override;
@ -335,17 +334,6 @@ class mapgen_function_json_nested : public mapgen_function_json_base
jmapgen_int rotation;
};
/////////////////////////////////////////////////////////////////////////////////
///// lua mapgen
class mapgen_function_lua : public virtual mapgen_function
{
public:
const std::string scr;
mapgen_function_lua( std::string s, int w = 1000 ) : mapgen_function( w ), scr( s ) {
// scr = s; // @todo: if ( luaL_loadstring(L, scr.c_str() ) ) { error }
}
void generate( map *, const oter_id &, const mapgendata &, const time_point &, float ) override;
};
/////////////////////////////////////////////////////////
///// global per-terrain mapgen function lists
/*

View File

@ -100,11 +100,6 @@ void mod_manager::load_replacement_mods( const std::string &path )
} );
}
bool MOD_INFORMATION::need_lua() const
{
return file_exist( path + "/main.lua" ) || file_exist( path + "/preload.lua" );
}
mod_manager::mod_manager()
{
load_replacement_mods( FILENAMES["mods-replacements"] );

View File

@ -36,7 +36,7 @@ struct MOD_INFORMATION {
mod_id ident;
/** Directory to load JSON and Lua from relative to directory containing modinfo.json */
/** Directory to load JSON from relative to directory containing modinfo.json */
std::string path;
/** If set load legacy migrations from this location dependent upon save version */
@ -63,9 +63,6 @@ struct MOD_INFORMATION {
/** Obsolete mods are loaded for legacy saves but cannot be used when starting new worlds */
bool obsolete = false;
/** Does this mod require Lua support? **/
bool need_lua() const;
std::pair<int, std::string> category = { -1, "" };
};

View File

@ -54,14 +54,6 @@ std::string mod_ui::get_information( const MOD_INFORMATION *mod )
info << _( mod->description.c_str() ) << "\n";
}
if( mod->need_lua() ) {
#ifdef LUA
info << _( "This mod requires <color_green>Lua support</color>" ) << "\n";
#else
info << _( "This mod requires <color_red>Lua support</color>" ) << "\n";
#endif
}
std::string note = !mm_tree.is_available( mod->ident ) ? mm_tree.get_node(
mod->ident )->s_errors() : "";
if( !note.empty() ) {

View File

@ -69,13 +69,6 @@ class MonsterGenerator
const std::vector<mtype> &get_all_mtypes() const;
mtype_id get_valid_hallucination() const;
/**
* Registers a LUA based monster attack function.
* @param name The name that is used in the json data to refer to the LUA function.
* It is stored in @ref attack_map
* @param lua_function The LUA id of the LUA function.
*/
void register_monattack_lua( const std::string &name, int lua_function );
friend struct mtype;
friend struct species_type;
friend class mattack_actor;

View File

@ -325,7 +325,6 @@ struct mutation_branch {
/**
* Return the idents of all trait groups that are known.
* This is meant to be accessed at startup by lua to do mod-related modifications of groups.
*/
static std::vector<trait_group::Trait_group_tag> get_all_group_names();
};

View File

@ -70,7 +70,6 @@ void PATH_INFO::update_datadir()
{
// Shared dirs
update_pathname( "gfxdir", FILENAMES["datadir"] + "gfx/" );
update_pathname( "luadir", FILENAMES["datadir"] + "lua/" );
update_pathname( "fontdir", FILENAMES["datadir"] + "font/" );
update_pathname( "rawdir", FILENAMES["datadir"] + "raw/" );
update_pathname( "jsondir", FILENAMES["datadir"] + "core/" );
@ -84,8 +83,6 @@ void PATH_INFO::update_datadir()
update_pathname( "helpdir", FILENAMES["datadir"] + "help/" );
// Shared files
update_pathname( "autoexeclua", FILENAMES["luadir"] + "autoexec.lua" );
update_pathname( "class_defslua", FILENAMES["luadir"] + "class_definitions.lua" );
update_pathname( "title", FILENAMES["titledir"] + "en.title" );
update_pathname( "halloween", FILENAMES["titledir"] + "en.halloween" );
update_pathname( "motd", FILENAMES["motddir"] + "en.motd" );
@ -121,26 +118,21 @@ void PATH_INFO::update_config_dir()
void PATH_INFO::set_standard_filenames()
{
// Special: data_dir lua_dir and gfx_dir
// Special: data_dir and gfx_dir
if( !FILENAMES["base_path"].empty() ) {
#ifdef DATA_DIR_PREFIX
update_pathname( "datadir", FILENAMES["base_path"] + "share/cataclysm-dda/" );
update_pathname( "gfxdir", FILENAMES["datadir"] + "gfx/" );
update_pathname( "luadir", FILENAMES["datadir"] + "lua/" );
#else
update_pathname( "datadir", FILENAMES["base_path"] + "data/" );
update_pathname( "gfxdir", FILENAMES["base_path"] + "gfx/" );
update_pathname( "luadir", FILENAMES["base_path"] + "lua/" );
#endif
} else {
update_pathname( "datadir", "data/" );
update_pathname( "gfxdir", "gfx/" );
update_pathname( "luadir", "lua/" );
}
// Shared dirs
update_pathname( "autoexeclua", FILENAMES["luadir"] + "autoexec.lua" );
update_pathname( "class_defslua", FILENAMES["luadir"] + "class_definitions.lua" );
update_pathname( "fontdir", FILENAMES["datadir"] + "font/" );
update_pathname( "rawdir", FILENAMES["datadir"] + "raw/" );
update_pathname( "jsondir", FILENAMES["datadir"] + "core/" );

View File

@ -16,7 +16,6 @@
#include "bionics.h"
#include "cata_utility.h"
#include "catacharset.h"
#include "catalua.h"
#include "coordinate_conversions.h"
#include "craft_command.h"
#include "cursesdef.h"
@ -3117,11 +3116,6 @@ void player::on_dodge( Creature *source, float difficulty )
melee_attack( *source, false, tec );
}
}
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( source );
lua_callback_args_info.emplace_back( difficulty );
lua_callback( "on_player_dodge", lua_callback_args_info );
}
void player::on_hit( Creature *source, body_part bp_hit,
@ -3198,12 +3192,6 @@ void player::on_hit( Creature *source, body_part bp_hit,
source->add_effect( effect_blind, 2_turns );
}
}
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( source );
lua_callback_args_info.emplace_back( bp_hit );
//lua_callback_args_info.emplace_back( proj );
lua_callback( "on_player_hit", lua_callback_args_info );
}
int player::get_lift_assist() const
@ -3247,11 +3235,6 @@ void player::on_hurt( Creature *source, bool disturb /*= true*/ )
if( is_dead_state() ) {
set_killer( source );
}
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( source );
lua_callback_args_info.emplace_back( disturb );
lua_callback( "on_player_hurt", lua_callback_args_info );
}
bool player::immune_to( body_part bp, damage_unit dam ) const
@ -9889,14 +9872,6 @@ void player::do_read( item &book )
pgettext( "memorial_female", "Reached skill level %1$d in %2$s." ),
skill_level.level(), skill_name );
}
const std::string skill_increase_source = "book";
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( skill_increase_source );
lua_callback_args_info.emplace_back( skill.str() );
lua_callback_args_info.emplace_back( originalSkillLevel + 1 );
lua_callback( "on_player_skill_increased", lua_callback_args_info );
lua_callback( "on_skill_increased" ); // Legacy callback
} else {
add_msg( m_good, _( "%s increases their %s level." ), learner->disp_name().c_str(), skill_name );
}
@ -11141,14 +11116,6 @@ void player::practice( const skill_id &id, int amount, int cap )
int newLevel = get_skill_level( id );
if( is_player() && newLevel > oldLevel ) {
add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel );
const std::string skill_increase_source = "training";
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( skill_increase_source );
lua_callback_args_info.emplace_back( id.str() );
lua_callback_args_info.emplace_back( newLevel );
lua_callback( "on_player_skill_increased", lua_callback_args_info );
lua_callback( "on_skill_increased" ); //Legacy callback
}
if( is_player() && newLevel > cap ) {
//inform player immediately that the current recipe can't be used to train further
@ -12371,47 +12338,26 @@ bool player::has_item_with_flag( const std::string &flag, bool need_charges ) co
void player::on_mutation_gain( const trait_id &mid )
{
morale->on_mutation_gain( mid );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( mid.str() );
lua_callback( "on_player_mutation_gain", lua_callback_args_info );
}
void player::on_mutation_loss( const trait_id &mid )
{
morale->on_mutation_loss( mid );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( mid.str() );
lua_callback( "on_player_mutation_loss", lua_callback_args_info );
}
void player::on_stat_change( const std::string &stat, int value )
{
morale->on_stat_change( stat, value );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( stat );
lua_callback_args_info.emplace_back( value );
lua_callback( "on_player_stat_change", lua_callback_args_info );
}
void player::on_item_wear( const item &it )
{
morale->on_item_wear( it );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( it );
lua_callback( "on_player_item_wear", lua_callback_args_info );
}
void player::on_item_takeoff( const item &it )
{
morale->on_item_takeoff( it );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( it );
lua_callback( "on_player_item_takeoff", lua_callback_args_info );
}
void player::on_worn_item_washed( const item &it )
@ -12431,22 +12377,12 @@ void player::on_effect_int_change( const efftype_id &eid, int intensity, body_pa
}
morale->on_effect_int_change( eid, intensity, bp );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( eid.str() );
lua_callback_args_info.emplace_back( intensity );
lua_callback_args_info.emplace_back( bp );
lua_callback( "on_player_effect_int_change", lua_callback_args_info );
}
void player::on_mission_assignment( mission &new_mission )
{
active_missions.push_back( &new_mission );
set_active_mission( new_mission );
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( new_mission.get_id() );
lua_callback( "on_player_mission_assignment", lua_callback_args_info );
}
void player::on_mission_finished( mission &cur_mission )
@ -12472,10 +12408,6 @@ void player::on_mission_finished( mission &cur_mission )
active_mission = active_missions.front();
}
}
CallbackArgumentContainer lua_callback_args_info;
lua_callback_args_info.emplace_back( getID() );
lua_callback_args_info.emplace_back( cur_mission.get_id() );
lua_callback( "on_player_mission_finished", lua_callback_args_info );
}
const targeting_data &player::get_targeting_data()

View File

@ -157,19 +157,6 @@ WORLDPTR worldfactory::make_new_world( bool show_prompt, const std::string &worl
if( curtab < 0 ) {
return nullptr;
}
} else { // 'Play NOW'
#ifndef LUA
// Silently remove all Lua mods set by default.
for( auto mod_it = retworld->active_mod_order.begin(); mod_it != retworld->active_mod_order.end();
) {
const MOD_INFORMATION &minfo = **mod_it;
if( minfo.need_lua() ) {
mod_it = retworld->active_mod_order.erase( mod_it );
} else {
mod_it++;
}
}
#endif
}
return add_world( std::move( retworld ) );
@ -347,8 +334,6 @@ WORLDPTR worldfactory::pick_world( bool show_prompt )
for( std::vector<std::string>::iterator it = world_names.begin(); it != world_names.end(); ) {
if( *it == "TUTORIAL" || *it == "DEFENSE" ) {
it = world_names.erase( it );
} else if( world_need_lua_build( *it ) ) {
it = world_names.erase( it );
} else {
++it;
}
@ -462,11 +447,7 @@ WORLDPTR worldfactory::pick_world( bool show_prompt )
wprintz( w_worlds, c_yellow, " " );
}
if( world_need_lua_build( world_name ) ) {
wprintz( w_worlds, c_dark_gray, "%s (%lu)", world_name.c_str(), saves_num );
} else {
wprintz( w_worlds, c_white, "%s (%lu)", world_name.c_str(), saves_num );
}
wprintz( w_worlds, c_white, "%s (%lu)", world_name.c_str(), saves_num );
}
//Draw Tabs
@ -522,12 +503,6 @@ WORLDPTR worldfactory::pick_world( bool show_prompt )
}
} while( world_pages[selpage].empty() );
} else if( action == "CONFIRM" ) {
if( world_need_lua_build( world_pages[selpage][sel] ) ) {
popup( _( "Can't start in world [%s]. Some of mods require Lua support." ),
world_pages[selpage][sel].c_str() );
continue;
}
werase( w_worlds );
werase( w_worlds_border );
werase( w_worlds_header );
@ -652,15 +627,7 @@ void worldfactory::draw_mod_list( const catacurses::window &w, int &start, size_
}
const MOD_INFORMATION &mod = **iter;
#ifndef LUA
if( mod.need_lua() ) {
trim_and_print( w, iNum - start, 4, wwidth, c_dark_gray, mod.name() );
} else {
trim_and_print( w, iNum - start, 4, wwidth, c_white, mod.name() );
}
#else
trim_and_print( w, iNum - start, 4, wwidth, c_white, mod.name() );
#endif
if( w_shift ) {
// get shift information for the active item
@ -974,15 +941,6 @@ int worldfactory::show_worldgen_tab_modselection( const catacurses::window &win,
active_header = prev_header;
} else if( action == "CONFIRM" ) {
if( active_header == 0 && !current_tab_mods.empty() ) {
#ifndef LUA
if( current_tab_mods[cursel[0]]->need_lua() ) {
popup( _( "Can't add mod. This mod requires Lua support." ) );
redraw_active = true;
draw_modselection_borders( win, ctxt );
redraw_description = true;
continue;
}
#endif
// try-add
mman_ui->try_add( current_tab_mods[cursel[0]], active_mod_order );
redraw_active = true;
@ -1144,15 +1102,6 @@ to continue, or <color_yellow>%s</color> to go back and review your world." ),
const std::string action = ctxt.handle_input();
if( action == "NEXT_TAB" ) {
#ifndef LUA
for( const mod_id &mod : world->active_mod_order ) {
const MOD_INFORMATION &temp = *mod;
if( temp.need_lua() ) {
popup( _( "Mod '%s' requires Lua support." ), temp.name() );
return -2; // Move back to modselect tab.
}
}
#endif
if( worldname.empty() ) {
mvwprintz( w_confirmation, namebar_y, namebar_x, h_light_gray,
_( "________NO NAME ENTERED!________" ) );
@ -1322,25 +1271,6 @@ void worldfactory::draw_worldgen_tabs( const catacurses::window &w, size_t curre
mvwputch( w, FULL_SCREEN_HEIGHT - 1, FULL_SCREEN_WIDTH - 1, BORDER_COLOR, LINE_XOOX ); // _|
}
bool worldfactory::world_need_lua_build( std::string world_name )
{
#ifndef LUA
WORLDPTR world = get_world( world_name );
if( world == nullptr ) {
return false;
}
for( const mod_id &mod : world->active_mod_order ) {
if( mod.is_valid() && mod->need_lua() ) {
return true;
}
}
#endif
// Prevent unused var error when LUA and RELEASE enabled.
world_name.size();
return false;
}
bool worldfactory::valid_worldname( const std::string &name, bool automated )
{
std::string msg;

View File

@ -112,12 +112,6 @@ class worldfactory
void remove_world( const std::string &worldname );
bool valid_worldname( const std::string &name, bool automated = false );
/**
* World need CDDA build with Lua support
* @param world_name World name to test
* @return True if world can't be loaded without Lua support. False otherwise. (When LUA is defined it's always false).
*/
bool world_need_lua_build( std::string world_name );
/**
* @param delete_folder If true: delete all the files and directories of the given
* world folder. Else just avoid deleting the config files and the directory

View File

@ -62,7 +62,6 @@ mkdir -p $1/share/save
mkdir -p $1/share/memorial
cp -r ./data/. $1/share/cataclysm-dda
cp -r ./gfx $1/share/cataclysm-dda
cp -r ./lua $1/share/cataclysm-dda
cp -r ./lang $1/share/cataclysm-dda
# Copying games.json