Compare commits

..

22 commits

Author SHA1 Message Date
Enno Rehling
585969bf98 2706 follow-up
invert the maintenance flag, update lighthouses before writing reports if that hasn't happened before.
2020-09-27 15:51:32 +02:00
Enno Rehling
220045f423 bug 2628 eindeutige meldung beim abtreiben 2020-09-25 18:20:45 +02:00
Enno Rehling
c2754687dc
Merge pull request from eressea/2706-lighthouse-drifting
2706 lighthouses and drifting
2020-09-25 17:39:26 +02:00
Enno Rehling
43a0368fb4 lighthouses protect from drifting
do not check for maintenance in update_lighthouse, but when the lighthouse is used.
2020-09-24 20:12:51 +02:00
Enno Rehling
65c05f37d2 ships on a ROUTE can drift. 2020-09-24 20:11:45 +02:00
Enno Rehling
d7d3b5d730 Merge branch 'master' into develop 2020-09-24 19:30:16 +02:00
Enno Rehling
912ce0f382 Regentanz / Segen der Erde
Der Effekt soll angeblich nur für Bauern gelten, nicht für Spieler.
2020-09-19 03:59:26 +02:00
Enno Rehling
44ac1d5573 Refactor the wage function for readability.
Add a test for wages at different castle sizes.
2020-09-16 19:04:58 +02:00
Enno Rehling
7af2735b7f screw you, iwyu 2020-09-14 12:37:03 +02:00
Enno Rehling
7712dcc0f0 move gcc-specific signal handling out of main.c 2020-09-13 20:34:45 +02:00
Enno Rehling
b988dd0a7d pointer out of scope 2020-09-13 19:55:10 +02:00
Enno Rehling
0165dbf759 Zauber, revisited.
Mauern der Ewigkeit und Störe Astrale Integrität brauchen keine Stufenangabe, ihre Kosten sind nicht variabel
2020-09-13 19:48:43 +02:00
Enno Rehling
a016ea9a14 Änderung an Heiliger Boden war ein Fehler. 2020-09-13 15:42:01 +02:00
Enno Rehling
1f1125f9fd https://bugs.eressea.de/view.php?id=2651
Materialkosten von Heiliger Boden, Mauern der Ewigkeit, Störe Astrale Integrität steigen mit der Stude des Zaubers.
2020-09-13 15:26:41 +02:00
Enno Rehling
e61b8ad557 update CHANGELOG 2020-09-13 14:33:13 +02:00
Enno Rehling
57b5e50db8 resource visibility, code clarification. 2020-09-13 14:33:13 +02:00
Enno Rehling
7c44ff2241 add a setting for an alternate resource discovery rule. 2020-09-13 14:33:13 +02:00
Enno Rehling
b7aad91ffb division by zero error 2020-09-13 14:33:13 +02:00
Enno Rehling
85f1207af0 teachers do not need to be in an academy.
remove source files for academy.
2020-09-13 14:33:13 +02:00
Enno Rehling
c884138351 coverity complains about possibly missing warden. 2020-09-13 14:33:13 +02:00
Enno Rehling
039d3ecc6b start version 3.26 development Q4/2020 2020-09-13 14:33:13 +02:00
Enno Rehling
1c8248ee0c https://bugs.eressea.de/view.php?id=2701
fix the academy
make academy, curses and potions work for LERNE AUTO
remove E3 study.speedup
2020-09-13 14:33:13 +02:00
320 changed files with 22791 additions and 6814 deletions

View file

@ -1,37 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master, develop ]
pull_request:
branches: [ master, develop ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Install dependencies
run: sudo apt install libexpat1-dev libtolua-dev libncurses5-dev libsqlite3-dev libiniparser-dev libcjson-dev libbsd-dev cppcheck shellcheck luarocks clang-tools
- name: Run .travis.yml build script
uses: ktomk/run-travis-yml@v1
with:
file: .travis.yml
steps: |
install
script
allow-failure: false

2
.gitignore vendored
View file

@ -1,3 +1,4 @@
tolua/
.vscode/
*.orig
eressea.ini
@ -46,3 +47,4 @@ tests/data/185.dat
/critbit/
*.mo
/.vs
/CMakeSettings.json

9
.gitmodules vendored
View file

@ -1,3 +1,12 @@
[submodule "dlmalloc"]
path = dlmalloc
url = https://github.com/ennorehling/dlmalloc.git
[submodule "iniparser"]
path = iniparser
url = https://github.com/ennorehling/iniparser.git
[submodule "cJSON"]
path = cJSON
url = https://github.com/ennorehling/cJSON.git
[submodule "storage"]
path = storage
url = https://github.com/ennorehling/storage.git

View file

@ -1,6 +1,5 @@
sudo: false
language: c
dist: focal
compiler:
- gcc
- clang
@ -10,15 +9,17 @@ addons:
packages:
- libbsd-dev
- libdb-dev
- liblua5.1-dev
- libtolua-dev
- libncurses5-dev
- libsqlite3-dev
- libexpat1-dev
- libiniparser-dev
- libcjson-dev
- valgrind
- cppcheck
- shellcheck
- luarocks
os:
- linux
notifications:
slack:
secure: F89aXLWaE125PaJIlETv12jT4EfH6wLXJmGCPZzrN3OcLn2ahDWqjwuzR7lOEDf2nAISmeMPyDZMhEHXLNHAE5qP6lg9yliYQw5hzGmDK9m1xUq/pPEne/b2Y7K3my1mkRZ6n3asbHgSmBWAfCIk1JN8R5Rv+rmbLuWLc+zofts=

View file

@ -1,23 +1,3 @@
# 3.28
- Bugfix für Schild des Fisches (Solthar)
- Dämonen können magisch reanimiert werden.
- "Schöne Träume" verliert seine Wirkung, wenn der Zauberer stirbt.
- Mit GIB 0 können hungernde Personen an die Bauern gegeben werden.
- Magieresistenz: Einheiten widerstehen nicht Zaubern der eigenen Partei [2733].
- Zauberkosten steigen durch Ring der Macht nicht an.
- Effektiv gezauberte Stufe von Zauber anhängig von Verfügbarkeit der Materialen.
- Ring der Macht und Steinkreis erhöhen nicht die Zauberkosten [2737].
- Limits für Vertrautenzauber korrekt implementiert.
- Kröten und Schlümpfe können nichts lernen.
# 3.27
- Schiffe sind kommentarlos nicht gesegelt [2722].
- Meermenschen konnten nicht mehr anschwimmen [2723].
- Magieresistenz repariert [2724].
- Kleine Änderung an Samenwachstum.
- Umstellung auf neue Versionen von externen Libraries.
# 3.26

View file

@ -1,74 +1,69 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 2.8)
if (WIN32)
file(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH )
file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH )
FILE(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH )
FILE(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH )
endif(WIN32)
project (eressea-server C)
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
if (WIN32)
# make subdirectories build to the same output folders (DLLs):
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
endif (WIN32)
if (MSVC)
find_package (PDCurses)
set (CURSES_FOUND ${PDCURSES_FOUND})
set (CURSES_LIBRARIES ${PDCURSES_LIBRARY})
set (CURSES_INCLUDE_DIRS ${PDCURSES_INCLUDE_DIR})
endif(MSVC)
if (NOT CURSES_FOUND)
set(CURSES_NEED_WIDE TRUE)
set(CURSES_NEED_NCURSES TRUE)
find_package (Curses)
if (NOT CURSES_FOUND)
set(CURSES_NEED_WIDE FALSE)
find_package (Curses REQUIRED)
endif(NOT CURSES_FOUND)
endif (NOT CURSES_FOUND)
find_package (ToLua 5.2 REQUIRED)
#find_package (BerkeleyDB REQUIRED)
find_package (SQLite3 REQUIRED)
find_package (IniParser REQUIRED)
find_package (CJSON REQUIRED)
find_package (EXPAT REQUIRED)
find_package (Lua)
if (NOT LUA_FOUND)
find_package (Lua51 REQUIRED)
endif()
if (MSVC)
find_package (PDCurses)
set (CURSES_FOUND ${PDCURSES_FOUND})
set (CURSES_LIBRARIES ${PDCURSES_LIBRARY})
set (CURSES_INCLUDE_DIR ${PDCURSES_INCLUDE_DIR})
set (HAVE_STRDUP 0)
set (HAVE_STRLCAT 0)
set (HAVE_LIBBSD 0)
set (HAVE_SIGNAL_H 0)
set (HAVE_EXECINFO_H 0)
include (MSVC)
else (MSVC)
include (CheckIncludeFile)
check_include_file(signal.h HAVE_SIGNAL_H)
check_include_file(execinfo.h HAVE_EXECINFO_H)
include (CheckLibraryExists)
check_library_exists(m fmin "" HAVE_LIBM)
check_library_exists(bsd strlcat "" HAVE_LIBBSD)
find_package (Curses)
include (CheckIncludeFile)
CHECK_INCLUDE_FILE(signal.h HAVE_SIGNAL_H)
CHECK_INCLUDE_FILE(execinfo.h HAVE_EXECINFO_H)
CHECK_INCLUDE_FILE(bsd/string.h HAVE_LIBBSD)
include (CheckFunctionExists)
check_function_exists(strdup HAVE_STRDUP)
check_function_exists(strlcat HAVE_STRLCAT)
CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP)
if (HAVE_LIBBSD)
set (HAVE_STRLCAT 1)
include (CheckLibraryExists)
CHECK_LIBRARY_EXISTS(bsd strlcat "bsd/string.h" HAVE_STRLCAT)
else (HAVE_LIBBSD)
CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT)
endif (HAVE_LIBBSD)
endif (MSVC)
find_package (Readline)
if (ERESSEA_DB STREQUAL "db")
find_package (BerkeleyDB REQUIRED QUIET)
else()
find_package (SQLite3 REQUIRED QUIET)
endif()
find_package(EXPAT REQUIRED)
find_package (ToLua REQUIRED)
if (TOLUA_FOUND)
if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.3")
find_package (Lua 5.3 REQUIRED)
elseif (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2")
find_package (Lua 5.2 REQUIRED)
elseif (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.3")
find_package ( Lua 5.3 REQUIRED)
else ()
find_package (Lua51 REQUIRED)
endif()
endif(TOLUA_FOUND)
enable_testing()
add_subdirectory (tools)
add_subdirectory (cJSON)
add_subdirectory (storage)
add_subdirectory (iniparser)
add_subdirectory (clibs)
add_subdirectory (process)
add_subdirectory (src eressea)

View file

@ -1,62 +0,0 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": "",
"variables": [
{
"name": "CMAKE_TOOLCHAIN_FILE",
"value": "${env.VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake",
"type": "STRING"
},
{
"name": "CMAKE_MODULE_PATH",
"value": "${workspaceRoot}/cmake/Modules",
"type": "STRING"
}
]
},
{
"name": "x86-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ],
"variables": [
{
"name": "CMAKE_TOOLCHAIN_FILE",
"value": "${env.VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake",
"type": "STRING"
},
{
"name": "CMAKE_MODULE_PATH",
"value": "${workspaceRoot}/cmake/Modules",
"type": "STRING"
}
]
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": []
}
]
}

View file

@ -5,5 +5,5 @@ test:
s/runtests
clean:
@rm -rf *.log.* Debug/CMake*
@rm -f *.log.*
@find . -name "*~" | xargs rm -f

View file

@ -9,9 +9,8 @@ Eressea depends on a number of external libraries. On a recent
Debian-based Linux system, this is the apt-get command to
install all of them:
sudo apt-get install git cmake gcc make luarocks \
liblua5.2-dev libtolua-dev libncurses5-dev libsqlite3-dev \
libcjson-dev libiniparser-dev libexpat1-dev
sudo apt-get install git cmake gcc make luarocks libxml2-dev \
liblua5.2-dev libtolua-dev libncurses5-dev libsqlite3-dev
# How to check out and build the Eressea server
@ -23,7 +22,6 @@ Here's how you clone and build the source on Linux or macOS:
git clone --recursive git://github.com/eressea/server.git source
cd source
git submodule update --init
s/cmake-init
s/build
If you got this far and all went well, you have built the server, and

1
cJSON Submodule

@ -0,0 +1 @@
Subproject commit 8df81fb497cc48b089a57fcdc3a9933540ebc7c9

2
clibs

@ -1 +1 @@
Subproject commit 61a19671c25184ffece2a2668c37e5b69e9f16a7
Subproject commit 484fbf23e34f6844f1c4e3f685bb6c53cadf5bfe

View file

@ -0,0 +1,50 @@
# -*- cmake -*-
# - Find BerkeleyDB
# Find the BerkeleyDB includes and library
# This module defines
# DB_INCLUDE_DIR, where to find db.h, etc.
# DB_LIBRARIES, the libraries needed to use BerkeleyDB.
# DB_FOUND, If false, do not try to use BerkeleyDB.
# also defined, but not for general use are
# DB_LIBRARY, where to find the BerkeleyDB library.
FIND_PATH(DB_INCLUDE_DIR db.h
/usr/local/include/db4
/usr/local/include
/usr/include/db4
/usr/include
)
SET(DB_NAMES ${DB_NAMES} db)
FIND_LIBRARY(DB_LIBRARY
NAMES ${DB_NAMES}
PATHS /usr/lib /usr/local/lib
)
IF (DB_LIBRARY AND DB_INCLUDE_DIR)
SET(DB_LIBRARIES ${DB_LIBRARY})
SET(DB_FOUND "YES")
ELSE (DB_LIBRARY AND DB_INCLUDE_DIR)
SET(DB_FOUND "NO")
ENDIF (DB_LIBRARY AND DB_INCLUDE_DIR)
IF (DB_FOUND)
IF (NOT DB_FIND_QUIETLY)
MESSAGE(STATUS "Found BerkeleyDB: ${DB_LIBRARIES}")
ENDIF (NOT DB_FIND_QUIETLY)
ELSE (DB_FOUND)
IF (DB_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find BerkeleyDB library")
ENDIF (DB_FIND_REQUIRED)
ENDIF (DB_FOUND)
# Deprecated declarations.
SET (NATIVE_DB_INCLUDE_PATH ${DB_INCLUDE_DIR} )
GET_FILENAME_COMPONENT (NATIVE_DB_LIB_PATH ${DB_LIBRARY} PATH)
MARK_AS_ADVANCED(
DB_LIBRARY
DB_INCLUDE_DIR
)

View file

@ -1,59 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindCJSON
-----------
.. versionadded:: 3.20
Find the cJSON libraries, v3
IMPORTED targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``DaveGamble::CJSON``
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables if found:
``CJSON_INCLUDE_DIRS``
where to find sqlite3.h, etc.
``CJSON_LIBRARIES``
the libraries to link against to use CJSON.
``CJSON_VERSION``
version of the CJSON library found
``CJSON_FOUND``
TRUE if found
#]=======================================================================]
# Look for the necessary header
find_path(CJSON_INCLUDE_DIR cJSON.h PATH_SUFFIXES cjson)
mark_as_advanced(CJSON_INCLUDE_DIR)
# Look for the necessary library
find_library(CJSON_LIBRARY cjson)
mark_as_advanced(CJSON_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CJSON
REQUIRED_VARS CJSON_INCLUDE_DIR CJSON_LIBRARY
VERSION_VAR CJSON_VERSION)
# Create the imported target
if(CJSON_FOUND)
set(CJSON_INCLUDE_DIRS ${CJSON_INCLUDE_DIR})
set(CJSON_LIBRARIES ${CJSON_LIBRARY})
if(NOT TARGET DaveGamble::CJSON)
add_library(DaveGamble::CJSON UNKNOWN IMPORTED)
set_target_properties(DaveGamble::CJSON PROPERTIES
IMPORTED_LOCATION "${CJSON_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${CJSON_INCLUDE_DIR}")
endif()
endif()

View file

@ -1,59 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindIniParser
-----------
.. versionadded:: 3.20
Find the IniParser libraries, v3
IMPORTED targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``Devillard::IniParser``
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables if found:
``IniParser_INCLUDE_DIRS``
where to find sqlite3.h, etc.
``IniParser_LIBRARIES``
the libraries to link against to use IniParser.
``IniParser_VERSION``
version of the IniParser library found
``IniParser_FOUND``
TRUE if found
#]=======================================================================]
# Look for the necessary header
find_path(IniParser_INCLUDE_DIR iniparser.h PATH_SUFFIXES iniparser)
mark_as_advanced(IniParser_INCLUDE_DIR)
# Look for the necessary library
find_library(IniParser_LIBRARY iniparser)
mark_as_advanced(IniParser_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(IniParser
REQUIRED_VARS IniParser_INCLUDE_DIR IniParser_LIBRARY
VERSION_VAR IniParser_VERSION)
# Create the imported target
if(IniParser_FOUND)
set(IniParser_INCLUDE_DIRS ${IniParser_INCLUDE_DIR})
set(IniParser_LIBRARIES ${IniParser_LIBRARY})
if(NOT TARGET Devillard::IniParser)
add_library(Devillard::IniParser UNKNOWN IMPORTED)
set_target_properties(Devillard::IniParser PROPERTIES
IMPORTED_LOCATION "${IniParser_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${IniParser_INCLUDE_DIR}")
endif()
endif()

View file

@ -0,0 +1,47 @@
# - Try to find readline include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(Readline)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# READLINE_ROOT_DIR Set this variable to the root installation of
# readline if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# READLINE_FOUND System has readline, include and lib dirs found
# READLINE_INCLUDE_DIR The readline include directories.
# READLINE_LIBRARY The readline library.
find_path(READLINE_ROOT_DIR
NAMES include/readline/readline.h
)
find_path(READLINE_INCLUDE_DIR
NAMES readline/readline.h
HINTS ${READLINE_ROOT_DIR}/include
)
find_library(READLINE_LIBRARY
NAMES readline
HINTS ${READLINE_ROOT_DIR}/lib
)
if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND Ncurses_LIBRARY)
set(READLINE_FOUND TRUE)
else(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND Ncurses_LIBRARY)
FIND_LIBRARY(READLINE_LIBRARY NAMES readline)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY )
MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY)
endif(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND Ncurses_LIBRARY)
mark_as_advanced(
READLINE_ROOT_DIR
READLINE_INCLUDE_DIR
READLINE_LIBRARY
)

View file

@ -1,69 +1,63 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# - Try to find the SQLite3 library
# Once done this will define
#
# SQLITE3_FOUND - System has SQLite3
# SQLITE3_INCLUDE_DIR - The SQLite3 include directory
# SQLITE3_LIBRARIES - The libraries needed to use SQLite3
# SQLITE3_DEFINITIONS - Compiler switches required for using SQLite3
# SQLITE3_EXECUTABLE - The SQLite3 command line shell
# SQLITE3_VERSION_STRING - the version of SQLite3 found (since CMake 2.8.8)
#[=======================================================================[.rst:
FindSQLite3
-----------
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
#
# 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.)
.. versionadded:: 3.14
# use pkg-config to get the directories and then use these values
# in the find_path() and find_library() calls
find_package(PkgConfig QUIET)
PKG_CHECK_MODULES(PC_SQLITE QUIET sqlite3)
set(SQLITE3_DEFINITIONS ${PC_SQLITE_CFLAGS_OTHER})
Find the SQLite libraries, v3
find_path(SQLITE3_INCLUDE_DIR NAMES sqlite3.h
HINTS
${PC_SQLITE_INCLUDEDIR}
${PC_SQLITE_INCLUDE_DIRS}
)
IMPORTED targets
^^^^^^^^^^^^^^^^
find_library(SQLITE3_LIBRARIES NAMES sqlite3
HINTS
${PC_SQLITE_LIBDIR}
${PC_SQLITE_LIBRARY_DIRS}
)
This module defines the following :prop_tgt:`IMPORTED` target:
find_program(SQLITE3_EXECUTABLE sqlite3)
``SQLite::SQLite3``
if(PC_SQLITE_VERSION)
set(SQLITE3_VERSION_STRING ${PC_SQLITE_VERSION})
elseif(SQLITE3_INCLUDE_DIR AND EXISTS "${SQLITE3_INCLUDE_DIR}/sqlite3.h")
file(STRINGS "${SQLITE3_INCLUDE_DIR}/sqlite3.h" sqlite3_version_str
REGEX "^#define[\t ]+SQLITE_VERSION[\t ]+\".*\"")
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables if found:
``SQLite3_INCLUDE_DIRS``
where to find sqlite3.h, etc.
``SQLite3_LIBRARIES``
the libraries to link against to use SQLite3.
``SQLite3_VERSION``
version of the SQLite3 library found
``SQLite3_FOUND``
TRUE if found
#]=======================================================================]
# Look for the necessary header
find_path(SQLite3_INCLUDE_DIR NAMES sqlite3.h)
mark_as_advanced(SQLite3_INCLUDE_DIR)
# Look for the necessary library
find_library(SQLite3_LIBRARY NAMES sqlite3 sqlite)
mark_as_advanced(SQLite3_LIBRARY)
# Extract version information from the header file
if(SQLite3_INCLUDE_DIR)
file(STRINGS ${SQLite3_INCLUDE_DIR}/sqlite3.h _ver_line
REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\""
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+"
SQLite3_VERSION "${_ver_line}")
unset(_ver_line)
string(REGEX REPLACE "^#define[\t ]+SQLITE_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
SQLITE3_VERSION_STRING "${sqlite3_version_str}")
unset(sqlite3_version_str)
endif()
# handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SQLite3
REQUIRED_VARS SQLite3_INCLUDE_DIR SQLite3_LIBRARY
VERSION_VAR SQLite3_VERSION)
# Create the imported target
if(SQLite3_FOUND)
set(SQLite3_INCLUDE_DIRS ${SQLite3_INCLUDE_DIR})
set(SQLite3_LIBRARIES ${SQLite3_LIBRARY})
if(NOT TARGET SQLite::SQLite3)
add_library(SQLite::SQLite3 UNKNOWN IMPORTED)
set_target_properties(SQLite::SQLite3 PROPERTIES
IMPORTED_LOCATION "${SQLite3_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SQLite3_INCLUDE_DIR}")
endif()
endif()
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLite3
REQUIRED_VARS SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIR
VERSION_VAR SQLITE3_VERSION_STRING)
mark_as_advanced(SQLITE3_INCLUDE_DIR SQLITE3_LIBRARIES SQLITE3_EXECUTABLE)

View file

@ -59,7 +59,7 @@ elseif(TOLUA_INCLUDE_DIR AND EXISTS "${TOLUA_INCLUDE_DIR}/tolua.h")
TOLUA_VERSION_STRING "${tolua_version_str}")
unset(tolua_version_str)
else(PC_TOLUA_VERSION)
message ("TOLUA_VERSION_STRING cannot be determined")
message(ERROR "TOLUA_VERSION_STRING cannot be determined")
endif(PC_TOLUA_VERSION)
# handle the QUIETLY and REQUIRED arguments and set TOLUA_FOUND to TRUE if

19
cmake/Modules/MSVC.cmake Normal file
View file

@ -0,0 +1,19 @@
MACRO (MSVC_CRT_SECURE_NO_WARNINGS)
IF (MSVC)
FOREACH (target ${ARGN})
SET_TARGET_PROPERTIES (${target} PROPERTIES
COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS
)
ENDFOREACH (target)
ENDIF (MSVC)
ENDMACRO (MSVC_CRT_SECURE_NO_WARNINGS)
MACRO (MSVC_SET_WARNING_LEVEL level)
IF (MSVC)
IF(CMAKE_C_FLAGS MATCHES "/W[0-4]")
STRING(REGEX REPLACE "/W[0-4]" "/W${level}" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W${level}")
ENDIF()
ENDIF(MSVC)
ENDMACRO (MSVC_SET_WARNING_LEVEL)

16
conf/e2/catalog.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!DOCTYPE catalog
PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<rewriteURI
uriStartString="config://core/"
rewritePrefix="../../res/core/" />
<rewriteURI
uriStartString="config://game/"
rewritePrefix="../../res/eressea/" />
<rewriteURI
uriStartString="config://default/"
rewritePrefix="../../res/" />
</catalog>

View file

@ -34,7 +34,8 @@
"rules.guard.castle_stop_prob": 0.05,
"rules.guard.region_type_stop_prob": 0.05,
"rules.economy.repopulate_maximum": 500,
"rules.lighthouse.unit_capacity": true
"rules.lighthouse.unit_capacity": true,
"resource.visibility.rule": 0
},
"disabled": [
"jsreport"

16
conf/e3/catalog.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!DOCTYPE catalog
PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<rewriteURI
uriStartString="config://core/"
rewritePrefix="../../res/core/" />
<rewriteURI
uriStartString="config://game/"
rewritePrefix="../../res/e3a/" />
<rewriteURI
uriStartString="config://default/"
rewritePrefix="../../res/" />
</catalog>

View file

@ -110,7 +110,6 @@
"rules.lighthouse.unit_capacity": true,
"movement.shipspeed.skillbonus": 6,
"alliance.auto": "fight",
"alliance.restricted": "fight",
"resource.visibility.rule": 0
"alliance.restricted": "fight"
}
}

View file

@ -1,68 +0,0 @@
{
"include": [
"config://conf/keywords.json",
"config://conf/calendar.json",
"config://conf/prefixes.json",
"config://conf/e2/locales.json",
"config://conf/e2/terrains.json",
"config://conf/e2/items.json",
"config://res/core/ships.xml",
"config://res/core/common/buildings.xml",
"config://res/eressea/buildings.xml",
"config://res/buildings/castle.xml",
"config://res/eressea/races.xml",
"config://res/eressea/artrewards.xml",
"config://res/eressea/spells.xml",
"config://res/eressea/spellbooks/gray.xml",
"config://res/eressea/spellbooks/gwyrrd.xml",
"config://res/eressea/spellbooks/draig.xml",
"config://res/eressea/spellbooks/illaun.xml",
"config://res/eressea/spellbooks/cerddor.xml",
"config://res/eressea/spellbooks/tybied.xml"
],
"disabled": [
"destroy",
"steal",
"number",
"jsreport"
],
"settings": {
"game.name" : "Eressea",
"game.mailcmd" : "ERESSEA",
"game.id" : 2,
"orders.default": "work",
"NewbieImmunity": 8,
"modules.market": false,
"modules.astralspace": true,
"modules.wormhole": true,
"modules.iceberg": true,
"modules.volcano": true,
"monsters.spawn.chance": 50,
"entertain.base": 0,
"entertain.perlevel": 20,
"taxing.perlevel": 20,
"nmr.timeout": 5,
"nmr.removenewbie": false,
"GiveRestriction": 3,
"hunger.long": false,
"hunger.damage": "1d8+6",
"init_spells": 0,
"game.era": 2,
"game.start": 184,
"rules.reserve.twophase": true,
"rules.give.max_men": -1,
"rules.check_overload": false,
"rules.wage.function": 2,
"monsters.spawn.chance" : 0,
"rules.limit.faction": 2500,
"rules.maxskills.magic": 5,
"rules.guard.base_stop_prob": 0.30,
"rules.guard.skill_stop_prob": 0.05,
"rules.guard.amulet_stop_prob": 0.10,
"rules.guard.guard_number_stop_prob": 0.001,
"rules.guard.castle_stop_prob": 0.05,
"rules.guard.region_type_stop_prob": 0.05,
"rules.economy.repopulate_maximum": 500,
"rules.lighthouse.unit_capacity": true
}
}

View file

@ -1,50 +0,0 @@
{
"include": [
"config://res/core/spoils.xml",
"config://res/core/common/herbs.xml",
"config://res/core/common/items.xml",
"config://res/core/common/luxuries.xml",
"config://res/core/common/potions.xml",
"config://res/core/armor/chainmail.xml",
"config://res/core/armor/laenmail.xml",
"config://res/core/armor/laenshield.xml",
"config://res/core/armor/plate.xml",
"config://res/core/armor/rustychainmail.xml",
"config://res/core/armor/rustyshield.xml",
"config://res/core/armor/shield.xml",
"config://res/core/resources/cart.xml",
"config://res/core/resources/horse.xml",
"config://res/core/resources/hp.xml",
"config://res/core/resources/iron.xml",
"config://res/core/resources/laen.xml",
"config://res/core/resources/log.xml",
"config://res/core/resources/mallorn.xml",
"config://res/core/resources/mallornseed.xml",
"config://res/core/resources/seed.xml",
"config://res/core/resources/peasant.xml",
"config://res/core/resources/stone.xml",
"config://res/core/weapons/axe.xml",
"config://res/core/weapons/bow.xml",
"config://res/core/weapons/catapult.xml",
"config://res/core/weapons/crossbow.xml",
"config://res/core/weapons/firesword.xml",
"config://res/core/weapons/greatbow.xml",
"config://res/core/weapons/greatsword.xml",
"config://res/core/weapons/halberd.xml",
"config://res/core/weapons/laensword.xml",
"config://res/core/weapons/lance.xml",
"config://res/core/weapons/mallornbow.xml",
"config://res/core/weapons/mallorncrossbow.xml",
"config://res/core/weapons/mallornlance.xml",
"config://res/core/weapons/mallornspear.xml",
"config://res/core/weapons/runesword.xml",
"config://res/core/weapons/rustyaxe.xml",
"config://res/core/weapons/rustygreatsword.xml",
"config://res/core/weapons/rustyhalberd.xml",
"config://res/core/weapons/rustysword.xml",
"config://res/core/weapons/spear.xml",
"config://res/core/weapons/sword.xml",
"config://res/eressea/items.xml",
"config://res/adamantium.xml"
]
}

View file

@ -1,34 +0,0 @@
{
"include": [
"config://res/translations/strings.de.po",
"config://res/translations/strings-e2.de.po",
"config://res/translations/strings.en.po",
"config://res/translations/strings-e2.en.po",
"config://res/translations/messages.de.po",
"config://res/translations/messages.en.po",
"config://res/core/messages.xml"
],
"aliases": {
"de": {
"spell::earthquake": [
"Beschwöre einen Erdelementar",
"Beschwörung eines Erdelementares"
],
"spell::goodwinds": [
"Beschwörung eines Wasserelementares",
"Beschwöre einen Wasserelementar"
],
"spell::stormwinds": [
"Beschwöre einen Sturmelementar",
"Beschwörung eines Sturmelementares"
],
"spell::summonfireelemental": [
"Beschwöre einen Hitzeelementar",
"Beschwörung eines Hitzeelementares"
]
},
"en": {
"spell::migration": "Rit of Acceptance"
}
}
}

View file

@ -1,8 +0,0 @@
# Änderungen gegenüber E2
- ARBEITE produziert nur genug Silber für den Unterhalt der Einheit
- NUMMER Befehl abgeschafft.
- Ebene und Hochland haben 20%, alle anderen Regionen 10% der Arbeitsplätze von E2.
- Keine Zufallsmonster
- ZERSTÖRE Befehl abgeschafft.
- BEKLAUE Befehl abgeschafft.

View file

@ -1,286 +0,0 @@
{
"terrains": {
"ocean": {
"size": 10,
"flags": [ "swim", "sea", "sail", "fly" ]
},
"plain": {
"size": 2000,
"herbs": [ "h0", "h1", "h2", "h3", "h4", "h5" ],
"seed": 3,
"road": 50,
"flags": [ "forest", "cavalry", "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 0.1,
"base": "5d8",
"div": "2d20+10",
"level": "2d4-1"
},
"stone": {
"chance": 0.15,
"base": "5d8",
"div": "2d30+20",
"level": "1d4"
},
"laen": {
"chance": 0.01,
"base": "1d4",
"div": "2d20+50",
"level": "1d4"
}
}
},
"swamp": {
"size": 200,
"herbs": [ "h6", "h7", "h8" ],
"seed": 2,
"road": 75,
"flags": [ "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 0.02,
"base": "5d8",
"div": "2d20+10",
"level": "2d4-1"
},
"stone": {
"chance": 0.02,
"base": "5d8",
"div": "2d30+20",
"level": "1d4"
},
"laen": {
"chance": 0.02,
"base": "1d4",
"div": "2d20+50",
"level": "1d4"
}
}
},
"desert": {
"size": 50,
"herbs": [ "h9", "h10", "h11" ],
"seed": 2,
"road": 100,
"flags": [ "land", "walk", "sail", "fly", "cavalry" ],
"production": {
"iron": {
"chance": 0.15,
"base": "5d8",
"div": "2d20+10",
"level": "2d4-1"
},
"stone": {
"chance": 0.25,
"base": "5d8",
"div": "2d30+20",
"level": "1d4"
},
"laen": {
"chance": 0.025,
"base": "1d4",
"div": "2d20+50",
"level": "1d4"
}
}
},
"highland": {
"size": 800,
"herbs": [ "h12", "h13", "h14" ],
"seed": 2,
"road": 100,
"flags": [ "land", "walk", "sail", "fly", "cavalry" ],
"production": {
"iron": {
"chance": 0.15,
"base": "5d8",
"div": "2d20+10",
"level": "2d4-1"
},
"stone": {
"chance": 0.25,
"base": "5d8",
"div": "2d30+20",
"level": "1d4"
},
"laen": {
"chance": 0.025,
"base": "1d4",
"div": "2d20+50",
"level": "1d4"
}
}
},
"mountain": {
"size": 100,
"herbs": [ "h15", "h16", "h17" ],
"seed": 2,
"road": 250,
"flags": [ "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 1.0,
"base": "50",
"div": "50",
"level": "1"
},
"stone": {
"chance": 1.0,
"base": "100",
"div": "100",
"level": "1"
},
"laen": {
"chance": 0.05,
"base": "4",
"div": "100",
"level": "1"
}
}
},
"glacier": {
"size": 10,
"herbs": [ "h18", "h19", "h20" ],
"seed": 2,
"road": 250,
"flags": [ "arctic", "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 1.0,
"base": "3",
"div": "50",
"level": "1"
},
"stone": {
"chance": 1.0,
"base": "2",
"div": "100",
"level": "1"
},
"laen": {
"chance": 0.05,
"base": "4",
"div": "100",
"level": "1"
}
}
},
"iceberg": {
"size": 10,
"herbs": [ "h18", "h19", "h20" ],
"flags": [ "arctic", "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 0.9,
"base": "3",
"div": "50",
"level": "1"
},
"stone": {
"chance": 0.9,
"base": "2",
"div": "100",
"level": "1"
}
}
},
"iceberg_sleep": {
"size": 10,
"herbs": [ "h18", "h19", "h20" ],
"flags": [ "arctic", "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 0.9,
"base": "3",
"div": "50",
"level": "1"
},
"stone": {
"chance": 0.9,
"base": "2",
"div": "100",
"level": "1"
},
"laen": {
"chance": 0.05,
"base": "4",
"div": "100",
"level": "1"
}
}
},
"firewall": {
"flags": [ "forbidden" ]
},
"fog": {
"flags": [ "walk", "fly" ]
},
"thickfog": {
"flags": [ "forbidden" ]
},
"volcano": {
"size": 50,
"road": 250,
"seed": 1,
"flags": [ "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 0.5,
"level": "1",
"base": "50",
"div": "50"
},
"stone": {
"chance": 0.5,
"level": "1",
"base": "100",
"div": "100"
},
"laen": {
"chance": 0.075,
"level": "1",
"base": "4",
"div": "100"
}
}
},
"activevolcano": {
"size": 50,
"road": 250,
"flags": [ "land", "walk", "sail", "fly" ],
"production": {
"iron": {
"chance": 0.5,
"level": "1",
"base": "50",
"div": "50"
},
"stone": {
"chance": 0.5,
"level": "1",
"base": "100",
"div": "100"
},
"laen": {
"chance": 0.075,
"level": "1",
"base": "4",
"div": "100"
}
}
},
"hell": {
"flags": [ "walk" ]
},
"hall1": {
"flags": [ "land", "walk", "sail" ]
},
"corridor1": {
"flags": [ "land", "walk", "sail" ]
},
"wall1": {
"flags": [ "forbidden", "land" ]
}
}
}

View file

@ -1,11 +1,11 @@
{
"keywords": {
"en" : {
"plant": "PLANT",
"grow": [ "GROW", "BREED" ],
"promote": ["PROMOTE", "PROMOTION" ],
"locale": ["LANGUAGE", "LOCALE"],
"combat": [ "COMBAT", "FIGHT" ]
"plant": "PLANT",
"grow": [ "GROW", "BREED" ],
"promote": ["PROMOTE", "PROMOTION" ],
"locale": ["LANGUAGE", "LOCALE"],
"combat": [ "COMBAT", "FIGHT" ]
},
"de": {
"//" : "//",
@ -36,7 +36,6 @@
"maketemp": ["MACHE TEMP", "MACHETEMP"],
"move" : "NACH",
"password" : "PASSWORT",
"expel" : "VERTREIBE",
"loot" : ["PLÜNDERE", "PLÜNDERN"],
"recruit": ["REKRUTIERE", "REKRUTIEREN"],
"reserve": ["RESERVIERE", "RESERVIEREN"],

1
dlmalloc Submodule

@ -0,0 +1 @@
Subproject commit f1446c47ca1774ae84bf86a28502e91daf6b421a

File diff suppressed because it is too large Load diff

1
iniparser Submodule

@ -0,0 +1 @@
Subproject commit 31d42782e2713591da4c1a7db1aca4937137e352

View file

@ -1,6 +1,6 @@
install(PROGRAMS create-orders backup-eressea run-turn send-zip-report
send-bz2-report compress.py compress.sh epasswd.py
accept-orders.py getemail.py checkpasswd.py
send-bz2-report compress.py compress.sh epasswd.py orders-process
process-orders.py accept-orders.py getemail.py checkpasswd.py
sendreport.sh sendreports.sh orders-accept DESTINATION bin)
install(DIRECTORY cron/ DESTINATION bin USE_SOURCE_PERMISSIONS

View file

@ -327,6 +327,11 @@ def accept(game, locale, stream, extend=None):
print text_ok, fail, email
print filename
if not fail:
queue = open(gamedir + "/orders.queue", "a")
queue.write("email=%s file=%s locale=%s game=%s\n" % (email, filename, locale, game))
queue.close()
logger.info("done - accepted orders from " + email)
return 0

View file

@ -10,6 +10,7 @@ fi
cd "$ERESSEA/game-$GAME" || exit
lockfile -r3 -l120 orders.queue.lock
if [ -d "orders.dir.$TURN" ]; then
echo "orders.dir.$TURN already exists"
exit
@ -24,3 +25,5 @@ cd .. || exit
mv orders.dir "orders.dir.$TURN"
mkdir -p orders.dir
rm -f orders.queue.lock

View file

@ -4,8 +4,6 @@
[ -z "${ERESSEA}" ] && ERESSEA="$HOME/eressea"
eval "$(luarocks path)"
export LUA_PATH="${ERESSEA}/git/scripts/?.lua;$LUA_PATH"
branch="develop"
if [ -e "${ERESSEA}/build/.preview" ]; then
branch=$(cat "${ERESSEA}/build/.preview")

View file

@ -1,13 +1,12 @@
#!/bin/bash
eval "$(luarocks path)"
GAME=$1
(
[ "$ENABLED" == "no" ] && exit
[ -z "$ERESSEA" ] && ERESSEA="$HOME/eressea"
export ERESSEA
eval "$(luarocks path)"
export LUA_PATH="${ERESSEA}/server/scripts/?.lua;$LUA_PATH"
BIN="$ERESSEA/server/bin"
TURN=$(cat "$ERESSEA/game-$GAME/turn")
if [ ! -e "$ERESSEA/game-$GAME/data/$TURN.dat" ]; then
@ -47,11 +46,6 @@ if [ ! -s "$ERESSEA/game-$GAME/data/$TURN.dat" ]; then
echo "server did not create data for turn $TURN in game $GAME"
exit 3
fi
if [ ! -f "express-$TURN.txt" ]; then
if [ -f express.txt ]; then
mv express.txt "express-$TURN.txt"
fi
fi
echo "sending reports for game $GAME, turn $TURN"
"$BIN/compress.sh" "$GAME" "$TURN"
"$BIN/sendreports.sh" "$GAME"

View file

@ -8,9 +8,14 @@ lang="$2"
SCRIPT=$(readlink -f "$0")
BIN=$(dirname "$SCRIPT")
LOCKFILE="$ERESSEA/game-$game/orders.queue.lock"
set -e
trap 'rm -f "$LOCKFILE"' EXIT
cd "$ERESSEA/game-$game"
mkdir -p orders.dir
cd orders.dir
lockfile -r3 -l120 "$LOCKFILE"
eval "$(python "$BIN/accept-orders.py" "$@")"
if [ -e "$ACCEPT_FILE" ]
then

8
process/orders-process Executable file
View file

@ -0,0 +1,8 @@
#!/bin/sh
SCRIPT=$(readlink -f "$0")
SCRDIR=$(dirname "$SCRIPT")
cd "$SCRDIR" || exit
lockfile -r3 -l120 orders.queue.lock
python process-orders.py "$@"
rm -f orders.queue.lock

187
process/process-orders.py Executable file
View file

@ -0,0 +1,187 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os import unlink, symlink, rename, popen, tmpfile
import sys
import os
import os.path
import ConfigParser
import subprocess
from re import compile, IGNORECASE
from string import split, join, upper, strip
from sys import argv, exit
from time import sleep, time, ctime
from syslog import openlog, closelog, syslog
from epasswd import EPasswd
def pwd_get_email(faction, pwd, pwdfile=None):
return None
def split_filename(filename):
return os.path.split(filename)
messages = {
"subject-de": "Befehle angekommen",
"subject-en": "orders received",
"validate-en": "Validating",
"validate-de": "Verarbeite",
"noorders-en": "The email contained no recognizable orders.",
"noorders-de": "Es konnten keine Befehle gefunden werden.",
"faction-en": "Faction",
"faction-de": "Partei",
"unknown-de": "WARNUNG: Die Partei ist nicht bekannt, oder das Passwort falsch!",
"unknown-en": "WARNING: This faction is unknown, or the password is incorrect!",
"warning-de": "Warnung",
"warning-en": "Warning",
"error-de": "Fehler",
"error-en": "Error",
}
game = int(sys.argv[1])
echeck_cmd = "/home/eressea/echeck/echeck.sh"
maxlines = 25
# base directory for all your games:
install_dir = "/home/eressea/eressea"
if 'ERESSEA' in os.environ:
install_dir = os.environ['ERESSEA']
elif 'HOME' in os.environ:
install_dir = os.path.join(os.environ['HOME'], 'eressea')
if not os.path.isdir(install_dir):
print "please set the ERESSEA environment variable to the install path"
sys.exit(1)
game_dir = os.path.join(install_dir, "game-%d" % (game, ))
gamename = 'Eressea'
inifile = os.path.join(game_dir, 'eressea.ini')
queue_file = os.path.join(game_dir, "orders.queue")
if not os.path.exists(queue_file):
exit(0)
# regular expression that finds the start of a faction
fact_re = compile("^\s*(eressea|partei|faction)\s+([a-zA-Z0-9]+)\s+\"?([^\"]*)\"?", IGNORECASE)
def check_pwd(filename, email, pw_data):
results = []
try:
file = open(filename, "r")
except:
print "could not open file", filename
return results
for line in file.readlines():
mo = fact_re.search(strip(line))
if mo != None:
fact_nr = str(mo.group(2))
fact_pw = str(mo.group(3))
if pw_data.fac_exists(fact_nr):
if not pw_data.check(fact_nr, fact_pw):
game_email = pw_data.get_email(fact_nr)
results = results + [ (fact_nr, game_email, False, fact_pw) ]
else:
game_email = pw_data.get_email(fact_nr)
results = results + [ (fact_nr, game_email, True, fact_pw) ]
else:
results = results + [ (fact_nr, None, False, fact_pw) ]
return results
def echeck(filename, locale, rules):
dirname, filename = split_filename(filename)
stream = popen("%s %s %s %s %s" % (echeck_cmd, locale, filename, dirname, rules), 'r')
lines = stream.readlines()
if len(lines)==0:
stream.close()
return None
if len(lines)>maxlines:
mail = join(lines[:maxlines-3] + ["...", "\n"] + lines[-3:], '')
else:
mail = join(lines[:maxlines], '')
stream.close()
return mail
#print "reading password file..."
pw_data = EPasswd()
try:
pw_data.load_database(os.path.join(game_dir, "eressea.db"))
except:
pw_data.load_file(os.path.join(game_dir, "passwd"))
#print "reading orders.queue..."
# move the queue file to a safe space while locking it:
queuefile = open(queue_file, "r")
lines = queuefile.readlines()
queuefile.close()
# copy to a temp file
tname="/tmp/orders.queue.%s" % str(time())
tmpfile=open(tname, "w")
for line in lines:
tmpfile.write(line)
tmpfile.close()
openlog("orders")
unlink(queue_file)
for line in lines:
tokens = split(line[:-1], ' ')
dict = {}
for token in tokens:
name, value = split(token, '=')
dict[name] = value
email = dict["email"]
locale = dict["locale"]
game = int(dict["game"])
infile = dict["file"]
gamename='[E%d]' % game
rules='e%d' % game
warning = ""
failed = True
results = check_pwd(infile, email, pw_data)
logfile = open(os.path.join(game_dir, "zug.log"), "a")
dirname, filename = split_filename(infile)
msg = messages["validate-"+locale] + " " + infile + "\n\n"
if len(results)==0:
msg = msg + messages["noorders-"+locale]
for faction, game_email, success, pwd in results:
msg = msg + messages["faction-"+locale] + " " + faction + "\n"
if success: failed = False
else: msg = msg + messages["unknown-"+locale] + "\n"
msg = msg + "\n"
logfile.write("%s:%s:%s:%s:%s\n" % (ctime(time()), email, game_email, faction, success))
logfile.close()
if failed:
warning = " (" + messages["warning-" + locale] + ")"
syslog("failed - no valid password in " + infile)
else:
result = None
if os.path.exists(echeck_cmd):
result = echeck(infile, locale, rules)
if result is None:
# echeck did not finish
msg = msg + "Echeck is broken. Your turn was accepted, but could not be verified.\n"
warning = " (" + messages["warning-" + locale] + ")"
syslog("process - echeck broken, " + infile)
else:
msg = msg + result
syslog("process - checked orders in " + infile)
subject = gamename + " " + messages["subject-" + locale] + warning
try:
sp = subprocess.Popen(['mutt', '-s', subject, email], stdin=subprocess.PIPE)
sp.communicate(msg)
except:
syslog("failed - cannot send to " + email)
closelog()
unlink(tname)

View file

@ -16,7 +16,7 @@
<requirement type="adamantium" quantity="1"/>
<requirement type="log" quantity="1"/>
</construction>
<weapon cut="true" magical="true" skill="melee" offmod="2" defmod="-2" magres="0.3">
<weapon cut="true" magical="true" skill="melee" offmod="2" defmod="-2" magres="0.30">
<damage type="rider" value="3d4+15"/>
<damage type="footman" value="3d4+15"/>
</weapon>
@ -28,7 +28,7 @@
<construction skill="armorer" minskill="10">
<requirement type="adamantium" quantity="3"/>
</construction>
<armor ac="7" penalty="0.1" magres="0.3"/>
<armor ac="7" penalty="0.1"/>
</item>
</resource>

View file

@ -1181,18 +1181,6 @@
<arg name="dir" type="direction"/>
</type>
</message>
<message name="ship_drift_overload" section="events">
<type>
<arg name="ship" type="ship"/>
<arg name="dir" type="direction"/>
</type>
</message>
<message name="ship_drift_nocrew" section="events">
<type>
<arg name="ship" type="ship"/>
<arg name="dir" type="direction"/>
</type>
</message>
<message name="iceberg_drift" section="events">
<type>
<arg name="region" type="region"/>
@ -2228,18 +2216,6 @@
<arg name="unit" type="unit"/>
</type>
</message>
<message name="followdetect_ship" section="movement">
<type>
<arg name="follower" type="ship"/>
<arg name="ship" type="ship"/>
</type>
</message>
<message name="followfail_ship" section="movement">
<type>
<arg name="follower" type="ship"/>
<arg name="ship" type="ship"/>
</type>
</message>
<message name="moveblocked" section="errors">
<type>
<arg name="unit" type="unit"/>
@ -3807,6 +3783,13 @@
<arg name="command" type="order"/>
</type>
</message>
<message name="error185" section="errors">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
</type>
</message>
<message name="error187" section="errors">
<type>
<arg name="unit" type="unit"/>
@ -4535,6 +4518,13 @@
<arg name="command" type="order"/>
</type>
</message>
<message name="error125" section="errors">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
</type>
</message>
<message name="error84" section="errors">
<type>
<arg name="unit" type="unit"/>
@ -4725,13 +4715,6 @@
<arg name="command" type="order"/>
</type>
</message>
<message name="feedback_not_inside" section="errors">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
</type>
</message>
<message name="feedback_unit_not_found" section="errors">
<type>
<arg name="unit" type="unit"/>
@ -5480,8 +5463,6 @@
<arg name="turns" type="int"/>
</type>
</message>
<message name="newbieimmunityending" section="nr" />
<message name="newbieimmunityended" section="nr" />
<message name="alliance::kickedout" section="events">
<type>
<arg name="votes" type="int"/>

View file

@ -5,7 +5,7 @@
<!-- begin main races -->
<race name="template" maintenance="0" magres="100" maxaura="0" regaura="0" weight="0" capacity="1000" speed="10.0" hp="10" damage="1d4" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" fly="yes" swim="yes" walk="yes" shapeshift="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" recruitunlimited="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<attack type="1" damage="1d4"/>
</race>
<race name="lynx" maxaura="0" regaura="0" weight="500" capacity="540" speed="1.0" hp="20" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="5" walk="yes" teach="no" getitem="yes">
@ -32,7 +32,7 @@
</race>
<race name="human" maxaura="1" regaura="1" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="other_race" value="elf"/>
<skill name="riding" modifier="+1"/>
<skill name="shipcraft" modifier="2"/>
@ -45,7 +45,7 @@
</race>
<race name="orc" studyspeed="-5" magres="-5" maxaura="1" regaura="1" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="other_race" value="troll"/>
<skill name="bow" speed="+5"/>
@ -76,7 +76,7 @@
capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2"
unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes"
giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="other_race" value="dwarf"/>
<param name="luxury_trade" value="600"/>
<skill name="bow" modifier="-1"/>
@ -102,7 +102,7 @@
<!-- begin secondary races -->
<race name="demon" magres="15" maxaura="1" regaura="1.1" recruitcost="360" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="30" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="cartmaking" modifier="-2"/>
<skill name="forestry" modifier="1"/>
<skill name="melee" modifier="1"/>
@ -125,7 +125,7 @@
speed="1.0" hp="20" damage="1d5" unarmedattack="-2"
unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes"
giveunit="yes" getitem="yes" equipment="yes" >
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="armorer" modifier="-1"/>
<skill name="bow" modifier="2"/>
<skill name="building" modifier="-1"/>
@ -143,7 +143,7 @@
</race>
<race name="troll" magres="10" maxaura="1" regaura="1" recruitcost="260" maintenance="10" weight="2000" capacity="1080" speed="1.0" hp="20" ac="1" damage="1d5+3" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="armor.stamina" value="4"/> <!-- +1 natural armor per X levels stamina -->
<skill name="armorer" modifier="2"/>
<skill name="bow" modifier="-2"/>
@ -169,7 +169,7 @@
speed="1.0" hp="20" damage="1d5" unarmedattack="-2"
unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes"
giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="armorer" modifier="2"/>
<skill name="bow" modifier="-1"/>
<skill name="building" modifier="2"/>
@ -598,13 +598,13 @@
<attack type="1" damage="1d6"/>
</race>
<race name="braineater" magres="90" maxaura="1.0" regaura="1.0" weight="100" capacity="540" speed="1.0" hp="20" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes">
<ai splitsize="500" scarepeasants="yes" killpeasants="yes" moverandom="yes"/>
<ai splitsize="500" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes"/>
<attack type="2" damage="3d15"/>
<attack type="3" damage="1d1"/>
<attack type="4" damage="1d1"/>
</race>
<race name="toad" magres="20" maxaura="1" regaura="1" maintenance="10" weight="100" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes" learn="no">
<ai splitsize="1"/>
<race name="toad" magres="20" maxaura="1" regaura="1" maintenance="10" weight="100" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes">
<ai splitsize="1" learn="yes"/>
<skill name="crossbow" modifier="-10"/>
<skill name="mining" modifier="-10"/>
<skill name="bow" modifier="-10"/>
@ -627,8 +627,8 @@
<skill name="stamina" modifier="-10"/>
<attack type="4" damage="1d2"/>
</race>
<race name="smurf" weight="1000" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes" learn="no">
<ai splitsize="1"/>
<race name="smurf" weight="1000" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes">
<ai splitsize="1" learn="yes"/>
<skill name="crossbow" modifier="-10"/>
<skill name="mining" modifier="-10"/>
<skill name="bow" modifier="-10"/>
@ -656,13 +656,13 @@
<attack type="4" damage="2d40"/>
</race>
<race name="shadowmaster" cansail="no" cansteal="no" learn="no" magres="75" maxaura="1.0" regaura="2.0" weight="500" capacity="540" speed="1.0" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" walk="yes" teach="no" desert="yes">
<ai splitsize="50" scarepeasants="yes" killpeasants="yes" moverandom="yes"/>
<ai splitsize="50" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes"/>
<attack type="4" damage="2d4"/>
<attack type="2" damage="2d30"/>
<attack type="3" damage="1d2"/>
</race>
<race name="shadowdemon" cansail="no" cansteal="no" learn="no" magres="75" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" walk="yes" teach="no" desert="yes" recruitethereal="yes">
<ai splitsize="1000" scarepeasants="yes" killpeasants="yes" moverandom="yes"/>
<ai splitsize="1000" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes"/>
<attack type="4" damage="2d3"/>
<attack type="3" damage="1d1"/>
</race>
@ -684,14 +684,14 @@
</race>
<race name="dracoid" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" teach="no" giveperson="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<attack type="4" damage="1d6"/>
<attack type="4" damage="1d6"/>
<attack type="1" damage="1d5"/>
</race>
<race name="ent" magres="25" maxaura="1.0" regaura="0.5" weight="5000" capacity="2500" speed="1.0" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" walk="yes" teach="no">
<ai splitsize="1000" moverandom="yes" scarepeasants="yes"/>
<ai splitsize="1000" moverandom="yes" learn="yes" scarepeasants="yes"/>
<attack type="4" damage="2d12"/>
<attack type="4" damage="2d12"/>
</race>
@ -732,7 +732,7 @@
<attack type="1" damage="0d0"/>
</race>
<race name="ghast" magres="60" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes" desert="yes">
<race name="ghast" magres="60" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes">
<ai splitsize="2000" killpeasants="yes" moverandom="yes" scarepeasants="yes" absorbpeasants="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="bow" modifier="1"/>
@ -750,7 +750,7 @@
<attack type="2" damage="1d30"/>
</race>
<race name="ghoul" magres="30" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes" desert="yes">
<race name="ghoul" magres="30" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes">
<ai splitsize="10000" killpeasants="yes" scarepeasants="yes" moverandom="yes" absorbpeasants="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="bow" modifier="1"/>
@ -783,7 +783,7 @@
<attack type="3" damage="1d1"/>
</race>
<race name="zombie" magres="20" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" giveperson="yes" desert="yes">
<race name="zombie" magres="20" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" giveperson="yes">
<ai splitsize="10000" killpeasants="yes" scarepeasants="yes" moverandom="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="bow" modifier="1"/>
@ -832,9 +832,8 @@
</race>
<race name="seaserpent" magres="50" maxaura="1.0" regaura="1.0" weight="20000" capacity="5000" speed="1.0" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" swim="yes" teach="no" getitem="yes" resistbash="yes">
<ai splitsize="6" scarepeasants="yes" killpeasants="yes" moverandom="yes" moveattack="yes"/>
<ai splitsize="6" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes" moveattack="yes"/>
<skill name="tactics" modifier="4"/>
<skill name="stealth" modifier="-99"/>
<attack type="4" damage="1d30"/>
<attack type="4" damage="1d30"/>
<attack type="4" damage="1d30"/>

View file

@ -436,7 +436,7 @@
<resource name="dragonblood" amount="1" cost="fixed"/><!-- Drachenblut -->
</spell>
<spell name="auratransfer" rank="1" syntax="aura" parameters="ui" noresist="true" ship="true">
<spell name="auratransfer" rank="1" syntax="aura" parameters="ui" ship="true">
<!-- Auratransfer -->
<resource name="aura" amount="1" cost="fixed"/>
</spell>
@ -528,7 +528,7 @@
<resource name="h12" amount="1" cost="fixed"/>
<resource name="h20" amount="1" cost="fixed"/>
</spell>
<spell name="sound_out" rank="5" parameters="ur" noresist="true" los="true">
<spell name="sound_out" rank="5" parameters="ur" los="true">
<resource name="aura" amount="4" cost="fixed"/>
<resource name="money" amount="100" cost="fixed"/>
</spell>

190
res/eressea.dtd Normal file
View file

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD generated by XMLSpy v2018 rel. 2 (x64) (http://www.altova.com) -->
<!ELEMENT ai EMPTY>
<!ATTLIST ai
splitsize (1 | 1000 | 10000 | 2 | 2000 | 20000 | 50 | 500 | 5000 | 6 | 9999 | 99999) #REQUIRED
moverandom CDATA #FIXED "yes"
learn CDATA #FIXED "yes"
killpeasants CDATA #FIXED "yes"
moveattack CDATA #FIXED "yes"
>
<!ELEMENT set ((item+, ((skill+, item*) | callback | subset+)?) | (skill+, ((item+, subset?) | callback | subset | spell+)?) | callback)?>
<!ATTLIST set
name (fam_direwolf | fam_dreamcat | fam_eagle | fam_fairy | fam_ghost | fam_hellcat | fam_imp | fam_lynx | fam_nymph | fam_owl | fam_rat | fam_songdragon | fam_tiger | fam_tunnelworm | fam_unicorn | i_bow | i_chain | i_plate | i_rustyshield | i_spear | i_sword | new_dracoid | new_orc | rand_bow | rand_crossbow | rand_desert | rand_forest | rand_glacier | rand_herbalist | rand_highland | rand_mountain | rand_plain | rand_rider | rand_spear | rand_swamp | rand_sword | rand_villagers | rising_undead | seed_aquarian | seed_braineater | seed_cat | seed_demon | seed_dragon | seed_dwarf | seed_elf | seed_goblin | seed_halfling | seed_human | seed_insect | seed_orc | seed_seaserpent | seed_troll | spo_dragon | spo_seaserpent | spo_wyrm | spo_youngdragon) #REQUIRED
chance (0.25 | 0.33 | 0.34) #IMPLIED
>
<!ELEMENT item (weapon?)>
<!ATTLIST item
name (axe | balm | bow | cart | chainmail | crossbow | dragonblood | dragonhead | fairyboot | horse | incense | jewel | money | myrrh | nestwarmth | oil | plate | roi | rustychainmail | rustyshield | rustysword | seaserpenthead | silk | spear | spice | stone | sword | wagon) #IMPLIED
amount CDATA #IMPLIED
notlost CDATA #FIXED "yes"
weight (0 | 1 | 100) #IMPLIED
use CDATA #FIXED "yes"
cursed (true | yes) #IMPLIED
score CDATA #FIXED "0"
>
<!ELEMENT race ((ai, ((skill+, attack+, familiar*) | (param, skill+, attack, familiar+) | attack+)) | attack+)>
<!ATTLIST race
name (aquarian | braineater | cat | catdragon | clone | demon | direwolf | dolphin | dracoid | dragon | dreamcat | dwarf | eagle | elf | ent | fairy | ghast | ghost | ghoul | giantturtle | gnome | goblin | halfling | hellcat | human | imp | insect | irongolem | juju | kraken | lynx | mountainguard | museumghost | nymph | orc | owl | peasant | rat | seaserpent | shadowdemon | shadowdragon | shadowknight | shadowmaster | skeleton | skeletonlord | smurf | snotling | snowman | songdragon | special | spell | stonegolem | template | tiger | toad | troll | tunnelworm | undead | unicorn | wolf | wyrm | youngdragon | zombie) #REQUIRED
magres (-0.050000 | -5 | 10 | 100 | 15 | 20 | 25 | 30 | 5 | 50 | 60 | 70 | 75 | 80 | 90 | 95 | 99) #IMPLIED
maxaura (0.000000 | 0.500000 | 1.000000 | 1.500000) #IMPLIED
regaura (0.000000 | 0.100000 | 0.500000 | 1.000000 | 1.250000 | 1.500000 | 2.000000 | 3.000000) #IMPLIED
weight (0 | 100 | 1000 | 10000 | 1600 | 18000 | 200 | 2000 | 20000 | 30000 | 500 | 5000 | 600) #REQUIRED
capacity (0 | 1000 | 10000 | 100000 | 1000000 | 1080 | 200 | 2000 | 2500 | 440 | 5000 | 540 | 600) #REQUIRED
equipment (no | yes) #IMPLIED
speed (0.000000 | 1.000000 | 1.500000 | 10.000000 | 2.000000) #REQUIRED
hp (1 | 10 | 1000 | 15 | 150 | 16 | 18 | 20 | 24 | 25 | 2700 | 30 | 300 | 40 | 50 | 6 | 60 | 600 | 80 | 9 | 900) #REQUIRED
ac (1 | 10 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8) #IMPLIED
damage CDATA #REQUIRED
unarmedattack (-2 | 0 | 1 | 10 | 2 | 3 | 6) #REQUIRED
unarmeddefense (-2 | 0 | 1 | 10 | 2 | 3 | 6) #REQUIRED
attackmodifier (1 | 10 | 11 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9) #IMPLIED
defensemodifier (1 | 10 | 11 | 12 | 13 | 14 | 2 | 3 | 4 | 5 | 50 | 6 | 7 | 8) #IMPLIED
fly (no | yes) #IMPLIED
walk (no | yes) #IMPLIED
canteach CDATA #FIXED "no"
getitem CDATA #FIXED "yes"
recruitcost (110 | 130 | 150 | 40 | 70 | 75 | 80 | 90) #IMPLIED
maintenance (0 | 10) #IMPLIED
playerrace (no | yes) #IMPLIED
giveperson CDATA #FIXED "yes"
giveunit CDATA #FIXED "yes"
coastal CDATA #FIXED "yes"
swim CDATA #FIXED "yes"
teach CDATA #FIXED "no"
resistpierce CDATA #FIXED "yes"
invinciblenonmagic CDATA #FIXED "yes"
scarepeasants CDATA #FIXED "yes"
unarmedguard CDATA #FIXED "yes"
cannotmove CDATA #FIXED "yes"
canlearn CDATA #FIXED "no"
noweapons CDATA #FIXED "yes"
cansail CDATA #FIXED "no"
cansteal CDATA #FIXED "no"
desert CDATA #FIXED "yes"
recruitethereal CDATA #FIXED "yes"
stonegolem CDATA #FIXED "true"
irongolem CDATA #FIXED "true"
noheal CDATA #FIXED "yes"
illusionary CDATA #FIXED "yes"
invisible CDATA #FIXED "yes"
shapeshift CDATA #FIXED "yes"
dragon CDATA #FIXED "yes"
resistbash CDATA #FIXED "yes"
undead CDATA #FIXED "yes"
shipspeed CDATA #FIXED "yes"
shapeshiftany CDATA #FIXED "yes"
recruitunlimited CDATA #FIXED "yes"
absorbpeasants CDATA #FIXED "yes"
resistcut CDATA #FIXED "yes"
noblock CDATA #FIXED "yes"
studyspeed CDATA #FIXED "-5"
>
<!ELEMENT text (#PCDATA)>
<!ATTLIST text
locale (de | en | fr) #REQUIRED
>
<!ELEMENT param EMPTY>
<!ATTLIST param
name (hunger.damage | migrants.formula | recruit_multi) #REQUIRED
value CDATA #REQUIRED
>
<!ELEMENT races (race+)>
<!ELEMENT skill EMPTY>
<!ATTLIST skill
name (alchemy | armorer | bow | building | cartmaking | catapult | crossbow | entertainment | espionage | forestry | herbalism | magic | melee | mining | perception | polearm | quarrying | riding | roadwork | sailing | shipcraft | stamina | stealth | tactics | taxation | trade | training | unarmed | weaponsmithing) #REQUIRED
level CDATA #IMPLIED
modifier (-1 | -10 | -2 | -3 | -99 | 1 | 10 | 12 | 14 | 2 | 20 | 3 | 4 | 5 | 8) #IMPLIED
>
<!ELEMENT spell (#PCDATA | resource)*>
<!ATTLIST spell
name CDATA #REQUIRED
level (1 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8) #IMPLIED
ship CDATA #FIXED "true"
rank (1 | 2 | 3 | 4 | 5 | 7) #IMPLIED
variable CDATA #FIXED "true"
combat (1 | 2 | 3) #IMPLIED
parameters CDATA #IMPLIED
los CDATA #FIXED "true"
far CDATA #FIXED "true"
ocean CDATA #FIXED "true"
syntax (aura | buildingtype | direction | race | spellid) #IMPLIED
regiontarget (false | true) #IMPLIED
unittarget CDATA #FIXED "false"
buildingtarget CDATA #FIXED "true"
shiptarget CDATA #FIXED "true"
globaltarget CDATA #FIXED "true"
>
<!ELEMENT attack EMPTY>
<!ATTLIST attack
type (1 | 2 | 3 | 4 | 5 | 6 | 8) #REQUIRED
damage CDATA #IMPLIED
spell (aura_of_fear | drain_skills | fiery_dragonbreath | icy_dragonbreath | powerful_dragonbreath) #IMPLIED
level (12 | 3 | 6) #IMPLIED
>
<!ELEMENT damage EMPTY>
<!ATTLIST damage
type (footman | rider) #REQUIRED
value CDATA #FIXED "3d8+8"
>
<!ELEMENT spells (spell+)>
<!ELEMENT string (text+)>
<!ATTLIST string
name (adamantium | adamantium_p | adamantiumaxe | adamantiumaxe_p | adamantiumplate | adamantiumplate_p | almond | analysedream | aoc | aoc_p | apple | artacademy | aurapotion50 | aurapotion50_p | bagpipeoffear | bagpipeoffear_p | balloon | birthdaycake | birthdaycake_p | cookie | eyeofdragon | headache | jadee_dress | jadee_dress_p | jadee_ring | jadee_ring_p | lifepotion | newbie_info_cr | nut | pavilion | portal | ring | ring_of_levitation | ring_of_levitation_p | ring_p | rm_adamantium | seaserpenthead | seaserpenthead_p | seashell | seashell_p | snowball | snowman | snowman_p | stardust | temple | wente_dress | wente_dress_p | wente_ring | wente_ring_p | xmastree) #REQUIRED
>
<!ELEMENT subset (set+)>
<!ATTLIST subset
chance (0.2 | 0.3 | 0.4 | 0.6) #IMPLIED
>
<!ELEMENT weapon (damage+, modifier+)>
<!ATTLIST weapon
bash CDATA #FIXED "true"
missile CDATA #FIXED "true"
skill CDATA #FIXED "unarmed"
offmod CDATA #FIXED "0"
defmod CDATA #FIXED "0"
reload CDATA #FIXED "0"
magres CDATA #FIXED "0.0"
>
<!ELEMENT eressea (equipment+, buildings, resources, races, strings, spells)>
<!ELEMENT strings (namespace+, string+)>
<!ELEMENT building EMPTY>
<!ATTLIST building
name (artacademy | pavilion | portal | temple) #REQUIRED
maxsize (100 | 2 | 50) #REQUIRED
maxcapacity CDATA #FIXED "2"
nobuild CDATA #FIXED "yes"
nodestroy CDATA #FIXED "yes"
unique CDATA #FIXED "yes"
auraregen CDATA #FIXED "1.00"
>
<!ELEMENT callback EMPTY>
<!ATTLIST callback
name CDATA #FIXED "equip_newunits"
>
<!ELEMENT familiar EMPTY>
<!ATTLIST familiar
race (demon | dolphin | dreamcat | eagle | fairy | ghost | giantturtle | goblin | hellcat | imp | kraken | lynx | nymph | owl | rat | songdragon | tiger | tunnelworm | unicorn | wolf) #REQUIRED
default CDATA #FIXED "yes"
>
<!ELEMENT modifier EMPTY>
<!ATTLIST modifier
type (missile_target | skill) #REQUIRED
value (-90 | 100 | 2) #REQUIRED
races CDATA #FIXED "snowman"
>
<!ELEMENT resource (item?)>
<!ATTLIST resource
name (almond | aoc | aog | apple | aura | birthdaycake | cookie | dragonblood | dragonhead | eyeofdragon | h12 | h20 | h7 | hp | iron | jadee_dress | jadee_ring | laen | laensword | lebkuchenherz | lifepotion | lmsreward | log | mallorn | money | museumexitticket | museumticket | nut | oil | p10 | peasant | permaura | questkey1 | questkey2 | ring_of_levitation | seaserpenthead | seashell | snowball | snowglobe | snowman | stardust | stone | sword | toadslime | wente_dress | wente_ring | xmastree) #REQUIRED
appearance (amulet | key | ring | vial) #IMPLIED
amount (1 | 10 | 100 | 1000 | 12 | 140 | 15 | 150 | 16 | 18 | 2 | 20 | 200 | 24 | 25 | 250 | 28 | 3 | 30 | 3000 | 30000 | 35 | 350 | 4 | 40 | 4000 | 5 | 50 | 5000 | 6 | 600 | 7 | 8 | 80 | 800 | 90) #IMPLIED
cost (fixed | level) #IMPLIED
>
<!ELEMENT buildings (building+)>
<!ELEMENT equipment (set+)>
<!ELEMENT namespace (string+)>
<!ATTLIST namespace
name (describe | iteminfo | race | shipinfo | spell | spellinfo) #REQUIRED
>
<!ELEMENT resources (resource+)>

View file

@ -12,7 +12,7 @@
</race>
<race name="human" maxaura="1.0" regaura="1.0" recruitcost="75" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes" migrants="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="trade" modifier="1"/>
<skill name="herbalism" modifier="-1"/>
<skill name="shipcraft" modifier="1"/>
@ -579,13 +579,13 @@
</race>
<race name="braineater" magres="90" maxaura="1.0"
regaura="1.0" weight="100" capacity="540" speed="1.0" hp="20" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes">
<ai splitsize="500" scarepeasants="yes" killpeasants="yes" moverandom="yes"/>
<ai splitsize="500" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes"/>
<attack type="2" damage="3d15"/>
<attack type="3" damage="1d1"/>
<attack type="4" damage="1d1"/>
</race>
<race name="toad" magres="20" maxaura="1" regaura="1" maintenance="10" weight="100" capacity="540" speed="1" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes" learn="no">
<ai splitsize="1"/>
<race name="toad" magres="20" maxaura="1" regaura="1" maintenance="10" weight="100" capacity="540" speed="1" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes">
<ai splitsize="1" learn="yes"/>
<skill name="alchemy" modifier="-10"/>
<skill name="crossbow" modifier="-10"/>
<skill name="mining" modifier="-10"/>
@ -616,8 +616,8 @@
<skill name="stamina" modifier="-10"/>
<attack type="4" damage="1d2"/>
</race>
<race name="smurf" weight="1000" capacity="540" speed="1" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes" learn="no">
<ai splitsize="1"/>
<race name="smurf" weight="1000" capacity="540" speed="1" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes">
<ai splitsize="1" learn="yes"/>
<skill name="alchemy" modifier="-10"/>
<skill name="crossbow" modifier="-10"/>
<skill name="mining" modifier="-10"/>
@ -653,13 +653,13 @@
<attack type="4" damage="2d40"/>
</race>
<race name="shadowmaster" cansail="no" cansteal="no" learn="no" magres="75" maxaura="1.0" regaura="2.0" weight="500" capacity="540" speed="1.0" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" walk="yes" teach="no" desert="yes">
<ai splitsize="50" scarepeasants="yes" killpeasants="yes" moverandom="yes"/>
<ai splitsize="50" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes"/>
<attack type="4" damage="2d4"/>
<attack type="2" damage="2d30"/>
<attack type="3" damage="1d2"/>
</race>
<race name="shadowdemon" cansail="no" cansteal="no" learn="no" magres="75" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" walk="yes" teach="no" desert="yes" recruitethereal="yes">
<ai splitsize="1000" scarepeasants="yes" killpeasants="yes" moverandom="yes"/>
<ai splitsize="1000" scarepeasants="yes" killpeasants="yes" moverandom="yes" learn="yes"/>
<attack type="4" damage="2d3"/>
<attack type="3" damage="1d1"/>
</race>
@ -680,7 +680,7 @@
<attack type="1" damage="1d4"/>
</race>
<race name="dracoid" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" teach="no" giveperson="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<attack type="4" damage="1d6"/>
<attack type="4" damage="1d6"/>
<attack type="1" damage="1d5"/>
@ -693,12 +693,12 @@
<attack type="4" damage="2d40"/>
</race>
<race name="ent" magres="25" maxaura="1.0" regaura="0.5" weight="5000" capacity="2500" speed="1.0" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" walk="yes" teach="no">
<ai splitsize="1000" moverandom="yes" scarepeasants="yes"/>
<ai splitsize="1000" moverandom="yes" learn="yes" scarepeasants="yes"/>
<attack type="4" damage="2d12"/>
<attack type="4" damage="2d12"/>
</race>
<race name="wyrm" magres="90" maxaura="1.0" regaura="3.0" weight="18000" capacity="1000000" speed="1.0" hp="2700" ac="8" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="10" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes" dragon="yes" unarmedguard="yes">
<ai splitsize="1" killpeasants="yes" scarepeasants="yes"/>
<ai splitsize="1" killpeasants="yes" learn="yes" scarepeasants="yes"/>
<skill name="magic" modifier="12"/>
<skill name="tactics" modifier="12"/>
<skill name="perception" modifier="10"/>
@ -708,7 +708,7 @@
<attack type="6" spell="powerful_dragonbreath" level="12" />
</race>
<race name="dragon" magres="70" maxaura="1.0" regaura="2.0" weight="10000" capacity="1000000" speed="1.500000" hp="900" ac="6" damage="2d30" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes" unarmedguard="yes" dragon="yes">
<ai splitsize="2" killpeasants="yes" scarepeasants="yes"/>
<ai splitsize="2" killpeasants="yes" learn="yes" scarepeasants="yes"/>
<skill name="magic" modifier="8"/>
<skill name="tactics" modifier="8"/>
<skill name="perception" modifier="5"/>
@ -718,7 +718,7 @@
<attack type="6" spell="icy_dragonbreath" level="6" />
</race>
<race name="youngdragon" magres="50" maxaura="1.0" regaura="1.0" weight="20000" capacity="10000" speed="1.0" hp="300" ac="4" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes" unarmedguard="yes" dragon="yes">
<ai splitsize="6" killpeasants="yes" scarepeasants="yes"/>
<ai splitsize="6" killpeasants="yes" learn="yes" scarepeasants="yes"/>
<skill name="magic" modifier="4"/>
<skill name="tactics" modifier="4"/>
<skill name="stealth" modifier="2"/>
@ -734,7 +734,7 @@
<attack type="5"/>
</race>
<race name="aquarian" maxaura="1" regaura="1" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" shipspeed="yes" playerrace="yes" coastal="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="mining" modifier="-2"/>
<skill name="building" modifier="-1"/>
<skill name="trade" modifier="2"/>
@ -752,7 +752,7 @@
<familiar race="kraken"/>
</race>
<race name="cat" maxaura="1" regaura="1" recruitcost="90" maintenance="10" weight="1000" capacity="540" speed="1" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" defensemodifier="1" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="alchemy" modifier="-1"/>
<skill name="mining" modifier="-2"/>
<skill name="building" modifier="-1"/>
@ -777,7 +777,7 @@
<familiar race="hellcat"/>
</race>
<race name="halfling" magres="5" maxaura="1" regaura="1" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1" hp="18" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="hunger_damage" value="1d10+7"/>
<skill name="crossbow" modifier="1"/>
<skill name="mining" modifier="1"/>
@ -809,7 +809,7 @@
<familiar race="rat"/>
</race>
<race name="insect" magres="5" maxaura="1" regaura="1" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1" hp="24" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="mining" modifier="1"/>
<skill name="bow" modifier="-2"/>
@ -840,7 +840,7 @@
maintenance="10" weight="1000" capacity="540" speed="1" hp="50" ac="2" damage="1d5"
unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes"
giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="alchemy" modifier="2"/>
<skill name="trade" modifier="-3"/>
<skill name="forestry" modifier="1"/>
@ -870,7 +870,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<familiar race="imp"/>
</race>
<race name="troll" magres="10" maxaura="1" regaura="1" recruitcost="90" maintenance="10" weight="2000" capacity="1080" speed="1" hp="30" ac="1" damage="1d5+3" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="mining" modifier="2"/>
<skill name="bow" modifier="-2"/>
<skill name="building" modifier="2"/>
@ -900,7 +900,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<familiar race="wolf"/>
</race>
<race name="goblin" magres="-5" maxaura="1" regaura="1" recruitcost="40" maintenance="10" weight="600" capacity="440" speed="1" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="alchemy" modifier="1"/>
<skill name="mining" modifier="1"/>
<skill name="building" modifier="1"/>
@ -957,7 +957,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<attack type="1" damage="0d0"/>
</race>
<race name="template" maintenance="0" magres="100" maxaura="0" regaura="0" weight="0" capacity="1000" speed="10" hp="10" damage="1d4" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" fly="yes" swim="yes" walk="yes" shapeshift="yes" shapeshiftany="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" recruitunlimited="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<attack type="1" damage="1d4"/>
</race>
<race name="gnome" magres="100" maxaura="0.0" regaura="0.0" weight="1000" capacity="540" speed="1.0" hp="50" damage="1d4" unarmedattack="10" unarmeddefense="10" attackmodifier="10" defensemodifier="10" walk="yes" teach="no">
@ -982,7 +982,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<attack type="2" damage="5d600"/>
<attack type="1" damage="1d4"/>
</race>
<race name="ghast" magres="60" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes" desert="yes">
<race name="ghast" magres="60" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes">
<ai splitsize="2000" killpeasants="yes" moverandom="yes" scarepeasants="yes" absorbpeasants="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="bow" modifier="1"/>
@ -999,7 +999,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<attack type="2" damage="1d30"/>
<attack type="2" damage="1d30"/>
</race>
<race name="ghoul" magres="30" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes" desert="yes">
<race name="ghoul" magres="30" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" giveperson="yes">
<ai splitsize="10000" absorbpeasants="yes" killpeasants="yes" moverandom="yes" scarepeasants="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="bow" modifier="1"/>
@ -1030,7 +1030,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<attack type="3" damage="1d1"/>
<attack type="3" damage="1d1"/>
</race>
<race name="zombie" magres="20" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" giveperson="yes" desert="yes">
<race name="zombie" magres="20" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" walk="yes" learn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" giveperson="yes">
<ai splitsize="10000" killpeasants="yes" moverandom="yes" scarepeasants="yes"/>
<skill name="crossbow" modifier="1"/>
<skill name="bow" modifier="1"/>
@ -1075,7 +1075,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<attack type="1" damage="1d1"/>
</race>
<race name="seaserpent" magres="50" maxaura="1.0" regaura="1.0" weight="20000" capacity="5000" speed="1.0" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" swim="yes" teach="no" getitem="yes" resistbash="yes" unarmedguard="yes">
<ai splitsize="6" killpeasants="yes" moverandom="yes" moveattack="yes" scarepeasants="yes"/>
<ai splitsize="6" killpeasants="yes" moverandom="yes" learn="yes" moveattack="yes" scarepeasants="yes"/>
<skill name="tactics" modifier="4"/>
<attack type="4" damage="1d30"/>
<attack type="4" damage="1d30"/>
@ -1086,7 +1086,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<race name="snotling" magres="-5" maxaura="1" regaura="1"
maintenance="10" weight="1000" capacity="540" speed="1" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="no" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="alchemy" modifier="1"/>
<skill name="mining" modifier="1"/>
<skill name="building" modifier="1"/>
@ -1115,7 +1115,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<familiar race="demon"/>
</race>
<race name="elf" magres="10" maxaura="1" regaura="1.25" recruitcost="130" maintenance="10" weight="1000" capacity="540" speed="1" hp="18" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="alchemy" modifier="-1"/>
<skill name="mining" modifier="-2"/>
<skill name="bow" modifier="2"/>
@ -1141,7 +1141,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<familiar race="imp"/>
</race>
<race name="dwarf" magres="5" maxaura="1" regaura="0.5" recruitcost="110" maintenance="10" weight="1000" capacity="540" speed="1" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<skill name="mining" modifier="2"/>
<skill name="bow" modifier="-1"/>
<skill name="building" modifier="2"/>
@ -1172,7 +1172,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<familiar race="rat"/>
</race>
<race name="orc" studyspeed="-5" magres="-5" maxaura="1" regaura="1" recruitcost="70" maintenance="10" weight="1000" capacity="540" speed="1" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes"/>
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="recruit_multi" value="0.5"/>
<skill name="alchemy" modifier="1"/>
<skill name="mining" modifier="1"/>
@ -1202,7 +1202,7 @@ giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes">
<familiar race="demon"/>
</race>
<race name="shadowdragon" magres="95" maxaura="1.0" regaura="3.0" weight="100" capacity="100000" speed="1.0" hp="2700" ac="10" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="12" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes">
<ai splitsize="1" killpeasants="yes" scarepeasants="yes"/>
<ai splitsize="1" killpeasants="yes" learn="yes" scarepeasants="yes"/>
<skill name="tactics" modifier="20"/>
<skill name="perception" modifier="20"/>
<attack type="4" damage="5d30"/>

View file

@ -93,7 +93,7 @@
<spell name="transferauratraum" rank="1" syntax="aura" parameters="ui" ship="true">
<resource name="aura" amount="2" cost="fixed"/>
</spell>
<spell name="auratransfer" rank="1" syntax="aura" parameters="ui" noresist="true" ship="true">
<spell name="auratransfer" rank="1" syntax="aura" parameters="ui" ship="true">
<resource name="aura" amount="1" cost="fixed"/>
</spell>
<spell name="stonegolem" rank="4" variable="true">
@ -192,7 +192,7 @@
<resource name="h7" amount="3" cost="fixed"/>
<resource name="money" amount="50" cost="fixed"/>
</spell>
<spell name="enterastral" rank="7" parameters="u+" noresist="true" variable="true">
<spell name="enterastral" rank="7" parameters="u+" variable="true">
<resource name="aura" amount="2" cost="level"/>
</spell>
<spell name="leaveastral" rank="7" parameters="ru+" variable="true">
@ -214,13 +214,13 @@
<spell name="view_reality" rank="5">
<resource name="aura" amount="40" cost="fixed"/>
</spell>
<spell name="astral_disruption" rank="4" noresist="true" variable="true">
<spell name="astral_disruption" rank="4">
<resource name="aura" amount="140" cost="fixed"/>
</spell>
<spell name="seduction" rank="5" parameters="u" los="true">
<resource name="aura" amount="12" cost="fixed"/>
</spell>
<spell name="sound_out" rank="5" parameters="ur" noresist="true" los="true">
<spell name="sound_out" rank="5" parameters="ur" los="true">
<resource name="aura" amount="4" cost="fixed"/>
<resource name="money" amount="100" cost="fixed"/>
</spell>
@ -422,7 +422,7 @@
<resource name="aura" amount="1" cost="fixed"/>
<resource name="permaura" amount="1" cost="fixed"/>
</spell>
<spell name="eternal_walls" rank="5" parameters="b" ship="true" variable="true">
<spell name="eternal_walls" rank="5" parameters="b" ship="true">
<resource name="aura" amount="50" cost="fixed"/>
<resource name="permaura" amount="1" cost="fixed"/>
</spell>

View file

@ -590,9 +590,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Um in Gletscher
msgid "feedback_unit_not_found"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit wurde nicht gefunden.\""
msgid "feedback_not_inside"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kontrolliert kein Schiff oder Gebäude.\""
msgid "error206"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Auf dem Gebäude liegt bereits so ein Zauber.\""
@ -692,6 +689,9 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kan
msgid "error85"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Es wurde keine Emailadresse angegeben.\""
msgid "error125"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Es wurde kein Banner angegeben.\""
msgid "starvation"
msgstr "\"$unit($unit) verliert in $region($region) $int($dead) von $int($add($live,$dead)) Personen durch Unterernährung.\""
@ -1161,12 +1161,6 @@ msgid "spyreport_faction"
msgstr "\"$unit($target) gehört der Partei $faction($faction) an.\""
msgid "ship_drift"
msgstr "\"Die $ship($ship) treibt nach $direction($dir).\""
msgid "ship_drift_overload"
msgstr "\"Die $ship($ship) ist überladen und treibt nach $direction($dir).\""
msgid "ship_drift_nocrew"
msgstr "\"Die $ship($ship) hat zu wenig Segler und treibt nach $direction($dir).\""
msgid "error_max_magicians"
@ -1428,7 +1422,7 @@ msgid "error259"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Befehl ist nur auf Einheiten innerhalb des selben Gebäudes oder Schiffes anwendbar.\""
msgid "building_needed"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit steht in keinem funktionierenden $localize($building).\""
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit steht nicht im benötigten Gebäude, $localize($building).\""
msgid "error149"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Wohin soll die Botschaft gehen?\""
@ -1937,6 +1931,9 @@ msgstr "\"Albträume plagen die Leute. ($int36($id))\""
msgid "error295"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Nur ein Magier kann einen Astralkristall benutzen.\""
msgid "error185"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Zauber scheint ungewöhnlich schwach zu sein. Irgendetwas hat die magischen Energien abgeleitet.\""
msgid "error181"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Dazu muß sich der Magier in der Burg oder an Bord des Schiffes befinden.\""
@ -2600,12 +2597,6 @@ msgstr "\"$unit($follower) konnte $unit($unit) nicht folgen.\""
msgid "followdetect"
msgstr "\"$unit($follower) ist $unit($unit) gefolgt.\""
msgid "followfail_ship"
msgstr "\"Die $ship($follower) konnte die $ship($ship) nicht einholen.\""
msgid "followdetect_ship"
msgstr "\"Die $ship($ship) wurde von $ship($follower) verfolgt.\""
msgid "unitnotfound_id"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Einheit $id wurde nicht gefunden.\""
@ -2649,13 +2640,7 @@ msgid "error201"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Rasse und Zieleinheit wurden vergessen.\""
msgid "newbieimmunity"
msgstr "\"Deine Partei ist noch die nächsten $int($turns) Wochen immun gegen Angriffe.\""
msgid "newbieimmunityending"
msgstr "\"Deine Partei ist nur noch in der kommenden Woche immun gegen Angriffe.\""
msgid "newbieimmunityended"
msgstr "\"Deine Partei ist nun nicht mehr immun gegen Angriffe.\""
msgstr "\"Deine Partei ist noch $int($turns) Wochen immun gegen Angriffe.\""
msgid "curseinfo::auraboost_0"
msgstr "\"$unit($unit) fühlt sich von starken magischen Energien durchströmt. ($int36($id))\""

View file

@ -590,9 +590,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - You must build
msgid "feedback_unit_not_found"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit could not be found.\""
msgid "feedback_unit_not_found"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit is not the owner of a ship or building.\""
msgid "error206"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - There is alrady a spell on that building.\""
@ -692,6 +689,9 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit cannot
msgid "error85"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - No email address was supplied.\""
msgid "error125"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - No banner text was supplied.\""
msgid "starvation"
msgstr "\"$unit($unit) loses $int($dead) of $int($add($live,$dead)) people due to starvation in $region($region).\""
@ -1161,12 +1161,6 @@ msgid "spyreport_faction"
msgstr "\"$unit($target) belongs to $faction($faction).\""
msgid "ship_drift"
msgstr "\"The ship $ship($ship) drifts to the $direction($dir).\""
msgid "ship_drift_overload"
msgstr "\"The ship $ship($ship) is too heavily loaded and drifts to the $direction($dir).\""
msgid "ship_drift_nocrew"
msgstr "\"The ship $ship($ship) needs more sailors and drifts to the $direction($dir).\""
msgid "error_max_magicians"
@ -1428,7 +1422,7 @@ msgid "error259"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - That order only applies to units in the same building or ship.\""
msgid "building_needed"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit must be in a working $localize($building) to produce this.\""
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit must be in a $localize($building) to produce this.\""
msgid "error149"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Who is supposed to get this message?\""
@ -1818,7 +1812,7 @@ msgid "error243"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - You did not specify a valid race.\""
msgid "error133"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - You must build a caravanserai before building roads through deserts.\""
msgstr "\"$unit($unit) in $region($region): '$order($command)' - You must build a caravansary before building roads through deserts.\""
msgid "changepasswd"
msgstr "\"The password of this faction is '$value'.\""
@ -1937,6 +1931,9 @@ msgstr "\"Nightmares plague the population. ($int36($id))\""
msgid "error295"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Only mages may use an astralcrystal.\""
msgid "error185"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The spell seems exceptionally weak. Something has interfred with the magical energies.\""
msgid "error181"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - To do this, the magician has to be in a castle or on board a ship.\""
@ -2594,12 +2591,6 @@ msgstr "\"$unit($mage) makes $unit($target) appear as $race($race,$unit.size($ta
msgid "error248"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The faction has to be 10 turns old.\""
msgid "followfail_ship"
msgstr "\"$ship($follower) could not catch up to $ship($ship).\""
msgid "followdetect_ship"
msgstr "\"$ship($follower) followed $ship($ship).\""
msgid "followfail"
msgstr "\"$unit($follower) could not follow $unit($unit).\""
@ -2649,13 +2640,7 @@ msgid "error201"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Race and target unit have not been supplied.\""
msgid "newbieimmunity"
msgstr "\"Your faction will be protected against attacks for the next $int($turns) weeks.\""
msgid "newbieimmunityending"
msgstr "\"Your faction will be protected against attacks only one more week.\""
msgid "newbieimmunityended"
msgstr "\"Your faction will no longer be protected against attacks.\""
msgstr "\"Your faction is immune against assaults for $int($turns) more weeks.\""
msgid "curseinfo::auraboost_0"
msgstr "\"Powerful magical energies are pulsing through $unit($unit). ($int36($id))\""

View file

@ -2496,10 +2496,6 @@ msgctxt "keyword"
msgid "loot"
msgstr "PLÜNDERE"
msgctxt "keyword"
msgid "expel"
msgstr "VERTREIBE"
msgctxt "calendar"
msgid "month_1"
msgstr "Feldsegen"
@ -6089,7 +6085,7 @@ msgstr "ENDE"
msgctxt "raceinfo"
msgid "tunnelworm"
msgstr "Dieses aus den Tiefen Eresseas stammende gigantische Geschöpf ist dem Leben im Untergrund hervorragend angepasst. Blind, taub und nicht besonders intelligent, aber mit seinen gewaltigen Kräften kann es ganze Berge versetzen oder Wälder roden."
msgstr "Diese aus den Tiefen Eresseas stammende gigantische Geschöpf ist dem Leben im Untergrund hervorragend angepasst. Blind, taub und nicht besonders intelligent, aber mit seinen gewaltigen Kräften kann es ganze Berge versetzen oder Wälder roden."
msgctxt "race"
msgid "aquarian_d"

View file

@ -1318,7 +1318,7 @@ msgid "peasantblood"
msgstr "peasant blood"
msgid "caravan"
msgstr "caravanserai"
msgstr "caravanserei"
msgctxt "race"
msgid "human"
@ -1741,6 +1741,10 @@ msgstr "caravel"
msgid "stone_p"
msgstr "stones"
msgctxt "keyword"
msgid "locale"
msgstr "LOCALE"
msgctxt "spellinfo"
msgid "song_suscept_magic"
msgstr "This song, which is woven into the magical essence of the region, weakens the natural resistance against a singular enchantment by 15%. Only the allies of the bard (HELP GUARD) are immune to the effect of the chant."
@ -2167,10 +2171,6 @@ msgctxt "keyword"
msgid "loot"
msgstr "loot"
msgctxt "keyword"
msgid "expel"
msgstr "EXPEL"
msgctxt "keyword"
msgid "guard"
msgstr "GUARD"

View file

@ -1,5 +1,6 @@
#!/bin/sh
ROOT=$(git rev-parse --show-toplevel)
eval $(luarocks path)
[ -z "$BUILD" ] && BUILD=Debug
if [ -z "$JOBS" ] ; then
if [ -e /usr/sbin/sysctl ]; then

View file

@ -6,6 +6,7 @@ pkg-config --exists sqlite3 && ERESSEA_DB=sqlite
GETOPT=getopt
GETOPT_LONG=1
luarocks install lunitx --local
if [ "Darwin" = "$(uname)" ] ; then
if [ -x "/usr/local/opt/gnu-getopt/bin/getopt" ] ; then
GETOPT="/usr/local/opt/gnu-getopt/bin/getopt"
@ -45,7 +46,6 @@ fi
shift 1
done
git submodule update --init
ROOT=$(git rev-parse --show-toplevel)
[ -z $BUILD ] && BUILD=Debug
[ -z "$CC" ] && [ ! -z `which clang` ] && CC="clang"
@ -75,20 +75,22 @@ fi
DEST=$(dirname $ROOT)/server
LUA_VERSION="5.2"
LUA_INCLUDE=/usr/include
LUA_DIR=/usr
if [ -d /usr/local/include/lua ]; then
LUA_INCLUDE=/usr/local/include/lua
elif [ -d /usr/include/lua5.4 ]; then
LUA_INCLUDE=/usr/include/lua5.4
elif [ -d /usr/include/lua5.3 ]; then
LUA_INCLUDE=/usr/include/lua5.3
if [ -d /usr/local/include/lua5.3 ]; then
LUA_VERSION="5.3"
LUA_INCLUDE=/usr/local/include/lua5.3
elif [ -d /usr/include/lua5.2 ]; then
export LUA_DIR=/usr
LUA_VERSION="5.2"
LUA_INCLUDE=/usr/include/lua5.2
elif [ -d /usr/include/lua5.1 ]; then
LUA_VERSION="5.1"
LUA_INCLUDE=/usr/include/lua5.1
elif [ -d /usr/local/include/lua5.1 ]; then
LUA_DIR=/usr/local
export LUA_DIR=/usr/local
LUA_VERSION="5.1"
LUA_INCLUDE=/usr/local/include/lua5.1
fi
@ -106,6 +108,27 @@ SET (CMAKE_LIBRARY_PATH "$LIBRARY_PATH" CACHE PATH "")
SET (CMAKE_PREFIX_PATH "$PREFIX_PATH" CACHE PATH "")
HEREDOC
path="$(which tolua)"
if [ "$HAVE_TOLUA" = "0" ] || [ -z $path ] ; then
echo "tolua is not installed, building from source"
cd $ROOT
if [ ! -d tolua/include ]; then
echo "fetching tolua ${LUA_VERSION} from github..."
git clone https://github.com/ennorehling/tolua-${LUA_VERSION}.git tolua
fi
echo "building tolua..."
cd tolua
make
cd -
cat >> $BUILD/config.cmake <<TOLUA
SET(PC_TOLUA_DIR "$ROOT/tolua" CACHE PATH "tolua root")
TOLUA
else
echo "tolua is $path"
fi
unset path
set -e
cd $BIN_DIR

View file

@ -58,6 +58,7 @@ cat >| eressea.ini <<HEREDOC
dbname = eressea.db
dbswap = :memory:
install = $SOURCE
paths = $SOURCE/lunit:$SOURCE/git/scripts
rules = e$game
HEREDOC
}

View file

@ -1,16 +1,19 @@
#!/bin/bash
set -e
eval $(luarocks path)
ROOT=$(git rev-parse --show-toplevel)
export LUA_PATH="$ROOT/scripts/?.lua;$LUA_PATH"
[ -z $BUILD ] && BUILD=Debug ; export BUILD
UNIT_TESTS=$ROOT/$BUILD/eressea/test_eressea
RUN_TESTS=$ROOT/$BUILD/eressea/eressea
if [ "$1" = "-V" ]; then
VALGRIND=$(which valgrind)
if [ -n "$VALGRIND" ]; then
SUPP=$ROOT/share/ubuntu-12_04.supp
UNIT_TESTS="valgrind --quiet --suppressions=$SUPP --error-exitcode=1 --leak-check=no $UNIT_TESTS"
RUN_TESTS="valgrind --quiet --suppressions=$SUPP --error-exitcode=1 --leak-check=no $RUN_TESTS"
UNIT_TESTS="$VALGRIND --quiet --suppressions=$SUPP --error-exitcode=1 --leak-check=no $UNIT_TESTS"
RUN_TESTS="$VALGRIND --quiet --suppressions=$SUPP --error-exitcode=1 --leak-check=no $RUN_TESTS"
fi
fi
if [ ! -e $ROOT/$BUILD ]; then
@ -18,8 +21,8 @@ if [ ! -e $ROOT/$BUILD ]; then
exit
fi
cd $ROOT/tests
$UNIT_TESTS
cd $ROOT/tests
$RUN_TESTS -v1 ../scripts/run-tests.lua
$RUN_TESTS -v1 ../scripts/run-tests-e2.lua
$RUN_TESTS -v1 ../scripts/run-tests-e3.lua

View file

@ -102,6 +102,7 @@ ini_add game id $game
ini_add game start 1
ini_sec lua
ini_add lua install $SOURCE
ini_add lua paths $SOURCE/scripts:$SOURCE/lunit
ini_add lua rules $rules
echo 0 > turn

View file

@ -6,7 +6,7 @@ inifile() {
cd $ROOT
if [ ! -e eressea.ini ]; then
cp conf/eressea.ini .
$BUILD/tools/inifile eressea.ini add lua:paths lunit:scripts
$BUILD/iniparser/inifile eressea.ini add lua:paths lunit:scripts
fi
}
@ -39,14 +39,5 @@ cd ../process
make
cd $ROOT
inifile
luarocks install lunitx --local
eval $(luarocks path)
export LUA_PATH="$ROOT/scripts/?.lua;$LUA_PATH"
echo $LUA_PATH
if [ -e /usr/bin/valgrind ]; then
s/runtests -V
else
s/runtests
fi
s/runtests -V
integration_tests

View file

@ -66,6 +66,7 @@ local sets = {
['seed_seaserpent'] = {
['skills'] = {
['magic'] = 4,
['stealth'] = 2,
['stamina'] = 1,
['perception'] = 3,
}

View file

@ -1,9 +1,5 @@
local path = '.'
if config.install then
path = config.install
else
path = os.getenv("ERESSEA_ROOT") or path
config.install = path
if config.paths ~= nil then
for path in string.gmatch(config.paths, "([^:]+)") do
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
end
end
path = path .. "/scripts"
package.path = path .. '/?.lua;' .. path .. '/?/init.lua;' .. package.path

View file

@ -18,7 +18,7 @@ end
local function get_target(param)
local ntargets = #targets
if ntargets == 0 then
eressea.log.error("No tunnel targets for [" .. param .. "]")
eressea.log.error("Zero tunnel targets for [" .. param .. "]")
return nil
end
local rn = math.fmod(rng_int(), ntargets)
@ -31,13 +31,10 @@ end
local function tunnel_action(b, param)
local units = tunnel_travelers(b)
local rto = get_target(param)
eressea.log.info("Tunnel from " .. tostring(b) .. " [" .. param .. "]")
if units then
if rto and units then
for _, u in pairs(units) do
local rto = get_target(param)
if not rto then
break
end
u.region = rto
eressea.log.info("teleported " .. tostring(u) .. " to " .. tostring(rto))
end

View file

@ -1,3 +1,8 @@
local path = 'scripts'
if config.install then
path = config.install .. '/' .. path
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
require 'eressea.path'
require 'eressea'
require 'eressea.xmlconf'

View file

@ -1,7 +1,4 @@
dofile('config.lua')
eressea.read_game(get_turn() .. '.dat')
init_reports()
-- do not use write_reports, since it will change passwords
for f in factions() do
write_report(f)
end
write_reports()

View file

@ -1,15 +1,22 @@
-- Tests that work in all games. With game config of E2.
-- Tests are under scripts/test/e2 and all files must be in scripts/test/e2/init.lua
config.rules = 'e2'
lunit = require 'lunit'
lunit = require('lunit')
if _VERSION >= 'Lua 5.2' then
module = lunit.module
module = lunit.module
end
require 'eressea.path'
path = 'scripts'
if config.install then
path = config.install .. '/' .. path
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
config.rules = 'e2'
require 'eressea'
require 'eressea.xmlconf'
require 'eressea.path'
require 'tests.e2'
rng.inject(0)

View file

@ -1,14 +1,21 @@
-- Tests that work in E3. With game config of E3.
-- Tests are under scripts/test/e3 and all files must be in scripts/test/e3/init.lua
config.rules = 'e3'
lunit = require 'lunit'
lunit = require('lunit')
if _VERSION >= 'Lua 5.2' then
module = lunit.module
module = lunit.module
end
require 'eressea.path'
path = 'scripts'
if config.install then
path = config.install .. '/' .. path
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
config.rules = 'e3'
require 'eressea'
require 'eressea.path'
require 'eressea.xmlconf'
require 'tests.e3'

View file

@ -1,13 +1,19 @@
-- Basic test without loading XML Config. Test care about needed settings.
-- Tests are under scripts/test/ and all files must be in scripts/test/init.lua
lunit = require 'lunit'
lunit = require('lunit')
if _VERSION >= 'Lua 5.2' then
module = lunit.module
end
require 'eressea.path'
path = 'scripts'
if config.install then
path = config.install .. '/' .. path
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
require 'eressea'
require 'eressea.path'
require 'tests'
result = lunit.main()
return result.errors + result.failed

View file

@ -1,5 +1,3 @@
require 'eressea.path'
function nmr_check(maxnmrs)
local nmrs = get_nmrs(1)
if nmrs > maxnmrs then
@ -16,15 +14,15 @@ function open_game(turn)
return eressea.read_game(file .. ".dat")
end
local function callbacks(rules, name, ...)
for k, v in pairs(rules) do
if 'table' == type(v) then
cb = v[name]
if 'function' == type(cb) then
cb(...)
end
end
end
function callbacks(rules, name, ...)
for k, v in pairs(rules) do
if 'table' == type(v) then
cb = v[name]
if 'function' == type(cb) then
cb(...)
end
end
end
end
local function write_emails(locales)
@ -49,8 +47,8 @@ local function write_emails(locales)
end
local function join_path(a, b)
if a then return a .. '/' .. b end
return b
if a then return a .. '/' .. b end
return b
end
local function write_addresses()
@ -85,23 +83,23 @@ local function write_aliases()
end
local function write_htpasswd()
local out = io.open(join_path(config.basepath, "htpasswd"), "w")
if out then
for f in factions() do
if f.password then
out:write(itoa36(f.id) .. ":" .. f.password .. "\n")
end
local out = io.open(join_path(config.basepath, "htpasswd"), "w")
if out then
for f in factions() do
if f.password then
out:write(itoa36(f.id) .. ":" .. f.password .. "\n")
end
end
out:close()
end
out:close()
end
end
local function write_files(locales)
write_reports()
write_summary()
write_database()
write_passwords()
write_htpasswd()
write_reports()
write_summary()
write_database()
write_passwords()
write_htpasswd()
end
local function write_scores()
@ -123,83 +121,86 @@ local function write_scores()
end
function process(rules, orders)
local confirmed_multis = { }
local suspected_multis = { }
local confirmed_multis = { }
local suspected_multis = { }
if open_game(get_turn())~=0 then
eressea.log.error("could not read game")
return -1
end
if open_game(get_turn())~=0 then
eressea.log.error("could not read game")
return -1
end
turn_begin()
-- create orders for monsters:
plan_monsters()
-- read orders for players:
if eressea.read_orders(orders) ~= 0 then
print("could not read " .. orders)
return -1
end
turn_begin()
-- create orders for monsters:
plan_monsters()
-- read orders for players:
if eressea.read_orders(orders) ~= 0 then
print("could not read " .. orders)
return -1
end
if nmr_check(config.maxnmrs or 80)~=0 then
return -1
end
callbacks(rules, 'init')
-- run the turn:
turn_process()
callbacks(rules, 'update')
turn_end() -- ageing, etc.
if nmr_check(config.maxnmrs or 80)~=0 then
return -1
end
callbacks(rules, 'init')
-- run the turn:
turn_process()
callbacks(rules, 'update')
turn_end() -- ageing, etc.
if not config.debug then
write_files(config.locales)
update_scores()
write_files(config.locales)
update_scores()
file = '' .. get_turn() .. '.dat'
if eressea.write_game(file)~=0 then
file = '' .. get_turn() .. '.dat'
if eressea.write_game(file)~=0 then
eressea.log.error("could not write game")
return -1
end
end
return 0
end
return 0
end
function run_turn(rules)
local turn = get_turn()
if turn<0 then
turn = read_turn()
set_turn(turn)
end
local turn = get_turn()
if turn<0 then
turn = read_turn()
set_turn(turn)
end
orderfile = orderfile or config.basepath .. '/orders.' .. turn
eressea.log.debug("executing turn " .. get_turn() .. " with " .. orderfile .. " with rules=" .. config.rules)
local result = process(rules, orderfile)
return result
orderfile = orderfile or config.basepath .. '/orders.' .. turn
eressea.log.debug("executing turn " .. get_turn() .. " with " .. orderfile .. " with rules=" .. config.rules)
local result = process(rules, orderfile)
return result
end
function file_exists(name)
local f=io.open(name,"r")
if not f then
return false
end
io.close(f)
return true
local f=io.open(name,"r")
if not f then
return false
end
io.close(f)
return true
end
if file_exists('execute.lock') then
eressea.log.error("Lockfile exists, aborting.")
assert(false)
eressea.log.error("Lockfile exists, aborting.")
assert(false)
end
math.randomseed(rng.random())
local path = 'scripts'
if config.install then
path = config.install .. '/' .. path
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
require 'eressea'
require 'eressea.xmlconf' -- read xml data
local rules = {}
if config.rules then
rules = require('eressea.' .. config.rules)
eressea.log.info('loaded ' .. #rules .. ' modules for ' .. config.rules)
rules = require('eressea.' .. config.rules)
eressea.log.info('loaded ' .. #rules .. ' modules for ' .. config.rules)
else
eressea.log.warning('no rule modules loaded, specify a game in eressea.ini or with -r')
eressea.log.warning('no rule modules loaded, specify a game in eressea.ini or with -r')
end
run_turn(rules)

View file

@ -66,7 +66,7 @@ function test_flags()
local f = create_faction('halfling')
local u = unit.create(f, r, 1)
local no = itoa36(f.id)
local flags = 50331648
local flags = 50332672
f.flags = flags
eressea.write_game("test.dat")
@ -136,9 +136,11 @@ function test_fleeing_units_can_be_transported()
u1.number = 100
u1:add_order("ATTACKIEREN " .. itoa36(u2.id))
u2.number = 100
u2.name = 'Passagier'
u2:add_order("FAHREN " .. itoa36(u3.id))
u2:add_order("KAEMPFE FLIEHE")
u3.number = 100
u3.name = 'Transporter'
u3:add_order("KAEMPFE FLIEHE")
u3:add_order("TRANSPORT " .. itoa36(u2.id))
u3:add_order("NACH O ")
@ -640,6 +642,7 @@ function test_laen2()
u1:set_skill("mining", 15)
u1:clear_orders()
u1:add_order("MACHEN Laen")
u1.name = "Laenmeister"
local b = building.create(r, "mine")
b.size = 10

View file

@ -13,7 +13,6 @@ function setup()
eressea.settings.set("NewbieImmunity", "0")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.peasants.growth.factor", "0")
eressea.settings.set("magic.resist.enable", "0")
eressea.settings.set("magic.fumble.enable", "0")
eressea.settings.set("magic.regeneration.enable", "0")
end

View file

@ -9,13 +9,11 @@ end
function setup()
eressea.free_game()
eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("rules.grow.formula", "0")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.ship.storms", "0")
eressea.settings.set("rules.encounters", "0")
eressea.settings.set("study.produceexp", "0")
eressea.settings.set("rules.peasants.growth.factor", "0")
eressea.settings.set("magic.resist.enable", "0")
end
function disabled_double_default()
@ -90,6 +88,7 @@ function test_herbalism()
local f = faction.create("human")
local u = unit.create(f, r, 1)
eressea.settings.set("rules.grow.formula", 0) -- plants do not grow
u:add_item("money", u.number * 100)
u:set_skill("herbalism", 5)
r:set_resource("seed", 100)
@ -115,6 +114,7 @@ function test_dwarf_bonus()
local u = unit.create(faction.create("dwarf"), r)
assert_equal("dwarf", u.faction.race)
assert_equal("dwarf", u.race)
u.faction.name = "Zwerge"
u.number = 10
u:set_skill("mining", 1)
u:add_order("MACHE EISEN")
@ -606,7 +606,7 @@ function test_seacast()
u2.ship = s1
u2:add_spell("stormwinds")
u2:clear_orders()
u2:add_order("ZAUBERE STUFE 2 'Sturmelementar' " .. itoa36(s1.id))
u2:add_order("Zaubere stufe 2 'Sturmelementar' " .. itoa36(s1.id))
u1:clear_orders()
u1:add_order("NACH O O O O")
process_orders()

View file

@ -1,84 +0,0 @@
local tcname = 'tests.e2.familiars'
local lunit = require('lunit')
if _VERSION >= 'Lua 5.2' then
_ENV = module(tcname, 'seeall')
else
module(tcname, lunit.testcase, package.seeall)
end
function setup()
eressea.game.reset()
eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.peasants.growth.factor", "0")
eressea.settings.set("magic.resist.enable", "0")
eressea.settings.set("magic.fumble.enable", "0")
eressea.settings.set("magic.regeneration.enable", "0")
end
local function setup_familiars(f, r)
f.magic = 'gwyrrd'
local uf = unit.create(f, r)
uf.magic = 'gray'
local u = unit.create(f, r)
u.magic = 'gwyrrd'
u:set_skill('magic', 9)
u.familiar = uf
return u, uf
end
function test_moneyspell()
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local um, uf = setup_familiars(f, r)
um.aura = 9
um:add_order('ZAUBERE STUFE 9 Viehheilung')
process_orders()
assert_equal(0, um.aura)
assert_equal(450, um:get_item('money'))
end
function test_moneyspell_through_familiar()
-- casting magician's spell with the familiar: double cost
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local um, uf = setup_familiars(f, r)
um.aura = 12
uf:add_order('ZAUBERE STUFE 3 Viehheilung')
process_orders()
assert_equal(0, uf:get_skill('magic'))
assert_equal(12, um.aura) -- cannot cast, familiar needs magic skill
assert_equal(0, uf:get_item('money'))
assert_equal(0, um:get_item('money'))
uf:set_skill('magic', 2) -- can cast no higher than level 2
process_orders()
assert_equal(8, um.aura) -- double the cost
assert_equal(100, uf:get_item('money'))
assert_equal(0, um:get_item('money'))
um:set_skill('magic', 4) -- use at most half of skill
uf:set_skill('magic', 1) -- too low for level 2 spell, cast at level 1
process_orders()
assert_equal(6, um.aura) -- double cost of level 1
assert_equal(150, uf:get_item('money'))
assert_equal(0, um:get_item('money'))
end
function test_moneyspell_as_familiar()
-- familiar has the spell and has magic skills: regular spellcasting rules apply
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local um, uf = setup_familiars(f, r)
um.aura = 9
uf.aura = 20
uf:set_skill('magic', 10)
uf:add_spell('earn_silver#gwyrrd')
uf:add_order('ZAUBERE STUFE 10 Viehheilung')
process_orders()
assert_equal(500, uf:get_item('money'))
assert_equal(10, uf.aura)
assert_equal(9, um.aura)
end

View file

@ -79,66 +79,3 @@ function test_no_guard_no_move_after_combat() -- bug 1493
u1 = get_unit(uid1)
assert_equal(r1, u1.region)
end
function test_move_stops_guarding()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "test@example.com", "de")
local u = unit.create(f, r1, 1)
u:add_item("sword", 1)
u:set_skill("melee", 2)
u:add_order("NACH O")
u:add_order("BEWACHE")
u.guard = true
process_orders()
assert_equal(r2, u.region)
assert_false(u.guard)
end
function test_move_to_same_region_stops_guarding()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "test@example.com", "de")
local u = unit.create(f, r1, 1)
u:add_item("horse", 1)
u:add_item("sword", 1)
u:set_skill("melee", 2)
u:set_skill("riding", 2)
u:add_order("NACH O W")
u.guard = true
process_orders()
assert_equal(r1, u.region)
assert_false(u.guard)
end
function test_mover_cannot_start_guarding()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "test@example.com", "de")
local u = unit.create(f, r1, 1)
u:add_item("horse", 1)
u:add_item("sword", 1)
u:set_skill("melee", 2)
u:set_skill("riding", 2)
u:add_order("BEWACHE")
u:add_order("NACH O")
process_orders()
assert_equal(r2, u.region)
assert_false(u.guard)
end
function test_move_to_same_region_stops_guarding()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "test@example.com", "de")
local u = unit.create(f, r1, 1)
u:add_item("horse", 1)
u:add_item("sword", 1)
u:set_skill("melee", 2)
u:set_skill("riding", 2)
u:add_order("BEWACHE")
u:add_order("NACH O W")
process_orders()
assert_equal(r1, u.region)
assert_false(u.guard)
end

View file

@ -1,4 +1,3 @@
require 'tests.e2.migration'
require 'tests.e2.trolls'
require 'tests.e2.trees'
require 'tests.e2.buildings'
@ -6,8 +5,6 @@ require 'tests.e2.movement'
require 'tests.e2.carts'
require 'tests.e2.astral'
require 'tests.e2.spells'
require 'tests.e2.migration'
require 'tests.e2.familiars'
require 'tests.e2.e2features'
require 'tests.e2.insects'
require 'tests.e2.production'
@ -33,5 +30,6 @@ require 'tests.magicbag'
require 'tests.process'
require 'tests.xmas'
require 'tests.production'
require 'tests.undead'
require 'tests.spells'
require 'tests.undead'

View file

@ -1,131 +0,0 @@
local tcname = 'tests.e2.migration'
local lunit = require('lunit')
if _VERSION >= 'Lua 5.2' then
_ENV = module(tcname, 'seeall')
else
module(tcname, lunit.testcase, package.seeall)
end
function setup()
eressea.game.reset()
eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.peasants.growth.factor", "0")
eressea.settings.set("magic.resist.enable", "0")
eressea.settings.set("magic.fumble.enable", "0")
eressea.settings.set("magic.regeneration.enable", "0")
end
local function setup_mage(f, r)
local u = unit.create(f, r)
u.magic = 'tybied'
u:set_skill('magic', 10)
u:add_spell('migration')
return u
end
function test_migration_success()
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local u = setup_mage(f, r)
local u2 = unit.create(faction.create('human'), r)
u2:add_order('KONTAKTIERE ' .. itoa36(u.id))
u:add_order('ZAUBERE STUFE 1 "Ritual der Aufnahme" ' .. itoa36(u2.id))
u.aura = 9
u.aura_max = 9
process_orders()
assert_equal(f, u2.faction)
assert_equal(6, u.aura)
assert_equal(8, u.aura_max)
end
function test_migration_no_contact()
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local u = setup_mage(f, r)
local u2 = unit.create(faction.create('human'), r)
u:add_order('ZAUBERE STUFE 1 "Ritual der Aufnahme" ' .. itoa36(u2.id))
u.aura = 9
u.aura_max = 9
process_orders()
assert_not_equal(f, u2.faction)
assert_equal(9, u.aura)
assert_equal(9, u.aura_max)
end
function test_migration_too_many()
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local u = setup_mage(f, r)
local u2 = unit.create(faction.create('human'), r)
u2:add_order('KONTAKTIERE ' .. itoa36(u.id))
u2.number = 2
u:add_order('ZAUBERE STUFE 1 "Ritual der Aufnahme" ' .. itoa36(u2.id))
u.aura = 9
u.aura_max = 9
process_orders()
assert_not_equal(f, u2.faction)
assert_equal(9, u.aura)
assert_equal(9, u.aura_max)
end
function test_migration_with_ring()
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local u = setup_mage(f, r)
local u2 = unit.create(faction.create('human'), r)
u2:add_order('KONTAKTIERE ' .. itoa36(u.id))
u2.number = 2
u:add_item('rop', 1)
u:add_order('ZAUBERE STUFE 1 "Ritual der Aufnahme" ' .. itoa36(u2.id))
u.aura = 9
u.aura_max = 9
process_orders()
assert_equal(f, u2.faction)
assert_equal(6, u.aura)
assert_equal(8, u.aura_max)
end
function test_migration_insufficient_aura()
-- if unit cannot pay full costs, it casts at a lower level.
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local u = setup_mage(f, r)
local u2 = unit.create(faction.create('human'), r)
u2:add_order('KONTAKTIERE ' .. itoa36(u.id))
u2.number = 2
u:add_order('ZAUBERE STUFE 2 "Ritual der Aufnahme" ' .. itoa36(u2.id))
u.aura = 3
u.aura_max = 9
process_orders()
-- spell fails, costs nothing:
assert_not_equal(f, u2.faction)
assert_equal(3, u.aura)
assert_equal(9, u.aura_max)
end
function test_migration_reduced_cost()
-- if unit cannot pay full costs, it casts at a lower level.
local r = region.create(0, 0, "plain")
local f = faction.create('human')
local u = setup_mage(f, r)
local u2 = unit.create(faction.create('human'), r)
u2:add_order('KONTAKTIERE ' .. itoa36(u.id))
u:add_order('ZAUBERE STUFE 2 "Ritual der Aufnahme" ' .. itoa36(u2.id))
u.aura = 3
u.aura_max = 9
process_orders()
-- spell is cast at level 1:
assert_equal(f, u2.faction)
assert_equal(0, u.aura)
assert_equal(7, u.aura_max)
end
--[[
additional tests:
- not enough aura, casting at lower level
- no aura, ring does not grant level 1
- magic tower, like ring, cumulative
]]--

View file

@ -165,73 +165,3 @@ function assert_capacity(text, u, silver, r1, r2, rx)
process_orders()
assert_equal(rx, u.region, text .. "unit should not move")
end
function test_move_to_same_region_leaves_building()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "test@example.com", "de")
local u = unit.create(f, r1, 1)
local b = building.create(u.region, "castle")
b.size = 2
u.building = b
assert_not_nil(u.building)
u:add_item("horse", 1)
u:set_skill("riding", 2)
u:add_order("NACH O W")
process_orders()
assert_equal(r1, u.region)
assert_nil(u.building)
end
function test_aquarians_can_swim()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "ocean")
local r3 = region.create(2, 0, "ocean")
local f = faction.create("aquarian")
local u1 = unit.create(f, r2, 1)
local u2 = unit.create(f, r2, 1)
local sh = ship.create(r2, 'boat')
u1.ship = sh
u1:set_skill('sailing', 2)
u1:add_order("NACH O")
u2.ship = sh
u2:add_order("NACH W")
process_orders()
assert_equal(r1, u2.region)
assert_equal(r3, u1.region)
end
function test_only_aquarians_can_swim()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "ocean")
local r3 = region.create(2, 0, "ocean")
local f = faction.create('human')
local u1 = unit.create(f, r2, 1)
local u2 = unit.create(f, r2, 1)
local sh = ship.create(r2, 'boat')
u1.ship = sh
u1:set_skill('sailing', 2)
u1:add_order("NACH O")
u2.ship = sh
u2:add_order("NACH W")
process_orders()
assert_equal(r3, u2.region)
assert_equal(r3, u1.region)
end
function test_looping_ship()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "ocean")
local f = faction.create("aquarian")
local u1 = unit.create(f, r1, 1)
u1.ship = ship.create(r1, 'boat')
local u2 = unit.create(f, r1, 1)
u2.ship = ship.create(r1, 'boat')
u1:set_skill('sailing', 2)
u1:add_order("NACH O W")
u2:set_skill('sailing', 2)
u2:add_order("NACH O")
process_orders()
assert_equal(r1, u1.region)
assert_equal(r2, u2.region)
end

View file

@ -22,6 +22,7 @@ function test_ship_requires_skill()
assert_not_nil(r2)
local f = faction.create("human", "fake@eressea.de", "de")
local u1 = unit.create(f, r1, 1)
u1.name = "fake"
u1.ship = ship.create(r1, "longboat")
u1:clear_orders()
u1:add_order("NACH O")
@ -518,29 +519,3 @@ function test_build_convoy_max()
assert_equal(100, sh.size)
assert_equal(25, u:get_item('log'))
end
function test_ship_crew_stops_guarding()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "ocean")
local f = faction.create("human")
local u1 = unit.create(f, r1, 1)
local u2 = unit.create(f, r1, 1)
local sh = ship.create(r1, "longboat")
u1.ship = sh
u2.ship = sh
u1:clear_orders()
u1:add_order("NACH O W")
u1:set_skill("sailing", 1) -- cptskill = 1
u2:set_skill("sailing", 9) -- sumskill = 10
u2:add_item("sword", 1)
u2:set_skill("melee", 2)
u2:add_order("BEWACHE")
u2.guard = true
process_orders()
assert_false(u2.guard)
assert_equal(sh, u1.ship)
assert_equal(sh, u2.ship)
assert_equal(r1, sh.region)
assert_equal(r1, u1.region)
assert_equal(r1, u2.region)
end

View file

@ -181,7 +181,7 @@ function test_familiar()
local f = faction.create("human")
local u = unit.create(f, r)
local uid = u.id
u.name = 'Bonzi'
u.name = 'Hodor'
u.magic = "gwyrrd"
u.race = "elf"
u:set_skill("magic", 10)
@ -192,7 +192,7 @@ function test_familiar()
process_orders()
for u in r.units do
if u.id ~= uid then
assert_equal('Vertrauter von Bonzi (' .. itoa36(uid) ..')', u.name)
assert_equal('Vertrauter von Hodor (' .. itoa36(uid) ..')', u.name)
end
end
end
@ -222,8 +222,6 @@ function test_bug_2480()
end
function test_bug_2517()
-- Magier macht lange Befehle, wenn sein Vertrauter
-- zaubert (auch wenn es nicht eigene Zauber sind).
local r = region.create(0, 0, "plain")
local f = faction.create("elf")
local um = unit.create(f, r, 1)
@ -244,25 +242,12 @@ function test_bug_2517()
assert_equal('gray', uf.magic)
uf:add_order('LERNE Magie')
um:clear_orders()
assert_equal(1, uf:get_skill('magic'))
um:add_order('ARBEITEN')
assert_equal(0, um:get_item('money'))
process_orders()
assert_equal('gray', uf.magic)
uf:add_order('ZAUBERE STUFE 1 Viehheilung')
um.aura = 10
uf.aura = 10
assert_equal(10, um:get_item('money')) -- langer Befehl wurde ausgefuehrt
process_orders()
assert_equal(50, uf:get_item('money'))
assert_equal(20, um:get_item('money')) -- langer Befehl wurde ausgefuehrt
assert_equal(8, um.aura) -- kein eigener Zauber, Aura des Magiers
assert_equal(10, uf.aura)
uf:add_spell('earn_silver#gwyrrd') -- ins private spellbook aufnehmen
process_orders()
assert_equal(9, uf.aura) -- einfache Kosten, aus eigener Aura
assert_equal(8, um.aura) -- keine Kosten für den Magier
assert_equal(30, um:get_item('money')) -- langer Befehl wurde ausgefuehrt
end
function test_familiar_school()
@ -288,64 +273,15 @@ end
function test_astral_disruption()
local r = region.create(0, 0, "plain")
local r2 = r:get_astral('fog')
local r3 = region.create(r2.x+1, r2.y, 'fog')
local f = faction.create("human")
local u = unit.create(f, r)
local uh = unit.create(get_monsters(), r2, 1, "braineater")
u.magic = "tybied"
u.magic = "draig"
u:set_skill("magic", 100) -- level 100 should beat magic resistance
u.aura = 200
u:add_spell("astral_disruption", 14)
u:add_spell("astral_disruption")
u:add_order('ZAUBERE STUFE 1 "Stoere Astrale Integritaet"')
process_orders()
assert_equal(60, u.aura)
assert_equal(100, r2:get_curse("astralblock"))
assert_nil(r3:get_curse("astralblock"))
assert_equal(r, uh.region)
end
function test_astral_disruption_levels()
local r = region.create(0, 0, "plain")
local r2 = r:get_astral('fog')
local r3 = region.create(r2.x+1, r2.y, 'fog')
local r4 = region.create(r2.x+2, r2.y, 'fog')
local f = faction.create("human")
local u = unit.create(f, r)
local uh = unit.create(get_monsters(), r2, 1, "braineater")
u.magic = "tybied"
u:set_skill("magic", 100) -- level 100 should beat magic resistance
u.aura = 200
u:add_spell("astral_disruption", 14)
-- at level 5, range +1:
u:add_order('ZAUBERE STUFE 5 "Stoere Astrale Integritaet"')
process_orders()
assert_equal(60, u.aura)
assert_equal(100, r2:get_curse("astralblock"))
assert_equal(100, r3:get_curse("astralblock"))
assert_nil(r4:get_curse("astralblock"))
assert_equal(r, uh.region)
end
function test_astral_disruption_default_level()
local r = region.create(0, 0, "plain")
local r2 = r:get_astral('fog')
local r3 = region.create(r2.x+1, r2.y, 'fog')
local r4 = region.create(r3.x+1, r2.y, 'fog')
local r5 = region.create(r4.x+1, r2.y, 'fog')
local f = faction.create("human")
local u = unit.create(f, r)
local uh = unit.create(get_monsters(), r2, 1, "braineater")
u.magic = "tybied"
u:set_skill("magic", 100) -- level 100 should beat magic resistance
u.aura = 200
u:add_spell("astral_disruption", 14)
-- no level means cast at the spell's level (14)
u:add_order('ZAUBERE "Stoere Astrale Integritaet"')
process_orders()
assert_equal(60, u.aura)
assert_equal(100, r2:get_curse("astralblock"))
assert_equal(100, r3:get_curse("astralblock"))
assert_equal(100, r4:get_curse("astralblock"))
assert_nil(r5:get_curse("astralblock"))
assert_not_nil(r2:get_curse("astralblock"))
assert_equal(r, uh.region)
end

View file

@ -45,6 +45,7 @@ function test_stealth_faction_on()
end
function test_stealth_faction_other()
u.name = "Enno"
u:clear_orders()
u:add_order("TARNEN PARTEI NUMMER " .. itoa36(f.id))

View file

@ -6,6 +6,7 @@ else
module(tcname, lunit.testcase, package.seeall)
end
local settings
-- use the C implementation in market.c, because the Lua
-- module is wrong (https://bugs.eressea.de/view.php?id=2225)
@ -15,14 +16,28 @@ local function process_markets()
eressea.process.markets()
end
local function set_rule(key, value)
if value==nil then
eressea.settings.set(key, settings[key])
else
settings[key] = settings[key] or eressea.settings.get(key)
eressea.settings.set(key, value)
end
end
function setup()
eressea.game.reset()
settings = {}
eressea.settings.set("rules.move.owner_leave", "1")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.ship.drifting", "0")
eressea.settings.set("rules.ship.storms", "0")
eressea.settings.set("magic.resist.enable", "0")
set_rule("rules.move.owner_leave", "1")
set_rule("rules.food.flags", "4")
set_rule("rules.ship.drifting", "0")
set_rule("rules.ship.storms", "0")
end
function teardown()
for k,_ in pairs(settings) do
set_rule(k)
end
end
function test_new_faction_cannot_give_unit()
@ -973,7 +988,7 @@ function test_no_uruk()
end
function test_bug2187()
eressea.settings.set("rules.food.flags", "0")
set_rule("rules.food.flags", "0")
local r = region.create(0,0,"plain")
local f = faction.create("goblin", "2187@eressea.de", "de")
@ -990,7 +1005,7 @@ function test_bug2187()
-- init_reports()
-- write_report(f)
eressea.settings.set("rules.food.flags", "4")
set_rule("rules.food.flags", "4")
end
@ -1012,8 +1027,8 @@ end
function test_demons_using_mallornlance()
-- bug 2392
eressea.settings.set("skillchange.demon.up", "0")
eressea.settings.set("NewbieImmunity", "0")
set_rule("skillchange.demon.up", "0")
set_rule("NewbieImmunity", "0")
local r = region.create(0, 0, "plain")
local f = faction.create('goblin')
local u = unit.create(f, r, 1, 'demon')

View file

@ -230,27 +230,6 @@ function test_use_domore()
assert_equal(2, u:get_item("sword"))
end
function test_make_greatbow()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "greatbow@eressea.de", "de")
local u = unit.create(f, r, 1)
turn_begin()
u:add_item('mallorn', 2)
u:set_skill('weaponsmithing', 5)
u:clear_orders()
u:add_order("MACHE 1 Elfenbogen")
turn_process()
assert_equal(2, u:get_item('mallorn'))
assert_equal(0, u:get_item('greatbow'))
assert_equal(1, f:count_msg_type('error117'))
u.race='elf'
turn_process()
assert_equal(0, u:get_item('mallorn'))
assert_equal(1, u:get_item('greatbow'))
turn_end()
end
function test_bloodpotion_demon()
local r = region.create(0, 0, "plain")
local f = faction.create("demon")

View file

@ -256,6 +256,7 @@ function test_promote_after_recruit()
local r1 = region.create(0, 0, 'plain')
local r2 = region.create(1, 0, 'plain')
local u1 = unit.create(f, r1, 1)
u1.name = 'Xolgrim'
local u2 = unit.create(f, r2, 55)
u2:add_order('REKRUTIERE 1')
u1:add_order('BEFOERDERE')

View file

@ -34,8 +34,9 @@ function test_laen_needs_mine()
assert_equal(1, f:count_msg_type("building_needed")) -- requires building
u.building = building.create(u.region, "mine")
u.building.working = true
u.building.size = 10
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process()
assert_equal(1, u:get_item('laen'))
assert_equal(99, r:get_resource('laen'))
@ -56,15 +57,19 @@ function test_mine_laen_bonus()
u:add_order("MACHE Laen")
u:set_skill('mining', 6)
u.building = building.create(u.region, "mine")
u.building.working = true
u.building.size = 10
u.number = 2
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process() -- T6 is not enough for laen
assert_equal(0, u:get_item('laen'))
assert_equal(100, r:get_resource('laen'))
assert_equal(1, f:count_msg_type("manufacture_skills"))
u:set_skill('mining', 13)
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process() -- T13 is enough, the +1 produces one extra Laen
assert_equal(4, u:get_item('laen')) -- FAIL (3)
assert_equal(96, r:get_resource('laen'))
@ -86,13 +91,14 @@ function test_mine_iron_bonus()
u:add_order("MACHE Eisen")
u:set_skill('mining', 1)
u.building = building.create(u.region, "mine")
u.building.working = false
u.building.size = 10
u.number = 2
turn_process() -- iron can be made without a working mine
assert_equal(2, u:get_item('iron'))
assert_equal(98, r:get_resource('iron'))
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process()
assert_equal(6, u:get_item('iron'))
@ -115,12 +121,13 @@ function test_quarry_bonus()
u:set_skill('quarrying', 1)
u.number = 2
u.building = building.create(u.region, 'quarry')
u.building.working = false
u.building.size = 10
turn_process()
assert_equal(2, u:get_item('stone'))
assert_equal(98, r:get_resource('stone'))
u:add_item('money', 250) -- Unterhalt Steinbruch
u.building.working = true
turn_process()
assert_equal(6, u:get_item('stone'))
@ -138,16 +145,18 @@ function test_smithy_no_bonus()
turn_begin()
u.building = building.create(u.region, 'smithy')
u.building.working = false
u.building.size = 10
u.number = 5
u:set_skill('cartmaking', 1) -- needs 1 min
u:add_item('log', 100)
u:add_order("MACHE Wagen")
turn_process() -- building disabled
turn_process() -- building disabled, money is missing
assert_equal(5, u:get_item('cart'))
assert_equal(75, u:get_item('log'))
u:add_item('money', 300) -- Unterhalt Schmiede
u:add_item('log', 1)
u.building.working = true
turn_process() -- building active
assert_equal(10, u:get_item('cart'))
@ -164,7 +173,7 @@ function test_smithy_bonus_iron()
turn_begin()
u.building = building.create(u.region, 'smithy')
u.building.working = false
u.building.size = 10
u:set_skill('weaponsmithing', 5) -- needs 3
u:add_item('iron', 100)
@ -173,6 +182,8 @@ function test_smithy_bonus_iron()
assert_equal(1, u:get_item('sword'))
assert_equal(99, u:get_item('iron'))
u:add_item('log', 1) -- Unterhalt Schmiede
u:add_item('money', 300) -- Unterhalt Schmiede
u.building.working = true
turn_process() -- building active
assert_equal(3, u:get_item('sword'))
@ -190,7 +201,7 @@ function test_smithy_bonus_mixed()
turn_begin()
u.building = building.create(u.region, 'smithy')
u.building.working = false
u.building.size = 10
u:set_skill('weaponsmithing', 5) -- needs 3
u:add_item('iron', 100)
@ -201,6 +212,8 @@ function test_smithy_bonus_mixed()
assert_equal(99, u:get_item('iron'))
assert_equal(99, u:get_item('log'))
u:add_item('money', 300) -- Unterhalt Schmiede
u:add_item('log', 1) -- Unterhalt Schmiede
u.building.working = true
turn_process() -- building active
assert_equal(3, u:get_item('axe'))

View file

@ -97,7 +97,7 @@ end
function test_lighthouse()
eressea.free_game()
local r = region.create(0, 0, "mountain")
local f = faction.create("human", "human@example.com")
local f = faction.create("human", "lighthouse@example.com")
local f2 = faction.create("dwarf")
local r2 = region.create(1, 0, "mountain")
unit.create(f2, r2, 1).name = 'The Babadook'
@ -108,7 +108,6 @@ function test_lighthouse()
local u = unit.create(f, r, 1)
local b = building.create(r, "lighthouse")
b.size = 100
b.working = true
u.building = b
u:set_skill("perception", 9)
u:add_item("money", 1000)

View file

@ -15,7 +15,6 @@ function setup()
eressea.settings.set("rules.encounters", "0")
eressea.settings.set("magic.fumble.enable", "0")
eressea.settings.set("magic.regeneration.enable", "0")
eressea.settings.set("magic.resist.enable", "0")
end
function test_create_bogus()
@ -94,6 +93,7 @@ function test_appeasement_can_move()
r2 = region.create(1, 0, 'plain')
u2 = unit.create(faction.create('human'), r1, 1)
u2.race = 'elf'
u2.name = 'Angsthase'
u2.magic = 'gwyrrd'
u2:set_skill('magic', 5)
u2.aura = 10
@ -117,6 +117,7 @@ function test_appeasement_break_guard()
r2 = region.create(1, 0, 'plain')
u2 = unit.create(faction.create('human'), r1, 1)
u2.race = 'elf'
u2.name = 'Angsthase'
u2.magic = 'gwyrrd'
u2.guard = true
u2.status = 1
@ -136,53 +137,3 @@ function test_appeasement_break_guard()
assert_equal(5, u2.status)
assert_equal(false, u2.guard)
end
local function create_cp_mage(f, r)
local u2 = unit.create(f, r, 1)
u2.race = 'human'
u2.magic = 'cerddor'
u2:set_skill('magic', 20)
u2.aura = 100
u2:add_spell('song_of_confusion')
u2:add_spell('frighten')
u2.status = 3
return u2
end
local function create_cp_front(f, r)
local u2 = unit.create(f, r, 1000)
u2:set_skill('melee', 20)
u2:set_skill('stamina', 3)
u2:add_item('axe', u2.number)
u2:add_item('plate', u2.number)
u2:add_item('shield', u2.number)
u2.hp = u2.hp_max * u2.number
return u2
end
function test_confusion_and_panic()
f = faction.create('demon')
f2 = faction.create('demon')
local u1, u2, u3, u4, r
r = region.create(0, 0, 'plain')
u1 = create_cp_front(f, r)
u2 = create_cp_mage(f, r)
u3 = create_cp_mage(f, r)
u2:add_order('KAMPFZAUBER STUFE 10 "Gesang der Angst"')
u3:add_order('KAMPFZAUBER STUFE 10 "Gesang der Verwirrung"')
create_cp_mage(f, r)
local u4 = create_cp_front(f2, r)
create_cp_mage(f2, r)
create_cp_mage(f2, r)
create_cp_mage(f2, r)
for ux in r.units do
for uy in r.units do
if ux.faction ~= uy.faction then
ux:add_order("ATTACKIERE " .. itoa36(uy.id))
end
end
end
process_orders()
end

View file

@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 2.8)
project (server C)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
include_directories (${CJSON_INCLUDE_DIR})
include_directories (${CRYPTO_INCLUDE_DIR})
include_directories (${CLIBS_INCLUDE_DIR})
include_directories (${STORAGE_INCLUDE_DIR})
@ -9,34 +10,43 @@ include_directories (${TOLUA_INCLUDE_DIR})
include_directories (${LUA_INCLUDE_DIR})
include_directories (${INIPARSER_INCLUDE_DIR})
if (CMAKE_COMPILER_IS_GNUCC)
add_compile_options(-Wvla)
endif()
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long)
elseif(MSVC)
add_compile_options(/WX /MP /FC)
# set(EXTRA_C_FLAGS /WX /MP /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES)
IF(DEFINED ERESSEA_VERSION)
set_source_files_properties(kernel/version.c PROPERTIES
COMPILE_DEFINITIONS ERESSEA_VERSION="${ERESSEA_VERSION}")
ENDIF()
IF(DEFINED ERESSEA_BUILDNO)
set_source_files_properties(kernel/version.c PROPERTIES
COMPILE_DEFINITIONS ERESSEA_BUILDNO="${ERESSEA_BUILDNO}")
ENDIF()
IF (CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvla")
ENDIF()
IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long")
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89")
ELSEIF(MSVC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG
"${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE
"${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib")
else()
message(STATUS "unknown compiler ${CMAKE_C_COMPILER_ID}")
endif()
ELSE()
MESSAGE(STATUS "unknown compiler ${CMAKE_C_COMPILER_ID}")
ENDIF()
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wtautological-compare -Weverything")
message(STATUS "compiler is clang: ${CMAKE_C_COMPILER_ID}")
elseif(CMAKE_COMPILER_IS_GCC)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
IF(CMAKE_COMPILER_IS_CLANG)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wtautological-compare -Weverything")
MESSAGE(STATUS "compiler is clang: ${CMAKE_C_COMPILER_ID}")
ELSEIF(CMAKE_COMPILER_IS_GCC)
EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_GREATER 4.9)
IF (GCC_VERSION VERSION_GREATER 4.9)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wfloat-conversion")
endif()
endif(CMAKE_COMPILER_IS_CLANG)
string(REGEX REPLACE "/W[3|4]" "/w" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
ENDIF()
ENDIF(CMAKE_COMPILER_IS_CLANG)
add_subdirectory(util)
add_subdirectory(kernel)
@ -47,24 +57,25 @@ add_subdirectory(triggers)
add_subdirectory(modules)
add_subdirectory(races)
macro(ADD_LUA_MODULE MODULE_NAME FILES)
add_library (${MODULE_NAME} SHARED ${FILES})
set_target_properties(${MODULE_NAME}
MACRO(ADD_LUA_MODULE MODULE_NAME FILES)
ADD_LIBRARY (${MODULE_NAME} SHARED ${FILES})
SET_TARGET_PROPERTIES(${MODULE_NAME}
PROPERTIES
PREFIX ""
)
endmacro(ADD_LUA_MODULE)
ENDMACRO(ADD_LUA_MODULE)
macro(TOLUA_BINDING PKGFILE FILES)
add_custom_command(
MACRO(TOLUA_BINDING PKGFILE FILES)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${PKGFILE}.c
DEPENDS ${FILES} ${PKGFILE}
COMMAND ${TOLUA_EXECUTABLE}
ARGS -o ${CMAKE_CURRENT_SOURCE_DIR}/${PKGFILE}.c ${PKGFILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endmacro(TOLUA_BINDING)
ENDMACRO(TOLUA_BINDING)
IF(NOT MSVC)
TOLUA_BINDING(log.pkg util/log.h)
TOLUA_BINDING(locale.pkg bind_locale.h)
TOLUA_BINDING(config.pkg bind_config.h)
@ -72,6 +83,7 @@ TOLUA_BINDING(process.pkg bind_process.h)
TOLUA_BINDING(game.pkg bind_eressea.h config.h)
TOLUA_BINDING(eressea.pkg bind_eressea.h)
TOLUA_BINDING(settings.pkg kenel/config.h)
ENDIF()
set (PARSER_SRC
${DB_SRC}
@ -113,7 +125,7 @@ set (ERESSEA_SRC
renumber.c
report.c
reports.c
sort.c
skill.c
spells.c
spy.c
steal.c
@ -167,49 +179,38 @@ set (SERVER_SRC ${SERVER_SRC}
)
endif(CURSES_FOUND)
#find_program(IWYU_PATH NAMES include-what-you-use iwyu)
find_program(IWYU_PATH NAMES include-what-you-use iwyu)
if(IWYU_PATH)
# set(C_INCLUDE_WHAT_YOU_USE "${IWYU_PATH} -Xiwyu --no_fwd_decls")
else(IWYU_PATH)
# message(STATUS "Could not find the program include-what-you-use")
message(STATUS "Could not find the program include-what-you-use")
endif()
add_library(version STATIC ${VERSION_SRC})
if(DEFINED ERESSEA_VERSION)
target_compile_definitions(version PRIVATE ERESSEA_VERSION="${ERESSEA_VERSION}")
endif()
if(DEFINED ERESSEA_BUILDNO)
target_compile_definitions(version PRIVATE ERESSEA_BUILDNO="${ERESSEA_BUILDNO}")
endif()
add_library(parser ${PARSER_SRC})
target_link_libraries(parser
${CLIBS_LIBRARIES}
${CRYPTO_LIBRARIES}
)
add_executable(checker ${CHECK_SRC})
target_link_libraries(checker parser)
if (HAVE_LIBBSD)
set (EXTRA_LIBS ${EXTRA_LIBS} bsd)
endif (HAVE_LIBBSD)
if (HAVE_LIBM)
set (EXTRA_LIBS ${EXTRA_LIBS} m)
endif (HAVE_LIBM)
add_library(game ${ERESSEA_SRC})
target_link_libraries(game ${EXTRA_LIBS} parser version)
target_link_libraries(game parser version)
add_executable(eressea ${SERVER_SRC})
if (IWYU_PATH)
set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})
endif(IWYU_PATH)
target_link_libraries(eressea
game
${TOLUA_LIBRARIES}
${LUA_LIBRARIES}
${STORAGE_LIBRARIES}
${CJSON_LIBRARIES}
${IniParser_LIBRARIES}
${INIPARSER_LIBRARIES}
)
set(TESTS_SRC
@ -238,7 +239,7 @@ set(TESTS_SRC
renumber.test.c
report.test.c
reports.test.c
sort.test.c
skill.test.c
spells.test.c
spy.test.c
study.test.c
@ -268,14 +269,9 @@ target_link_libraries(test_eressea
${CLIBS_LIBRARIES}
${STORAGE_LIBRARIES}
${CJSON_LIBRARIES}
${IniParser_LIBRARIES}
${INIPARSER_LIBRARIES}
)
set_target_properties(test_eressea eressea PROPERTIES C_STANDARD 90)
if (IWYU_PATH)
set_target_properties(test_eressea eressea PROPERTIES C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})
endif(IWYU_PATH)
add_test(server test_eressea)
#add_test(NAME E3
# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/game-e3
@ -287,54 +283,51 @@ add_test(server test_eressea)
install(TARGETS eressea DESTINATION "bin")
if (HAVE_EXECINFO_H AND HAVE_SIGNAL_H)
add_compile_definitions(HAVE_BACKTRACE)
add_definitions(-DHAVE_BACKTRACE)
endif ()
if (HAVE_LIBBSD)
add_compile_definitions(HAVE_LIBBSD)
add_definitions(-DHAVE_LIBBSD)
endif (HAVE_LIBBSD)
if (HAVE_STRLCAT)
add_compile_definitions(HAVE_BSDSTRING)
add_definitions(-DHAVE_BSDSTRING)
endif (HAVE_STRLCAT)
if (HAVE_STRDUP)
add_compile_definitions(HAVE_STRDUP)
add_definitions(-DHAVE_STRDUP)
endif(HAVE_STRDUP)
if (HAVE_LIBBSD)
target_link_libraries(parser bsd)
endif (HAVE_LIBBSD)
target_include_directories (game PUBLIC ${CJSON_INCLUDE_DIRS})
target_include_directories (game PUBLIC ${IniParser_INCLUDE_DIRS})
if (SQLite3_FOUND)
target_include_directories (game PRIVATE ${SQLite3_INCLUDE_DIRS})
target_link_libraries(eressea ${SQLite3_LIBRARIES})
target_link_libraries(test_eressea ${SQLite3_LIBRARIES})
target_compile_definitions(game PRIVATE USE_SQLITE)
if (SQLITE3_FOUND)
include_directories (${SQLITE3_INCLUDE_DIR})
target_link_libraries(eressea ${SQLITE3_LIBRARIES})
target_link_libraries(test_eressea ${SQLITE3_LIBRARIES})
add_definitions(-DUSE_SQLITE)
elseif (DB_FOUND)
#include_directories (${DB_INCLUDE_DIR})
include_directories (${DB_INCLUDE_DIR})
target_link_libraries(eressea ${DB_LIBRARIES})
target_link_libraries(test_eressea ${DB_LIBRARIES})
target_compile_definitions(game PRIVATE USE_DB)
endif(SQLite3_FOUND)
add_definitions(-DUSE_DB)
endif(SQLITE3_FOUND)
if (READLINE_FOUND)
#include_directories (${READLINE_INCLUDE_DIR})
include_directories (${READLINE_INCLUDE_DIR})
target_link_libraries(eressea ${READLINE_LIBRARY})
target_compile_definitions(eressea PRIVATE DUSE_READLINE)
add_definitions(-DUSE_READLINE)
endif (READLINE_FOUND)
if (CURSES_FOUND)
target_include_directories (eressea PRIVATE ${CURSES_INCLUDE_DIRS})
include_directories (${CURSES_INCLUDE_DIR})
target_link_libraries(eressea ${CURSES_LIBRARIES})
target_compile_definitions(eressea PRIVATE USE_CURSES)
add_definitions(-DUSE_CURSES)
endif(CURSES_FOUND)
if (EXPAT_FOUND)
target_include_directories (game PRIVATE ${EXPAT_INCLUDE_DIRS})
include_directories (${EXPAT_INCLUDE_DIRS})
target_link_libraries(eressea ${EXPAT_LIBRARIES})
target_link_libraries(test_eressea ${EXPAT_LIBRARIES})
endif (EXPAT_FOUND)

View file

@ -2,21 +2,21 @@
#include <kernel/config.h>
#include "alchemy.h"
#include "guard.h"
#include "skill.h"
#include "study.h"
#include <kernel/attrib.h>
#include <kernel/build.h>
#include <kernel/faction.h>
#include <kernel/gamedata.h>
#include <kernel/item.h>
#include <kernel/faction.h>
#include <kernel/messages.h>
#include <kernel/build.h>
#include <kernel/region.h>
#include <kernel/pool.h>
#include <kernel/race.h>
#include "kernel/skill.h"
#include "kernel/unit.h"
#include <kernel/unit.h>
/* util includes */
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/base36.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -29,10 +29,10 @@ static void test_herbsearch(CuTest * tc)
r = test_create_region(0, 0, NULL);
rc = rc_get_or_create("dragon");
rc->flags |= RCF_UNARMEDGUARD;
u2 = test_create_unit(test_create_faction_ex(rc, NULL), r);
u2 = test_create_unit(test_create_faction(rc), r);
setguard(u2, true);
f = test_create_faction();
f = test_create_faction(NULL);
u = test_create_unit(f, r);
itype = test_create_itemtype("rosemary");

View file

@ -14,6 +14,7 @@
#include "stealth.h"
#include "magic.h"
#include "movement.h"
#include "dict.h"
#include "otherfaction.h"
#include "overrideroads.h"
#include "racename.h"
@ -60,7 +61,7 @@ static int obs_age(struct attrib *a, void *owner)
UNUSED_ARG(owner);
update_interval(od->f, (region *)owner);
return --od->timer > 0;
return --od->timer;
}
static void obs_write(const variant *var, const void *owner,
@ -89,13 +90,13 @@ attrib_type at_observer = {
"observer", obs_init, a_free_voidptr, obs_age, obs_write, obs_read
};
static attrib *make_observer(faction *f, int perception, int timer)
static attrib *make_observer(faction *f, int perception)
{
attrib * a = a_new(&at_observer);
obs_data *od = (obs_data *)a->data.v;
od->f = f;
od->skill = perception;
od->timer = timer;
od->timer = 2;
return a;
}
@ -131,7 +132,7 @@ void set_observer(region *r, faction *f, int skill, int turns)
else {
fset(r, RF_OBSERVER);
}
a_add(&r->attribs, make_observer(f, skill, turns));
a_add(&r->attribs, make_observer(f, skill));
}
attrib_type at_unitdissolve = {
@ -144,7 +145,7 @@ static int read_ext(variant *var, void *owner, gamedata *data)
UNUSED_ARG(var);
READ_INT(data->store, &len);
data->store->api->r_str(data->store->handle, NULL, (size_t)len);
data->store->api->r_bin(data->store->handle, NULL, (size_t)len);
return AT_READ_OK;
}
@ -197,6 +198,7 @@ void register_attributes(void)
at_deprecate("gm", a_readint);
at_deprecate("guard", a_readint); /* used to contain guard-flags (v3.10.0-259-g8597e8b) */
at_register(&at_stealth);
at_register(&at_dict);
at_register(&at_unitdissolve);
at_register(&at_observer);
at_register(&at_overrideroads);

View file

@ -1,6 +1,4 @@
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <platform.h>
#include <kernel/config.h>
#include "key.h"

View file

@ -38,8 +38,8 @@ static void test_otherfaction(CuTest *tc) {
faction *f;
test_setup();
u = test_create_unit(test_create_faction(), test_create_region(0, 0, NULL));
f = test_create_faction_ex(u->faction->race, u->faction->locale);
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
f = test_create_faction(NULL);
config_set("stealth.faction.other", "1");
CuAssertIntEquals(tc, true, rule_stealth_other());
CuAssertPtrEquals(tc, u->faction, visible_faction(f, u));

View file

@ -15,7 +15,7 @@ static void test_stealth(CuTest *tc) {
unit *u;
test_setup();
u = test_create_unit(test_create_faction(), test_create_region(0, 0, NULL));
u = test_create_unit(test_create_faction(test_create_race("human")), test_create_region(0, 0, NULL));
set_level(u, SK_STEALTH, 2);
CuAssertIntEquals(tc, -1, u_geteffstealth(u));
CuAssertIntEquals(tc, 2, eff_stealth(u, u->region));

View file

@ -11,7 +11,6 @@
#include "util/keyword.h"
#include "util/log.h"
#include "util/stats.h"
#include "automate.h"
#include "laws.h"
@ -39,7 +38,7 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t *
if (kwd == K_AUTOSTUDY) {
if (f == u->faction) {
unext = u->next;
if (long_order_allowed(u, false)) {
if (long_order_allowed(u)) {
scholar * st = scholars + nscholars;
skill_t sk = getskill(u->faction->locale);
if (skill == NOSKILL && sk != NOSKILL) {
@ -198,7 +197,6 @@ void do_autostudy(region *r)
assert(batchsize <= MAXSCHOLARS);
}
for (u = r->units; u; u = u->next) {
if (is_paused(u->faction)) continue;
if (!fval(u, UFL_MARK)) {
unit *ulist = u;
int sum_scholars = 0;
@ -218,7 +216,7 @@ void do_autostudy(region *r)
if (money > 0) {
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money);
ADDMSG(&u->faction->msgs, msg_message("studycost",
"unit region cost skill", scholars[i].u, r, money, skill));
"unit region cost skill", u, u->region, money, skill));
}
}
}

View file

@ -3,9 +3,10 @@
#ifndef H_GC_AUTOMATE
#define H_GC_AUTOMATE
#include "skill.h"
struct region;
struct unit;
enum skill_t;
typedef struct scholar {
struct unit *u;
@ -18,8 +19,7 @@ typedef struct scholar {
void do_autostudy(struct region *r);
int autostudy_init(scholar scholars[], int max_scholars,
struct unit **units, enum skill_t *o_skill);
int autostudy_init(scholar scholars[], int max_scholars, struct unit **units, skill_t *o_skill);
void autostudy_run(scholar scholars[], int nscholars);
#endif

View file

@ -29,7 +29,7 @@ static void test_autostudy_init(CuTest *tc) {
mt_create_error(771);
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
test_create_unit(f, r);
@ -40,7 +40,7 @@ static void test_autostudy_init(CuTest *tc) {
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, "Dudelidu");
u3 = test_create_unit(f, r);
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
u5 = test_create_unit(test_create_faction(), r);
u5 = test_create_unit(test_create_faction(NULL), r);
u5->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
scholars[2].u = NULL;
@ -82,7 +82,7 @@ static void test_autostudy_run_twoteachers(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
set_level(u1, SK_ENTERTAINMENT, 2);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
@ -123,7 +123,7 @@ static void test_autostudy_run_bigunit(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
set_number(u1, 20);
set_level(u1, SK_ENTERTAINMENT, 16);
@ -154,7 +154,7 @@ static void test_autostudy_run_few_teachers(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
set_number(u1, 20);
set_level(u1, SK_ENTERTAINMENT, 16);
@ -190,7 +190,7 @@ static void test_autostudy_run_few_teachers_reverse(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
set_number(u1, 20);
set_level(u1, SK_ENTERTAINMENT, 16);
@ -224,7 +224,7 @@ static void test_autostudy_run(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
set_number(u1, 2);
@ -268,7 +268,7 @@ static void test_autostudy_run_noteachers(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
set_number(u1, 5);
@ -303,7 +303,7 @@ static void test_autostudy_run_teachers_learn(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
set_number(u1, 2);
@ -332,7 +332,7 @@ static void test_autostudy_run_skilldiff(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u1, 1);
@ -364,7 +364,7 @@ static void test_autostudy_batches(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u1, 1);
@ -396,7 +396,7 @@ static void test_do_autostudy(CuTest *tc) {
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction();
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u1, 1);
@ -406,7 +406,7 @@ static void test_do_autostudy(CuTest *tc) {
set_number(u2, 10);
u3 = test_create_unit(f, r);
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
u4 = test_create_unit(test_create_faction(), r);
u4 = test_create_unit(test_create_faction(NULL), r);
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
do_autostudy(r);
CuAssertIntEquals(tc, 2, get_level(u1, SK_PERCEPTION));

View file

@ -1,5 +1,4 @@
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#include <platform.h>
#endif
@ -10,57 +9,56 @@
#include "laws.h"
#include "monsters.h"
#include "move.h"
#include "skill.h"
#include "study.h"
#include "spy.h"
#include "spells/buildingcurse.h"
#include "spells/regioncurse.h"
#include "spells/unitcurse.h"
#include <spells/buildingcurse.h>
#include <spells/regioncurse.h>
#include <spells/unitcurse.h>
#include "kernel/ally.h"
#include "kernel/alliance.h"
#include "kernel/build.h"
#include "kernel/building.h"
#include "kernel/curse.h"
#include "kernel/equipment.h"
#include "kernel/faction.h"
#include "kernel/group.h"
#include "kernel/item.h"
#include "kernel/messages.h"
#include "kernel/order.h"
#include "kernel/plane.h"
#include "kernel/race.h"
#include "kernel/region.h"
#include "kernel/ship.h"
#include "kernel/skill.h"
#include "kernel/terrain.h"
#include "kernel/unit.h"
#include "kernel/spell.h"
#include <kernel/ally.h>
#include <kernel/alliance.h>
#include <kernel/build.h>
#include <kernel/building.h>
#include <kernel/curse.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/group.h>
#include <kernel/item.h>
#include <kernel/messages.h>
#include <kernel/order.h>
#include <kernel/plane.h>
#include <kernel/race.h>
#include <kernel/region.h>
#include <kernel/ship.h>
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include <kernel/spell.h>
#include "reports.h"
#include <reports.h>
/* attributes includes */
#include "attributes/key.h"
#include "attributes/racename.h"
#include "attributes/otherfaction.h"
#include <attributes/key.h>
#include <attributes/racename.h>
#include <attributes/otherfaction.h>
/* util includes */
#include "kernel/attrib.h"
#include "util/base36.h"
#include "util/language.h"
#include "util/lists.h"
#include "util/log.h"
#include "util/macros.h"
#include "util/parser.h"
#include "util/strings.h"
#include "util/stats.h"
#include "util/rand.h"
#include "util/rng.h"
#include <util/assert.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/language.h>
#include <util/lists.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/parser.h>
#include <util/strings.h>
#include <util/rand.h>
#include <util/rng.h>
#include <selist.h>
/* libc includes */
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
@ -111,7 +109,6 @@ const troop no_troop = { 0, 0 };
static int max_turns;
static int rule_damage;
static int rule_loot;
static double loot_divisor;
static int flee_chance_max_percent;
static int flee_chance_base;
static int flee_chance_skill_bonus;
@ -149,7 +146,6 @@ static void init_rules(void)
rule_vampire = config_get_int("rules.combat.demon_vampire", 0);
rule_loot = config_get_int("rules.combat.loot",
LOOT_MONSTERS | LOOT_OTHERS | LOOT_KEEPLOOT);
loot_divisor = config_get_flt("rules.items.loot_divisor", 1);
/* new formula to calculate to-hit-chance */
skill_formula = config_get_int("rules.combat.skill_formula",
FORMULA_ORIG);
@ -197,7 +193,7 @@ void battle_message_faction(battle * b, faction * f, struct message *m)
assert(f);
if (f->battles == NULL || f->battles->r != r) {
struct bmsg *bm = (struct bmsg *)calloc(1, sizeof(struct bmsg));
assert(bm);
assert_alloc(bm);
bm->next = f->battles;
f->battles = bm;
bm->r = r;
@ -379,7 +375,7 @@ static int get_row(const side * s, int row, const side * vs)
memset(size, 0, sizeof(size));
for (line = FIRST_ROW; line != NUMROWS; ++line) {
int si, sa_i;
/* how many enemies are there in this row? */
/* how many enemies are there in the first row? */
for (si = 0; s->enemies[si]; ++si) {
side *se = s->enemies[si];
if (se->size[line] > 0) {
@ -429,14 +425,24 @@ int get_unitrow(const fighter * af, const side * vs)
int row = statusrow(af->status);
if (vs == NULL) {
int i;
for (i = FIGHT_ROW; i != row; ++i) {
if (af->side->size[i]) {
for (i = FIGHT_ROW; i != row; ++i)
if (af->side->size[i])
break;
}
}
return FIGHT_ROW + (row - i);
}
return get_row(af->side, row, vs);
else {
battle *b = vs->battle;
if (row != b->rowcache.row || b->alive != b->rowcache.alive
|| af->side != b->rowcache.as || vs != b->rowcache.vs) {
b->rowcache.alive = b->alive;
b->rowcache.as = af->side;
b->rowcache.vs = vs;
b->rowcache.row = row;
b->rowcache.result = get_row(af->side, row, vs);
return b->rowcache.result;
}
return b->rowcache.result;
}
}
static void reportcasualties(battle * b, fighter * fig, int dead)
@ -768,28 +774,7 @@ int select_magicarmor(troop t)
return ma;
}
int meffect_apply(struct meffect *me, int damage) {
assert(0 <= damage); /* damage sollte hier immer mindestens 0 sein */
/* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */
if (me->typ == SHIELD_REDUCE && me->effect <= 100) {
int hp = damage * me->effect / 100;
if (hp > me->duration) {
hp = me->duration;
}
damage -= hp;
me->duration -= hp;
}
/* gibt Ruestung +effect fuer duration Treffer */
else if (me->typ == SHIELD_ARMOR) {
damage -= me->effect;
if (damage < 0) damage = 0;
me->duration--;
}
return damage;
}
/* Sind side ds und Magier des meffect verbuendet? */
/* Sind side ds und Magier des meffect verbuendet, dann return 1*/
bool meffect_protection(battle * b, meffect * s, side * ds)
{
UNUSED_ARG(b);
@ -804,7 +789,7 @@ bool meffect_protection(battle * b, meffect * s, side * ds)
return false;
}
/* Sind side as und Magier des meffect verfeindet? */
/* Sind side as und Magier des meffect verfeindet, dann return 1*/
bool meffect_blocked(battle * b, meffect * s, side * as)
{
UNUSED_ARG(b);
@ -830,6 +815,7 @@ void rmfighter(fighter * df, int i)
/* erst ziehen wir die Anzahl der Personen von den Kaempfern in der
* Schlacht, dann von denen auf dieser Seite ab*/
df->side->alive -= i;
df->side->battle->alive -= i;
/* Dann die Kampfreihen aktualisieren */
ds->size[SUM_ROW] -= i;
@ -866,7 +852,9 @@ void remove_troop(troop dt)
{
fighter *df = dt.fighter;
struct person p = df->person[dt.index];
battle *b = df->side->battle;
b->fast.alive = -1; /* invalidate cached value */
b->rowcache.alive = -1; /* invalidate cached value */
++df->removed;
++df->side->removed;
df->person[dt.index] = df->person[df->alive - df->removed];
@ -1227,25 +1215,37 @@ static int apply_race_resistance(int reduced_damage, fighter *df,
return reduced_damage;
}
static int apply_magicshield(int damage, fighter *df,
static int apply_magicshield(int reduced_damage, fighter *df,
const weapon_type *awtype, battle *b, bool magic) {
side *ds = df->side;
selist *ql;
int qi;
if (damage <= 0) {
if (reduced_damage <= 0)
return 0;
}
/* Schilde */
for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
meffect *me = (meffect *)selist_get(ql, qi);
if (meffect_protection(b, me, ds) != 0) {
damage = meffect_apply(me, damage);
assert(0 <= reduced_damage); /* rda sollte hier immer mindestens 0 sein */
/* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */
if (me->typ == SHIELD_REDUCE) {
int hp = reduced_damage * (me->effect / 100);
reduced_damage -= hp;
me->duration -= hp;
}
/* gibt Ruestung +effect fuer duration Treffer */
if (me->typ == SHIELD_ARMOR) {
reduced_damage -= me->effect;
if (reduced_damage < 0) reduced_damage = 0;
me->duration--;
}
}
}
return damage;
return reduced_damage;
}
bool
@ -1406,11 +1406,35 @@ count_enemies_i(battle * b, const fighter * af, int minrow, int maxrow,
}
int
count_enemies(battle *b, const fighter *af, int minrow, int maxrow,
count_enemies(battle * b, const fighter * af, int minrow, int maxrow,
int select)
{
int sr = statusrow(af->status);
side *as = af->side;
if (b->alive == b->fast.alive && as == b->fast.side && sr == b->fast.status
&& minrow == b->fast.minrow && maxrow == b->fast.maxrow) {
if (b->fast.enemies[select] >= 0) {
return b->fast.enemies[select];
}
else if (select & SELECT_FIND) {
if (b->fast.enemies[select - SELECT_FIND] >= 0) {
return b->fast.enemies[select - SELECT_FIND];
}
}
}
else if (select != SELECT_FIND || b->alive != b->fast.alive) {
b->fast.side = as;
b->fast.status = sr;
b->fast.minrow = minrow;
b->fast.alive = b->alive;
b->fast.maxrow = maxrow;
memset(b->fast.enemies, -1, sizeof(b->fast.enemies));
}
if (maxrow >= FIRST_ROW) {
return count_enemies_i(b, af, minrow, maxrow, select);
int i = count_enemies_i(b, af, minrow, maxrow, select);
b->fast.enemies[select] = i;
return i;
}
return 0;
}
@ -1685,52 +1709,60 @@ void do_combatmagic(battle * b, combatmagic_t was)
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig;
for (fig = s->fighters; fig; fig = fig->next) {
unit *u = fig->unit;
unit *caster = u;
unit *mage = fig->unit;
unit *caster = mage;
if (fig->alive <= 0)
continue; /* fighter kann im Kampf getoetet worden sein */
level = effskill(u, SK_MAGIC, r);
level = effskill(mage, SK_MAGIC, r);
if (level > 0) {
double power;
const spell *sp;
const struct locale *lang = u->faction->locale;
const struct locale *lang = mage->faction->locale;
order *ord;
switch (was) {
case DO_PRECOMBATSPELL:
sp = mage_get_combatspell(get_mage(u), 0, &sl);
sp = get_combatspell(mage, 0);
sl = get_combatspelllevel(mage, 0);
break;
case DO_POSTCOMBATSPELL:
sp = mage_get_combatspell(get_mage(u), 2, &sl);
sp = get_combatspell(mage, 2);
sl = get_combatspelllevel(mage, 2);
break;
default:
/* Fehler! */
return;
}
if (sp == NULL || !u_hasspell(u, sp))
if (sp == NULL)
continue;
level = max_spell_level(u, caster, sp, level, 1, NULL);
ord = create_order(K_CAST, lang, "'%s'", spell_name(mkname_spell(sp), lang));
if (!cancast(mage, sp, 1, 1, ord)) {
free_order(ord);
continue;
}
level = eff_spelllevel(mage, caster, sp, level, 1);
if (sl > 0 && sl < level) {
level = sl;
}
if (level < 1) {
report_failed_spell(b, u, sp);
if (level < 0) {
report_failed_spell(b, mage, sp);
free_order(ord);
continue;
}
ord = create_order(K_CAST, lang, "'%s'", spell_name(mkname_spell(sp), lang));
power = spellpower(r, u, sp, level);
power = spellpower(r, mage, sp, level, ord);
free_order(ord);
if (power <= 0) { /* Effekt von Antimagie */
report_failed_spell(b, u, sp);
pay_spell(u, NULL, sp, level, 1);
report_failed_spell(b, mage, sp);
pay_spell(mage, NULL, sp, level, 1);
}
else if (fumble(r, u, sp, level)) {
report_failed_spell(b, u, sp);
pay_spell(u, NULL, sp, level, 1);
else if (fumble(r, mage, sp, level)) {
report_failed_spell(b, mage, sp);
pay_spell(mage, NULL, sp, level, 1);
}
else {
co = create_castorder_combat(0, fig, sp, level, power);
@ -1772,35 +1804,37 @@ static void do_combatspell(troop at)
{
const spell *sp;
fighter *fi = at.fighter;
unit *u = fi->unit;
unit *mage = fi->unit;
battle *b = fi->side->battle;
region *r = b->region;
selist *ql;
int level, qi, sl;
int level, qi;
double power;
int fumblechance = 0;
struct sc_mage *mage = get_mage(u);
order *ord;
int sl;
const struct locale *lang = mage->faction->locale;
if (!mage) {
sp = get_combatspell(mage, 1);
if (sp == NULL) {
fi->magic = 0; /* Hat keinen Kampfzauber, kaempft nichtmagisch weiter */
return;
}
sp = mage_get_combatspell(mage, 1, &sl);
if (sp == NULL || sl <= 0 || !u_hasspell(u, sp)) {
fi->magic = 0; /* Hat keinen Kampfzauber, kaempft nichtmagisch weiter */
return;
}
level = max_spell_level(u, u, sp, fi->magic, 1, NULL);
if (level < 1) {
ord = create_order(K_CAST, lang, "'%s'", spell_name(mkname_spell(sp), lang));
if (!cancast(mage, sp, 1, 1, ord)) {
fi->magic = 0; /* Kann nicht mehr Zaubern, kaempft nichtmagisch weiter */
return;
}
else if (sl < level) {
level = eff_spelllevel(mage, mage, sp, fi->magic, 1);
sl = get_combatspelllevel(mage, 1);
if (sl > 0 && sl < level) {
level = sl;
}
if (fumble(r, u, sp, level)) {
report_failed_spell(b, u, sp);
pay_spell(u, NULL, sp, level, 1);
if (fumble(r, mage, sp, level)) {
report_failed_spell(b, mage, sp);
pay_spell(mage, NULL, sp, level, 1);
return;
}
@ -1816,14 +1850,16 @@ static void do_combatspell(troop at)
/* Antimagie die Fehlschlag erhoeht */
if (rng_int() % 100 < fumblechance) {
report_failed_spell(b, u, sp);
pay_spell(u, NULL, sp, level, 1);
report_failed_spell(b, mage, sp);
pay_spell(mage, NULL, sp, level, 1);
free_order(ord);
return;
}
power = spellpower(r, u, sp, level);
power = spellpower(r, mage, sp, level, ord);
free_order(ord);
if (power <= 0) { /* Effekt von Antimagie */
report_failed_spell(b, u, sp);
pay_spell(u, NULL, sp, level, 1);
report_failed_spell(b, mage, sp);
pay_spell(mage, NULL, sp, level, 1);
return;
}
@ -1888,7 +1924,8 @@ int skilldiff(troop at, troop dt, int dist)
}
}
if (b->type->flags & BTF_FORTIFICATION) {
int beff = building_protection(b);
int stage = buildingeffsize(b, false);
int beff = building_protection(b->type, stage);
if (beff > 0) {
skdiff -= beff;
is_protected = 2;
@ -2086,13 +2123,12 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
* sonst helden mit feuerschwertern zu maechtig */
if (numattack == 0 && wp && wp->type->attack) {
int dead = 0;
standard_attack = false;
if (wp->type->attack(&ta, wp->type, &dead)) {
standard_attack = wp->type->attack(&ta, wp->type, &dead);
if (!standard_attack)
reload = true;
af->catmsg += dead;
if (af->person[ta.index].last_action < b->turn) {
af->person[ta.index].last_action = b->turn;
}
af->catmsg += dead;
if (!standard_attack && af->person[ta.index].last_action < b->turn) {
af->person[ta.index].last_action = b->turn;
}
}
if (standard_attack) {
@ -2389,7 +2425,7 @@ troop select_ally(fighter * af, int minrow, int maxrow, int allytype)
dt.fighter = df;
return dt;
}
allies -= (df->alive - df->removed);
allies -= df->alive;
}
}
}
@ -2403,9 +2439,10 @@ static int loot_quota(const unit * src, const unit * dst,
{
UNUSED_ARG(type);
if (dst && src && src->faction != dst->faction) {
assert(loot_divisor <= 0 || loot_divisor >= 1);
if (loot_divisor > 1) {
double r = n / loot_divisor;
double divisor = config_get_flt("rules.items.loot_divisor", 1);
assert(divisor <= 0 || divisor >= 1);
if (divisor >= 1) {
double r = n / divisor;
int x = (int)r;
r = r - x;
@ -3071,6 +3108,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
fig->side = s1;
fig->alive = u->number;
fig->side->alive += u->number;
fig->side->battle->alive += u->number;
fig->catmsg = -1;
/* Freigeben nicht vergessen! */
@ -3127,8 +3165,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
int dwp[WMAX];
int wcount[WMAX];
int wused[WMAX];
int oi = 0, di = 0;
int w = 0;
int oi = 0, di = 0, w = 0;
for (itm = u->items; itm && w != WMAX; itm = itm->next) {
const weapon_type *wtype = resource2weapon(itm->type->rtype);
if (wtype == NULL || itm->number == 0)
@ -3143,9 +3180,9 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
}
assert(w != WMAX);
}
fig->weapons = malloc((1 + (size_t)w) * sizeof(weapon));
memcpy(fig->weapons, weapons, w * sizeof(weapon));
fig->weapons[w].type = NULL;
assert(w >= 0);
fig->weapons = (weapon *)calloc((size_t)(w + 1), sizeof(weapon));
memcpy(fig->weapons, weapons, (size_t)w * sizeof(weapon));
for (i = 0; i != w; ++i) {
int j, o = 0, d = 0;
@ -3229,7 +3266,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
for (itm = u->items; itm; itm = itm->next) {
if (itm->type->rtype->atype) {
if (i_canuse(u, itm->type)) {
struct armor *adata = malloc(sizeof(armor)), **aptr;
struct armor *adata = (struct armor *)malloc(sizeof(armor)), **aptr;
adata->atype = itm->type->rtype->atype;
adata->count = itm->number;
for (aptr = &fig->armors; *aptr; aptr = &(*aptr)->next) {
@ -3524,8 +3561,6 @@ static void join_allies(battle * b)
faction *f = u->faction;
fighter *c = NULL;
if (is_paused(u->faction)) continue;
for (s = b->sides; s != s_end; ++s) {
side *se;
/* Wenn alle attackierten noch FFL_NOAID haben, dann kaempfe nicht mit. */
@ -3650,7 +3685,8 @@ static bool start_battle(region * r, battle ** bp)
bool fighting = false;
for (u = r->units; u != NULL; u = u->next) {
if (!long_order_allowed(u, true)) continue;
if (fval(u, UFL_LONGACTION))
continue;
if (u->number > 0) {
order *ord;
@ -3684,6 +3720,10 @@ static bool start_battle(region * r, battle ** bp)
continue;
}
/* ist ein Fluechtling aus einem andern Kampf */
if (fval(u, UFL_LONGACTION))
continue;
if (curse_active(get_curse(r->attribs, &ct_peacezone))) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "peace_active", ""));
continue;
@ -3852,6 +3892,10 @@ static void battle_flee(battle * b)
int runhp = (int)(0.9 + unit_max_hp(u) * hpflee(u->status));
if (runhp > 600) runhp = 600;
if (u->ship && fval(u->region->terrain, SEA_REGION)) {
/* keine Flucht von Schiffen auf hoher See */
continue;
}
if (fval(u_race(u), RCF_UNDEAD) || u_race(u) == get_race(RC_SHADOWKNIGHT)) {
/* Untote fliehen nicht. Warum eigentlich? */
continue;
@ -3915,31 +3959,24 @@ void force_leave(region *r, battle *b) {
for (u = r->units; u; u = u->next) {
unit *uo = NULL;
if (is_paused(u->faction)) continue;
if (u->building) {
uo = building_owner(u->building);
}
else if (u->ship && r->land) {
if (u->ship && r->land) {
uo = ship_owner(u->ship);
}
else {
continue;
}
if (is_enemy(b, uo, u)) {
if (leave(u, true)) {
message *msg;
if (uo->building) {
msg = msg_message("force_leave_building", "unit owner building", u, uo, uo->building);
}
else {
msg = msg_message("force_leave_ship", "unit owner ship", u, uo, uo->ship);
}
add_message(&u->faction->msgs, msg);
add_message(&uo->faction->msgs, msg);
msg_release(msg);
if (uo && is_enemy(b, uo, u)) {
message *msg = NULL;
if (u->building) {
msg = msg_message("force_leave_building", "unit owner building", u, uo, u->building);
}
else {
msg = msg_message("force_leave_ship", "unit owner ship", u, uo, u->ship);
}
if (msg) {
ADDMSG(&u->faction->msgs, msg);
}
leave(u, false);
}
}
}

View file

@ -85,6 +85,21 @@ extern "C" {
signed char keeploot; /* keep (50 + keeploot) percent of items as loot */
bool has_tactics_turn;
bool reelarrow;
int alive;
struct {
const struct side *as;
const struct side *vs;
int alive;
int row;
int result;
} rowcache;
struct {
struct side *side;
int status;
int alive;
int minrow, maxrow;
int enemies[8];
} fast;
} battle;
typedef struct weapon {
@ -239,7 +254,6 @@ extern "C" {
void battle_message_faction(struct battle * b, struct faction * f, struct message *m);
double tactics_chance(const struct unit *u, int skilldiff);
int meffect_apply(struct meffect *me, int damage);
#ifdef __cplusplus
}
#endif

View file

@ -1,13 +1,10 @@
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#endif
#include <platform.h>
#include "battle.h"
#include "guard.h"
#include "reports.h"
#include "skill.h"
#include <kernel/config.h>
#include <kernel/building.h>
@ -18,8 +15,7 @@
#include <kernel/race.h>
#include <kernel/region.h>
#include <kernel/ship.h>
#include "kernel/skill.h"
#include "kernel/unit.h"
#include <kernel/unit.h>
#include <spells/buildingcurse.h>
@ -67,7 +63,7 @@ static void test_make_fighter(CuTest * tc)
test_setup();
test_create_horse();
r = test_create_region(0, 0, NULL);
f = test_create_faction();
f = test_create_faction(NULL);
au = test_create_unit(f, r);
enable_skill(SK_MAGIC, true);
enable_skill(SK_RIDING, true);
@ -107,7 +103,7 @@ static void test_select_weapon_restricted(CuTest *tc) {
race * rc;
test_setup();
au = test_create_unit(test_create_faction(), test_create_plain(0, 0));
au = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
itype = test_create_itemtype("halberd");
wtype = new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, SK_MELEE);
i_change(&au->items, itype, 1);
@ -164,7 +160,7 @@ static void test_select_armor(CuTest *tc) {
battle *b;
test_setup();
au = test_create_unit(test_create_faction(), test_create_plain(0, 0));
au = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
itype = test_create_itemtype("plate");
new_armortype(itype, 0.0, frac_zero, 1, 0);
i_change(&au->items, itype, 2);
@ -186,7 +182,21 @@ static void test_select_armor(CuTest *tc) {
}
static building_type * setup_castle(void) {
return test_create_castle();
building_type * btype;
construction *cons;
btype = test_create_buildingtype("castle");
assert(btype->stages);
assert(btype->stages->construction);
btype->flags |= BTF_FORTIFICATION;
cons = btype->stages->construction;
cons->maxsize = 5;
btype->stages->next = calloc(1, sizeof(building_stage));
cons = calloc(1, sizeof(construction));
cons->maxsize = -1;
btype->stages->next->construction = cons;
return btype;
}
static void test_defenders_get_building_bonus(CuTest * tc)
@ -205,8 +215,8 @@ static void test_defenders_get_building_bonus(CuTest * tc)
r = test_create_region(0, 0, NULL);
bld = test_create_building(r, btype);
du = test_create_unit(test_create_faction(), r);
au = test_create_unit(test_create_faction(), r);
du = test_create_unit(test_create_faction(NULL), r);
au = test_create_unit(test_create_faction(NULL), r);
u_set_building(du, bld);
b = make_battle(r);
@ -223,14 +233,9 @@ static void test_defenders_get_building_bonus(CuTest * tc)
at.fighter = af;
at.index = 0;
bld->size = 10; /* stage 2 building */
CuAssertIntEquals(tc, 2, buildingeffsize(bld, false));
CuAssertIntEquals(tc, -1, skilldiff(at, dt, 0));
CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0));
bld->size = 9; /* stage 1 building */
bld->size = 10; /* stage 1 building */
CuAssertIntEquals(tc, 1, buildingeffsize(bld, false));
CuAssertIntEquals(tc, 0, skilldiff(at, dt, 0));
CuAssertIntEquals(tc, -1, skilldiff(at, dt, 0));
CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0));
bld->size = 1; /* stage 0 building */
@ -259,7 +264,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
bld = test_create_building(r, btype);
bld->size = 10;
au = test_create_unit(test_create_faction(), r);
au = test_create_unit(test_create_faction(NULL), r);
u_set_building(au, bld);
b = make_battle(r);
@ -289,7 +294,7 @@ static void test_building_bonus_respects_size(CuTest * tc)
bld = test_create_building(r, btype);
bld->size = 10;
f = test_create_faction();
f = test_create_faction(NULL);
au = test_create_unit(f, r);
scale_number(au, 9);
u_set_building(au, bld);
@ -315,21 +320,20 @@ static void test_building_defense_bonus(CuTest * tc)
test_setup();
btype = setup_castle();
btype->maxsize = -1; /* unlimited buildings get the castle bonus */
CuAssertIntEquals(tc, 0, bt_protection(btype, 0));
CuAssertIntEquals(tc, 0, bt_protection(btype, 1));
CuAssertIntEquals(tc, 1, bt_protection(btype, 2));
CuAssertIntEquals(tc, 2, bt_protection(btype, 3));
CuAssertIntEquals(tc, 3, bt_protection(btype, 4));
CuAssertIntEquals(tc, 4, bt_protection(btype, 5));
CuAssertIntEquals(tc, 5, bt_protection(btype, 6));
CuAssertIntEquals(tc, 5, bt_protection(btype, 7)); /* illegal castle size */
btype->maxsize = -1; /* unlimited buildigs get the castle bonus */
CuAssertIntEquals(tc, 0, building_protection(btype, 0));
CuAssertIntEquals(tc, 1, building_protection(btype, 1));
CuAssertIntEquals(tc, 3, building_protection(btype, 2));
CuAssertIntEquals(tc, 5, building_protection(btype, 3));
CuAssertIntEquals(tc, 8, building_protection(btype, 4));
CuAssertIntEquals(tc, 12, building_protection(btype, 5));
CuAssertIntEquals(tc, 12, building_protection(btype, 6));
btype->maxsize = 10; /* limited-size buildings are treated like an E3 watchtower */
CuAssertIntEquals(tc, 0, bt_protection(btype, 0));
CuAssertIntEquals(tc, 1, bt_protection(btype, 1));
CuAssertIntEquals(tc, 2, bt_protection(btype, 2));
CuAssertIntEquals(tc, 2, bt_protection(btype, 3));
CuAssertIntEquals(tc, 0, building_protection(btype, 0));
CuAssertIntEquals(tc, 1, building_protection(btype, 1));
CuAssertIntEquals(tc, 2, building_protection(btype, 2));
CuAssertIntEquals(tc, 2, building_protection(btype, 3));
test_teardown();
}
@ -351,7 +355,7 @@ static void test_natural_armor(CuTest * tc)
test_setup();
rc = test_create_race("human");
u = test_create_unit(test_create_faction_ex(rc, NULL), test_create_region(0, 0, NULL));
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
set_level(u, SK_STAMINA, 2);
CuAssertIntEquals(tc, 0, rc_armor_bonus(rc));
CuAssertIntEquals(tc, 0, natural_armor(u));
@ -395,7 +399,7 @@ static void test_calculate_armor(CuTest * tc)
achain = new_armortype(ichain, 0.0, v50p, 3, ATF_NONE);
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, v50p, 0, 0, 0, 0, SK_MELEE);
rc = test_create_race("human");
du = test_create_unit(test_create_faction_ex(rc, NULL), r);
du = test_create_unit(test_create_faction(rc), r);
dt.index = 0;
dt.fighter = setup_fighter(&b, du);
@ -448,30 +452,6 @@ static void test_calculate_armor(CuTest * tc)
test_teardown();
}
static void test_spells_reduce_damage(CuTest *tc)
{
struct meffect me;
me.typ = SHIELD_ARMOR;
me.duration = 10;
me.effect = 5;
CuAssertIntEquals(tc, 5, meffect_apply(&me, 10));
CuAssertIntEquals(tc, 9, me.duration);
CuAssertIntEquals(tc, 5, me.effect);
CuAssertIntEquals(tc, 0, meffect_apply(&me, 1));
CuAssertIntEquals(tc, 8, me.duration);
CuAssertIntEquals(tc, 5, me.effect);
me.typ = SHIELD_REDUCE;
me.duration = 10;
me.effect = 50;
CuAssertIntEquals(tc, 5, meffect_apply(&me, 10));
CuAssertIntEquals(tc, 5, me.duration);
CuAssertIntEquals(tc, 50, me.effect);
CuAssertIntEquals(tc, 7, meffect_apply(&me, 12));
CuAssertIntEquals(tc, 0, me.duration);
}
static void test_magic_resistance(CuTest *tc)
{
troop dt;
@ -492,7 +472,7 @@ static void test_magic_resistance(CuTest *tc)
ichain = it_get_or_create(rt_get_or_create("chainmail"));
achain = new_armortype(ichain, 0.0, v50p, 3, ATF_NONE);
rc = test_create_race("human");
du = test_create_unit(test_create_faction_ex(rc, NULL), r);
du = test_create_unit(test_create_faction(rc), r);
dt.index = 0;
i_change(&du->items, ishield, 1);
@ -563,7 +543,7 @@ static void test_projectile_armor(CuTest * tc)
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, v50p, 0, 0, 0, 0, SK_MELEE);
rc = test_create_race("human");
rc->battle_flags |= BF_EQUIPMENT;
du = test_create_unit(test_create_faction_ex(rc, NULL), r);
du = test_create_unit(test_create_faction(rc), r);
dt.index = 0;
i_change(&du->items, ishield, 1);
@ -591,8 +571,8 @@ static void test_battle_skilldiff(CuTest *tc)
test_setup();
r = test_create_region(0, 0, NULL);
ud = test_create_unit(test_create_faction(), r);
ua = test_create_unit(test_create_faction(), r);
ud = test_create_unit(test_create_faction(NULL), r);
ua = test_create_unit(test_create_faction(NULL), r);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
@ -626,8 +606,8 @@ static void test_terminate(CuTest * tc)
r = test_create_region(0, 0, NULL);
rc = test_create_race("human");
au = test_create_unit(test_create_faction_ex(rc, NULL), r);
du = test_create_unit(test_create_faction_ex(rc, NULL), r);
au = test_create_unit(test_create_faction(rc), r);
du = test_create_unit(test_create_faction(rc), r);
dt.index = 0;
at.index = 0;
@ -658,8 +638,8 @@ static void test_battle_report_one(CuTest *tc)
test_setup();
setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction(), r);
u2 = test_create_unit(test_create_faction(), r);
u1 = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(test_create_faction(NULL), r);
b = make_battle(r);
join_battle(b, u1, true, &fig);
join_battle(b, u2, false, &fig);
@ -689,8 +669,9 @@ static void test_battle_report_two(CuTest *tc)
locale_setstring(lang, "and", "and");
setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction_ex(NULL, lang), r);
u2 = test_create_unit(test_create_faction_ex(NULL, lang), r);
u1 = test_create_unit(test_create_faction(NULL), r);
u1->faction->locale = lang;
u2 = test_create_unit(test_create_faction(NULL), r);
u2->faction->locale = lang;
str_slprintf(expect, sizeof(expect), "%s and %s", factionname(u1->faction), factionname(u2->faction));
@ -721,11 +702,11 @@ static void test_battle_report_three(CuTest *tc)
locale_setstring(lang, "and", "and");
setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction(), r);
u1 = test_create_unit(test_create_faction(NULL), r);
u1->faction->locale = lang;
u2 = test_create_unit(test_create_faction(), r);
u2 = test_create_unit(test_create_faction(NULL), r);
u2->faction->locale = lang;
u3 = test_create_unit(test_create_faction(), r);
u3 = test_create_unit(test_create_faction(NULL), r);
u3->faction->locale = lang;
str_slprintf(expect, sizeof(expect), "%s, %s and %s", factionname(u1->faction), factionname(u2->faction), factionname(u3->faction));
@ -754,9 +735,9 @@ static void test_battle_skilldiff_building(CuTest *tc)
btype = setup_castle();
r = test_create_region(0, 0, NULL);
ud = test_create_unit(test_create_faction(), r);
ud = test_create_unit(test_create_faction(NULL), r);
ud->building = test_create_building(ud->region, btype);
ua = test_create_unit(test_create_faction(), r);
ua = test_create_unit(test_create_faction(NULL), r);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
@ -765,14 +746,13 @@ static void test_battle_skilldiff_building(CuTest *tc)
CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
ud->building->size = 10;
CuAssertIntEquals(tc, 2, buildingeffsize(ud->building, false));
CuAssertIntEquals(tc, 1, building_protection(ud->building));
CuAssertIntEquals(tc, 1, buildingeffsize(ud->building, false));
CuAssertIntEquals(tc, -1, skilldiff(ta, td, 0));
create_curse(ud, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1);
create_curse(NULL, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1);
CuAssertIntEquals(tc, -2, skilldiff(ta, td, 0));
create_curse(ud, &ud->building->attribs, &ct_strongwall, 1, 1, 2, 1);
create_curse(NULL, &ud->building->attribs, &ct_strongwall, 1, 1, 2, 1);
CuAssertIntEquals(tc, -4, skilldiff(ta, td, 0));
free_battle(b);
@ -804,7 +784,7 @@ static void test_drain_exp(CuTest *tc)
test_setup();
config_set("study.random_progress", "0");
u = test_create_unit(test_create_faction(), test_create_region(0, 0, NULL));
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
set_level(u, SK_STAMINA, 3);
CuAssertIntEquals(tc, 3, unit_skill(u, SK_STAMINA)->level);
@ -862,7 +842,7 @@ static void test_tactics_chance(CuTest *tc) {
ship_type *stype;
test_setup();
u = test_create_unit(test_create_faction(), test_create_ocean(0, 0));
u = test_create_unit(test_create_faction(NULL), test_create_ocean(0, 0));
CuAssertDblEquals(tc, 0.1, tactics_chance(u, 1), 0.01);
CuAssertDblEquals(tc, 0.3, tactics_chance(u, 3), 0.01);
stype = test_create_shiptype("brot");
@ -879,8 +859,8 @@ static void test_battle_fleeing(CuTest *tc) {
test_setup();
setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction(), r);
u2 = test_create_unit(test_create_faction(), r);
u1 = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(test_create_faction(NULL), r);
u1->status = ST_FLEE;
u2->status = ST_AGGRO;
#if 0
@ -922,7 +902,6 @@ CuSuite *get_battle_suite(void)
SUITE_ADD_TEST(suite, test_calculate_armor);
SUITE_ADD_TEST(suite, test_natural_armor);
SUITE_ADD_TEST(suite, test_magic_resistance);
SUITE_ADD_TEST(suite, test_spells_reduce_damage);
SUITE_ADD_TEST(suite, test_projectile_armor);
SUITE_ADD_TEST(suite, test_tactics_chance);
SUITE_ADD_TEST(suite, test_terminate);

View file

@ -39,15 +39,15 @@ static int tolua_building_set_working(lua_State * L)
{
building *self = (building *)tolua_tousertype(L, 1, 0);
bool flag = !!lua_toboolean(L, 2);
if (flag) self->flags |= BLD_MAINTAINED;
else self->flags &= ~BLD_MAINTAINED;
return 1;
if (flag) self->flags &= ~BLD_UNMAINTAINED;
else self->flags |= BLD_UNMAINTAINED;
return 0;
}
static int tolua_building_get_working(lua_State * L)
{
building *self = (building *)tolua_tousertype(L, 1, 0);
bool flag = (self->flags&BLD_MAINTAINED) != 0;
bool flag = (self->flags & BLD_UNMAINTAINED) == 0;
lua_pushboolean(L, flag);
return 1;
}

View file

@ -1,8 +1,7 @@
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <platform.h>
#endif
#include "bind_config.h"
#include "jsonconf.h"

View file

@ -1,7 +1,5 @@
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <platform.h>
#endif
#include "bind_eressea.h"
@ -28,65 +26,52 @@ void eressea_free_game(void) {
}
int eressea_read_game(const char * filename) {
if (filename) {
return readgame(filename);
}
return -1;
return readgame(filename);
}
int eressea_write_game(const char * filename) {
if (filename) {
remove_empty_factions();
return writegame(filename);
}
return -1;
remove_empty_factions();
return writegame(filename);
}
int eressea_read_orders(const char * filename) {
if (filename) {
FILE *F = fopen(filename, "r");
int result;
FILE * F = fopen(filename, "r");
int result;
if (!F) {
perror(filename);
return -1;
}
log_info("reading orders from %s", filename);
result = parseorders(F);
fclose(F);
return result;
if (!F) {
perror(filename);
return -1;
}
return -1;
log_info("reading orders from %s", filename);
result = parseorders(F);
fclose(F);
return result;
}
int eressea_export_json(const char * filename, int flags) {
if (filename) {
FILE *F = fopen(filename, "w");
if (F) {
stream out = { 0 };
int err;
fstream_init(&out, F);
err = json_export(&out, flags);
fstream_done(&out);
return err;
}
perror(filename);
FILE *F = fopen(filename, "w");
if (F) {
stream out = { 0 };
int err;
fstream_init(&out, F);
err = json_export(&out, flags);
fstream_done(&out);
return err;
}
perror(filename);
return -1;
}
int eressea_import_json(const char * filename) {
if (filename) {
FILE *F = fopen(filename, "r");
if (F) {
stream out = { 0 };
int err;
fstream_init(&out, F);
err = json_import(&out);
fstream_done(&out);
return err;
}
perror(filename);
FILE *F = fopen(filename, "r");
if (F) {
stream out = { 0 };
int err;
fstream_init(&out, F);
err = json_import(&out);
fstream_done(&out);
return err;
}
perror(filename);
return -1;
}

View file

@ -188,7 +188,7 @@ static void lua_paint_info(struct window *wnd, const struct state *st)
int size = getmaxx(win) - 2;
int line = 0, maxline = getmaxy(win) - 2;
const char *str = result;
box(win, 0, 0);
wxborder(win);
while (*str && line < maxline) {
const char *end = strchr(str, '\n');

View file

@ -10,7 +10,6 @@
#include "magic.h"
#include "market.h"
#include "move.h"
#include "sort.h"
#include "study.h"
#include <kernel/alliance.h>

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