Merge pull request #682 from ennorehling/develop

cmake changes, skillmod rewrite
This commit is contained in:
Enno Rehling 2017-04-08 22:14:53 +02:00 committed by GitHub
commit 1c509485f7
61 changed files with 1181 additions and 669 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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

@ -1 +1 @@
Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1
Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001

1
cmake

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

172
cmake/Modules/FindLua.cmake Normal file
View File

@ -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)

View File

@ -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)

View File

@ -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)

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

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

@ -1 +1 @@
Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258
Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b

View File

@ -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">

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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"/>

View File

@ -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">

View File

@ -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>

View File

@ -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">

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -12,7 +12,6 @@ follow.c
hate.c
iceberg.c
key.c
matmod.c
moved.c
movement.c
dict.c

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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 ***/

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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);
}

View File

@ -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");

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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 */

View File

@ -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;

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();

@ -1 +1 @@
Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86
Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a

View File

@ -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