forked from github/server
Merge pull request #682 from ennorehling/develop
cmake changes, skillmod rewrite
This commit is contained in:
commit
1c509485f7
|
@ -1,9 +1,6 @@
|
|||
[submodule "lunit"]
|
||||
path = lunit
|
||||
url = https://github.com/ennorehling/lunit.git
|
||||
[submodule "cmake"]
|
||||
path = cmake
|
||||
url = https://github.com/ennorehling/cmake.git
|
||||
[submodule "dlmalloc"]
|
||||
path = dlmalloc
|
||||
url = https://github.com/ennorehling/dlmalloc.git
|
||||
|
|
|
@ -1,17 +1,29 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project (eressea-server C)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH})
|
||||
|
||||
if (WIN32)
|
||||
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)
|
||||
if (MSVC)
|
||||
include(MSVC)
|
||||
endif (MSVC)
|
||||
|
||||
enable_testing()
|
||||
find_package (LibXml2)
|
||||
find_package (SQLite3)
|
||||
find_package (Curses)
|
||||
find_package (Lua REQUIRED)
|
||||
find_package (LibXml2)
|
||||
find_package (ToLua REQUIRED)
|
||||
if (TOLUA_FOUND)
|
||||
if (${TOLUA_VERSION_STRING} VERSION_GREATER "5.2")
|
||||
find_package (Lua 5.2 REQUIRED)
|
||||
elseif (${TOLUA_VERSION_STRING} VERSION_GREATER "5.1")
|
||||
find_package (Lua 5.1 REQUIRED)
|
||||
endif()
|
||||
endif(TOLUA_FOUND)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory (cJSON)
|
||||
add_subdirectory (storage)
|
||||
|
@ -19,8 +31,10 @@ add_subdirectory (iniparser)
|
|||
add_subdirectory (clibs)
|
||||
add_subdirectory (process)
|
||||
add_subdirectory (src eressea)
|
||||
|
||||
install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.xml")
|
||||
install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.json")
|
||||
install(DIRECTORY scripts DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua")
|
||||
install(DIRECTORY lunit DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua")
|
||||
install(DIRECTORY share DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
|
|
2
cJSON
2
cJSON
|
@ -1 +1 @@
|
|||
Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1
|
||||
Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001
|
1
cmake
1
cmake
|
@ -1 +0,0 @@
|
|||
Subproject commit f1fb3943ace59994d90d71a891b80033dc2700a2
|
|
@ -0,0 +1,172 @@
|
|||
#.rst:
|
||||
# FindLua
|
||||
# -------
|
||||
#
|
||||
#
|
||||
#
|
||||
# Locate Lua library This module defines
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# LUA_FOUND - if false, do not try to link to Lua
|
||||
# LUA_LIBRARIES - both lua and lualib
|
||||
# LUA_INCLUDE_DIR - where to find lua.h
|
||||
# LUA_VERSION_STRING - the version of Lua found
|
||||
# LUA_VERSION_MAJOR - the major version of Lua
|
||||
# LUA_VERSION_MINOR - the minor version of Lua
|
||||
# LUA_VERSION_PATCH - the patch version of Lua
|
||||
#
|
||||
#
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# #include "lua.h"
|
||||
#
|
||||
# and not
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# #include <lua/lua.h>
|
||||
#
|
||||
# This is because, the lua location is not standardized and may exist in
|
||||
# locations other than lua/
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
# Copyright 2013 Rolf Eike Beer <eike@sf-mail.de>
|
||||
#
|
||||
# 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.)
|
||||
|
||||
unset(_lua_include_subdirs)
|
||||
unset(_lua_library_names)
|
||||
|
||||
# this is a function only to have all the variables inside go away automatically
|
||||
function(set_lua_version_vars)
|
||||
set(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
|
||||
|
||||
if (Lua_FIND_VERSION_EXACT)
|
||||
if (Lua_FIND_VERSION_COUNT GREATER 1)
|
||||
set(lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
|
||||
endif ()
|
||||
elseif (Lua_FIND_VERSION)
|
||||
# once there is a different major version supported this should become a loop
|
||||
if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
|
||||
if (Lua_FIND_VERSION_COUNT EQUAL 1)
|
||||
set(lua_append_versions ${LUA_VERSIONS5})
|
||||
else ()
|
||||
foreach (subver IN LISTS LUA_VERSIONS5)
|
||||
if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
|
||||
list(APPEND lua_append_versions ${subver})
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
endif ()
|
||||
else ()
|
||||
# once there is a different major version supported this should become a loop
|
||||
set(lua_append_versions ${LUA_VERSIONS5})
|
||||
endif ()
|
||||
|
||||
foreach (ver IN LISTS lua_append_versions)
|
||||
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
|
||||
list(APPEND _lua_include_subdirs
|
||||
include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
|
||||
include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
)
|
||||
list(APPEND _lua_library_names
|
||||
lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
|
||||
lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
lua.${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
|
||||
set(_lua_library_names "${_lua_library_names}" PARENT_SCOPE)
|
||||
endfunction(set_lua_version_vars)
|
||||
|
||||
set_lua_version_vars()
|
||||
|
||||
find_path(LUA_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES ${_lua_include_subdirs} include/lua include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
unset(_lua_include_subdirs)
|
||||
|
||||
find_library(LUA_LIBRARY
|
||||
NAMES ${_lua_library_names} lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
unset(_lua_library_names)
|
||||
|
||||
if (LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if (UNIX AND NOT APPLE AND NOT BEOS)
|
||||
find_library(LUA_MATH_LIBRARY m)
|
||||
set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
else ()
|
||||
set(LUA_LIBRARIES "${LUA_LIBRARY}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
# At least 5.[012] have different ways to express the version
|
||||
# so all of them need to be tested. Lua 5.2 defines LUA_VERSION
|
||||
# and LUA_RELEASE as joined by the C preprocessor, so avoid those.
|
||||
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_strings
|
||||
REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
|
||||
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
|
||||
if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
|
||||
set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
|
||||
else ()
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
|
||||
if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
|
||||
endif ()
|
||||
string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
|
||||
endif ()
|
||||
|
||||
unset(lua_version_strings)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
|
|
@ -0,0 +1,63 @@
|
|||
# - 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)
|
||||
|
||||
#=============================================================================
|
||||
# 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.)
|
||||
|
||||
# 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_path(SQLITE3_INCLUDE_DIR NAMES sqlite3.h
|
||||
HINTS
|
||||
${PC_SQLITE_INCLUDEDIR}
|
||||
${PC_SQLITE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(SQLITE3_LIBRARIES NAMES sqlite3
|
||||
HINTS
|
||||
${PC_SQLITE_LIBDIR}
|
||||
${PC_SQLITE_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
find_program(SQLITE3_EXECUTABLE 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 ]+\".*\"")
|
||||
|
||||
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_LIBRARIES SQLITE3_INCLUDE_DIR
|
||||
VERSION_VAR SQLITE3_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(SQLITE3_INCLUDE_DIR SQLITE3_LIBRARIES SQLITE3_EXECUTABLE)
|
|
@ -0,0 +1,71 @@
|
|||
# - Try to find the ToLua library
|
||||
# Once done this will define
|
||||
#
|
||||
# TOLUA_FOUND - System has ToLua
|
||||
# TOLUA_INCLUDE_DIR - The ToLua include directory
|
||||
# TOLUA_LIBRARIES - The libraries needed to use ToLua
|
||||
# TOLUA_DEFINITIONS - Compiler switches required for using ToLua
|
||||
# TOLUA_EXECUTABLE - The ToLua command line shell
|
||||
# TOLUA_VERSION_STRING - the version of ToLua found (since CMake 2.8.8)
|
||||
|
||||
#=============================================================================
|
||||
# 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.)
|
||||
|
||||
# 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_TOLUA QUIET ToLua)
|
||||
set(TOLUA_DEFINITIONS ${PC_TOLUA_CFLAGS_OTHER})
|
||||
|
||||
find_path(TOLUA_INCLUDE_DIR NAMES tolua.h
|
||||
HINTS
|
||||
${PC_TOLUA_DIR}/include
|
||||
${PC_TOLUA_INCLUDEDIR}
|
||||
${PC_TOLUA_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(TOLUA_LIBRARY NAMES tolua
|
||||
HINTS
|
||||
${PC_TOLUA_DIR}/lib
|
||||
${PC_TOLUA_LIBDIR}
|
||||
${PC_TOLUA_LIBRARY_DIRS}
|
||||
)
|
||||
find_program(TOLUA_EXECUTABLE tolua
|
||||
HINTS
|
||||
${PC_TOLUA_DIR}/bin
|
||||
${PC_TOLUA_LIBDIR}
|
||||
${PC_TOLUA_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
SET( TOLUA_LIBRARIES "${TOLUA_LIBRARY}" CACHE STRING "ToLua Libraries")
|
||||
|
||||
if(PC_TOLUA_VERSION)
|
||||
set(TOLUA_VERSION_STRING ${PC_TOLUA_VERSION})
|
||||
elseif(TOLUA_INCLUDE_DIR AND EXISTS "${TOLUA_INCLUDE_DIR}/tolua.h")
|
||||
file(STRINGS "${TOLUA_INCLUDE_DIR}/tolua.h" tolua_version_str
|
||||
REGEX "^#define[\t ]+TOLUA_VERSION[\t ]+\".*\"")
|
||||
|
||||
string(REGEX REPLACE "^#define[\t ]+TOLUA_VERSION[\t ]+\"tolua ([^\"]*)\".*" "\\1"
|
||||
TOLUA_VERSION_STRING "${tolua_version_str}")
|
||||
unset(tolua_version_str)
|
||||
endif()
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set TOLUA_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ToLua
|
||||
REQUIRED_VARS TOLUA_LIBRARY TOLUA_INCLUDE_DIR TOLUA_EXECUTABLE
|
||||
VERSION_VAR TOLUA_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(TOLUA_INCLUDE_DIR TOLUA_LIBRARIES TOLUA_EXECUTABLE)
|
||||
|
|
@ -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)
|
|
@ -1 +1 @@
|
|||
Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258
|
||||
Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b
|
|
@ -93,7 +93,6 @@
|
|||
</building>
|
||||
|
||||
<building name="smithy" capacity="1">
|
||||
<function name="init" value="init_smithy"/>
|
||||
<maintenance type="money" amount="300"/>
|
||||
<maintenance type="log" amount="1"/>
|
||||
<construction skill="building" minskill="3">
|
||||
|
@ -102,6 +101,8 @@
|
|||
<requirement type="iron" quantity="2"/>
|
||||
<requirement type="money" quantity="200"/>
|
||||
</construction>
|
||||
<modifier type="skill" skill="weaponsmithing" value="1"/>
|
||||
<modifier type="skill" skill="armorer" value="1"/>
|
||||
</building>
|
||||
|
||||
<building name="magictower" maxcapacity="2" maxsize="50" magic="yes" magres="40" fumblebonus="10" auraregen="1.75">
|
||||
|
|
|
@ -5536,8 +5536,8 @@
|
|||
<arg name="region" type="region"/>
|
||||
<arg name="command" type="order"/>
|
||||
</type>
|
||||
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Nur Elfen können diese Bögen herstellen."</text>
|
||||
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - Only elves can make these bows."</text>
|
||||
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Diesen Gegenstand kann die Einheit nicht herstellen."</text>
|
||||
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - This unit cannot produce that."</text>
|
||||
</message>
|
||||
<message name="error117" section="errors">
|
||||
<type>
|
||||
|
@ -5545,8 +5545,8 @@
|
|||
<arg name="region" type="region"/>
|
||||
<arg name="command" type="order"/>
|
||||
</type>
|
||||
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Nur die EMail-Adresse angeben!"</text>
|
||||
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - Please provide only an email address!"</text>
|
||||
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Diese Rasse kann das nicht herstellen."</text>
|
||||
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - This race cannot produce that."</text>
|
||||
</message>
|
||||
<message name="error116" section="errors">
|
||||
<type>
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
<item weight="500" score="10">
|
||||
<construction skill="mining" minskill="1"/>
|
||||
</item>
|
||||
<modifier building="smithy" type="save" value="2"/>
|
||||
<modifier building="mine" type="skill" value="1"/>
|
||||
<modifier building="mine" type="material" value="0.5"/>
|
||||
<modifier race="dwarf" type="material" value="0.60"/>
|
||||
<modifier race="dwarf" type="material" value="0.6"/>
|
||||
</resource>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<resource name="greatbow">
|
||||
<modifier type="require" race="elf"/>
|
||||
<item weight="100">
|
||||
<construction skill="weaponsmithing" minskill="5">
|
||||
<modifier function="mod_elves_only"/>
|
||||
<requirement type="mallorn" quantity="2"/>
|
||||
</construction>
|
||||
<weapon pierce="true" missile="true" skill="bow" offmod="0" defmod="0" reload="0" magres="0.0">
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<resource name="scale">
|
||||
<modifier type="require" race="dwarf"/>
|
||||
<modifier type="require" race="irongolem"/>
|
||||
<item weight="300" score="150" allow="dwarf halfling">
|
||||
<construction skill="armorer" minskill="5">
|
||||
<modifier function="mod_dwarves_only"/>
|
||||
<requirement type="iron" quantity="2"/>
|
||||
</construction>
|
||||
<armor ac="3" penalty="0.10" projectile="0.05" magres="0.0"/>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<resource name="towershield">
|
||||
<modifier type="require" race="dwarf"/>
|
||||
<modifier type="require" race="irongolem"/>
|
||||
<item weight="200" score="60" allow="dwarf">
|
||||
<construction skill="armorer" minskill="4">
|
||||
<modifier function="mod_dwarves_only"/>
|
||||
<requirement type="iron" quantity="1"/>
|
||||
</construction>
|
||||
<armor ac="0" penalty="-0.15" projectile="0.25" magres="0.0" shield="yes">
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<item weight="500" score="10">
|
||||
<construction skill="mining" minskill="1"/>
|
||||
</item>
|
||||
<modifier building="smithy" type="save" value="2"/>
|
||||
<modifier building="mine" type="skill" value="1"/>
|
||||
<modifier building="mine" type="material" value="0.5"/>
|
||||
</resource>
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* has lower damage
|
||||
-->
|
||||
<resource name="greatbow">
|
||||
<modifier type="require" race="elf"/>
|
||||
<item weight="100" allow="elf">
|
||||
<construction skill="weaponsmithing" minskill="5">
|
||||
<modifier function="mod_elves_only"/>
|
||||
<requirement type="mallorn" quantity="2"/>
|
||||
</construction>
|
||||
<weapon pierce="true" missile="true" skill="bow" offmod="0" defmod="0" reload="0" magres="0.0">
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<resource name="rep_crossbow">
|
||||
<modifier type="require" race="dwarf"/>
|
||||
<item weight="100" allow="dwarf halfling">
|
||||
<construction skill="weaponsmithing" minskill="5">
|
||||
<modifier function="mod_dwarves_only"/>
|
||||
<requirement type="log" quantity="1"/>
|
||||
<requirement type="iron" quantity="1"/>
|
||||
</construction>
|
||||
|
|
2
s/build
2
s/build
|
@ -33,7 +33,7 @@ fi
|
|||
echo "build eressea"
|
||||
cd $ROOT/$BUILD
|
||||
BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//')
|
||||
if [ "$BRANCH"=="master" ] ; then
|
||||
if [ "$BRANCH" = "master" ] ; then
|
||||
VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//')
|
||||
cmake -DERESSEA_VERSION="$VERSION" ..
|
||||
else
|
||||
|
|
|
@ -10,6 +10,7 @@ ROOT=$(git rev-parse --show-toplevel)
|
|||
MACHINE=`$CC -dumpmachine`
|
||||
[ -z $MACHINE ] && MACHINE=`uname -m`
|
||||
BIN_DIR="$ROOT/build-$MACHINE-$CC-$BUILD"
|
||||
rm -rf $BIN_DIR
|
||||
mkdir -p $BIN_DIR
|
||||
rm -f $BUILD
|
||||
ln -sf $BIN_DIR $BUILD
|
||||
|
@ -29,12 +30,11 @@ if [ -d $HOME/usr ]; then
|
|||
fi
|
||||
|
||||
DEST=$(dirname $ROOT)/server
|
||||
ARGS=" -DCMAKE_MODULE_PATH=$ROOT/cmake/Modules \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD \
|
||||
ARGS=" -DCMAKE_BUILD_TYPE=$BUILD \
|
||||
-DCMAKE_LIBRARY_PATH=$LIBRARY_PATH \
|
||||
-DCMAKE_INCLUDE_PATH=$INCLUDE_PATH \
|
||||
-DCMAKE_PREFIX_PATH=$PREFIX_PATH \
|
||||
-DCMAKE_INSTALL_PREFIX=$DEST"
|
||||
# -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH
|
||||
|
||||
git submodule update --init
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ cd $ROOT
|
|||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests.lua
|
||||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e2.lua
|
||||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e3.lua
|
||||
$ROOT/$BUILD/eressea/eressea --version
|
||||
rm -rf data reports orders.txt score score.alliances datum turn
|
||||
|
||||
cd $OLDWPD
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'tests.e2.production'
|
||||
require 'tests.e2.adamantium'
|
||||
require 'tests.e2.undead'
|
||||
require 'tests.e2.shiplanding'
|
||||
|
@ -17,3 +18,4 @@ require 'tests.storage'
|
|||
require 'tests.magicbag'
|
||||
require 'tests.process'
|
||||
require 'tests.xmas'
|
||||
require 'tests.production'
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
require "lunit"
|
||||
|
||||
module("tests.e2.production", package.seeall, lunit.testcase )
|
||||
|
||||
function setup()
|
||||
eressea.game.reset()
|
||||
eressea.settings.set("rules.food.flags", "4") -- food is free
|
||||
eressea.settings.set("NewbieImmunity", "0")
|
||||
end
|
||||
|
||||
local function create_faction(race)
|
||||
return faction.create(race, race .. '@example.com', "de")
|
||||
end
|
||||
|
||||
function test_greatbow_needs_elf()
|
||||
-- only elves can build a greatbow
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
u:set_skill('weaponsmithing', 5)
|
||||
u:add_item('mallorn', 2)
|
||||
u:add_order("MACHE Elfenbogen")
|
||||
turn_process() -- humans cannot do it
|
||||
assert_equal(1, f:count_msg_type("error117"))
|
||||
assert_equal(0, u:get_item('greatbow'))
|
||||
assert_equal(2, u:get_item('mallorn'))
|
||||
|
||||
u.race = 'elf'
|
||||
turn_process() -- but elves can
|
||||
assert_equal(1, u:get_item('greatbow'))
|
||||
assert_equal(0, u:get_item('mallorn'))
|
||||
end
|
||||
|
||||
function test_troll_quarrying_bonus()
|
||||
-- Von Trollen abgebaute Steine werden nur zu 75% vom "Regionsvorrat" abgezogen.
|
||||
-- Dieser Effekt ist kumulativ zu einem Steinbruch.
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource("stone", 100)
|
||||
u:set_skill('quarrying', 4)
|
||||
u:add_order("MACHE Steine")
|
||||
turn_process() -- humans get no bonus
|
||||
assert_equal(4, u:get_item('stone'))
|
||||
assert_equal(96, r:get_resource('stone'))
|
||||
|
||||
u.race = 'troll'
|
||||
u:set_skill('quarrying', 2)
|
||||
turn_process() -- trolls have +2 to quarrying, and save 25%
|
||||
assert_equal(8, u:get_item('stone'))
|
||||
assert_equal(93, r:get_resource('stone'))
|
||||
end
|
||||
|
||||
function test_dwarf_mining_bonus()
|
||||
-- Von Zwergen abgebautes Eisen wird nur zu 60% vom "Regionsvorrat" abgezogen.
|
||||
-- Dieser Effekt ist kumulativ zu einem Bergwerk (siehe hier und hier).
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('iron', 100)
|
||||
u:set_skill('mining', 10)
|
||||
u:add_order('MACHE Eisen')
|
||||
turn_process() -- humans get no bonus
|
||||
assert_equal(10, u:get_item('iron'))
|
||||
assert_equal(90, r:get_resource('iron'))
|
||||
|
||||
u.race = 'dwarf'
|
||||
u:set_skill('mining', 8)
|
||||
turn_process() -- dwarves have +2 to mining, and save 40%
|
||||
assert_equal(20, u:get_item('iron'))
|
||||
assert_equal(84, r:get_resource('iron'))
|
||||
end
|
|
@ -1,14 +1,15 @@
|
|||
require 'tests.e3.production'
|
||||
require 'tests.e3.castles'
|
||||
require 'tests.e3.stealth'
|
||||
require 'tests.e3.spells'
|
||||
-- require 'tests.e3.castles'
|
||||
-- require 'tests.e3.stealth'
|
||||
-- require 'tests.e3.spells'
|
||||
require 'tests.e3.rules'
|
||||
require 'tests.e3.parser'
|
||||
require 'tests.e3.morale'
|
||||
require 'tests.e3.items'
|
||||
require 'tests.economy'
|
||||
require 'tests.orders'
|
||||
require 'tests.common'
|
||||
require 'tests.items'
|
||||
require 'tests.magicbag'
|
||||
require 'tests.process'
|
||||
-- require 'tests.e3.parser'
|
||||
-- require 'tests.e3.morale'
|
||||
-- require 'tests.e3.items'
|
||||
-- require 'tests.economy'
|
||||
-- require 'tests.orders'
|
||||
-- require 'tests.common'
|
||||
-- require 'tests.items'
|
||||
-- require 'tests.magicbag'
|
||||
-- require 'tests.process'
|
||||
-- require 'tests.e3.production'
|
||||
-- require 'tests.production'
|
||||
|
|
|
@ -9,171 +9,129 @@ function setup()
|
|||
end
|
||||
|
||||
local function create_faction(race)
|
||||
return faction.create(race, race .. '@eressea.de', "de")
|
||||
return faction.create(race, race .. '@example.com', "de")
|
||||
end
|
||||
|
||||
function test_laen_needs_mine()
|
||||
-- some resources require a building
|
||||
-- i.e. you cannot create laen without a mine
|
||||
local r = region.create(0, 0, "mountain")
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('laen', 100)
|
||||
u:add_order("MACHE Laen")
|
||||
u:set_skill('mining', 7)
|
||||
turn_process()
|
||||
assert_equal(0, u:get_item('laen'))
|
||||
assert_equal(100, r:get_resource('laen'))
|
||||
assert_equal(1, f:count_msg_type("error104")) -- requires building
|
||||
|
||||
u.building = building.create(u.region, "mine")
|
||||
u.building.working = true
|
||||
u.building.size = 10
|
||||
turn_process()
|
||||
assert_equal(1, u:get_item('laen'))
|
||||
assert_equal(99, r:get_resource('laen'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_mine_laen_bonus()
|
||||
-- some buildings grant a bonus on the production skill
|
||||
-- i.e. a mine adds +1 to mining
|
||||
function test_greatbow_needs_elf()
|
||||
-- only elves can build a greatbow
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('laen', 100)
|
||||
assert_equal(100, r:get_resource('laen'))
|
||||
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
|
||||
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('weaponsmithing', 5)
|
||||
u:add_item('mallorn', 2)
|
||||
u:add_order("MACHE Elfenbogen")
|
||||
turn_process() -- humans cannot do it
|
||||
assert_equal(1, f:count_msg_type("error117"))
|
||||
assert_equal(0, u:get_item('greatbow'))
|
||||
assert_equal(2, u:get_item('mallorn'))
|
||||
|
||||
u:set_skill('mining', 13)
|
||||
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'))
|
||||
|
||||
turn_end()
|
||||
u.race = 'elf'
|
||||
turn_process() -- but elves can
|
||||
assert_equal(1, u:get_item('greatbow'))
|
||||
assert_equal(0, u:get_item('mallorn'))
|
||||
end
|
||||
|
||||
function test_mine_iron_bonus()
|
||||
-- some buildings grant a bonus on the production skill
|
||||
-- i.e. a mine adds +1 to mining iron
|
||||
--
|
||||
function test_troll_no_quarrying_bonus()
|
||||
-- Trolle kriegen keinen Rohstoffbonus wie in E2
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local f = create_faction('troll')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource("stone", 100)
|
||||
u:set_skill('quarrying', 2) -- +2 Rassenbonus
|
||||
u:add_order("MACHE Steine")
|
||||
turn_process()
|
||||
assert_equal(4, u:get_item('stone'))
|
||||
assert_equal(96, r:get_resource('stone'))
|
||||
end
|
||||
|
||||
function test_dwarf_no_mining_bonus()
|
||||
-- E3: Zwerge verlieren den Eisenabbaubonus
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('dwarf')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('iron', 100)
|
||||
assert_equal(100, r:get_resource('iron'))
|
||||
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
|
||||
u:set_skill('mining', 8) -- +2 skill bonus
|
||||
u:add_order('MACHE Eisen')
|
||||
turn_process()
|
||||
assert_equal(10, u:get_item('iron'))
|
||||
assert_equal(90, r:get_resource('iron'))
|
||||
end
|
||||
|
||||
function test_dwarf_towershield()
|
||||
-- Zwerge können als einzige Rasse Turmschilde, Schuppenpanzer
|
||||
-- und Repetierarmbrüste bauen.
|
||||
local r = region.create(0, 0, 'plain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
u:set_skill('armorer', 4)
|
||||
u:add_item('iron', 1)
|
||||
u:add_order("MACHE Turmschild")
|
||||
turn_process() -- humans cannot do it
|
||||
assert_equal(1, f:count_msg_type("error117"))
|
||||
assert_equal(0, u:get_item('towershield'))
|
||||
assert_equal(1, u:get_item('iron'))
|
||||
|
||||
u.race = 'dwarf'
|
||||
u:set_skill('armorer', 2) -- dwarf has bonus +2
|
||||
turn_process() -- but dwarves can
|
||||
assert_equal(1, u:get_item('towershield'))
|
||||
assert_equal(0, u:get_item('iron'))
|
||||
|
||||
end
|
||||
|
||||
function test_dwarf_scale()
|
||||
-- Zwerge können als einzige Rasse Turmschilde, Schuppenpanzer
|
||||
-- und Repetierarmbrüste bauen.
|
||||
local r = region.create(0, 0, 'plain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
u:set_skill('armorer', 5)
|
||||
u:add_item('iron', 2)
|
||||
u:add_order("MACHE Schuppenpanzer")
|
||||
turn_process() -- humans cannot do it
|
||||
assert_equal(1, f:count_msg_type("error117"))
|
||||
assert_equal(0, u:get_item('scale'))
|
||||
assert_equal(2, u:get_item('iron'))
|
||||
assert_equal(98, r:get_resource('iron'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process()
|
||||
assert_equal(6, u:get_item('iron'))
|
||||
assert_equal(96, r:get_resource('iron'))
|
||||
|
||||
turn_end()
|
||||
u.race = 'dwarf'
|
||||
u:set_skill('armorer', 3) -- dwarf has bonus +2
|
||||
turn_process() -- but dwarves can
|
||||
assert_equal(1, u:get_item('scale'))
|
||||
assert_equal(0, u:get_item('iron'))
|
||||
end
|
||||
|
||||
function test_quarry_bonus()
|
||||
-- a quarry grants +1 to quarrying, and saves 50% stone
|
||||
--
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
function test_dwarf_rep_xbow()
|
||||
-- Zwerge können als einzige Rasse Turmschilde, Schuppenpanzer
|
||||
-- und Repetierarmbrüste bauen.
|
||||
local r = region.create(0, 0, 'plain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('stone', 100)
|
||||
assert_equal(100, r:get_resource('stone'))
|
||||
u:add_order("MACHE Stein")
|
||||
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:set_skill('weaponsmithing', 5)
|
||||
u:add_item('iron', 1)
|
||||
u:add_item('log', 1)
|
||||
u:add_order("MACHE Repetierarmbrust")
|
||||
turn_process() -- humans cannot do it
|
||||
assert_equal(1, f:count_msg_type("error117"))
|
||||
assert_equal(0, u:get_item('rep_crossbow'))
|
||||
assert_equal(1, u:get_item('iron'))
|
||||
assert_equal(1, u:get_item('log'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process()
|
||||
assert_equal(6, u:get_item('stone'))
|
||||
assert_equal(96, r:get_resource('stone'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_smithy_bonus_iron()
|
||||
-- a smithy adds +1 to weaponsmithing, and saves 50% iron
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
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)
|
||||
u:add_order("MACHE Schwert")
|
||||
turn_process() -- building disabled
|
||||
assert_equal(1, u:get_item('sword'))
|
||||
assert_equal(99, u:get_item('iron'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process() -- building active
|
||||
assert_equal(3, u:get_item('sword'))
|
||||
assert_equal(98, u:get_item('iron'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_smithy_bonus_mixed()
|
||||
-- a smithy adds +1 to weaponsmithing, and saves 50% iron
|
||||
-- it does not save any other resource, though.
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
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)
|
||||
u:add_item('log', 100)
|
||||
u:add_order("MACHE Kriegsaxt")
|
||||
turn_process() -- building disabled
|
||||
assert_equal(1, u:get_item('axe'))
|
||||
assert_equal(99, u:get_item('iron'))
|
||||
assert_equal(99, u:get_item('log'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process() -- building active
|
||||
assert_equal(3, u:get_item('axe'))
|
||||
assert_equal(98, u:get_item('iron'))
|
||||
assert_equal(97, u:get_item('log'))
|
||||
|
||||
turn_end()
|
||||
u.race = 'dwarf'
|
||||
u:set_skill('weaponsmithing', 3) -- dwarf has bonus +2
|
||||
turn_process() -- but dwarves can
|
||||
assert_equal(1, u:get_item('rep_crossbow'))
|
||||
assert_equal(0, u:get_item('iron'))
|
||||
assert_equal(0, u:get_item('log'))
|
||||
end
|
||||
|
|
|
@ -824,8 +824,8 @@ function test_golem_use_four_iron()
|
|||
|
||||
process_orders()
|
||||
|
||||
assert_equal(2, u1.number)
|
||||
assert_equal(4, u1:get_item("towershield"))
|
||||
assert_equal(2, u1.number)
|
||||
end
|
||||
|
||||
function test_silver_weight_stops_movement()
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
require "lunit"
|
||||
|
||||
module("tests.production", package.seeall, lunit.testcase )
|
||||
|
||||
function setup()
|
||||
eressea.game.reset()
|
||||
eressea.settings.set("rules.food.flags", "4") -- food is free
|
||||
eressea.settings.set("NewbieImmunity", "0")
|
||||
end
|
||||
|
||||
local function create_faction(race)
|
||||
return faction.create(race, race .. '@eressea.de', "de")
|
||||
end
|
||||
|
||||
function test_laen_needs_mine()
|
||||
-- some resources require a building
|
||||
-- i.e. you cannot create laen without a mine
|
||||
local r = region.create(0, 0, "mountain")
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('laen', 100)
|
||||
u:add_order("MACHE Laen")
|
||||
u:set_skill('mining', 7)
|
||||
turn_process()
|
||||
assert_equal(0, u:get_item('laen'))
|
||||
assert_equal(100, r:get_resource('laen'))
|
||||
assert_equal(1, f:count_msg_type("error104")) -- requires building
|
||||
|
||||
u.building = building.create(u.region, "mine")
|
||||
u.building.working = true
|
||||
u.building.size = 10
|
||||
turn_process()
|
||||
assert_equal(1, u:get_item('laen'))
|
||||
assert_equal(99, r:get_resource('laen'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_mine_laen_bonus()
|
||||
-- some buildings grant a bonus on the production skill
|
||||
-- i.e. a mine adds +1 to mining
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('laen', 100)
|
||||
assert_equal(100, r:get_resource('laen'))
|
||||
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
|
||||
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)
|
||||
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'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_mine_iron_bonus()
|
||||
-- some buildings grant a bonus on the production skill
|
||||
-- i.e. a mine adds +1 to mining iron
|
||||
--
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('iron', 100)
|
||||
assert_equal(100, r:get_resource('iron'))
|
||||
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.building.working = true
|
||||
turn_process()
|
||||
assert_equal(6, u:get_item('iron'))
|
||||
assert_equal(96, r:get_resource('iron'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_quarry_bonus()
|
||||
-- a quarry grants +1 to quarrying, and saves 50% stone
|
||||
--
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
turn_begin()
|
||||
r:set_resource('stone', 100)
|
||||
assert_equal(100, r:get_resource('stone'))
|
||||
u:add_order("MACHE Stein")
|
||||
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.building.working = true
|
||||
turn_process()
|
||||
assert_equal(6, u:get_item('stone'))
|
||||
assert_equal(96, r:get_resource('stone'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_smithy_no_bonus()
|
||||
-- a smithy does not give a bonus to other skills
|
||||
-- five cartmakers make 5 carts, no matter what
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
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
|
||||
assert_equal(5, u:get_item('cart'))
|
||||
assert_equal(75, u:get_item('log'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process() -- building active
|
||||
assert_equal(10, u:get_item('cart'))
|
||||
assert_equal(50, u:get_item('log'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_smithy_bonus_iron()
|
||||
-- a smithy adds +1 to weaponsmithing, and saves 50% iron
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
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)
|
||||
u:add_order("MACHE Schwert")
|
||||
turn_process() -- building disabled
|
||||
assert_equal(1, u:get_item('sword'))
|
||||
assert_equal(99, u:get_item('iron'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process() -- building active
|
||||
assert_equal(3, u:get_item('sword'))
|
||||
assert_equal(98, u:get_item('iron'))
|
||||
|
||||
turn_end()
|
||||
end
|
||||
|
||||
function test_smithy_bonus_mixed()
|
||||
-- a smithy adds +1 to weaponsmithing, and saves 50% iron
|
||||
-- it does not save any other resource, though.
|
||||
local r = region.create(0, 0, 'mountain')
|
||||
local f = create_faction('human')
|
||||
local u = unit.create(f, r, 1)
|
||||
|
||||
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)
|
||||
u:add_item('log', 100)
|
||||
u:add_order("MACHE Kriegsaxt")
|
||||
turn_process() -- building disabled
|
||||
assert_equal(1, u:get_item('axe'))
|
||||
assert_equal(99, u:get_item('iron'))
|
||||
assert_equal(99, u:get_item('log'))
|
||||
|
||||
u.building.working = true
|
||||
turn_process() -- building active
|
||||
assert_equal(3, u:get_item('axe'))
|
||||
assert_equal(98, u:get_item('iron'))
|
||||
assert_equal(97, u:get_item('log'))
|
||||
|
||||
turn_end()
|
||||
end
|
|
@ -12,7 +12,6 @@ follow.c
|
|||
hate.c
|
||||
iceberg.c
|
||||
key.c
|
||||
matmod.c
|
||||
moved.c
|
||||
movement.c
|
||||
dict.c
|
||||
|
|
|
@ -94,7 +94,6 @@ void register_attributes(void)
|
|||
at_register(&at_woodcount);
|
||||
|
||||
/* neue UNIT-Attribute */
|
||||
at_register(&at_fleechance);
|
||||
at_register(&at_siege);
|
||||
at_register(&at_effect);
|
||||
at_register(&at_private);
|
||||
|
@ -103,7 +102,6 @@ void register_attributes(void)
|
|||
at_register(&at_group);
|
||||
|
||||
at_register(&at_building_generic_type);
|
||||
at_register(&at_maxmagicians);
|
||||
at_register(&at_npcfaction);
|
||||
|
||||
/* connection-typen */
|
||||
|
@ -115,6 +113,7 @@ void register_attributes(void)
|
|||
|
||||
at_register(&at_germs);
|
||||
|
||||
at_deprecate("maxmagicians", a_readint); /* factions with differnt magician limits, probably unused */
|
||||
at_deprecate("hurting", a_readint); /* an old arena attribute */
|
||||
at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */
|
||||
at_deprecate("orcification", a_readint); /* required for old datafiles */
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
**/
|
||||
|
||||
#include <platform.h>
|
||||
#include "matmod.h"
|
||||
|
||||
#include <util/attrib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
attrib_type at_matmod = {
|
||||
"matmod",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ATF_PRESERVE
|
||||
};
|
||||
|
||||
attrib *make_matmod(mm_fun function)
|
||||
{
|
||||
attrib *a = a_new(&at_matmod);
|
||||
a->data.f = (void(*)(void))function;
|
||||
return a;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
**/
|
||||
|
||||
#ifndef H_ATTRIBUTE_MATMOD
|
||||
#define H_ATTRIBUTE_MATMOD
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct resource_type;
|
||||
struct unit;
|
||||
typedef int(*mm_fun) (const struct unit * u,
|
||||
const struct resource_type * rtype, int value);
|
||||
|
||||
extern struct attrib_type at_matmod;
|
||||
extern struct attrib *make_matmod(mm_fun function);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -123,13 +123,8 @@ extern "C" {
|
|||
typedef struct weapon {
|
||||
int count, used;
|
||||
const struct weapon_type *type;
|
||||
# ifdef LOMEM
|
||||
int attackskill : 8;
|
||||
int defenseskill : 8;
|
||||
# else
|
||||
int attackskill;
|
||||
int defenseskill;
|
||||
# endif
|
||||
} weapon;
|
||||
|
||||
/*** fighter::person::flags ***/
|
||||
|
|
|
@ -787,7 +787,13 @@ static int tolua_unit_get_curse(lua_State *L) {
|
|||
static int tolua_unit_has_attrib(lua_State *L) {
|
||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
||||
const char *name = tolua_tostring(L, 2, 0);
|
||||
attrib * a = self->attribs ? a_find(self->attribs, at_find(name)) : NULL;
|
||||
attrib * a = self->attribs;
|
||||
while (a) {
|
||||
if (strcmp(a->type->name, name) == 0) {
|
||||
break;
|
||||
}
|
||||
a = a->nexttype;
|
||||
}
|
||||
lua_pushboolean(L, a != NULL);
|
||||
return 1;
|
||||
}
|
||||
|
|
144
src/economy.c
144
src/economy.c
|
@ -468,7 +468,6 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
assert(rc);
|
||||
u_setrace(u, rc);
|
||||
|
||||
#if GUARD_DISABLES_RECRUIT
|
||||
/* this is a very special case because the recruiting unit may be empty
|
||||
* at this point and we have to look at the creating unit instead. This
|
||||
* is done in cansee, which is called indirectly by is_guarded(). */
|
||||
|
@ -476,13 +475,11 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
cmistake(u, ord, 70, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc == get_race(RC_INSECT)) {
|
||||
gamedate date;
|
||||
get_gamedate(turn, &date);
|
||||
if (date.season == 0 && r->terrain != newterrain(T_DESERT)) {
|
||||
#ifdef INSECT_POTION
|
||||
bool usepotion = false;
|
||||
unit *u2;
|
||||
|
||||
|
@ -492,7 +489,6 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
break;
|
||||
}
|
||||
if (!usepotion)
|
||||
#endif
|
||||
{
|
||||
cmistake(u, ord, 98, MSG_EVENT);
|
||||
return;
|
||||
|
@ -802,30 +798,88 @@ void economics(region * r)
|
|||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
static void mod_skill(const resource_mod *mod, skill_t sk, int *skill) {
|
||||
skill_t msk;
|
||||
assert(mod->type == RMT_PROD_SKILL);
|
||||
msk = (skill_t)mod->value.sa[0];
|
||||
if (msk == NOSKILL || msk == sk) {
|
||||
*skill += mod->value.sa[1];
|
||||
}
|
||||
}
|
||||
|
||||
static struct message * get_modifiers(unit *u, skill_t sk, const resource_type *rtype, variant *savep, int *skillp) {
|
||||
struct building *b = inside_building(u);
|
||||
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
||||
int save_n = 1, save_d = 1;
|
||||
int skill = 0;
|
||||
int need_race = 0, need_bldg = 0;
|
||||
resource_mod *mod;
|
||||
|
||||
if (btype && btype->modifiers) {
|
||||
for (mod = btype->modifiers; mod && mod->type != RMT_END; ++mod) {
|
||||
if (mod->type == RMT_PROD_SKILL) {
|
||||
mod_skill(mod, sk, &skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (mod = rtype->modifiers; mod && mod->type != RMT_END; ++mod) {
|
||||
if (mod->btype == NULL || mod->btype == btype) {
|
||||
if (mod->race == NULL || mod->race == u_race(u)) {
|
||||
switch (mod->type) {
|
||||
case RMT_PROD_SAVE:
|
||||
if (savep) {
|
||||
save_n *= mod->value.sa[0];
|
||||
save_d *= mod->value.sa[1];
|
||||
}
|
||||
break;
|
||||
case RMT_PROD_SKILL:
|
||||
mod_skill(mod, sk, &skill);
|
||||
break;
|
||||
case RMT_PROD_REQUIRE:
|
||||
if (mod->race) need_race |= 1;
|
||||
if (mod->btype) need_bldg |= 1;
|
||||
break;
|
||||
default:
|
||||
/* is not a production modifier, ignore it */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mod->type == RMT_PROD_REQUIRE) {
|
||||
if (mod->race) need_race |= 2;
|
||||
if (mod->btype) need_bldg |= 2;
|
||||
}
|
||||
}
|
||||
if (need_race == 2) {
|
||||
return msg_error(u, u->thisorder, 117);
|
||||
}
|
||||
if (need_bldg == 2) {
|
||||
return msg_error(u, u->thisorder, 104);
|
||||
}
|
||||
*skillp = skill;
|
||||
if (savep) *savep = frac_make(save_n, save_d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void manufacture(unit * u, const item_type * itype, int want)
|
||||
{
|
||||
int n;
|
||||
int skill;
|
||||
int minskill = itype->construction->minskill;
|
||||
skill_t sk = itype->construction->skill;
|
||||
message *msg;
|
||||
int skill_mod;
|
||||
|
||||
skill = effskill(u, sk, 0);
|
||||
skill =
|
||||
skillmod(itype->construction->attribs, u, u->region, sk, skill, SMF_PRODUCTION);
|
||||
|
||||
if (skill < 0) {
|
||||
/* an error occured */
|
||||
int err = -skill;
|
||||
cmistake(u, u->thisorder, err, MSG_PRODUCE);
|
||||
msg = get_modifiers(u, sk, itype->rtype, NULL, &skill_mod);
|
||||
if (msg) {
|
||||
ADDMSG(&u->faction->msgs, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (want == 0) {
|
||||
want = maxbuild(u, itype->construction);
|
||||
}
|
||||
n = build(u, itype->construction, 0, want);
|
||||
n = build(u, itype->construction, 0, want, skill_mod);
|
||||
switch (n) {
|
||||
case ENEEDSKILL:
|
||||
ADDMSG(&u->faction->msgs,
|
||||
|
@ -883,37 +937,6 @@ enum {
|
|||
AFL_LOWSKILL = 1 << 1
|
||||
};
|
||||
|
||||
struct message * get_modifiers(unit *u, const resource_mod *mod, variant *savep, int *skillp) {
|
||||
struct building *b = inside_building(u);
|
||||
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
||||
int save_n = 1, save_d = 1;
|
||||
int skill = 0;
|
||||
|
||||
for (; mod->flags != 0; ++mod) {
|
||||
if (mod->btype == NULL || mod->btype == btype) {
|
||||
if (mod->race == NULL || mod->race == u_race(u)) {
|
||||
if (mod->flags & RMF_SAVEMATERIAL) {
|
||||
save_n *= mod->value.sa[0];
|
||||
save_d *= mod->value.sa[1];
|
||||
}
|
||||
if (mod->flags & RMF_SKILL) {
|
||||
skill += mod->value.i;
|
||||
}
|
||||
}
|
||||
} else if (mod->flags & RMF_REQUIREDBUILDING) {
|
||||
return msg_error(u, u->thisorder, 104);
|
||||
}
|
||||
}
|
||||
*skillp = skill;
|
||||
assert(save_n < SHRT_MAX);
|
||||
assert(save_n > SHRT_MIN);
|
||||
assert(save_d < SHRT_MAX);
|
||||
assert(save_d > SHRT_MIN);
|
||||
savep->sa[0] = (short)save_n;
|
||||
savep->sa[1] = (short)save_d;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
||||
{
|
||||
const item_type *itype = resource2item(rtype);
|
||||
|
@ -924,12 +947,14 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|||
const resource_type *rring;
|
||||
int amount, skill, skill_mod = 0;
|
||||
variant save_mod;
|
||||
skill_t sk;
|
||||
|
||||
/* momentan kann man keine ressourcen abbauen, wenn man daf<61>r
|
||||
* Materialverbrauch hat: */
|
||||
assert(itype != NULL && (itype->construction == NULL
|
||||
|| itype->construction->materials == NULL));
|
||||
|
||||
sk = itype->construction->skill;
|
||||
if (!rtype->raw) {
|
||||
int avail = limit_resource(r, rtype);
|
||||
if (avail <= 0) {
|
||||
|
@ -944,7 +969,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|||
}
|
||||
|
||||
if (rtype->modifiers) {
|
||||
message *msg = get_modifiers(u, rtype->modifiers, &save_mod, &skill_mod);
|
||||
message *msg = get_modifiers(u, sk, rtype, &save_mod, &skill_mod);
|
||||
if (msg) {
|
||||
ADDMSG(&u->faction->msgs, msg);
|
||||
return;
|
||||
|
@ -972,17 +997,14 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|||
}
|
||||
}
|
||||
|
||||
assert(itype->construction->skill != 0
|
||||
|| "limited resource needs a required skill for making it");
|
||||
skill = effskill(u, itype->construction->skill, 0);
|
||||
assert(sk != NOSKILL || "limited resource needs a required skill for making it");
|
||||
skill = effskill(u, sk, 0);
|
||||
if (skill == 0) {
|
||||
skill_t sk = itype->construction->skill;
|
||||
add_message(&u->faction->msgs,
|
||||
msg_feedback(u, u->thisorder, "skill_needed", "skill", sk));
|
||||
return;
|
||||
}
|
||||
if (skill < itype->construction->minskill) {
|
||||
skill_t sk = itype->construction->skill;
|
||||
add_message(&u->faction->msgs,
|
||||
msg_feedback(u, u->thisorder, "manufacture_skills",
|
||||
"skill minskill product", sk, itype->construction->minskill,
|
||||
|
@ -1207,7 +1229,7 @@ static void create_potion(unit * u, const potion_type * ptype, int want)
|
|||
if (want == 0) {
|
||||
want = maxbuild(u, ptype->itype->construction);
|
||||
}
|
||||
built = build(u, ptype->itype->construction, 0, want);
|
||||
built = build(u, ptype->itype->construction, 0, want, 0);
|
||||
switch (built) {
|
||||
case ELOWSKILL:
|
||||
case ENEEDSKILL:
|
||||
|
@ -1242,12 +1264,10 @@ static void create_potion(unit * u, const potion_type * ptype, int want)
|
|||
void make_item(unit * u, const item_type * itype, int want)
|
||||
{
|
||||
if (itype->construction && fval(itype->rtype, RTF_LIMITED)) {
|
||||
#if GUARD_DISABLES_PRODUCTION == 1
|
||||
if (is_guarded(u->region, u)) {
|
||||
cmistake(u, u->thisorder, 70, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
allocate_resource(u, itype->rtype, want);
|
||||
}
|
||||
else {
|
||||
|
@ -2020,20 +2040,6 @@ static void expandstealing(region * r, request * stealorders)
|
|||
if (u && u->region == r) {
|
||||
n = get_pooled(u, rsilver, GET_ALL, INT_MAX);
|
||||
}
|
||||
#ifndef GOBLINKILL
|
||||
if (oa[i].type.goblin) { /* Goblin-Spezialklau */
|
||||
int uct = 0;
|
||||
unit *u2;
|
||||
assert(effskill(oa[i].unit, SK_STEALTH) >= 4
|
||||
|| !"this goblin\'s skill is too low");
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (u2->faction == u->faction) {
|
||||
uct += maintenance_cost(u2);
|
||||
}
|
||||
}
|
||||
n -= uct * 2;
|
||||
}
|
||||
#endif
|
||||
if (n > 10 && rplane(r) && (rplane(r)->flags & PFL_NOALLIANCES)) {
|
||||
/* In Questen nur reduziertes Klauen */
|
||||
n = 10;
|
||||
|
|
|
@ -345,7 +345,114 @@ static void test_income(CuTest *tc)
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_make_item(CuTest *tc) {
|
||||
static void test_modify_material(CuTest *tc) {
|
||||
unit *u;
|
||||
struct item_type *itype;
|
||||
resource_type *rtype;
|
||||
resource_mod *mod;
|
||||
|
||||
test_setup();
|
||||
init_resources();
|
||||
|
||||
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||
set_level(u, SK_WEAPONSMITH, 1);
|
||||
|
||||
/* the unit's race gets 2x savings on iron used to produce goods */
|
||||
itype = test_create_itemtype("iron");
|
||||
rtype = itype->rtype;
|
||||
mod = rtype->modifiers = calloc(2, sizeof(resource_mod));
|
||||
mod[0].type = RMT_USE_SAVE;
|
||||
mod[0].value = frac_make(2, 1);
|
||||
mod[0].race = u_race(u);
|
||||
|
||||
itype = test_create_itemtype("sword");
|
||||
make_item(u, itype, 1);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_cannotmake"));
|
||||
CuAssertIntEquals(tc, 0, get_item(u, itype));
|
||||
test_clear_messages(u->faction);
|
||||
itype->construction = calloc(1, sizeof(construction));
|
||||
itype->construction->skill = SK_WEAPONSMITH;
|
||||
itype->construction->minskill = 1;
|
||||
itype->construction->maxsize = 1;
|
||||
itype->construction->reqsize = 1;
|
||||
itype->construction->materials = calloc(2, sizeof(requirement));
|
||||
itype->construction->materials[0].rtype = rtype;
|
||||
itype->construction->materials[0].number = 2;
|
||||
|
||||
set_item(u, rtype->itype, 1); /* 1 iron should get us 1 sword */
|
||||
make_item(u, itype, 1);
|
||||
CuAssertIntEquals(tc, 1, get_item(u, itype));
|
||||
CuAssertIntEquals(tc, 0, get_item(u, rtype->itype));
|
||||
|
||||
u_setrace(u, test_create_race("smurf"));
|
||||
set_item(u, rtype->itype, 2); /* 2 iron should be required now */
|
||||
make_item(u, itype, 1);
|
||||
CuAssertIntEquals(tc, 2, get_item(u, itype));
|
||||
CuAssertIntEquals(tc, 0, get_item(u, rtype->itype));
|
||||
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_modify_skill(CuTest *tc) {
|
||||
unit *u;
|
||||
struct item_type *itype;
|
||||
/* building_type *btype; */
|
||||
resource_type *rtype;
|
||||
resource_mod *mod;
|
||||
|
||||
test_setup();
|
||||
init_resources();
|
||||
|
||||
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||
set_level(u, SK_WEAPONSMITH, 1);
|
||||
|
||||
itype = test_create_itemtype("iron");
|
||||
rtype = itype->rtype;
|
||||
|
||||
itype = test_create_itemtype("sword");
|
||||
make_item(u, itype, 1);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_cannotmake"));
|
||||
CuAssertIntEquals(tc, 0, get_item(u, itype));
|
||||
test_clear_messages(u->faction);
|
||||
itype->construction = calloc(1, sizeof(construction));
|
||||
itype->construction->skill = SK_WEAPONSMITH;
|
||||
itype->construction->minskill = 1;
|
||||
itype->construction->maxsize = -1;
|
||||
itype->construction->reqsize = 1;
|
||||
itype->construction->materials = calloc(2, sizeof(requirement));
|
||||
itype->construction->materials[0].rtype = rtype;
|
||||
itype->construction->materials[0].number = 1;
|
||||
|
||||
/* our race gets a +1 bonus to the item's production skill */
|
||||
mod = itype->rtype->modifiers = calloc(2, sizeof(resource_mod));
|
||||
mod[0].type = RMT_PROD_SKILL;
|
||||
mod[0].value.sa[0] = SK_WEAPONSMITH;
|
||||
mod[0].value.sa[1] = 1;
|
||||
mod[0].race = u_race(u);
|
||||
|
||||
set_item(u, rtype->itype, 2); /* 2 iron should get us 2 swords */
|
||||
make_item(u, itype, 2);
|
||||
CuAssertIntEquals(tc, 2, get_item(u, itype));
|
||||
CuAssertIntEquals(tc, 0, get_item(u, rtype->itype));
|
||||
|
||||
mod[0].value.sa[0] = NOSKILL; /* match any skill */
|
||||
set_item(u, rtype->itype, 2);
|
||||
make_item(u, itype, 2);
|
||||
CuAssertIntEquals(tc, 4, get_item(u, itype));
|
||||
CuAssertIntEquals(tc, 0, get_item(u, rtype->itype));
|
||||
|
||||
|
||||
u_setrace(u, test_create_race("smurf"));
|
||||
set_item(u, rtype->itype, 2);
|
||||
make_item(u, itype, 1); /* only enough skill to make 1 now */
|
||||
CuAssertIntEquals(tc, 5, get_item(u, itype));
|
||||
CuAssertIntEquals(tc, 1, get_item(u, rtype->itype));
|
||||
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
||||
static void test_modify_production(CuTest *tc) {
|
||||
unit *u;
|
||||
struct item_type *itype;
|
||||
const struct resource_type *rt_silver;
|
||||
|
@ -393,7 +500,7 @@ static void test_make_item(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, 290, region_getresource(u->region, rtype)); /* used 10 stones to make 10 stones */
|
||||
|
||||
rtype->modifiers = calloc(2, sizeof(resource_mod));
|
||||
rtype->modifiers[0].flags = RMF_SAVEMATERIAL;
|
||||
rtype->modifiers[0].type = RMT_PROD_SAVE;
|
||||
rtype->modifiers[0].race = u->_race;
|
||||
rtype->modifiers[0].value.sa[0] = (short)(0.5+100*d);
|
||||
rtype->modifiers[0].value.sa[1] = 100;
|
||||
|
@ -413,13 +520,34 @@ static void test_make_item(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, 28, get_item(u, itype));
|
||||
CuAssertIntEquals(tc, 280, region_getresource(u->region, rtype)); /* 50% saving = 3 stones make 6 stones */
|
||||
|
||||
rtype->modifiers[0].flags = RMF_REQUIREDBUILDING;
|
||||
rtype->modifiers[0].type = RMT_PROD_REQUIRE;
|
||||
rtype->modifiers[0].race = NULL;
|
||||
rtype->modifiers[0].btype = bt_get_or_create("mine");
|
||||
|
||||
test_clear_messages(u->faction);
|
||||
make_item(u, itype, 10);
|
||||
CuAssertIntEquals(tc, 28, get_item(u, itype));
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error104"));
|
||||
|
||||
rtype->modifiers[0].type = RMT_PROD_REQUIRE;
|
||||
rtype->modifiers[0].race = test_create_race("smurf");
|
||||
rtype->modifiers[0].btype = NULL;
|
||||
|
||||
test_clear_messages(u->faction);
|
||||
make_item(u, itype, 10);
|
||||
CuAssertIntEquals(tc, 28, get_item(u, itype));
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error117"));
|
||||
|
||||
rtype->modifiers[1].type = RMT_PROD_REQUIRE;
|
||||
rtype->modifiers[1].race = u_race(u);
|
||||
rtype->modifiers[1].btype = NULL;
|
||||
|
||||
test_clear_messages(u->faction);
|
||||
make_item(u, itype, 10);
|
||||
CuAssertPtrEquals(tc, NULL, u->faction->msgs);
|
||||
split_allocations(u->region);
|
||||
CuAssertIntEquals(tc, 38, get_item(u, itype));
|
||||
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -429,7 +557,9 @@ CuSuite *get_economy_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_give_control_building);
|
||||
SUITE_ADD_TEST(suite, test_give_control_ship);
|
||||
SUITE_ADD_TEST(suite, test_income);
|
||||
SUITE_ADD_TEST(suite, test_make_item);
|
||||
SUITE_ADD_TEST(suite, test_modify_production);
|
||||
SUITE_ADD_TEST(suite, test_modify_skill);
|
||||
SUITE_ADD_TEST(suite, test_modify_material);
|
||||
SUITE_ADD_TEST(suite, test_steal_okay);
|
||||
SUITE_ADD_TEST(suite, test_steal_ocean);
|
||||
SUITE_ADD_TEST(suite, test_steal_nosteal);
|
||||
|
|
|
@ -43,6 +43,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/pool.h>
|
||||
#include <kernel/race.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/resources.h>
|
||||
#include <kernel/ship.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include <kernel/terrainid.h>
|
||||
|
@ -67,9 +68,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* attributes inclues */
|
||||
#include <attributes/matmod.h>
|
||||
|
||||
struct building *getbuilding(const struct region *r)
|
||||
{
|
||||
building *b = findbuilding(getid());
|
||||
|
@ -404,16 +402,26 @@ static int required(int size, int msize, int maxneed)
|
|||
return used;
|
||||
}
|
||||
|
||||
static int
|
||||
matmod(const attrib * a, const unit * u, const resource_type * material,
|
||||
int value)
|
||||
static int matmod(const unit * u, const resource_type * rtype, int value)
|
||||
{
|
||||
for (a = a_find((attrib *)a, &at_matmod); a && a->type == &at_matmod;
|
||||
a = a->next) {
|
||||
mm_fun fun = (mm_fun)a->data.f;
|
||||
value = fun(u, material, value);
|
||||
if (value < 0)
|
||||
return value; /* pass errors to caller */
|
||||
if (rtype->modifiers) {
|
||||
variant save = frac_make(1, 1);
|
||||
const struct building_type *btype = NULL;
|
||||
const struct race *rc = u_race(u);
|
||||
resource_mod *mod;
|
||||
if (u->building && inside_building(u)) {
|
||||
btype = u->building->type;
|
||||
}
|
||||
for (mod = rtype->modifiers; mod->type != RMT_END; ++mod) {
|
||||
if (mod->type == RMT_USE_SAVE) {
|
||||
if (!mod->btype || mod->btype == btype) {
|
||||
if (!mod->race || mod->race == rc) {
|
||||
save = frac_mul(save, mod->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return value * save.sa[0] / save.sa[1];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -439,14 +447,8 @@ static int use_materials(unit *u, const construction *type, int n, int completed
|
|||
required(completed + n, type->reqsize, type->materials[c].number);
|
||||
int multi = 1;
|
||||
int canuse = 100; /* normalization */
|
||||
if (building_is_active(u->building) && inside_building(u)) {
|
||||
canuse = matmod(u->building->type->attribs, u, rtype, canuse);
|
||||
}
|
||||
if (canuse < 0) {
|
||||
return canuse; /* pass errors to caller */
|
||||
}
|
||||
canuse = matmod(type->attribs, u, rtype, canuse);
|
||||
|
||||
canuse = matmod(u, rtype, canuse);
|
||||
assert(canuse >= 0);
|
||||
assert(canuse % 100 == 0
|
||||
|| !"only constant multipliers are implemented in build()");
|
||||
multi = canuse / 100;
|
||||
|
@ -468,14 +470,9 @@ static int count_materials(unit *u, const construction *type, int n, int complet
|
|||
const struct resource_type *rtype = type->materials[c].rtype;
|
||||
int need, prebuilt;
|
||||
int canuse = get_pooled(u, rtype, GET_DEFAULT, INT_MAX);
|
||||
canuse = matmod(u, rtype, canuse);
|
||||
|
||||
if (building_is_active(u->building) && inside_building(u)) {
|
||||
canuse = matmod(u->building->type->attribs, u, rtype, canuse);
|
||||
}
|
||||
|
||||
if (canuse < 0)
|
||||
return canuse; /* pass errors to caller */
|
||||
canuse = matmod(type->attribs, u, rtype, canuse);
|
||||
assert(canuse >= 0);
|
||||
if (type->reqsize > 1) {
|
||||
prebuilt =
|
||||
required(completed, type->reqsize, type->materials[c].number);
|
||||
|
@ -503,7 +500,7 @@ static int count_materials(unit *u, const construction *type, int n, int complet
|
|||
* of the first object have already been finished. return the
|
||||
* actual size that could be built.
|
||||
*/
|
||||
int build(unit * u, const construction * ctype, int completed, int want)
|
||||
int build(unit * u, const construction * ctype, int completed, int want, int skill_mod)
|
||||
{
|
||||
const construction *type = ctype;
|
||||
int skills = INT_MAX; /* number of skill points remainig */
|
||||
|
@ -536,17 +533,8 @@ int build(unit * u, const construction * ctype, int completed, int want)
|
|||
if (basesk == 0)
|
||||
return ENEEDSKILL;
|
||||
|
||||
effsk = basesk;
|
||||
if (building_is_active(u->building) && inside_building(u)) {
|
||||
effsk = skillmod(u->building->type->attribs, u, u->region, type->skill,
|
||||
effsk, SMF_PRODUCTION);
|
||||
}
|
||||
effsk = skillmod(type->attribs, u, u->region, type->skill,
|
||||
effsk, SMF_PRODUCTION);
|
||||
if (effsk < 0)
|
||||
return effsk; /* pass errors to caller */
|
||||
if (effsk == 0)
|
||||
return ENEEDSKILL;
|
||||
effsk = basesk + skill_mod;
|
||||
assert(effsk >= 0);
|
||||
|
||||
skills = effsk * u->number;
|
||||
|
||||
|
@ -799,7 +787,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
|
|||
}
|
||||
}
|
||||
}
|
||||
built = build(u, btype->construction, built, n);
|
||||
built = build(u, btype->construction, built, n, 0);
|
||||
|
||||
switch (built) {
|
||||
case ECOMPLETE:
|
||||
|
@ -884,7 +872,7 @@ static void build_ship(unit * u, ship * sh, int want)
|
|||
const construction *construction = sh->type->construction;
|
||||
int size = (sh->size * DAMAGE_SCALE - sh->damage) / DAMAGE_SCALE;
|
||||
int n;
|
||||
int can = build(u, construction, size, want);
|
||||
int can = build(u, construction, size, want, 0);
|
||||
|
||||
if ((n = construction->maxsize - sh->size) > 0 && can > 0) {
|
||||
if (can >= n) {
|
||||
|
|
|
@ -32,8 +32,6 @@ extern "C" {
|
|||
* wichtig
|
||||
*/
|
||||
|
||||
struct xml_tag;
|
||||
|
||||
typedef struct requirement {
|
||||
const struct resource_type *rtype;
|
||||
int number;
|
||||
|
@ -57,14 +55,11 @@ extern "C" {
|
|||
* last level of a building points to NULL, as do objects of
|
||||
* an unlimited size.
|
||||
*/
|
||||
struct attrib *attribs;
|
||||
/* stores skill modifiers and other attributes */
|
||||
|
||||
} construction;
|
||||
|
||||
void free_construction(struct construction *cons);
|
||||
extern int destroy_cmd(struct unit *u, struct order *ord);
|
||||
extern int leave_cmd(struct unit *u, struct order *ord);
|
||||
int destroy_cmd(struct unit *u, struct order *ord);
|
||||
int leave_cmd(struct unit *u, struct order *ord);
|
||||
|
||||
void build_road(struct unit *u, int size, direction_t d);
|
||||
void create_ship(struct unit *u, const struct ship_type *newtype,
|
||||
|
@ -74,16 +69,15 @@ extern "C" {
|
|||
struct building *getbuilding(const struct region *r);
|
||||
struct ship *getship(const struct region *r);
|
||||
|
||||
void reportevent(struct region *r, char *s);
|
||||
|
||||
void shash(struct ship *sh);
|
||||
void sunhash(struct ship *sh);
|
||||
extern int roqf_factor(void);
|
||||
int roqf_factor(void);
|
||||
|
||||
int build(struct unit *u, const construction * ctype, int completed, int want, int skill_mod);
|
||||
int maxbuild(const struct unit *u, const construction * cons);
|
||||
struct message *msg_materials_required(struct unit *u, struct order *ord,
|
||||
const struct construction *ctype, int multi);
|
||||
|
||||
int build(struct unit *u, const construction * ctype, int completed, int want);
|
||||
extern int maxbuild(const struct unit *u, const construction * cons);
|
||||
extern struct message *msg_materials_required(struct unit *u,
|
||||
struct order *ord, const struct construction *ctype, int multi);
|
||||
/** error messages that build may return: */
|
||||
#define ELOWSKILL -1
|
||||
#define ENEEDSKILL -2
|
||||
|
|
|
@ -63,10 +63,10 @@ static void test_build_requires_materials(CuTest *tc) {
|
|||
|
||||
u = setup_build(&bf);
|
||||
set_level(u, SK_ARMORER, 2);
|
||||
CuAssertIntEquals(tc, ENOMATERIALS, build(u, &bf.cons, 0, 1));
|
||||
CuAssertIntEquals(tc, ENOMATERIALS, build(u, &bf.cons, 0, 1, 0));
|
||||
itype = bf.cons.materials[0].rtype->itype;
|
||||
i_change(&u->items, itype, 2);
|
||||
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
|
||||
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1, 0));
|
||||
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
@ -84,12 +84,12 @@ static void test_build_requires_building(CuTest *tc) {
|
|||
bf.cons.btype = btype = bt_get_or_create("hodor");
|
||||
btype->maxcapacity = 1;
|
||||
btype->capacity = 1;
|
||||
CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1));
|
||||
CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0));
|
||||
u->building = test_create_building(u->region, btype);
|
||||
fset(u->building, BLD_MAINTAINED);
|
||||
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
|
||||
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1, 0));
|
||||
btype->maxcapacity = 0;
|
||||
CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1));
|
||||
CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ static void test_build_failure_missing_skill(CuTest *tc) {
|
|||
u = setup_build(&bf);
|
||||
rtype = bf.cons.materials[0].rtype;
|
||||
i_change(&u->items, rtype->itype, 1);
|
||||
CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1));
|
||||
CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1, 0));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ static void test_build_failure_low_skill(CuTest *tc) {
|
|||
rtype = bf.cons.materials[0].rtype;
|
||||
i_change(&u->items, rtype->itype, 1);
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill - 1);
|
||||
CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10));
|
||||
CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10, 0));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ static void test_build_failure_completed(CuTest *tc) {
|
|||
i_change(&u->items, rtype->itype, 1);
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill);
|
||||
bf.cons.maxsize = 1;
|
||||
CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10));
|
||||
CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10, 0));
|
||||
CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
@ -143,19 +143,19 @@ static void test_build_limits(CuTest *tc) {
|
|||
assert(rtype);
|
||||
i_change(&u->items, rtype->itype, 1);
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill);
|
||||
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 10));
|
||||
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 10, 0));
|
||||
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
|
||||
|
||||
scale_number(u, 2);
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill);
|
||||
i_change(&u->items, rtype->itype, 2);
|
||||
CuAssertIntEquals(tc, 2, build(u, &bf.cons, 0, 10));
|
||||
CuAssertIntEquals(tc, 2, build(u, &bf.cons, 0, 10, 0));
|
||||
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
|
||||
|
||||
scale_number(u, 2);
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill * 2);
|
||||
i_change(&u->items, rtype->itype, 4);
|
||||
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 10));
|
||||
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 10, 0));
|
||||
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ static void test_build_with_ring(CuTest *tc) {
|
|||
set_level(u, SK_ARMORER, bf.cons.minskill);
|
||||
i_change(&u->items, rtype->itype, 20);
|
||||
i_change(&u->items, ring, 1);
|
||||
CuAssertIntEquals(tc, 10, build(u, &bf.cons, 0, 20));
|
||||
CuAssertIntEquals(tc, 10, build(u, &bf.cons, 0, 20, 0));
|
||||
CuAssertIntEquals(tc, 10, i_get(u->items, rtype->itype));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
@ -193,16 +193,16 @@ static void test_build_with_potion(CuTest *tc) {
|
|||
i_change(&u->items, rtype->itype, 20);
|
||||
change_effect(u, ptype, 4);
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill);
|
||||
CuAssertIntEquals(tc, 2, build(u, &bf.cons, 0, 20));
|
||||
CuAssertIntEquals(tc, 2, build(u, &bf.cons, 0, 20, 0));
|
||||
CuAssertIntEquals(tc, 18, i_get(u->items, rtype->itype));
|
||||
CuAssertIntEquals(tc, 3, get_effect(u, ptype));
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill * 2);
|
||||
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20));
|
||||
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20, 0));
|
||||
CuAssertIntEquals(tc, 2, get_effect(u, ptype));
|
||||
set_level(u, SK_ARMORER, bf.cons.minskill);
|
||||
scale_number(u, 2); /* OBS: this scales the effects, too: */
|
||||
CuAssertIntEquals(tc, 4, get_effect(u, ptype));
|
||||
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20));
|
||||
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20, 0));
|
||||
CuAssertIntEquals(tc, 2, get_effect(u, ptype));
|
||||
teardown_build(&bf);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
/* attributes includes */
|
||||
#include <attributes/reduceproduction.h>
|
||||
#include <attributes/matmod.h>
|
||||
|
||||
typedef struct building_typelist {
|
||||
struct building_typelist *next;
|
||||
|
@ -99,9 +98,6 @@ bool bt_changed(int *cache)
|
|||
|
||||
void bt_register(building_type * type)
|
||||
{
|
||||
if (type->init) {
|
||||
type->init(type);
|
||||
}
|
||||
selist_push(&buildingtypes, (void *)type);
|
||||
++bt_changes;
|
||||
}
|
||||
|
@ -224,31 +220,6 @@ building *findbuilding(int i)
|
|||
return bfindhash(i);
|
||||
}
|
||||
|
||||
/* ** old building types ** */
|
||||
|
||||
static int sm_smithy(const unit * u, const region * r, skill_t sk, int value)
|
||||
{ /* skillmod */
|
||||
if (sk == SK_WEAPONSMITH || sk == SK_ARMORER) {
|
||||
if (u->region == r)
|
||||
return value + 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static int mm_smithy(const unit * u, const resource_type * rtype, int value)
|
||||
{ /* material-mod */
|
||||
if (rtype == get_resourcetype(R_IRON))
|
||||
return value * 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void init_smithy(struct building_type *bt)
|
||||
{
|
||||
a_add(&bt->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, sm_smithy, 1.0,
|
||||
0));
|
||||
a_add(&bt->attribs, make_matmod(mm_smithy));
|
||||
}
|
||||
|
||||
static const char *castle_name_i(const struct building_type *btype,
|
||||
const struct building *b, int bsize, const char *fname[])
|
||||
{
|
||||
|
@ -915,7 +886,6 @@ int cmp_current_owner(const building * b, const building * a)
|
|||
|
||||
void register_buildings(void)
|
||||
{
|
||||
register_function((pf_generic)init_smithy, "init_smithy");
|
||||
register_function((pf_generic)castle_name, "castle_name");
|
||||
register_function((pf_generic)castle_name_2, "castle_name_2");
|
||||
register_function((pf_generic)fort_name, "fort_name");
|
||||
|
|
|
@ -66,10 +66,10 @@ extern "C" {
|
|||
double auraregen; /* modifier for aura regeneration inside building */
|
||||
struct maintenance *maintenance; /* array of requirements */
|
||||
struct construction *construction; /* construction of 1 building-level */
|
||||
struct resource_mod *modifiers; /* modify production skills */
|
||||
|
||||
const char *(*name) (const struct building_type *,
|
||||
const struct building * b, int size);
|
||||
void(*init) (struct building_type *);
|
||||
void(*age) (struct building *);
|
||||
double(*taxes) (const struct building *, int size);
|
||||
struct attrib *attribs;
|
||||
|
|
|
@ -296,7 +296,6 @@ static void test_btype_defaults(CuTest *tc) {
|
|||
CuAssertPtrEquals(tc, 0, btype->maintenance);
|
||||
CuAssertPtrEquals(tc, 0, btype->construction);
|
||||
CuAssertTrue(tc, !btype->name);
|
||||
CuAssertTrue(tc, !btype->init);
|
||||
CuAssertTrue(tc, !btype->age);
|
||||
CuAssertTrue(tc, !btype->taxes);
|
||||
CuAssertDblEquals(tc, 1.0, btype->auraregen, 0.0);
|
||||
|
|
|
@ -644,7 +644,7 @@ int skill_limit(faction * f, skill_t sk)
|
|||
m = max_magicians(f);
|
||||
}
|
||||
else if (sk == SK_ALCHEMY) {
|
||||
m = config_get_int("rules.maxskills.alchemy", MAXALCHEMISTS);
|
||||
m = config_get_int("rules.maxskills.alchemy", 3);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
@ -752,22 +752,6 @@ int count_maxmigrants(const faction * f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void init_maxmagicians(struct attrib *a)
|
||||
{
|
||||
a->data.i = MAXMAGICIANS;
|
||||
}
|
||||
|
||||
attrib_type at_maxmagicians = {
|
||||
"maxmagicians",
|
||||
init_maxmagicians,
|
||||
NULL,
|
||||
NULL,
|
||||
a_writeint,
|
||||
a_readint,
|
||||
NULL,
|
||||
ATF_UNIQUE
|
||||
};
|
||||
|
||||
int max_magicians(const faction * f)
|
||||
{
|
||||
static int rule, config, rc_cache;
|
||||
|
@ -775,15 +759,9 @@ int max_magicians(const faction * f)
|
|||
int m;
|
||||
|
||||
if (config_changed(&config)) {
|
||||
rule = config_get_int("rules.maxskills.magic", MAXMAGICIANS);
|
||||
rule = config_get_int("rules.maxskills.magic", 3);
|
||||
}
|
||||
m = rule;
|
||||
if (f->attribs) {
|
||||
attrib *a = a_find(f->attribs, &at_maxmagicians);
|
||||
if (a) {
|
||||
m = a->data.i;
|
||||
}
|
||||
}
|
||||
if (rc_changed(&rc_cache)) {
|
||||
rc_elf = get_race(RC_ELF);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,6 @@ extern "C" {
|
|||
struct gamedata;
|
||||
struct selist;
|
||||
|
||||
extern struct attrib_type at_maxmagicians;
|
||||
|
||||
/* faction flags */
|
||||
#define FFL_NEWID (1<<0) /* Die Partei hat bereits einmal ihre no gewechselt */
|
||||
#define FFL_ISNEW (1<<1)
|
||||
|
@ -44,8 +42,8 @@ extern "C" {
|
|||
#define FFL_QUIT (1<<3)
|
||||
#define FFL_CURSED (1<<4) /* you're going to have a bad time */
|
||||
#define FFL_DEFENDER (1<<10)
|
||||
#define FFL_SELECT (1<<18) /* ehemals f->dh, u->dh, r->dh, etc... */
|
||||
#define FFL_NOAID (1<<21) /* Hilfsflag Kampf */
|
||||
#define FFL_SELECT (1<<22) /* ehemals f->dh, u->dh, r->dh, etc... */
|
||||
#define FFL_MARK (1<<23) /* f<>r markierende algorithmen, die das
|
||||
* hinterher auch wieder l<EFBFBD>schen m<EFBFBD>ssen!
|
||||
* (FFL_SELECT muss man vorher initialisieren,
|
||||
|
|
|
@ -90,11 +90,6 @@ extern "C" {
|
|||
const resource_type *findresourcetype(const char *name,
|
||||
const struct locale *lang);
|
||||
|
||||
/* resource-limits for regions */
|
||||
#define RMF_SKILL 0x01 /* int, bonus on resource production skill */
|
||||
#define RMF_SAVEMATERIAL 0x02 /* fraction (sa[0]/sa[1]), multiplier on resource usage */
|
||||
#define RMF_REQUIREDBUILDING 0x04 /* building, required to build */
|
||||
|
||||
/* bitfield values for item_type::flags */
|
||||
#define ITF_NONE 0x0000
|
||||
#define ITF_HERB 0x0001 /* this item is a herb */
|
||||
|
|
|
@ -44,13 +44,8 @@ static struct locale_data *locale_array[MAXLOCALES];
|
|||
|
||||
typedef struct order_data {
|
||||
const char *_str;
|
||||
# ifdef LOMEM
|
||||
int _refcount:20;
|
||||
int _lindex:4;
|
||||
# else
|
||||
int _refcount;
|
||||
int _lindex;
|
||||
# endif
|
||||
keyword_t _keyword;
|
||||
} order_data;
|
||||
|
||||
|
|
|
@ -25,29 +25,29 @@ extern "C" {
|
|||
|
||||
typedef struct rawmaterial {
|
||||
const struct resource_type *rtype;
|
||||
#ifdef LOMEM
|
||||
int amount:16;
|
||||
int level:8;
|
||||
int flags:8;
|
||||
int base:8;
|
||||
int divisor:8;
|
||||
int startlevel:8;
|
||||
#else
|
||||
int amount;
|
||||
int level;
|
||||
int flags;
|
||||
int base;
|
||||
int divisor;
|
||||
int startlevel;
|
||||
#endif
|
||||
struct rawmaterial *next;
|
||||
} rawmaterial;
|
||||
|
||||
/* resource-limits for regions */
|
||||
typedef enum resource_modifier_type {
|
||||
RMT_END, /* array terminator */
|
||||
RMT_PROD_SKILL, /* bonus on resource production skill */
|
||||
RMT_PROD_SAVE, /* fractional multiplier when produced */
|
||||
RMT_PROD_REQUIRE, /* building or race is required to produce this item */
|
||||
RMT_USE_SAVE, /* fractional multiplier when used to manufacture something */
|
||||
} resource_modifier_type;
|
||||
|
||||
typedef struct resource_mod {
|
||||
resource_modifier_type type;
|
||||
variant value;
|
||||
const struct building_type *btype;
|
||||
const struct race *race;
|
||||
unsigned int flags;
|
||||
} resource_mod;
|
||||
|
||||
typedef struct rawmaterial_type {
|
||||
|
|
|
@ -1121,9 +1121,7 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state)
|
|||
ally *sf;
|
||||
|
||||
state &= ~HELP_OBSERVE;
|
||||
#ifndef REGIONOWNERS
|
||||
state &= ~HELP_TRAVEL;
|
||||
#endif
|
||||
state &= HelpMask();
|
||||
|
||||
if (state == 0)
|
||||
|
|
|
@ -62,8 +62,7 @@ attrib_type at_skillmod = {
|
|||
ATF_PRESERVE
|
||||
};
|
||||
|
||||
attrib *make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special,
|
||||
double multiplier, int bonus)
|
||||
attrib *make_skillmod(skill_t sk, skillmod_fun special, double multiplier, int bonus)
|
||||
{
|
||||
attrib *a = a_new(&at_skillmod);
|
||||
skillmod_data *smd = (skillmod_data *)a->data.v;
|
||||
|
@ -72,22 +71,19 @@ attrib *make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special,
|
|||
smd->special = special;
|
||||
smd->bonus = bonus;
|
||||
smd->multiplier = multiplier;
|
||||
smd->flags = flags;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
skillmod(const attrib * a, const unit * u, const region * r, skill_t sk,
|
||||
int value, int flags)
|
||||
skillmod(const unit * u, const region * r, skill_t sk, int value)
|
||||
{
|
||||
const attrib * a = u->attribs;
|
||||
for (a = a_find((attrib *)a, &at_skillmod); a && a->type == &at_skillmod;
|
||||
a = a->next) {
|
||||
skillmod_data *smd = (skillmod_data *)a->data.v;
|
||||
if (smd->skill != NOSKILL && smd->skill != sk)
|
||||
continue;
|
||||
if (flags != SMF_ALWAYS && (smd->flags & flags) == 0)
|
||||
continue;
|
||||
if (smd->special) {
|
||||
value = smd->special(u, r, sk, value);
|
||||
if (value < 0)
|
||||
|
|
|
@ -25,23 +25,11 @@ struct attrib_type;
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* skillmod_data::flags -- wann gilt der modifier? */
|
||||
#define SMF_ALWAYS (1<<0) /* immer */
|
||||
#define SMF_PRODUCTION (1<<1) /* für Produktion - am gebäude, an der einheit */
|
||||
#define SMF_RIDING (1<<2) /* Bonus für berittene - an der rasse */
|
||||
|
||||
typedef struct skill {
|
||||
#ifdef LOMEM
|
||||
int id:8;
|
||||
unsigned int level:8;
|
||||
unsigned int weeks:8;
|
||||
unsigned int old:8;
|
||||
#else
|
||||
int id;
|
||||
skill_t id;
|
||||
int level;
|
||||
int weeks;
|
||||
int old;
|
||||
#endif
|
||||
} skill;
|
||||
|
||||
typedef int(*skillmod_fun) (const struct unit *, const struct region *,
|
||||
|
@ -52,25 +40,23 @@ extern "C" {
|
|||
double multiplier;
|
||||
int number;
|
||||
int bonus;
|
||||
int flags;
|
||||
} skillmod_data;
|
||||
extern struct attrib_type at_skillmod;
|
||||
extern int rc_skillmod(const struct race *rc, const struct region *r,
|
||||
skill_t sk);
|
||||
extern int skillmod(const struct attrib *a, const struct unit *u,
|
||||
const struct region *r, skill_t sk, int value, int flags);
|
||||
extern struct attrib *make_skillmod(skill_t sk, unsigned int flags,
|
||||
skillmod_fun special, double multiplier, int bonus);
|
||||
|
||||
extern int level_days(int level);
|
||||
extern int level(int days);
|
||||
extern struct attrib_type at_skillmod;
|
||||
|
||||
int rc_skillmod(const struct race *rc, const struct region *r, skill_t sk);
|
||||
int skillmod(const struct unit *u, const struct region *r, skill_t sk, int value);
|
||||
struct attrib *make_skillmod(skill_t sk, skillmod_fun special, double multiplier, int bonus);
|
||||
|
||||
int level_days(int level);
|
||||
int level(int days);
|
||||
|
||||
#define skill_level(level) (level)
|
||||
extern void reduce_skill(struct unit *u, skill * sv, unsigned int change);
|
||||
extern int skill_weeks(int level);
|
||||
extern int skill_compare(const skill * sk, const skill * sc);
|
||||
void reduce_skill(struct unit *u, skill * sv, unsigned int change);
|
||||
int skill_weeks(int level);
|
||||
int skill_compare(const skill * sk, const skill * sc);
|
||||
|
||||
extern void sk_set(skill * sv, int level);
|
||||
void sk_set(skill * sv, int level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1333,8 +1333,9 @@ int get_modifier(const unit * u, skill_t sk, int level, const region * r, bool n
|
|||
|
||||
skill += rc_skillmod(u_race(u), r, sk);
|
||||
skill += att_modification(u, sk);
|
||||
|
||||
skill = skillmod(u->attribs, u, r, sk, skill, SMF_ALWAYS);
|
||||
if (u->attribs) {
|
||||
skill = skillmod(u, r, sk, skill);
|
||||
}
|
||||
|
||||
if (fval(u, UFL_HUNGER)) {
|
||||
if (sk == SK_SAILING && skill > 2) {
|
||||
|
@ -1724,13 +1725,13 @@ int unit_max_hp(const unit * u)
|
|||
int h;
|
||||
double p;
|
||||
static int config;
|
||||
static int rule_stamina;
|
||||
static bool rule_stamina;
|
||||
h = u_race(u)->hitpoints;
|
||||
|
||||
if (config_changed(&config)) {
|
||||
rule_stamina = config_get_int("rules.stamina", STAMINA_AFFECTS_HP);
|
||||
rule_stamina = config_get_int("rules.stamina", 1)!=0;
|
||||
}
|
||||
if (rule_stamina & 1) {
|
||||
if (rule_stamina) {
|
||||
p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2;
|
||||
h += (int)(h * p + 0.5);
|
||||
}
|
||||
|
|
|
@ -256,19 +256,19 @@ static void test_skillmod(CuTest *tc) {
|
|||
set_level(u, SK_ARMORER, 5);
|
||||
CuAssertIntEquals(tc, 5, effskill(u, SK_ARMORER, 0));
|
||||
|
||||
a_add(&u->attribs, a = make_skillmod(SK_ARMORER, SMF_ALWAYS, 0, 2.0, 0));
|
||||
a_add(&u->attribs, a = make_skillmod(SK_ARMORER, 0, 2.0, 0));
|
||||
CuAssertIntEquals(tc, 10, effskill(u, SK_ARMORER, 0));
|
||||
a_remove(&u->attribs, a);
|
||||
|
||||
a_add(&u->attribs, a = make_skillmod(NOSKILL, SMF_ALWAYS, 0, 2.0, 0)); /* NOSKILL means any skill */
|
||||
a_add(&u->attribs, a = make_skillmod(NOSKILL, 0, 2.0, 0)); /* NOSKILL means any skill */
|
||||
CuAssertIntEquals(tc, 10, effskill(u, SK_ARMORER, 0));
|
||||
a_remove(&u->attribs, a);
|
||||
|
||||
a_add(&u->attribs, a = make_skillmod(SK_ARMORER, SMF_ALWAYS, 0, 0, 2));
|
||||
a_add(&u->attribs, a = make_skillmod(SK_ARMORER, 0, 0, 2));
|
||||
CuAssertIntEquals(tc, 7, effskill(u, SK_ARMORER, 0));
|
||||
a_remove(&u->attribs, a);
|
||||
|
||||
a_add(&u->attribs, a = make_skillmod(SK_ARMORER, SMF_ALWAYS, cb_skillmod, 0, 0));
|
||||
a_add(&u->attribs, a = make_skillmod(SK_ARMORER, cb_skillmod, 0, 0));
|
||||
CuAssertIntEquals(tc, 8, effskill(u, SK_ARMORER, 0));
|
||||
a_remove(&u->attribs, a);
|
||||
|
||||
|
|
|
@ -120,6 +120,72 @@ static xmlChar *xml_cleanup_string(xmlChar * str)
|
|||
return str;
|
||||
}
|
||||
|
||||
static resource_mod * xml_readmodifiers(xmlXPathObjectPtr result, xmlNodePtr node) {
|
||||
/* reading eressea/resources/resource/modifier */
|
||||
if (result->nodesetval != NULL && result->nodesetval->nodeNr > 0) {
|
||||
int k;
|
||||
resource_mod * modifiers =
|
||||
calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod));
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
xmlChar *propValue;
|
||||
building_type *btype = NULL;
|
||||
const race *rc = NULL;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "race");
|
||||
if (propValue != NULL) {
|
||||
rc = rc_find((const char *)propValue);
|
||||
if (rc == NULL)
|
||||
rc = rc_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
modifiers[k].race = rc;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "building");
|
||||
if (propValue != NULL) {
|
||||
btype = bt_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
modifiers[k].btype = btype;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "type");
|
||||
assert(propValue != NULL);
|
||||
if (strcmp((const char *)propValue, "skill") == 0) {
|
||||
xmlChar *propSkill;
|
||||
skill_t sk = NOSKILL;
|
||||
|
||||
modifiers[k].type = RMT_PROD_SKILL;
|
||||
propSkill = xmlGetProp(node, BAD_CAST "skill");
|
||||
if (propSkill) {
|
||||
sk = findskill((const char *)propSkill);
|
||||
xmlFree(propSkill);
|
||||
}
|
||||
modifiers[k].value.sa[0] = (short)sk;
|
||||
modifiers[k].value.sa[1] = (short)xml_ivalue(node, "value", 0);
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "material") == 0) {
|
||||
modifiers[k].value = xml_fraction(node, "value");
|
||||
modifiers[k].type = RMT_PROD_SAVE;
|
||||
}
|
||||
else {
|
||||
if (strcmp((const char *)propValue, "require") == 0) {
|
||||
modifiers[k].type = RMT_PROD_REQUIRE;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "save") == 0) {
|
||||
modifiers[k].type = RMT_USE_SAVE;
|
||||
modifiers[k].value = xml_fraction(node, "value");
|
||||
}
|
||||
else {
|
||||
log_error("unknown type '%s' for resourcelimit-modifier", (const char *)propValue);
|
||||
}
|
||||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_readrequirements(xmlNodePtr * nodeTab, int nodeNr, requirement ** reqArray)
|
||||
{
|
||||
|
@ -157,7 +223,6 @@ construction ** consPtr)
|
|||
xmlChar *propValue;
|
||||
construction *con;
|
||||
xmlXPathObjectPtr req;
|
||||
int m;
|
||||
skill_t sk = NOSKILL;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "skill");
|
||||
|
@ -193,23 +258,6 @@ construction ** consPtr)
|
|||
xml_readrequirements(req->nodesetval->nodeTab,
|
||||
req->nodesetval->nodeNr, &con->materials);
|
||||
xmlXPathFreeObject(req);
|
||||
|
||||
/* read construction/modifier */
|
||||
xpath->node = node;
|
||||
req = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
||||
for (m = 0; m != req->nodesetval->nodeNr; ++m) {
|
||||
xmlNodePtr node = req->nodesetval->nodeTab[m];
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "function");
|
||||
if (propValue != NULL) {
|
||||
pf_generic foo = get_function((const char *)propValue);
|
||||
a_add(&con->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION,
|
||||
(skillmod_fun)foo, 1.0, 0));
|
||||
xmlFree(propValue);
|
||||
}
|
||||
|
||||
}
|
||||
xmlXPathFreeObject(req);
|
||||
}
|
||||
xpath->node = pushNode;
|
||||
}
|
||||
|
@ -280,6 +328,12 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
if (xml_bvalue(node, "fort", false))
|
||||
btype->flags |= BTF_FORTIFICATION;
|
||||
|
||||
/* reading eressea/buildings/building/modifier */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
||||
btype->modifiers = xml_readmodifiers(result, node);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/buildings/building/construction */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
|
||||
|
@ -305,9 +359,6 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
(const char *(*)(const struct building_type *,
|
||||
const struct building *, int))fun;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "init") == 0) {
|
||||
btype->init = (void(*)(struct building_type *))fun;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "age") == 0) {
|
||||
btype->age = (void(*)(struct building *))fun;
|
||||
}
|
||||
|
@ -344,10 +395,6 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
mt->flags |= MTF_VARIABLE;
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* finally, initialize the new building type */
|
||||
if (btype->init)
|
||||
btype->init(btype);
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(buildings);
|
||||
|
@ -951,58 +998,9 @@ static int parse_resources(xmlDocPtr doc)
|
|||
if (xml_bvalue(node, "limited", false)) {
|
||||
rtype->flags |= RTF_LIMITED;
|
||||
}
|
||||
/* reading eressea/resources/resource/modifier */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
||||
if (result->nodesetval != NULL && result->nodesetval->nodeNr > 0) {
|
||||
rtype->modifiers =
|
||||
calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod));
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
building_type *btype = NULL;
|
||||
const race *rc = NULL;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "race");
|
||||
if (propValue != NULL) {
|
||||
rc = rc_find((const char *)propValue);
|
||||
if (rc == NULL)
|
||||
rc = rc_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
rtype->modifiers[k].race = rc;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "building");
|
||||
if (propValue != NULL) {
|
||||
btype = bt_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
rtype->modifiers[k].btype = btype;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "type");
|
||||
assert(propValue != NULL);
|
||||
if (strcmp((const char *)propValue, "skill") == 0) {
|
||||
rtype->modifiers[k].value.i = xml_ivalue(node, "value", 0);
|
||||
rtype->modifiers[k].flags = RMF_SKILL;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "material") == 0) {
|
||||
rtype->modifiers[k].value = xml_fraction(node, "value");
|
||||
rtype->modifiers[k].flags = RMF_SAVEMATERIAL;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "require") == 0) {
|
||||
xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building");
|
||||
if (propBldg != NULL) {
|
||||
btype = bt_get_or_create((const char *)propBldg);
|
||||
rtype->modifiers[k].btype = btype;
|
||||
rtype->modifiers[k].flags = RMF_REQUIREDBUILDING;
|
||||
xmlFree(propBldg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name);
|
||||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
rtype->modifiers = xml_readmodifiers(result, node);
|
||||
xmlXPathFreeObject(result);
|
||||
/* reading eressea/resources/resource/resourcelimit/function */
|
||||
xpath->node = node;
|
||||
|
|
35
src/laws.c
35
src/laws.c
|
@ -284,31 +284,6 @@ static double peasant_growth_factor(void)
|
|||
return config_get_flt("rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH);
|
||||
}
|
||||
|
||||
#ifdef SLOWLUCK
|
||||
int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
|
||||
int n, births = 0;
|
||||
double factor = peasant_growth_factor();
|
||||
for (n = peasants; n && luck; --n) {
|
||||
int chances = 0;
|
||||
|
||||
if (luck > 0) {
|
||||
--luck;
|
||||
chances += PEASANTLUCK;
|
||||
}
|
||||
|
||||
while (chances--) {
|
||||
if (rng_double() < factor) {
|
||||
/* Only raise with 75% chance if peasants have
|
||||
* reached 90% of maxpopulation */
|
||||
if (peasants / (float)maxp < 0.9 || chance(PEASANTFORCE)) {
|
||||
++births;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return births;
|
||||
}
|
||||
#else
|
||||
static double peasant_luck_factor(void)
|
||||
{
|
||||
return config_get_flt("rules.peasants.peasantluck.factor", PEASANTLUCK);
|
||||
|
@ -331,8 +306,6 @@ int peasant_luck_effect(int peasants, int luck, int maxp, double variance)
|
|||
return births;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void peasants(region * r, int rule)
|
||||
{
|
||||
int peasants = rpeasants(r);
|
||||
|
@ -1610,10 +1583,12 @@ int display_cmd(unit * u, struct order *ord)
|
|||
|
||||
free(*s);
|
||||
if (s2) {
|
||||
*s = strdup(s2);
|
||||
if (strlen(s2) >= DISPLAYSIZE) {
|
||||
(*s)[DISPLAYSIZE] = 0;
|
||||
char * str = strdup(s2);
|
||||
unicode_utf8_trim(str);
|
||||
if (strlen(str) >= DISPLAYSIZE) {
|
||||
str[DISPLAYSIZE-1] = 0;
|
||||
}
|
||||
*s = str;
|
||||
}
|
||||
else {
|
||||
*s = 0;
|
||||
|
|
19
src/main.c
19
src/main.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||
Copyright (c) 1998-2017, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
|
@ -165,7 +165,7 @@ static int verbosity_to_flags(int verbosity) {
|
|||
return flags;
|
||||
}
|
||||
|
||||
static int parse_args(int argc, char **argv, int *exitcode)
|
||||
static int parse_args(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int log_stderr = LOG_CPERROR;
|
||||
|
@ -178,10 +178,10 @@ static int parse_args(int argc, char **argv, int *exitcode)
|
|||
}
|
||||
else if (argi[1] == '-') { /* long format */
|
||||
if (strcmp(argi + 2, "version") == 0) {
|
||||
printf("\n%s PBEM host\n"
|
||||
"Copyright (C) 1996-2005 C. Schlittchen, K. Zedel, E. Rehling, H. Peters.\n\n"
|
||||
"Compilation: " __DATE__ " at " __TIME__ "\nVersion: %s\n\n",
|
||||
game_name(), eressea_version());
|
||||
printf("Eressea version %s, "
|
||||
"Copyright (C) 2017 Enno Rehling et al.\n",
|
||||
eressea_version());
|
||||
return 1;
|
||||
#ifdef USE_CURSES
|
||||
}
|
||||
else if (strcmp(argi + 2, "color") == 0) {
|
||||
|
@ -229,7 +229,6 @@ static int parse_args(int argc, char **argv, int *exitcode)
|
|||
usage(argv[0], NULL);
|
||||
return 1;
|
||||
default:
|
||||
*exitcode = -1;
|
||||
usage(argv[0], argi);
|
||||
return 1;
|
||||
}
|
||||
|
@ -300,8 +299,10 @@ int main(int argc, char **argv)
|
|||
dictionary *d = 0;
|
||||
setup_signal_handler();
|
||||
/* parse arguments again, to override ini file */
|
||||
parse_args(argc, argv, &err);
|
||||
|
||||
err = parse_args(argc, argv);
|
||||
if (err!=0) {
|
||||
return (err>0) ? 0 : err;
|
||||
}
|
||||
d = parse_config(inifile);
|
||||
if (!d) {
|
||||
log_error("could not open ini configuration %s\n", inifile);
|
||||
|
|
|
@ -323,6 +323,7 @@ static void test_newbie_password_message(CuTest *tc) {
|
|||
prepare_report(&ctx, f);
|
||||
CuAssertIntEquals(tc, FFL_PWMSG, f->flags&FFL_PWMSG);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd"));
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -359,6 +360,7 @@ static void test_prepare_travelthru(CuTest *tc) {
|
|||
CuAssertPtrEquals(tc, f2, ctx.f);
|
||||
CuAssertPtrEquals(tc, r1, ctx.first);
|
||||
CuAssertPtrEquals(tc, NULL, ctx.last);
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -384,6 +386,7 @@ static void test_get_addresses(CuTest *tc) {
|
|||
CuAssertTrue(tc, selist_contains(ctx.addresses, f1, NULL));
|
||||
CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL));
|
||||
CuAssertIntEquals(tc, 3, selist_length(ctx.addresses));
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -411,6 +414,7 @@ static void test_get_addresses_fstealth(CuTest *tc) {
|
|||
CuAssertTrue(tc, !selist_contains(ctx.addresses, f1, NULL));
|
||||
CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL));
|
||||
CuAssertIntEquals(tc, 2, selist_length(ctx.addresses));
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -441,6 +445,7 @@ static void test_get_addresses_travelthru(CuTest *tc) {
|
|||
CuAssertTrue(tc, !selist_contains(ctx.addresses, f1, NULL));
|
||||
CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL));
|
||||
CuAssertIntEquals(tc, 2, selist_length(ctx.addresses));
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -523,6 +528,7 @@ static void test_prepare_lighthouse(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode);
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -560,6 +566,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode);
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -585,7 +592,6 @@ static void test_prepare_report(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, seen_unit, r->seen.mode);
|
||||
finish_reports(&ctx);
|
||||
CuAssertIntEquals(tc, seen_none, r->seen.mode);
|
||||
finish_reports(&ctx);
|
||||
|
||||
r = test_create_region(2, 0, 0);
|
||||
CuAssertPtrEquals(tc, r, regions->next);
|
||||
|
@ -593,6 +599,7 @@ static void test_prepare_report(CuTest *tc) {
|
|||
CuAssertPtrEquals(tc, regions, ctx.first);
|
||||
CuAssertPtrEquals(tc, r, ctx.last);
|
||||
CuAssertIntEquals(tc, seen_none, r->seen.mode);
|
||||
finish_reports(&ctx);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
#define ENTERTAINFRACTION 20
|
||||
#define TEACHDIFFERENCE 2
|
||||
#define GUARD_DISABLES_RECRUIT 1
|
||||
#define GUARD_DISABLES_PRODUCTION 1
|
||||
#define RESOURCE_QUANTITY 0.5
|
||||
#define RECRUITFRACTION 40 /* 100/RECRUITFRACTION% */
|
||||
#define COMBAT_TURNS 5
|
||||
|
@ -32,25 +30,13 @@
|
|||
*/
|
||||
#define MUSEUM_MODULE 1
|
||||
|
||||
#undef REGIONOWNERS /* (WIP) region-owner uses HELP_TRAVEL to control entry to region */
|
||||
|
||||
/* experimental gameplay features (that don't affect the savefile) */
|
||||
/* TODO: move these settings to settings.h or into configuration files */
|
||||
#define GOBLINKILL /* Goblin-Spezialklau kann toedlich enden */
|
||||
#define INSECT_POTION /* Spezialtrank fuer Insekten */
|
||||
|
||||
#define TREESIZE (8) /* space used by trees (in #peasants) */
|
||||
|
||||
#define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */
|
||||
|
||||
/* Gebaeudegroesse = Minimalbelagerer */
|
||||
/* Gebaeudegroesse = Minimalbelagerer */
|
||||
#define SIEGEFACTOR 2
|
||||
|
||||
/** Magic */
|
||||
#define MAXMAGICIANS 3
|
||||
#define MAXALCHEMISTS 3
|
||||
|
||||
#define ENCCHANCE 10 /* %-Chance fuer einmalige Zufallsbegegnung */
|
||||
#define BAGCAPACITY 20000 /* soviel passt in einen Bag of Holding */
|
||||
#define PERSON_WEIGHT 1000 /* weight of a "normal" human unit */
|
||||
#define STAMINA_AFFECTS_HP 1<<0
|
||||
|
|
|
@ -556,7 +556,7 @@ int sp_mindblast_temp(struct castorder * co)
|
|||
skill_t sk = random_skill(du, true);
|
||||
if (sk != NOSKILL) {
|
||||
int n = 1 + rng_int() % maxloss;
|
||||
attrib *a = make_skillmod(sk, SMF_ALWAYS, NULL, 0.0, n);
|
||||
attrib *a = make_skillmod(sk, NULL, 0.0, n);
|
||||
/* neat: you can add a whole lot of these to a unit, they stack */
|
||||
a_add(&du->attribs, a);
|
||||
}
|
||||
|
|
|
@ -163,6 +163,8 @@ static void init_learning(struct attrib *a)
|
|||
|
||||
static void done_learning(struct attrib *a)
|
||||
{
|
||||
teaching_info *teach = (teaching_info *)a->data.v;
|
||||
selist_free(teach->teachers);
|
||||
free(a->data.v);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ static void test_attrib_rwstring(CuTest *tc) {
|
|||
data.strm.api->rewind(data.strm.handle);
|
||||
a_readstring(&a, NULL, &data);
|
||||
CuAssertStrEquals(tc, "Hello World", (const char *)a.data.v);
|
||||
a_finalizestring(&a);
|
||||
mstream_done(&data.strm);
|
||||
gamedata_done(&data);
|
||||
test_cleanup();
|
||||
|
|
2
storage
2
storage
|
@ -1 +1 @@
|
|||
Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86
|
||||
Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a
|
|
@ -8,6 +8,7 @@ SET SERVER=%BUILD%\eressea.exe
|
|||
%SERVER% ..\scripts\run-tests.lua
|
||||
%SERVER% -re2 ..\scripts\run-tests-e2.lua
|
||||
%SERVER% -re3 ..\scripts\run-tests-e3.lua
|
||||
%SERVER% --version
|
||||
PAUSE
|
||||
RMDIR /s /q reports
|
||||
DEL score score.alliances datum turn
|
||||
|
|
Loading…
Reference in New Issue