Merge branch 'master' of github.com:eressea/server

This commit is contained in:
Enno Rehling 2018-02-11 10:10:14 +01:00
commit 2d296d5b2a
350 changed files with 8434 additions and 6785 deletions

View file

@ -7,12 +7,15 @@ script: s/travis-build
addons:
apt:
packages:
- libbsd-dev
- liblua5.1-dev
- libtolua-dev
- libncurses5-dev
- libsqlite3-dev
- libxml2-dev
- valgrind
- cppcheck
- shellcheck
os:
- linux
notifications:

View file

@ -1,25 +1,56 @@
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)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH})
if (MSVC)
include(MSVC)
set (HAVE_STRDUP 0)
set (HAVE_STRLCAT 0)
set (HAVE_LIBBSD 0)
else (MSVC)
INCLUDE (CheckIncludeFile)
CHECK_INCLUDE_FILE(bsd/string.h HAVE_LIBBSD)
INCLUDE (CheckFunctionExists)
CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP)
IF (HAVE_LIBBSD)
INCLUDE (CheckLibraryExists)
CHECK_LIBRARY_EXISTS(bsd strlcat "bsd/string.h" HAVE_STRLCAT)
ELSE (HAVE_LIBBSD)
CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT)
ENDIF(HAVE_LIBBSD)
endif (MSVC)
find_package (SQLite3)
if (MSVC)
find_package (PDCurses)
SET(CURSES_FOUND ${PDCURSES_FOUND})
SET(CURSES_LIBRARIES ${PDCURSES_LIBRARY})
SET(CURSES_INCLUDE_DIR ${PDCURSES_INCLUDE_DIR})
else (MSVC)
find_package (Curses)
find_package (LibXml2)
endif (MSVC)
if (ERESSEA_DB STREQUAL "db")
find_package (BerkeleyDB REQUIRED QUIET)
else()
find_package (SQLite3 REQUIRED QUIET)
endif()
find_package (LibXml2 REQUIRED)
find_package (ToLua REQUIRED)
if (TOLUA_FOUND)
if (${TOLUA_VERSION_STRING} VERSION_GREATER "5.2")
if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2")
find_package (Lua 5.2 REQUIRED)
elseif (${TOLUA_VERSION_STRING} VERSION_GREATER "5.1")
find_package (Lua 5.1 REQUIRED)
else ()
find_package (Lua51 REQUIRED)
endif()
endif(TOLUA_FOUND)
@ -39,3 +70,4 @@ install(DIRECTORY scripts DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PAT
install(DIRECTORY lunit DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua")
install(DIRECTORY share DESTINATION ${CMAKE_INSTALL_PREFIX})

View file

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

View file

@ -0,0 +1,38 @@
# Locate PDCurses library
# This module defines
# PDCURSES_LIBRARIES, the name of the library to link against
# PDCURSES_FOUND, if false, do not try to link to PDCurses
# PDCURSES_INCLUDE_DIR, where to find curses.h
FIND_PATH(PDCURSES_INCLUDE_DIR curses.h
HINTS
$ENV{PDCURSESDIR}
PATH_SUFFIXES include/pdcurses include)
FIND_LIBRARY(PDCURSES_LIBRARY
NAMES pdcurses
HINTS
$ENV{PDCURSESDIR}
PATH_SUFFIXES lib64 lib)
FIND_LIBRARY(PDCURSES_PANEL_LIBRARY
NAMES panel
HINTS
$ENV{PDCURSESDIR}
PATH_SUFFIXES lib64 lib)
IF(PDCURSES_LIBRARY)
SET(PDCURSES_LIBRARIES ${PDCURSES_LIBRARY})
IF(PDCURSES_PANEL_LIBRARY)
SET(PDCURSES_LIBRARIES ${PDCURSES_LIBRARIES} ${PDCURSES_PANEL_LIBRARY})
ENDIF(PDCURSES_PANEL_LIBRARY)
ENDIF(PDCURSES_LIBRARY)
SET(PDCURSES_FOUND "NO")
IF(PDCURSES_INCLUDE_DIR AND PDCURSES_LIBRARY)
# message(STATUS "Found PDCurses library: ${PDCURSES_LIBRARIES}")
# Set the final string here so the GUI reflects the final state.
SET(PDCURSES_LIBRARIES PDCURSES_LIBRARY} CACHE STRING "Where the PDCurses Library can be found")
SET(PDCURSES_FOUND "YES")
ENDIF(PDCURSES_INCLUDE_DIR AND PDCURSES_LIBRARY)

View file

@ -13,7 +13,12 @@
"game.id" : 2,
"orders.default": "work",
"NewbieImmunity": 8,
"modules.wormholes": true,
"modules.market": false,
"modules.astralspace": true,
"modules.wormhole": true,
"modules.iceberg": true,
"modules.volcano": true,
"monsters.spawn.chance": 50,
"entertain.base": 0,
"entertain.perlevel": 20,
"taxing.perlevel": 20,

View file

@ -32,8 +32,10 @@
"database.gameid": 7,
"NewbieImmunity": 4,
"modules.astralspace": false,
"modules.wormholes": false,
"modules.markets": true,
"modules.wormhole": false,
"modules.market": true,
"modules.iceberg": false,
"modules.volcano": true,
"magic.regeneration": 0.75,
"magic.power": 0.5,
"resource.factor": 0.25,
@ -46,8 +48,8 @@
"healing.forest": 2.0,
"hunger.long": false,
"hunger.damage": "1d9+9",
"hunger.demons.skill": true,
"hunger.demons.peasant_tolerance": true,
"hunger.demon.skills": true,
"hunger.demon.peasant_tolerance": true,
"init_spells": 0,
"recruit.allow_merge": true,
"study.expensivemigrants": true,
@ -63,6 +65,7 @@
"rules.stealth.anon_battle": false,
"rules.check_overload": false,
"rules.combat.goblinbonus": 3,
"rules.ship.damage_drift": 0.0,
"rules.alliances": true,
"rules.combat.herospeed": 3,
"rules.combat.demon_vampire": 5,

View file

@ -1,10 +1,9 @@
[game]
email = eressea-server@kn-bremen.de
email = eressea-server@example.com
sender = Eressea Server
name = Eressea
report = reports
verbose = 0
lomem = 0
memcheck = 0
locales = de,en

6
process/Makefile Normal file
View file

@ -0,0 +1,6 @@
SCRIPTS=compress.sh send-bz2-report send-zip-report create-orders \
run-turn sendreports.sh
IGNORE=sendreport.sh
shellcheck: $(SCRIPTS)
shellcheck $(SCRIPTS)

View file

@ -1,24 +1,25 @@
#!/bin/bash
if [ -z $ERESSEA ]; then
if [ -z "$ERESSEA" ]; then
echo "You need to define the \$ERESSEA environment variable to run $0"
exit -2
fi
GAME=$ERESSEA/game-$1
GAME_NAME=$(grep -w name $GAME/eressea.ini | sed 's/.*=\s*//')
GAME="$ERESSEA/game-$1"
GAME_NAME=$(grep -w name "$GAME/eressea.ini" | sed 's/.*=\s*//')
TURN=$2
if [ -z $TURN ]
if [ -z "$TURN" ]
then
TURN=`cat $GAME/turn`
TURN=$(cat "$GAME/turn")
fi
if [ ! -d $GAME/reports ]; then
if [ ! -d "$GAME/reports" ]; then
echo "cannot find reports directory in $GAME"
exit -1
fi
cd $GAME/reports
$ERESSEA/server/bin/compress.py $TURN "$GAME_NAME"
cd -
cd "$GAME/reports" || exit
"$ERESSEA/server/bin/compress.py" "$TURN" "$GAME_NAME"
cd - || exit

View file

@ -3,17 +3,17 @@
GAME=$1
TURN=$2
if [ ! -d $ERESSEA/game-$GAME ] ; then
if [ ! -d "$ERESSEA/game-$GAME" ] ; then
echo "No such game: $GAME"
exit 1
fi
cd $ERESSEA/game-$GAME
cd "$ERESSEA/game-$GAME" || exit
if [ -d orders.dir.$TURN ]; then
if [ -d "orders.dir.$TURN" ]; then
echo "orders.dir.$TURN already exists"
else
mv orders.dir orders.dir.$TURN
mv orders.dir "orders.dir.$TURN"
mkdir -p orders.dir
fi
find "orders.dir.$TURN" -maxdepth 1 -type f -printf "%T+\t%p\n" | sort | cut -f2 | while read -r

View file

@ -1,17 +1,17 @@
#!/bin/sh
GAME=$1
TURN=$2
GAME="$1"
TURN="$2"
if [ ! -d $ERESSEA/game-$GAME ] ; then
if [ ! -d "$ERESSEA/game-$GAME" ] ; then
echo "No such game: $GAME"
exit 1
fi
cd $ERESSEA/game-$GAME
cd "$ERESSEA/game-$GAME" || exit
echo "running turn $TURN, game $GAME"
$ERESSEA/server/bin/eressea -t $TURN run-turn.lua
"$ERESSEA/server/bin/eressea" -t "$TURN" run-turn.lua
mkdir -p log
ln -f eressea.log log/eressea.log.$TURN
ln -f eressea.log "log/eressea.log.$TURN"

View file

@ -1,13 +1,12 @@
#!/bin/bash
if [ -z $ERESSEA ]; then
ERESSEA=`echo $PWD |sed -e 's/\/game.*//'`
if [ -z "$ERESSEA" ]; then
ERESSEA=$(echo "$PWD" |sed -e 's/\/game.*//')
echo "Assuming that ERESSEA=$ERESSEA"
fi
if [ ! -f reports.txt ]; then
echo "need to run $0 from the report direcory"
exit -2
fi
source $HOME/bin/functions.sh
TEMPLATE=report-mail.txt
if [ "$1" == "-Lde" ]
@ -16,7 +15,7 @@ then
shift
fi
if [ "$1" == "-Lde" ]
if [ "$1" == "-Len" ]
then
TEMPLATE=report-mail.en.txt
shift
@ -26,4 +25,6 @@ addr=$1
subj=$2
shift 2
cat $ERESSEA/server/etc/$TEMPLATE | mutt -F $ERESSEA/etc/muttrc -s "$subj" -a $* -- $addr
mutt -F "$ERESSEA/etc/muttrc" -s "$subj" -a "$@" -- "$addr" \
< "$ERESSEA/server/etc/$TEMPLATE"

View file

@ -1,6 +1,7 @@
#!/bin/bash
if [ -z $ERESSEA ]; then
ERESSEA=`echo $PWD |sed -e 's/\/game.*//'`
if [ -z "$ERESSEA" ]; then
ERESSEA=$(echo "$PWD" |sed -e 's/\/game.*//')
echo "Assuming that ERESSEA=$ERESSEA"
fi
if [ ! -f reports.txt ]; then
@ -9,7 +10,7 @@ if [ ! -f reports.txt ]; then
fi
PWD=$(pwd)
GAME=$(dirname $PWD)
GAME=$(dirname "$PWD")
TEMPLATE=report-mail.txt
if [ "$1" == "-Lde" ]
@ -24,13 +25,13 @@ then
shift
fi
if [ -e $GAME/$TEMPLATE ]; then
TEMPLATE=$GAME/$TEMPLATE
if [ -e "$GAME/$TEMPLATE" ]; then
TEMPLATE="$GAME/$TEMPLATE"
else
TEMPLATE=$ERESSEA/server/etc/$TEMPLATE
TEMPLATE="$ERESSEA/server/etc/$TEMPLATE"
fi
if [ ! -e $TEMPLATE ]; then
if [ ! -e "$TEMPLATE" ]; then
echo "no such email template: $TEMPLATE"
exit -3
fi
@ -42,8 +43,7 @@ done
addr=$1
subject=$2
shift 2
mutt -F $ERESSEA/etc/muttrc -s "$subject" -a $* -- $addr < $TEMPLATE
if [ $? -ne 0 ] ; then
echo "Sending failed for email/report: $2/$3"
fi
mutt -F "$ERESSEA/etc/muttrc" -s "$subject" -a "$@" -- "$addr" \
< "$TEMPLATE" || echo "Sending failed for email/report: $2/$3"

View file

@ -1,7 +1,5 @@
#!/bin/bash
## this script takes a backup of a turn.
## usage: backup.sh <turn>
if [ -z $ERESSEA ]; then
echo "You have to define the \$ERESSEA environment variable to run $0"

View file

@ -3,30 +3,23 @@
##
## Prepare the report
if [ -z $ERESSEA ]; then
if [ -z "$ERESSEA" ]; then
echo "You have to define the \$ERESSEA environment variable to run $0"
exit -2
fi
source $HOME/bin/functions.sh
if [ ! -z $1 ]; then
GAME=$ERESSEA/game-$1
if [ ! -z "$1" ]; then
GAME="$ERESSEA/game-$1"
else
GAME=$ERESSEA
fi
cd $GAME/reports || abort "could not chdir to reports directory"
cd "$GAME/reports" || exit
for REPORT in *.sh
do
echo -n "Sending "
basename $REPORT .sh
bash $REPORT
basename "$REPORT" .sh
bash "$REPORT"
done
cd -
if [ -e $GAME/ages.sh ]; then
cd $GAME
./ages.sh
cd -
fi
cd - || exit

View file

@ -1,13 +0,0 @@
<?xml version="1.0"?>
<resources xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- this file contains a lot of armor -->
<xi:include href="eressea://core/armor/plate.xml"/>
<xi:include href="eressea://core/armor/chainmail.xml"/>
<xi:include href="eressea://core/armor/laenmail.xml"/>
<xi:include href="eressea://core/armor/laenshield.xml"/>
<xi:include href="eressea://core/armor/rustychainmail.xml"/>
<xi:include href="eressea://core/armor/rustyshield.xml"/>
<xi:include href="eressea://core/armor/shield.xml"/>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" ?>
<buildings xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="buildings/castle.xml"/>
</buildings>

View file

@ -46,7 +46,7 @@
</resource>
<resource name="magicbag">
<item big="yes" notlost="yes" weight="100" score="6000"/>
<item notlost="yes" big="yes" weight="100" score="6000"/>
</resource>
<resource name="magicherbbag" appearance="">

View file

@ -818,6 +818,10 @@
<string name="section_events">
<text locale="de">Ereignisse</text>
</string>
<string name="section_nr">
<text locale="de">Hinweise</text>
<text locale="en">Notifications</text>
</string>
<string name="section_mail">
<text locale="de">Botschaften</text>
</string>
@ -3699,7 +3703,7 @@
</string>
<string name="sound_out">
<text locale="de">Aushorchen</text>
<text locale="en">sound_out</text>
<text locale="en">Sound out</text>
</string>
<string name="bloodthirst">
<text locale="de">Kriegsgesang</text>
@ -7305,16 +7309,6 @@
<text locale="en">regular spell</text>
</string>
<string name="nr_insectwinter">
<text locale="de">Es ist Winter, und Insekten können nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren.</text>
<text locale="en">It is winter, and insects can only recruit in deserts or with the aid of nestwarmth potions.</text>
</string>
<string name="nr_insectfall">
<text locale="de">Es ist Spätherbst, und diese Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können.</text>
<text locale="en">It is the last week before winter in which insects can still recruit.</text>
</string>
<string name="nr_owner">
<text locale="de">Eigentümer</text>
<text locale="en">Owner</text>
@ -7337,8 +7331,8 @@
</string>
<string name="a_road_percent">
<text locale="de">eine zu %d%% vollendete Straße</text>
<text locale="en">a road that is %d%% complete</text>
<text locale="de">eine zu $percent% vollendete Straße</text>
<text locale="en">a road that is $percent% complete</text>
</string>
<string name="a_road_connection">

View file

@ -1,5 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<messages>
<message name="nr_insectwinter" section="nr">
<text locale="de">Es ist Winter, und Insekten können nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren.</text>
<text locale="en">It is winter, and insects can only recruit in deserts or with the aid of nestwarmth potions.</text>
</message>
<message name="nr_insectfall" section="nr">
<text locale="de">Es ist Spätherbst, und diese Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können.</text>
<text locale="en">It is the last week before winter in which insects can still recruit.</text>
</message>
<message name="newbie_info_game" section="events">
<type>
<arg name="subject" type="string"/>
@ -157,8 +165,8 @@
</message>
<message name="curseinfo::maelstrom">
<type><arg name="id" type="int"/></type>
<text locale="de">Dieser Zauber verursacht einen gigantischen magischen Strudel. Der Mahlstrom wird alle Schiffe, die in seinen Sog geraten, schwer beschädigen. ($int36($id))</text>
<text locale="en">This spell causes a gargantuan vortex. The maelstrom will heavily damage all ships coming into its wake. ($int36($id))</text>
<text locale="de">Der Mahlstrom in dieser Region wird alle Schiffe, die in seinen Sog geraten, schwer beschädigen. ($int36($id))</text>
<text locale="en">The maelstrom in this area will heavily damage all ships coming into its wake. ($int36($id))</text>
</message>
<message name="curseinfo::healingzone">
<type><arg name="id" type="int"/></type>
@ -460,7 +468,7 @@
<text locale="de">"Die Ausrüstung von $unit($unit) scheint unsichtbar. ($int36($id))"</text>
<text locale="en">"$unit($unit)'s equipment is invisible. ($int36($id))"</text>
</message>
<message name="curseinfo::magicresistance_unit" section="events">
<message name="magicresistance_unit" section="events">
<type>
<arg name="unit" type="unit"/>
<arg name="id" type="int"/>
@ -468,7 +476,7 @@
<text locale="de">"Die natürliche Widerstandskraft gegen Verzauberung ist gestärkt. ($int36($id))"</text>
<text locale="en">"The magical resistance has been strengthened. ($int36($id))"</text>
</message>
<message name="curseinfo::magicresistance_building" section="events">
<message name="magicresistance_building" section="events">
<type>
<arg name="building" type="building"/>
<arg name="id" type="int"/>
@ -6807,19 +6815,10 @@
<type>
<arg name="unit" type="unit"/>
<arg name="item" type="resource"/>
<arg name="amount" type="int"/>
</type>
<text locale="de">"$unit($unit) benutzt ein $resource($item,1)."</text>
<text locale="en">"$unit($unit) uses a $resource($item,1)."</text>
</message>
<message name="use_singleperson" section="errors">
<type>
<arg name="unit" type="unit"/>
<arg name="item" type="resource"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - $resource($item,0) können nur von Ein-Personen Einheiten benutzt werden."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - $resource($item,0) can only be used by single-person units."</text>
<text locale="de">"$unit($unit) benutzt $amount $resource($item,$amount)."</text>
<text locale="en">"$unit($unit) uses $amount $resource($item,$amount)."</text>
</message>
<message name="no_attack_after_advance" section="errors">
<type>
@ -7061,7 +7060,7 @@
<text locale="en">"Please send in orders for the next turn if you want to continue playing."</text>
</message>
<message name="newbieimmunity" section="events">
<message name="newbieimmunity" section="nr">
<type>
<arg name="turns" type="int"/>
</type>

View file

@ -14,7 +14,7 @@
</construction>
</ship>
<ship name="dragonship" range="5" storm="1.00" damage="1.00" cargo="100000" cptskill="2" minskill="1" sumskill="50" opensea="yes">
<ship name="dragonship" range="5" storm="1.00" damage="1.00" cargo="100000" cptskill="2" minskill="1" sumskill="50" opensea="yes" speedy="yes">
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="2" maxsize="100">
<requirement type="log" quantity="1"/>

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<resource name="firesword">
<item weight="100">
<weapon minskill="7" magres="0.3" cut="true" skill="melee" offmod="1" defmod="1">
<weapon magres="0.3" cut="true" skill="melee" offmod="1" defmod="1">
<function name="attack" value="attack_firesword"/>
<damage type="rider" value="3d6+10"/>
<damage type="footman" value="3d6+10"/>

View file

@ -4,7 +4,7 @@
<construction skill="weaponsmithing" minskill="5">
<requirement type="mallorn" quantity="2"/>
</construction>
<weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15">
<weapon pierce="true" skill="polearm" offmod="0" defmod="0" magres="0.15">
<damage type="footman" value="1d5+1"/>
<damage type="rider" value="2d6+6"/>
</weapon>

View file

@ -4,7 +4,7 @@
<construction skill="weaponsmithing" minskill="5">
<requirement type="mallorn" quantity="1"/>
</construction>
<weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15">
<weapon pierce="true" skill="polearm" offmod="0" defmod="0" magres="0.15">
<damage type="footman" value="1d10+1"/>
<damage type="rider" value="1d12+3"/>
<modifier type="skill" value="1" riding="true" against_riding="true" against_walking="true" offensive="true"/>

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<resource name="runesword">
<item weight="100" score="2000">
<weapon minskill="7" cut="true" magical="yes" skill="melee" offmod="2" defmod="2">
<weapon cut="true" magical="yes" skill="melee" offmod="2" defmod="2">
<function name="attack" value="attack_firesword"/>
<damage type="rider" value="3d10+10"/>
<damage type="footman" value="3d10+10"/>

View file

@ -33,4 +33,5 @@
<entry spell="big_recruit" level="14" />
<entry spell="calm_riot" level="14" />
<entry spell="incite_riot" level="15" />
<entry spell="summon_familiar" level="9" />
</spellbook>

View file

@ -34,7 +34,6 @@
<entry spell="fish_shield" level="8" />
<entry spell="armor_shield" level="12" />
<entry spell="living_rock" level="13" />
<entry spell="summon_familiar" level="9" />
<entry spell="draigfumbleshield" level="9" />
<entry spell="gwyrrdfumbleshield" level="5" />
<entry spell="cerddorfumbleshield" level="5" />

View file

@ -29,4 +29,5 @@
<entry spell="summondragon" level="11" />
<entry spell="summonshadowlords" level="12" />
<entry spell="unholypower" level="14" />
<entry spell="summon_familiar" level="9" />
</spellbook>

View file

@ -127,7 +127,6 @@
<entry spell="strongwall" level="8" />
<entry spell="summondragon" level="11" />
<entry spell="summonent" level="10" />
<entry spell="summon_familiar" level="9" />
<entry spell="summonfireelemental" level="13" />
<entry spell="summonshadow" level="8" />
<entry spell="summonshadowlords" level="12" />

View file

@ -30,4 +30,5 @@
<entry spell="summonfireelemental" level="13" />
<entry spell="maelstrom" level="15" />
<entry spell="rustweapon" level="3" />
<entry spell="summon_familiar" level="9" />
</spellbook>

View file

@ -30,4 +30,5 @@
<entry spell="bad_dreams" level="10" />
<entry spell="mindblast" level="11" />
<entry spell="create_dreameye" level="14" />
<entry spell="summon_familiar" level="9" />
</spellbook>

View file

@ -282,4 +282,11 @@
</string>
</namespace>
<namespace name="potion">
<string name="p2">
<text locale="en">The "Water of Life" allows living trees to be created from logs. A Knotroot and Elvendear are heated until one can just still keep one's finger in. This is then poured into a jar and allowed to cool slowly. The extract is sufficient for five trees to be grown from logs.</text>
<text locale="de">Das 'Wasser des Lebens' ist in der Lage, aus gefällten Baumstämmen wieder lebende Bäume zu machen. Dazu wird ein knotiger Saugwurz zusammen mit einem Elfenlieb erwärmt, so dass man gerade noch den Finger reinhalten kann. Dies gieße man in ein Gefäß und lasse es langsam abkühlen. Der Extrakt reicht um aus fünf Holzstämmen neue Bäume wachsen zu lassen.</text>
</string>
</namespace>
</strings>

View file

@ -4,7 +4,7 @@
<construction skill="weaponsmithing" minskill="5">
<requirement type="mallorn" quantity="2"/>
</construction>
<weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15">
<weapon pierce="true" skill="polearm" offmod="0" defmod="0" magres="0.15">
<damage type="footman" value="1d5+2"/>
<damage type="rider" value="2d6+7"/>
</weapon>

View file

@ -957,7 +957,7 @@
<skill name="unarmed" modifier="-99"/>
<attack type="1" damage="0d0"/>
</race>
<race name="template" magres="100" maxaura="0.000000" regaura="0.000000" weight="0" capacity="1000" speed="10.000000" hp="10" damage="1d4" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" fly="yes" swim="yes" walk="yes" shapeshift="yes" shapeshiftany="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" recruitunlimited="yes" equipment="yes">
<race name="template" maintenance="0" magres="100" maxaura="0.000000" regaura="0.000000" weight="0" capacity="1000" speed="10.000000" hp="10" damage="1d4" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" fly="yes" swim="yes" walk="yes" shapeshift="yes" shapeshiftany="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" recruitunlimited="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<attack type="1" damage="1d4"/>
</race>

View file

@ -1,89 +0,0 @@
<?xml version="1.0"?>
<resources>
<!-- this file contains herbs that are part of the alchemy system -->
<resource name="h0" appearance="herbbag"><!-- Flachwurz -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h1" appearance="herbbag"><!-- Würziger Wagemut -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h2" appearance="herbbag"><!-- Eulenauge -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h3" appearance="herbbag"><!-- Grüner Spinnerich -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h4" appearance="herbbag"><!-- Blauer Baumringel -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h5" appearance="herbbag"><!-- Elfenlieb -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h6" appearance="herbbag"><!-- Gurgelkraut -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h7" appearance="herbbag"><!-- Knotiger Saugwurz -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h8" appearance="herbbag"><!-- Blasenmorchel -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h9" appearance="herbbag"><!-- Wasserfinder -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h10" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h11" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h12" appearance="herbbag"><!-- Windbeutel -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h13" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h14" appearance="herbbag"><!-- Alraune -->
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h15" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h16" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h17" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h18" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h19" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
<resource name="h20" appearance="herbbag">
<item weight="0" score="10" herb="yes" />
</resource>
</resources>

View file

@ -1,40 +0,0 @@
<?xml version="1.0"?>
<resources>
<!-- this file contains luxury items that are part of the trade system -->
<resource name="balm">
<item weight="200">
<luxury price="4" />
</item>
</resource>
<resource name="spice">
<item weight="200">
<luxury price="5" />
</item>
</resource>
<resource name="jewel">
<item weight="100">
<luxury price="7" />
</item>
</resource>
<resource name="myrrh">
<item weight="200">
<luxury price="5" />
</item>
</resource>
<resource name="oil">
<item weight="300">
<luxury price="3" />
</item>
</resource>
<resource name="silk">
<item weight="300">
<luxury price="6" />
</item>
</resource>
<resource name="incense">
<item weight="200">
<luxury price="4" />
</item>
</resource>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" ?>
<ships xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="ships/boat.xml"/>
</ships>

View file

@ -1,25 +0,0 @@
<?xml version="1.0"?>
<resources xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- this file contains a lot of weapons -->
<xi:include href="eressea://core/weapons/axe.xml"/>
<xi:include href="eressea://core/weapons/bow.xml"/>
<xi:include href="eressea://core/weapons/catapult.xml"/>
<xi:include href="eressea://core/weapons/crossbow.xml"/>
<xi:include href="eressea://core/weapons/firesword.xml"/>
<xi:include href="eressea://core/weapons/greatbow.xml"/>
<xi:include href="eressea://core/weapons/greatsword.xml"/>
<xi:include href="eressea://core/weapons/halberd.xml"/>
<xi:include href="eressea://core/weapons/laensword.xml"/>
<xi:include href="eressea://core/weapons/lance.xml"/>
<xi:include href="eressea://core/weapons/mallornbow.xml"/>
<xi:include href="eressea://core/weapons/mallorncrossbow.xml"/>
<xi:include href="eressea://core/weapons/mallornlance.xml"/>
<xi:include href="eressea://core/weapons/mallornspear.xml"/>
<xi:include href="eressea://core/weapons/runesword.xml"/>
<xi:include href="eressea://core/weapons/rustyaxe.xml"/>
<xi:include href="eressea://core/weapons/rustygreatsword.xml"/>
<xi:include href="eressea://core/weapons/rustyhalberd.xml"/>
<xi:include href="eressea://core/weapons/rustysword.xml"/>
<xi:include href="eressea://core/weapons/spear.xml"/>
<xi:include href="eressea://core/weapons/sword.xml"/>
</resources>

View file

@ -31,15 +31,18 @@ if [ ! -d $ROOT/$BUILD ]; then
fi
echo "build eressea"
CMAKE_ARGS=".."
cd $ROOT/$BUILD
BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//')
if [ "$BRANCH" = "master" ] ; then
VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//')
echo "$BRANCH $VERSION"
cmake -DERESSEA_VERSION="$VERSION" ..
CMAKE_ARGS="-DERESSEA_VERSION=$VERSION ${CMAKE_ARGS}"
else
REV=$(git rev-parse --short HEAD)
cmake -DERESSEA_BUILDNO="$REV" ..
CMAKE_ARGS="-DERESSEA_BUILDNO=$REV $CMAKE_ARGS"
fi
cmake ${CMAKE_ARGS}
make $MAKEOPTS && make test
cd $OLDPWD

View file

@ -1,5 +1,20 @@
#!/bin/sh
ERESSEA_DB=sqlite
if [ -e /usr/include/db.h ] ; then
ERESSEA_DB=db
fi
# Parse command line arguments
while [ ! -z "$1" ] ; do
if [ "$1" = "--with-db" ] ; then
ERESSEA_DB=db
elif [ "$1" = "--with-sqlite" ] ; then
ERESSEA_DB=sqlite
fi
shift 1
done
ROOT=$(git rev-parse --show-toplevel)
[ -z $BUILD ] && BUILD=Debug
[ -z "$CC" ] && [ ! -z `which clang` ] && CC="clang"
@ -15,8 +30,6 @@ mkdir -p $BIN_DIR
rm -f $BUILD
ln -sf $BIN_DIR $BUILD
rm -f CMakeCache.txt
# use anything installed in /opt or /usr
LIBRARY_PATH=/opt/lib:/opt/lib/$MACHINE:/usr/lib/$MACHINE
INCLUDE_PATH=/opt/include:/usr/include
@ -30,30 +43,43 @@ if [ -d $HOME/usr ]; then
fi
DEST=$(dirname $ROOT)/server
ARGS=" -DCMAKE_BUILD_TYPE=$BUILD \
-DCMAKE_LIBRARY_PATH=$LIBRARY_PATH \
-DCMAKE_PREFIX_PATH=$PREFIX_PATH \
-DCMAKE_INSTALL_PREFIX=$DEST"
# -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH
git submodule update --init
LUA_VERSION="5.2"
LUA_DIR=/usr
if [ -d /usr/include/lua5.1 ]; then
LUA_VERSION="5.1"
elif [ -d /usr/local/include/lua5.1 ]; then
export LUA_DIR=/usr/local
LUA_VERSION="5.1"
fi
cat >| $BUILD/config.cmake <<HEREDOC
SET (ERESSEA_DB "$ERESSEA_DB" CACHE STRING "Database driver")
SET (LUA_DIR "$LUA_DIR" CACHE PATH "Lua root path")
SET (CMAKE_BUILD_TYPE "$BUILD" CACHE STRING "")
SET (CMAKE_INSTALL_PREFIX "$DEST" CACHE PATH "")
SET (CMAKE_LIBRARY_PATH "$LIBRARY_PATH" CACHE PATH "")
SET (CMAKE_PREFIX_PATH "$PREFIX_PATH" CACHE PATH "")
HEREDOC
path="$(which tolua)"
if [ "$HAVE_TOLUA" = "0" ] || [ -z $path ] ; then
echo "tolua is not installed, building from source"
cd $ROOT
if [ ! -d tolua ]; then
LUA_VERSION="5.2"
if [ -d /usr/include/lua5.1 ] || [ -d /usr/local/include/lua5.1 ]; then
LUA_VERSION="5.1"
fi
echo "fetching tolua ${LUA_VERSION} from github..."
git clone https://github.com/ennorehling/tolua-${LUA_VERSION}.git tolua
fi
echo "building tolua..."
cd tolua
make
ARGS="$ARGS -DPC_TOLUA_DIR=$ROOT/tolua"
cd -
cat >> $BUILD/config.cmake <<TOLUA
SET(PC_TOLUA_DIR "$ROOT/tolua" CACHE PATH "tolua root")
TOLUA
else
echo "tolua is $path"
fi
@ -62,6 +88,6 @@ unset path
set -e
cd $BIN_DIR
cmake .. $ARGS $*
cmake -C config.cmake .. $*
cd $OLDPWD

View file

@ -10,7 +10,7 @@ done
if [ "$FORCE" != "yes" ] ; then
BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//')
if [ "$BRANCH" != "master" ] ; then
echo "you should only install stable versions from the master branch"
echo "You should only install stable versions from the master branch. Use -f to override."
exit
fi
fi

50
s/setup
View file

@ -11,9 +11,9 @@ done
ERESSEA=$(dirname $ROOT)
function abort() {
echo $1
[ -z $2 ] && exit -1
exit $2 # otherwise
echo $1
[ -z $2 ] && exit -1
exit $2 # otherwise
}
function usage() {
@ -63,34 +63,36 @@ if [ -d $dir ] ; then
[ $force -eq 1 ] || abort "$dir directory exists. Use -f to force"
fi
mkdir -p $dir
cd $dir || abort "could not chdir to game-$game"
cd $dir || abort "could not chdir to $dir"
mkdir -p data reports
function ini_sec() {
if [ $edit -eq 1 ]; then
$INIFILE eressea.ini add $1
else
echo "[$1]" >> eressea.ini
fi
if [ $edit -eq 1 ]; then
$INIFILE eressea.ini add $1
else
echo "[$1]" >> eressea.ini
fi
}
function ini_add() {
if [ $edit -eq 1 ]; then
$INIFILE eressea.ini add $1:$2 $3
else
echo "$2 = $3" >> eressea.ini
fi
if [ $edit -eq 1 ]; then
$INIFILE eressea.ini add $1:$2 $3
else
echo "$2 = $3" >> eressea.ini
fi
}
function ini_start() {
if [ -e eressea.ini ]; then
if [ ! -e $INIFILE ] && [ $edit -eq 1 ]; then
abort "missing editor for eressea.ini. use -n to create new file."
fi
rm -f eressea.ini
edit=0
else
edit=0
fi
touch eressea.ini
if [ -e eressea.ini ]; then
if [ ! -e $INIFILE ] && [ $edit -eq 1 ]; then
abort "missing editor for eressea.ini. use -n to create new file."
fi
rm -f eressea.ini
edit=0
else
edit=0
fi
touch eressea.ini
}
ini_start

View file

@ -16,12 +16,27 @@ cd tests
./run-turn.sh
}
cppcheck_tests() {
cppcheck --version
DIRS="util kernel modules races attributes triggers items tools spells"
IGNORE=""
for DIR in $DIRS ; do
IGNORE="$IGNORE -i src/$DIR"
echo "cppcheck src/$DIR"
cppcheck --quiet -Isrc -Iclibs -Istorage -IcJSON --error-exitcode=1 "src/$DIR"
done
echo "cppcheck src"
cppcheck --quiet -Isrc -Iclibs -Istorage -IcJSON --error-exitcode=1 $IGNORE src
}
set -e
[ -z $BUILD ] && BUILD=Debug ; export BUILD
s/cmake-init
# cppcheck_tests
s/build
cd process
make
cd $ROOT
inifile
s/runtests -V
integration_tests

View file

@ -25,20 +25,6 @@ function callbacks(rules, name, ...)
end
end
local function dbupdate()
update_scores()
if config.dbname then
dbname = config.basepath..'/'..config.dbname
edb = db.open(dbame)
if edb~=nil then
edb:update_factions()
edb:update_scores()
else
eressea.log.error("could not open "..dbname)
end
end
end
local function write_emails(locales)
local files = {}
local key
@ -143,7 +129,6 @@ function process(rules, orders)
end
turn_begin()
init_summary()
-- run the turn:
if eressea.read_orders(orders) ~= 0 then
@ -161,7 +146,7 @@ function process(rules, orders)
turn_end() -- ageing, etc.
write_files(config.locales)
dbupdate()
update_scores()
file = '' .. get_turn() .. '.dat'
if eressea.write_game(file)~=0 then

View file

@ -121,9 +121,11 @@ function test_fleeing_units_can_be_transported()
u1.number = 100
u1:add_order("ATTACKIEREN " .. itoa36(u2.id))
u2.number = 100
u2.name = 'Passagier'
u2:add_order("FAHREN " .. itoa36(u3.id))
u2:add_order("KAEMPFE FLIEHE")
u3.number = 100
u3.name = 'Transporter'
u3:add_order("KAEMPFE FLIEHE")
u3:add_order("TRANSPORT " .. itoa36(u2.id))
u3:add_order("NACH O ")
@ -131,8 +133,8 @@ function test_fleeing_units_can_be_transported()
u3:add_item("horse", u2.number)
u3:add_order("KAEMPFE FLIEHE")
process_orders()
assert_equal(u3.region.id, r1.id, "transporter did not move")
assert_equal(u2.region.id, r1.id, "transported unit did not move")
assert_equal(u3.region, r1, "transporter did not move")
assert_equal(u2.region, r1, "transported unit did not move")
end
function test_plane()
@ -807,7 +809,6 @@ end
function test_swim_and_survive()
local r = region.create(0, 0, "plain")
local f = create_faction('human')
f.nam = "chaos"
local u = unit.create(f, r, 1)
process_orders()
r.terrain = "ocean"
@ -1111,3 +1112,67 @@ function test_build_castle()
assert_equal(1, u.building.size)
assert_equal(u.building.name, "Burg")
end
function test_route()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "route@example.com")
local u = unit.create(f, r1, 1)
u:add_order("ROUTE O W P")
process_orders()
assert_equal("ROUTE West PAUSE Ost", u:get_order(0))
assert_equal(r2, u.region)
end
function test_route_horse()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "route@example.com")
local u = unit.create(f, r1, 1)
u:add_order("ROUTE O P W P")
u:add_item('horse', 1)
u:set_skill('riding', 1)
process_orders()
assert_equal("ROUTE West PAUSE Ost PAUSE", u:get_order(0))
assert_equal(r2, u.region)
end
function test_route_pause()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "route@example.com")
local u = unit.create(f, r1, 1)
u:add_order("ROUTE P O W")
process_orders()
assert_equal("ROUTE P O W", u:get_order(0))
assert_equal(r1, u.region)
end
function test_bug_2393_cart()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "cart@example.com")
local u = unit.create(f, r1, 2)
u:add_order("NACH O")
u:add_item('stone', 2)
u:add_item('horse', 2)
u:add_item('cart', 1)
process_orders()
assert_equal(r1, u.region)
end
function test_immunity_stops_guard()
eressea.settings.set("NewbieImmunity", 2)
local f = faction.create('human')
local r = region.create(0, 0, 'plain')
local u = unit.create(f, r)
u:set_skill('polearm', 2)
u:add_item('lance', 1)
u:add_order('BEWACHE')
process_orders()
assert_equal(f.age, 1)
assert_true(not u.guard)
process_orders()
assert_equal(f.age, 2)
assert_true(u.guard)
end

View file

@ -214,8 +214,8 @@ end
function test_can_give_person()
local r = region.create(0, 0, "plain")
local f1 = faction.create("human", "noreply@eressea.de", "de")
local f2 = faction.create("human", "noreply@eressea.de", "de")
local f1 = faction.create("human")
local f2 = faction.create("human")
local u1 = unit.create(f1, r, 10)
local u2 = unit.create(f2, r, 10)
u1.faction.age = 10
@ -403,3 +403,45 @@ function test_give_to_other_okay()
assert_equal(1, u1.number)
assert_equal(2, u2.number)
end
local function get_name(x)
return x.name .. " (" .. itoa36(x.id) .. ")"
end
function test_faction_stealth()
local f = faction.create('human')
local f2 = faction.create('human')
local r = region.create(0, 0, 'plain')
local u = unit.create(f, r)
local u2 = unit.create(f2, r)
assert_equal(get_name(u) .. ", 1 Mensch, aggressiv.", u:show(f))
assert_equal(get_name(u) .. ", " .. get_name(f) .. ", 1 Mensch.", u:show(f2))
u:add_order("TARNE PARTEI NUMMER " .. itoa36(f2.id))
process_orders()
assert_equal(get_name(u) .. ", " .. get_name(f2) .. ", 1 Mensch, aggressiv.", u:show(f))
assert_equal(get_name(u) .. ", " .. get_name(f2) .. ", 1 Mensch.", u:show(f2))
u:clear_orders()
u:add_order("TARNE PARTEI NUMMER")
process_orders()
assert_equal(get_name(u) .. ", 1 Mensch, aggressiv.", u:show(f))
assert_equal(get_name(u) .. ", " .. get_name(f) .. ", 1 Mensch.", u:show(f2))
end
function test_faction_anonymous()
local f = faction.create('human')
local f2 = faction.create('human')
local r = region.create(0, 0, 'plain')
local u = unit.create(f, r)
local u2 = unit.create(f2, r)
assert_equal(get_name(u) .. ", 1 Mensch, aggressiv.", u:show(f))
assert_equal(get_name(u) .. ", " .. get_name(f) .. ", 1 Mensch.", u:show(f2))
u:add_order("TARNE PARTEI")
process_orders()
assert_equal(get_name(u) .. ", anonym, 1 Mensch, aggressiv.", u:show(f))
assert_equal(get_name(u) .. ", anonym, 1 Mensch.", u:show(f2))
u:clear_orders()
u:add_order("TARNE PARTEI NICHT")
process_orders()
assert_equal(get_name(u) .. ", 1 Mensch, aggressiv.", u:show(f))
assert_equal(get_name(u) .. ", " .. get_name(f) .. ", 1 Mensch.", u:show(f2))
end

View file

@ -1,15 +1,17 @@
require 'tests.e2.e2features'
require 'tests.e2.insects'
require 'tests.e2.spells'
require 'tests.e2.buildings'
require 'tests.e2.production'
require 'tests.e2.adamantium'
require 'tests.e2.undead'
require 'tests.e2.shiplanding'
require 'tests.e2.e2features'
require 'tests.e2.movement'
require 'tests.e2.destroy'
require 'tests.e2.guard'
require 'tests.e2.stealth'
require 'tests.e2.items'
require 'tests.e2.ships'
require 'tests.items'
require 'tests.economy'
require 'tests.orders'

View file

@ -0,0 +1,87 @@
require "lunit"
module("tests.e2.insects", package.seeall, lunit.testcase)
function setup()
eressea.free_game()
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0")
end
function test_move_to_glacier()
local r = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "glacier")
local f = faction.create("insect")
local u = unit.create(f, r, 1)
u:clear_orders()
u:add_order("NACH OST")
process_orders()
assert_equal(r, u.region)
end
function test_sail_to_glacier()
local r = region.create(0, 0, "ocean")
local r2 = region.create(1, 0, "glacier")
local f = faction.create("insect")
local u1 = unit.create(f, r, 1, 'insect')
u1.ship = ship.create(r, 'boat')
u1:set_skill("sailing", 10)
u1:clear_orders()
u1:add_order("NACH OST")
process_orders()
assert_equal(r, u1.region)
end
function test_passenger_into_glacier()
local r = region.create(0, 0, "ocean")
local r2 = region.create(1, 0, "glacier")
local f = faction.create("insect")
local u1 = unit.create(f, r, 1, 'human')
local u2 = unit.create(f, r, 1, 'insect')
u1.ship = ship.create(r, 'boat')
u1:set_skill("sailing", 10)
u1:clear_orders()
u1:add_order("NACH OST")
u2.ship = u1.ship
process_orders()
assert_equal(r2, u2.region)
end
function test_recruit_in_winter()
local r = region.create(0, 0, "plain")
local f = faction.create("insect")
local u = unit.create(f, r, 1)
u:add_item('money', 1000)
u:clear_orders()
u:add_order("REKRUTIERE 1")
set_turn(1010)
process_orders()
assert_equal('winter', get_season(get_turn()))
assert_equal(1, u.number)
u:clear_orders()
u:add_order("REKRUTIERE 1")
set_turn(1011)
process_orders()
assert_equal('spring', get_season(get_turn()))
assert_equal(2, u.number)
end
function test_recruit_in_desert()
local r = region.create(0, 0, "desert")
local f = faction.create("insect")
local u = unit.create(f, r, 1)
u:add_item('money', 1000)
u:clear_orders()
u:add_order("REKRUTIERE 1")
set_turn(1010)
process_orders()
assert_equal('winter', get_season(get_turn()))
assert_equal(2, u.number)
end

View file

@ -11,6 +11,21 @@ function setup()
eressea.settings.set("magic.regeneration.enable", "0")
end
function test_water_of_life()
local r = region.create(0, 0, "plain")
r:set_flag(1, false) -- no mallorn
local f = faction.create("human")
local u = unit.create(f, r, 1)
local trees = r:get_resource('sapling')
u:add_item('p2', 1)
u:add_item('log', 10)
u:add_order("BENUTZE 1 'Wasser des Lebens'")
process_orders()
assert_equal(0, u:get_item('p2'))
assert_equal(0, u:get_item('log'))
assert_equal(trees+10, r:get_resource('sapling'))
end
function test_nestwarmth_insect()
local r = region.create(0, 0, "plain")
local f = faction.create("insect", "noreply@eressea.de", "de")
@ -113,28 +128,31 @@ function test_speedsail()
assert_equal(1, u.ship:get_curse('shipspeed')) -- effect stays forever
end
function test_foolpotion()
function disable_test_foolpotion()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local u = unit.create(f, r, 1)
turn_begin()
u:add_item("p7", 1)
u:add_item('p7', 2)
u:clear_orders()
u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242")
turn_process()
assert_equal(1, u:get_item("p7"))
assert_equal(2, u:get_item('p7'))
assert_equal(1, f:count_msg_type('feedback_unit_not_found'))
local u2 = unit.create(f, r, 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id))
u:add_order("BENUTZEN 2 Dumpfbackenbrot " .. itoa36(u2.id))
turn_process()
assert_equal(1, u:get_item("p7"))
assert_equal(2, u:get_item('p7'))
assert_equal(1, f:count_msg_type('error64'))
u:set_skill("stealth", 1);
u:set_skill("stealth", 1)
u2:set_skill('crossbow', 1)
turn_process()
assert_equal(0, u:get_item("p7"))
assert_equal(0, u:get_item('p7'))
assert_equal(0, u2:effect('p7'))
assert_equal(0, u2:get_skill('crossbow'))
assert_equal(1, f:count_msg_type('givedumb'))
turn_end()
end

View file

@ -111,3 +111,86 @@ function test_follow_ship()
assert_equal(2, u1.region.x)
assert_equal(2, u2.region.x)
end
function assert_nomove(text, u)
if text == nil then text = "" else text = text .. "; " end
local r = u.region
u:add_order("NACH O O")
process_orders()
assert_equal(r, u.region, text .. "unit should never move")
end
function assert_capacity(text, u, silver, r1, r2, rx)
if text == nil then text = "" else text = text .. "; " end
if rx == nil then rx = r1 end
u.region = r1
u:add_item("money", silver-u:get_item("money"))
u:add_order("NACH O O")
process_orders()
assert_equal(r2, u.region, text .. "unit should move")
u.region = r1
u:add_item("money", 1)
process_orders()
assert_equal(rx, u.region, text .. "unit should not move")
end
function test_dwarf_example()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
region.create(2, 0, "plain")
local f = faction.create("dwarf", "dwarf@example.com", "de")
local u = unit.create(f, r1, 5)
u:add_item("horse", 5)
u:add_item("cart", 2)
-- 5 dwarves + 5 horse - 2 carts = 27 + 100 - 80 = 47.00
assert_capacity("dwarves", u, 4700, r1, r2)
u:set_skill("riding", 3)
assert_equal(1, u:eff_skill("riding"))
-- 5 dwarves + 5 horses + 2 carts = 327.00
assert_capacity("riding", u, 32700, r1, r2)
end
function test_troll_example()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local r3 = region.create(2, 0, "plain")
local f = faction.create("troll", "troll@example.com", "de")
local u1 = unit.create(f, r1, 3)
u1:add_item("cart", 1)
u1:clear_orders()
-- 3 trolls - 1 cart = 320, but not allowed?
u1.name='XXX'
assert_nomove("3 trolls", u1)
u1.number = 4
-- 4 trolls + 1 cart = 14320
assert_capacity("1 cart", u1, 14320, r1, r2)
u1:add_item("horse", 4)
-- 4 horses, 4 trolls, 1 cart
assert_capacity("4 horses", u1, 22320, r1, r2)
u1:add_item("cart", 1)
-- 4 horses + 4 trolls + 1 cart - 1 cart
assert_capacity("2 carts", u1, 18320, r1, r2)
u1:set_skill("riding", 3)
assert_equal(1, u1:eff_skill("riding"))
-- 4 horses + 4 trolls + 2 carts = 323.20
assert_capacity("walking", u1, 32320, r1, r2)
-- 4 horses + 2 carts - 4 trolls = 200.00
assert_capacity("riding", u1, 20000, r1, r3, r2)
end

View file

@ -76,3 +76,29 @@ function test_dwarf_mining_bonus()
assert_equal(20, u:get_item('iron'))
assert_equal(84, r:get_resource('iron'))
end
function test_build_boat_low_skill()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "build@example.com")
local u = unit.create(f, r, 1)
u:set_skill("shipcraft", 3) -- humans get +1
u:add_item("log", 10)
u:add_order("MACHE BOOT")
process_orders()
assert_not_equal(nil, u.ship)
assert_equal(4, u.ship.size)
assert_equal(6, u:get_item('log'))
end
function test_build_boat_high_skill()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "build@example.com")
local u = unit.create(f, r, 1)
u:set_skill("shipcraft", 5) -- humans get +1
u:add_item("log", 10)
u:add_order("MACHE BOOT")
process_orders()
assert_not_equal(nil, u.ship)
assert_equal(5, u.ship.size)
assert_equal(5, u:get_item('log'))
end

View file

@ -3,17 +3,22 @@ require "lunit"
module("tests.e2.ships", package.seeall, lunit.testcase)
function setup()
eressea.game.reset()
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.ship.damage.nocrewocean", "0")
eressea.settings.set("rules.ship.damage.nocrew", "0")
eressea.settings.set("rules.ship.drifting", "0")
eressea.settings.set("rules.ship.storms", "0")
end
function test_ship_requires_skill()
local r1 = region.create(0, 0, "ocean")
assert_not_nil(r1)
local r2 = region.create(1, 0, "ocean")
assert_not_nil(r2)
local f = faction.create("human", "fake@eressea.de", "de")
local u1 = unit.create(f, r1, 1)
u1.name = "fake"
u1.name = "fake"
u1.ship = ship.create(r1, "longboat")
u1:clear_orders()
u1:add_order("NACH O")
@ -22,21 +27,51 @@ function test_ship_requires_skill()
assert_equal(r1, u1.region)
end
function no_test_ship_happy_case()
function test_ship_happy_case()
local r1 = region.create(0, 0, "ocean")
local r2 = region.create(1, 0, "ocean")
local f = faction.create("human", "hodor@eressea.de", "de")
local f = faction.create("human")
local u1 = unit.create(f, r1, 1)
local u2 = unit.create(f, r1, 1)
u1.ship = ship.create(r1, "longboat")
u2.ship = u1.ship
u2.ship = u1.ship
u1:clear_orders()
u1:add_order("NACH O")
u1:set_skill("sailing", 1) -- cptskill = 1
u2:set_skill("sailing", 9) -- sumskill = 10
u1:set_skill("sailing", 1) -- cptskill = 1
u2:set_skill("sailing", 9) -- sumskill = 10
process_orders()
assert_equal(r2, u1.ship.region)
assert_equal(r2, u1.region)
assert_equal(r2, u2.region)
end
function test_speedy_ship_slow()
local r1 = region.create(0, 0, 'ocean')
local f = faction.create("human")
local u1 = unit.create(f, r1, 1)
local u2 = unit.create(f, r1, 2)
for x = 1, 10 do
region.create(x, 0, 'ocean')
end
u1.ship = ship.create(r1, "dragonship")
u2.ship = u1.ship
u1:set_skill("sailing", 2) -- cptskill = 2^1
u2:set_skill("sailing", 24) -- sumskill = 50
u1:add_order("NACH O O O O O O O O O O")
process_orders()
assert_equal(5, u1.region.x)
end
function test_speedy_ship_fast()
local r1 = region.create(0, 0, 'ocean')
local f = faction.create("human")
local u1 = unit.create(f, r1, 1)
for x = 1, 10 do
region.create(x, 0, 'ocean')
end
u1.ship = ship.create(r1, "dragonship")
u1:set_skill("sailing", 54) -- cptskill = 2*3^3
u1:add_order("NACH O O O O O O O O O O")
process_orders()
assert_equal(8, u1.region.x)
end

View file

@ -9,6 +9,7 @@ function setup()
eressea.settings.set("NewbieImmunity", "0")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.peasants.growth.factor", "0")
eressea.settings.set("magic.fumble.enable", "0")
end
function test_shapeshift()
@ -102,3 +103,24 @@ function test_earn_silver()
assert_equal(350, u:get_item("money"))
assert_equal(0, r:get_resource("money"))
end
function test_familiar()
local r = region.create(0, 0, "mountain")
local f = faction.create("human")
local u = unit.create(f, r)
local uid = u.id
u.name = 'Hodor'
u.magic = "gwyrrd"
u.race = "elf"
u:set_skill("magic", 10)
u.aura = 200
local err = u:add_spell("summon_familiar")
assert_equal(0, err)
u:add_order("ZAUBERE Vertrauten~rufen")
process_orders()
for u in r.units do
if u.id ~= uid then
assert_equal('Vertrauter von Hodor (' .. itoa36(uid) ..')', u.name)
end
end
end

View file

@ -8,6 +8,28 @@ function setup()
eressea.settings.set("NewbieImmunity", "0")
end
function test_water_of_life()
local r = region.create(0, 0, "plain")
r:set_flag(1, false) -- no mallorn
local f = faction.create("human")
local u = unit.create(f, r, 1)
local trees = r:get_resource('tree')
u:add_item('p2', 1)
u:add_item('log', 10)
u:add_order("BENUTZE 1 'Wasser des Lebens'")
u:add_order("ZEIGE 'Wasser des Lebens'")
process_orders()
assert_equal(0, u:get_item('p2'))
assert_equal(5, u:get_item('log'))
trees = r:get_resource('tree')-trees
if trees~=5 then
init_reports()
write_report(f)
print(f, get_turn())
end
assert_equal(5, trees)
end
function test_give_horses()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")

View file

@ -31,10 +31,9 @@ function setup()
end
function teardown()
set_rule("rules.move.owner_leave")
set_rule("rules.food.flags")
set_rule("rules.ship.drifting")
set_rule("rules.ship.storms")
for k,_ in pairs(settings) do
set_rule(k)
end
end
function test_calendar()
@ -1008,3 +1007,22 @@ function test_give_to_other_fails()
assert_equal(2, u1.number)
assert_equal(1, u2.number)
end
function test_demons_using_mallornlance()
-- bug 2392
set_rule("skillchange.demon.up", "0")
set_rule("NewbieImmunity", "0")
local r = region.create(0, 0, "plain")
local f = faction.create('goblin')
local u = unit.create(f, r, 1, 'demon')
u:set_skill('taxation', 1)
u:set_skill('polearm', 1)
u:add_item('mallornlance', 1)
u:add_order('BEWACHE')
process_orders()
if not u.guard then
init_reports()
write_report(f)
end
assert_true(u.guard)
end

108
scripts/tests/hunger.lua Normal file
View file

@ -0,0 +1,108 @@
require "lunit"
module("tests.hunger", package.seeall, lunit.testcase)
function setup()
eressea.free_game()
conf = [[{
"races": {
"demon": {
"maintenance": 10,
"hp" : 50
},
"insect": {
"maintenance": 10,
"hp" : 50
}
},
"terrains" : {
"plain": { "flags" : [ "land", "walk" ] },
"glacier": { "flags" : [ "arctic", "land", "walk" ] }
}
}]]
eressea.config.reset()
eressea.config.parse(conf)
eressea.settings.set("rules.peasants.growth.factor", "0")
eressea.settings.set("rules.peasantluck.growth.factor", "0")
eressea.settings.set("hunger.damage", "10")
end
function test_maintenance()
local r = region.create(0, 0, "plain")
local f = faction.create("insect")
local u = unit.create(f, r, 2)
local flags = u.flags
u:add_item('money', 100)
process_orders()
assert_equal(flags, u.flags, "should not be hungry")
assert_equal(80, u:get_item('money'), "should pay maintenance")
assert_equal(100, u.hp, "should not take damage")
end
function test_demons_eat_peasants()
local r = region.create(0, 0, "plain")
local f = faction.create("demon")
local u = unit.create(f, r, 10)
local flags = u.flags
u:add_item('money', 120)
r.peasants = 3
process_orders()
assert_equal(20, u:get_item('money'))
assert_equal(2, r.peasants)
assert_equal(flags, u.flags)
assert_equal(500, u.hp)
end
function test_demons_need_peasants()
local r = region.create(0, 0, "plain")
local f = faction.create("demon")
local u = unit.create(f, r, 1)
local flags = u.flags
u:add_item('money', 100)
eressea.settings.set("hunger.demon.peasant_tolerance", "0")
r.peasants = 0
process_orders()
assert_equal(90, u:get_item('money')) -- use money even if no peasants
assert_equal(flags+2048, u.flags)
assert_equal(40, u.hp)
eressea.settings.set("hunger.demon.peasant_tolerance", "1")
u.flags = flags
u.hp = 50
process_orders()
assert_equal(80, u:get_item('money')) -- use money even if no peasants
assert_equal(flags+2048, u.flags)
assert_equal(50, u.hp)
assert_equal(0, r.peasants)
end
function test_insects_hunger_in_glacier()
-- bug 2389
local r = region.create(0, 0, "plain")
local f = faction.create("insect")
local u = unit.create(f, r, 1)
local flags = u.flags
u:add_item('money', 1000)
-- eressea.settings.set("hunger.insect.cold", "1") -- default
process_orders()
assert_equal(flags, u.flags)
assert_equal(50, u.hp)
r.terrain = 'glacier'
process_orders()
assert_equal(flags+2048, u.flags)
assert_equal(40, u.hp)
u.flags = u.flags-2048
u.hp = 50
eressea.settings.set("hunger.insect.cold", "0")
process_orders()
assert_equal(flags, u.flags)
assert_equal(50, u.hp)
end

View file

@ -9,3 +9,4 @@ require 'tests.settings'
require 'tests.study'
require 'tests.laws'
require 'tests.bindings'
require 'tests.hunger'

View file

@ -5,48 +5,42 @@ module("tests.items", package.seeall, lunit.testcase )
function setup()
eressea.free_game()
eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0")
eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.ship.storms", "0")
eressea.settings.set("rules.encounters", "0")
eressea.settings.set("magic.regeneration.enable", "0")
end
function test_mistletoe_okay()
function test_use_mistletoe()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
turn_begin()
u:add_item('mistletoe', 2)
u:clear_orders()
u:add_order("BENUTZEN 1 Mistelzweig")
assert_false(u:has_attrib('fleechance'))
turn_process()
assert_true(u:has_attrib('fleechance'))
u:add_item('mistletoe', 3)
u:add_order("BENUTZEN 2 Mistelzweig")
process_orders()
assert_equal(2, u:effect('mistletoe'))
assert_equal(1, u:get_item('mistletoe'))
assert_equal(1, f:count_msg_type('use_item'))
turn_end()
end
function test_mistletoe_fail()
function test_mistletoe_survive()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local u = unit.create(f, r, 1)
turn_begin()
u:add_item('mistletoe', 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Mistelzweig")
assert_false(u:has_attrib('fleechance'))
u.number = 2
turn_process()
assert_false(u:has_attrib('fleechance'))
assert_equal(1, u:get_item('mistletoe'))
assert_equal(1, f:count_msg_type('use_singleperson'))
turn_end()
local u = unit.create(faction.create("human"), r, 1)
local u2 = unit.create(faction.create("human"), r, 1)
local uno = u.id
u:add_item('mistletoe', 2)
u:add_order("BENUTZEN 2 Mistelzweig")
u2:add_order('ATTACKIERE ' .. itoa36(uno))
process_orders()
u = get_unit(uno)
assert_not_nil(u)
assert_equal(1, u:effect('mistletoe'))
end
function test_dreameye()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
u:add_item("dreameye", 2)
u:clear_orders()
@ -63,7 +57,7 @@ end
function test_manacrystal()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
u:add_item("manacrystal", 2)
u:clear_orders()
@ -81,7 +75,7 @@ end
function test_skillpotion()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
u:add_item("skillpotion", 2)
u:clear_orders()
@ -93,7 +87,7 @@ end
function test_studypotion()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
turn_begin()
u:add_item("studypotion", 2)
@ -109,7 +103,7 @@ end
function test_antimagic()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
turn_begin()
@ -129,7 +123,7 @@ end
function test_ointment()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
local hp = u.hp
u.hp = 1
@ -142,14 +136,35 @@ function test_ointment()
assert_equal(hp, u.hp)
end
function test_use_domore()
local r = region.create(0, 0, "plain")
local f = faction.create("human")
local u = unit.create(f, r, 1)
u:add_item("p3", 1)
u:add_order("BENUTZEN 1 Schaffenstrunk")
process_orders()
assert_equal(10, u:effect("p3"))
assert_equal(0, u:get_item("p3"))
assert_equal(1, f:count_msg_type('usepotion'))
u:clear_orders()
u:set_skill('weaponsmithing', 3)
u:add_item("iron", 2)
u:add_order("MACHEN Schwert")
process_orders()
assert_equal(9, u:effect("p3"))
assert_equal(0, u:get_item("iron"))
assert_equal(2, u:get_item("sword"))
end
function test_bloodpotion_demon()
local r = region.create(0, 0, "plain")
local f = faction.create("demon", "noreply@eressea.de", "de")
local f = faction.create("demon")
local u = unit.create(f, r, 1)
u:add_item("peasantblood", 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Bauernblut")
process_orders()
assert_equal(100, u:effect('peasantblood'))
assert_equal(0, u:get_item("peasantblood"))
assert_equal(1, f:count_msg_type('usepotion'))
assert_equal("demon", u.race)
@ -157,12 +172,13 @@ end
function test_bloodpotion_other()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "noreply@eressea.de", "de")
local f = faction.create("human")
local u = unit.create(f, r, 1)
u:add_item("peasantblood", 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Bauernblut")
process_orders()
assert_equal(0, u:effect('peasantblood'))
assert_equal(0, u:get_item("peasantblood"))
assert_equal(1, f:count_msg_type('usepotion'))
assert_equal("smurf", u.race)

View file

@ -47,7 +47,8 @@ function test_give()
assert_not_equal(5, u2:get_item("money"))
end
function test_make_temp()
function disable_test_make_temp()
-- disabled because of TOLUA_ORDERS_CLOSURE
u:add_order("MACHE TEMP 123 'Herpderp'")
u:add_order("// this comment will be copied")
u:add_order("ENDE")

View file

@ -2,15 +2,15 @@ require "lunit"
module("tests.process", package.seeall, lunit.testcase)
local u, r, f,turn
local u, r, f, turn
function setup()
eressea.free_game()
turn = get_turn()
r = region.create(0, 0, "plain")
f = faction.create("human", "bernd@eressea.de", "de")
u = unit.create(f, r, 1)
u:add_item("money", 10)
turn = get_turn()
end
local function file_exists(name)
@ -31,9 +31,6 @@ function test_process_turn()
assert_equal(0, write_reports())
assert_equal(0, eressea.write_game("test.dat"))
assert_file("data/test.dat")
assert_file("reports/" .. get_turn() .. "-ii.nr", false)
assert_file("reports/" .. get_turn() .. "-ii.cr", false)
assert_file("reports/" .. get_turn() .. "-ii.txt", false)
assert_file("reports/" .. get_turn() .. "-777.nr")
assert_file("reports/" .. get_turn() .. "-777.cr")
assert_file("reports/" .. get_turn() .. "-777.txt")

View file

@ -81,3 +81,53 @@ function test_create_dreameye()
assert_equal(amax - 5, u.aura_max)
end
function test_appeasement_can_move()
local u1, u2, r1, r2, uno
r1 = region.create(0, 0, 'plain')
r2 = region.create(1, 0, 'plain')
u2 = unit.create(faction.create('human'), r1, 1)
u2.race = 'elf'
u2.name = 'Angsthase'
u2.magic = 'gwyrrd'
u2:set_skill('magic', 5)
u2.aura = 10
u2:add_spell('appeasement')
u2:add_order('NACH O')
u2:add_order('KAMPFZAUBER STUFE 1 Friedenslied')
uno = u2.id
u1 = unit.create(faction.create('human'), r1, 1)
u1:set_skill('polearm', 5)
u1:add_order('ATTACKIERE ' .. itoa36(uno))
process_orders()
u2 = get_unit(uno)
assert_not_nil(u2)
assert_equal(r2, u2.region)
assert_equal(5, u2.status)
end
function test_appeasement_break_guard()
local u1, u2, r1, r2, uno
r1 = region.create(0, 0, 'plain')
r2 = region.create(1, 0, 'plain')
u2 = unit.create(faction.create('human'), r1, 1)
u2.race = 'elf'
u2.name = 'Angsthase'
u2.magic = 'gwyrrd'
u2.guard = true
u2.status = 1
u2:set_skill('magic', 5)
u2.aura = 10
u2:add_spell('appeasement')
u2:add_order('BEWACHE')
u2:add_order('KAMPFZAUBER STUFE 1 Friedenslied')
uno = u2.id
u1 = unit.create(faction.create('human'), r1, 1)
u1:set_skill('polearm', 5)
u1:add_order('ATTACKIERE ' .. itoa36(uno))
process_orders()
u2 = get_unit(uno)
assert_not_nil(u2)
assert_equal(r1, u2.region)
assert_equal(5, u2.status)
assert_equal(false, u2.guard)
end

3
share/magic Normal file
View file

@ -0,0 +1,3 @@
4 lelong 0x00000002
>0 leshort x eressea data version %d

View file

@ -5,9 +5,8 @@ include_directories (${CMAKE_CURRENT_SOURCE_DIR})
include_directories (${CJSON_INCLUDE_DIR})
include_directories (${CLIBS_INCLUDE_DIR})
include_directories (${STORAGE_INCLUDE_DIR})
include_directories (${LUA_INCLUDE_DIR})
include_directories (${TOLUA_INCLUDE_DIR})
include_directories (${BSON_INCLUDE_DIR})
include_directories (${LUA_INCLUDE_DIR})
include_directories (${INIPARSER_INCLUDE_DIR})
IF(DEFINED ERESSEA_VERSION)
@ -26,9 +25,9 @@ ENDIF()
IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89")
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89")
ELSEIF(MSVC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall /WX /MP")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /Za /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG
"${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE
@ -100,6 +99,7 @@ set (ERESSEA_SRC
reports.c
teleport.c
guard.c
jsonconf.c
prefix.c
donations.c
eressea.c
@ -109,6 +109,7 @@ set (ERESSEA_SRC
json.c
creport.c
report.c
steal.c
economy.c
give.c
items.c
@ -127,6 +128,7 @@ set (ERESSEA_SRC
travelthru.c
monsters.c
wormhole.c
xmlreader.c
${SPELLS_SRC}
${RACES_SRC}
${ITEMS_SRC}
@ -134,12 +136,12 @@ set (ERESSEA_SRC
${TRIGGERS_SRC}
${ATTRIBUTES_SRC}
${KERNEL_SRC}
${DB_SRC}
${UTIL_SRC}
)
set(SERVER_SRC
main.c
building_action.c
console.c
helpers.c
bind_tolua.c
@ -159,13 +161,6 @@ set(SERVER_SRC
bind_unit.c
)
if (SQLITE3_FOUND)
set (SERVER_SRC ${SERVER_SRC}
sqlite.c
bind_sqlite.c
)
endif (SQLITE3_FOUND)
if (CURSES_FOUND)
set (SERVER_SRC ${SERVER_SRC}
gmtool.c
@ -200,6 +195,7 @@ target_link_libraries(convert
set(TESTS_SRC
test_eressea.c
tests.c
academy.test.c
alchemy.test.c
battle.test.c
calendar.test.c
@ -210,6 +206,7 @@ set(TESTS_SRC
give.test.c
guard.test.c
json.test.c
jsonconf.test.c
keyword.test.c
laws.test.c
lighthouse.test.c
@ -235,6 +232,7 @@ set(TESTS_SRC
volcano.test.c
vortex.test.c
wormhole.test.c
# xmlreader.test.c
spells/flyingship.test.c
spells/magicresistance.test.c
triggers/shock.test.c
@ -265,9 +263,36 @@ add_test(server test_eressea)
install(TARGETS eressea DESTINATION "bin")
if (HAVE_LIBBSD)
add_definitions(-DHAVE_LIBBSD)
endif (HAVE_LIBBSD)
if (HAVE_STRLCAT)
add_definitions(-DHAVE_BSDSTRING)
endif (HAVE_STRLCAT)
if (HAVE_STRDUP)
add_definitions(-DHAVE_STRDUP)
endif(HAVE_STRDUP)
if (HAVE_LIBBSD)
target_link_libraries(test_eressea bsd)
target_link_libraries(eressea bsd)
target_link_libraries(convert bsd)
endif (HAVE_LIBBSD)
if (SQLITE3_FOUND)
include_directories (${SQLITE3_INCLUDE_DIR})
target_link_libraries(eressea ${SQLITE3_LIBRARIES})
target_link_libraries(convert ${SQLITE3_LIBRARIES})
target_link_libraries(test_eressea ${SQLITE3_LIBRARIES})
add_definitions(-DUSE_SQLITE)
elseif (DB_FOUND)
include_directories (${DB_INCLUDE_DIR})
target_link_libraries(convert ${DB_LIBRARIES})
target_link_libraries(eressea ${DB_LIBRARIES})
target_link_libraries(test_eressea ${DB_LIBRARIES})
add_definitions(-DUSE_DB)
endif(SQLITE3_FOUND)
if (CURSES_FOUND)
@ -281,5 +306,4 @@ include_directories (${LIBXML2_INCLUDE_DIR})
target_link_libraries(eressea ${LIBXML2_LIBRARIES})
target_link_libraries(convert ${LIBXML2_LIBRARIES})
target_link_libraries(test_eressea ${LIBXML2_LIBRARIES})
add_definitions(-DUSE_LIBXML2)
endif (LIBXML2_FOUND)

View file

@ -36,8 +36,8 @@ void academy_teaching_bonus(struct unit *u, skill_t sk, int students) {
bool academy_can_teach(unit *teacher, unit *student, skill_t sk) {
const struct building_type *btype = bt_find("academy");
if (active_building(teacher, btype) && active_building(student, btype)) {
int j = study_cost(student, sk);
j = MAX(50, j * 2);
int j = study_cost(student, sk) * 2;
if (j < 50) j = 50;
/* kann Einheit das zahlen? */
return get_pooled(student, get_resourcetype(R_SILVER), GET_DEFAULT, j) >= j;
/* sonst nehmen sie nicht am Unterricht teil */

56
src/academy.test.c Normal file
View file

@ -0,0 +1,56 @@
#include <platform.h>
#include "academy.h"
#include "skill.h"
#include <kernel/config.h>
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/unit.h>
#include <kernel/item.h>
#include <kernel/region.h>
#include <CuTest.h>
#include "tests.h"
static void test_academy(CuTest * tc)
{
faction *f;
unit *u, *u2;
region *r;
building *b;
const item_type *it_silver;
test_setup();
config_set_int("skills.cost.alchemy", 100);
r = test_create_region(0, 0, NULL);
f = test_create_faction(NULL);
u = test_create_unit(f, r);
b = test_create_building(r, test_create_buildingtype("academy"));
u2 = test_create_unit(f, r);
it_silver = test_create_silver();
CuAssert(tc, "teacher must be in academy", !academy_can_teach(u, u2, SK_CROSSBOW));
u_set_building(u, b);
CuAssert(tc, "student must be in academy", !academy_can_teach(u, u2, SK_CROSSBOW));
u_set_building(u2, b);
CuAssert(tc, "student must have 50 silver", !academy_can_teach(u, u2, SK_CROSSBOW));
i_change(&u2->items, it_silver, 50);
CuAssert(tc, "building must be maintained", !academy_can_teach(u, u2, SK_CROSSBOW));
b->flags |= BLD_MAINTAINED;
CuAssert(tc, "building must have capacity", !academy_can_teach(u, u2, SK_CROSSBOW));
b->size = 2;
CuAssertTrue(tc, academy_can_teach(u, u2, SK_CROSSBOW));
CuAssert(tc, "student must pay skillcost", !academy_can_teach(u, u2, SK_ALCHEMY));
i_change(&u2->items, it_silver, 150);
CuAssertTrue(tc, academy_can_teach(u, u2, SK_ALCHEMY));
test_teardown();
}
CuSuite *get_academy_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_academy);
return suite;
}

View file

@ -37,6 +37,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/gamedata.h>
#include <util/base36.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/rand.h>
#include <storage.h>
@ -47,14 +48,49 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h>
#include <assert.h>
/* ------------------------------------------------------------- */
typedef struct potion_type {
struct potion_type *next;
const struct item_type *itype;
int level;
} potion_type;
void herbsearch(unit * u, int max)
static potion_type *potiontypes;
static void pt_register(potion_type * ptype)
{
ptype->next = potiontypes;
potiontypes = ptype;
}
void new_potiontype(item_type * itype, int level)
{
potion_type *ptype;
ptype = (potion_type *)calloc(sizeof(potion_type), 1);
itype->flags |= ITF_POTION;
ptype->itype = itype;
ptype->level = level;
pt_register(ptype);
}
int potion_level(const item_type *itype)
{
potion_type *ptype;
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (ptype->itype == itype) {
return ptype->level;
}
}
return 0;
}
void herbsearch(unit * u, int max_take)
{
region * r = u->region;
int herbsfound;
const item_type *whichherb;
int effsk = effskill(u, SK_HERBALISM, 0);
int herbs = rherbs(r);
if (effsk == 0) {
cmistake(u, u->thisorder, 59, MSG_PRODUCE);
@ -72,14 +108,14 @@ void herbsearch(unit * u, int max)
return;
}
if (max)
max = MIN(max, rherbs(r));
else
max = rherbs(r);
if (max_take < herbs) {
herbs = max_take;
}
herbsfound = ntimespprob(effsk * u->number,
(double)rherbs(r) / 100.0F, -0.01F);
herbsfound = MIN(herbsfound, max);
rsetherbs(r, (short) (rherbs(r) - herbsfound));
if (herbsfound > herbs) herbsfound = herbs;
rsetherbs(r, rherbs(r) - herbsfound);
if (herbsfound) {
produceexp(u, SK_HERBALISM, u->number);
@ -93,33 +129,37 @@ void herbsearch(unit * u, int max)
}
}
static int begin_potion(unit * u, const potion_type * ptype, struct order *ord)
static int begin_potion(unit * u, const item_type * itype, struct order *ord)
{
bool rule_multipotion;
assert(ptype != NULL);
static int config;
static bool rule_multipotion;
assert(itype);
if (config_changed(&config)) {
/* should we allow multiple different potions to be used the same turn? */
rule_multipotion = config_get_int("rules.magic.multipotion", 0) != 0;
}
/* should we allow multiple different potions to be used the same turn? */
rule_multipotion = config_get_int("rules.magic.multipotion", 0) != 0;
if (!rule_multipotion) {
const potion_type *use = ugetpotionuse(u);
if (use != NULL && use != ptype) {
const item_type *use = ugetpotionuse(u);
if (use != NULL && use != itype) {
ADDMSG(&u->faction->msgs,
msg_message("errusingpotion", "unit using command",
u, use->itype->rtype, ord));
u, use->rtype, ord));
return ECUSTOM;
}
}
return 0;
}
static void end_potion(unit * u, const potion_type * ptype, int amount)
static void end_potion(unit * u, const item_type * itype, int amount)
{
use_pooled(u, ptype->itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
amount);
usetpotionuse(u, ptype);
usetpotionuse(u, itype);
ADDMSG(&u->faction->msgs, msg_message("usepotion",
"unit potion", u, ptype->itype->rtype));
"unit potion", u, itype->rtype));
}
static int potion_water_of_life(unit * u, region *r, int amount) {
@ -155,8 +195,26 @@ static int potion_water_of_life(unit * u, region *r, int amount) {
return amount;
}
void show_potions(faction *f, int sklevel)
{
const potion_type *ptype;
for (ptype = potiontypes; ptype; ptype = ptype->next) {
if (ptype->level > 0 && sklevel == ptype->level * 2) {
attrib *a = a_find(f->attribs, &at_showitem);
while (a && a->type == &at_showitem && a->data.v != ptype)
a = a->next;
if (a == NULL || a->type != &at_showitem) {
a = a_add(&f->attribs, a_new(&at_showitem));
a->data.v = (void *)ptype->itype;
}
}
}
}
static int potion_healing(unit * u, int amount) {
u->hp = MIN(unit_max_hp(u) * u->number, u->hp + 400 * amount);
int maxhp = unit_max_hp(u) * u->number;
u->hp = u->hp + 400 * amount;
if (u->hp > maxhp) u->hp = maxhp;
return amount;
}
@ -170,62 +228,51 @@ static int potion_luck(unit *u, region *r, attrib_type *atype, int amount) {
return amount;
}
static int potion_truth(unit *u) {
UNUSED_ARG(u);
/* TODO: this potion does nothing! */
return 1;
}
static int potion_power(unit *u, int amount) {
int use = u->number / 10;
if (use < amount) {
if (u->number % 10 > 0) ++use;
amount = use;
int hp = 10 * amount;
if (hp > u->number) {
hp = u->number;
amount = (hp + 9) % 10;
}
/* Verf<72>nffacht die HP von max. 10 Personen in der Einheit */
u->hp += MIN(u->number, 10 * amount) * unit_max_hp(u) * 4;
u->hp += hp * unit_max_hp(u) * 4;
return amount;
}
static int do_potion(unit * u, region *r, const potion_type * ptype, int amount)
static int do_potion(unit * u, region *r, const item_type * itype, int amount)
{
if (ptype == oldpotiontype[P_LIFE]) {
if (itype == oldpotiontype[P_LIFE]) {
return potion_water_of_life(u, r, amount);
}
else if (ptype == oldpotiontype[P_HEILWASSER]) {
else if (itype == oldpotiontype[P_HEILWASSER]) {
return potion_healing(u, amount);
}
else if (ptype == oldpotiontype[P_PEOPLE]) {
else if (itype == oldpotiontype[P_PEOPLE]) {
return potion_luck(u, r, &at_peasantluck, amount);
}
else if (ptype == oldpotiontype[P_HORSE]) {
else if (itype == oldpotiontype[P_HORSE]) {
return potion_luck(u, r, &at_horseluck, amount);
}
else if (ptype == oldpotiontype[P_WAHRHEIT]) {
return potion_truth(u);
}
else if (ptype == oldpotiontype[P_MACHT]) {
else if (itype == oldpotiontype[P_MACHT]) {
return potion_power(u, amount);
}
else {
change_effect(u, ptype, 10 * amount);
change_effect(u, itype, 10 * amount);
}
return amount;
}
int use_potion(unit * u, const item_type * itype, int amount, struct order *ord)
{
const potion_type *ptype = resource2potion(itype->rtype);
if (oldpotiontype[P_HEAL] && ptype == oldpotiontype[P_HEAL]) {
if (oldpotiontype[P_HEAL] && itype == oldpotiontype[P_HEAL]) {
return EUNUSABLE;
}
else {
int result = begin_potion(u, ptype, ord);
int result = begin_potion(u, itype, ord);
if (result)
return result;
amount = do_potion(u, u->region, ptype, amount);
end_potion(u, ptype, amount);
amount = do_potion(u, u->region, itype, amount);
end_potion(u, itype, amount);
}
return 0;
}
@ -233,7 +280,7 @@ int use_potion(unit * u, const item_type * itype, int amount, struct order *ord)
typedef struct potiondelay {
unit *u;
region *r;
const potion_type *ptype;
const item_type *itype;
int amount;
} potiondelay;
@ -250,7 +297,7 @@ static int age_potiondelay(attrib * a, void *owner)
{
potiondelay *pd = (potiondelay *)a->data.v;
UNUSED_ARG(owner);
pd->amount = do_potion(pd->u, pd->r, pd->ptype, pd->amount);
pd->amount = do_potion(pd->u, pd->r, pd->itype, pd->amount);
return AT_AGE_REMOVE;
}
@ -261,13 +308,13 @@ attrib_type at_potiondelay = {
age_potiondelay, 0, 0
};
static attrib *make_potiondelay(unit * u, const potion_type * ptype, int amount)
static attrib *make_potiondelay(unit * u, const item_type * itype, int amount)
{
attrib *a = a_new(&at_potiondelay);
potiondelay *pd = (potiondelay *)a->data.v;
pd->u = u;
pd->r = u->region;
pd->ptype = ptype;
pd->itype = itype;
pd->amount = amount;
return a;
}
@ -276,14 +323,13 @@ int
use_potion_delayed(unit * u, const item_type * itype, int amount,
struct order *ord)
{
const potion_type *ptype = resource2potion(itype->rtype);
int result = begin_potion(u, ptype, ord);
int result = begin_potion(u, itype, ord);
if (result)
return result;
a_add(&u->attribs, make_potiondelay(u, ptype, amount));
a_add(&u->attribs, make_potiondelay(u, itype, amount));
end_potion(u, ptype, amount);
end_potion(u, itype, amount);
return 0;
}
@ -306,7 +352,7 @@ a_writeeffect(const attrib * a, const void *owner, struct storage *store)
{
effect_data *edata = (effect_data *)a->data.v;
UNUSED_ARG(owner);
WRITE_TOK(store, resourcename(edata->type->itype->rtype, 0));
WRITE_TOK(store, resourcename(edata->type->rtype, 0));
WRITE_INT(store, edata->value);
}
@ -323,14 +369,16 @@ static int a_readeffect(attrib * a, void *owner, struct gamedata *data)
rtype = rt_find(zText);
READ_INT(store, &power);
if (rtype == NULL || rtype->ptype == NULL || power <= 0) {
if (rtype == NULL || rtype->itype == NULL || power <= 0) {
return AT_READ_FAIL;
}
if (rtype->ptype==oldpotiontype[P_HEAL]) {
/* healing potions used to have long-term effects */
return AT_READ_FAIL;
if (data->version < NOLANDITEM_VERSION) {
if (rtype->itype == oldpotiontype[P_HEAL]) {
/* healing potions used to have long-term effects */
return AT_READ_FAIL;
}
}
edata->type = rtype->ptype;
edata->type = rtype->itype;
edata->value = power;
return AT_READ_OK;
}
@ -344,7 +392,7 @@ attrib_type at_effect = {
a_readeffect,
};
int get_effect(const unit * u, const potion_type * effect)
int get_effect(const unit * u, const item_type * effect)
{
const attrib *a;
for (a = a_find(u->attribs, &at_effect); a != NULL && a->type == &at_effect;
@ -356,7 +404,7 @@ int get_effect(const unit * u, const potion_type * effect)
return 0;
}
int change_effect(unit * u, const potion_type * effect, int delta)
int change_effect(unit * u, const item_type * effect, int delta)
{
if (delta != 0) {
attrib *a = a_find(u->attribs, &at_effect);
@ -386,3 +434,17 @@ int change_effect(unit * u, const potion_type * effect, int delta)
log_error("change effect with delta==0 for unit %s\n", itoa36(u->no));
return 0;
}
bool display_potions(struct unit *u)
{
int skill = effskill(u, SK_ALCHEMY, 0);
int c = 0;
const potion_type *ptype;
for (ptype = potiontypes; ptype != NULL; ptype = ptype->next) {
if (ptype->level * 2 <= skill) {
show_item(u, ptype->itype);
++c;
}
}
return (c > 0);
}

View file

@ -19,6 +19,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef H_KRNL_ALCHEMY_H
#define H_KRNL_ALCHEMY_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -26,9 +28,12 @@ extern "C" {
struct potion_type;
struct unit;
struct region;
struct faction;
struct item_type;
struct order;
extern struct attrib_type at_effect;
enum {
/* Stufe 1 */
P_FAST,
@ -41,11 +46,7 @@ extern "C" {
/* Stufe 3 */
P_WISE, /* 6 */
P_FOOL,
#ifdef INSECT_POTION
P_WARMTH,
#else
P_STEEL,
#endif
P_HORSE,
P_BERSERK, /* 10 */
/* Stufe 4 */
@ -56,22 +57,24 @@ extern "C" {
MAX_POTIONS
};
void new_potiontype(struct item_type * itype, int level);
int potion_level(const struct item_type *itype);
void show_potions(struct faction *f, int sklevel);
void herbsearch(struct unit *u, int max);
extern int use_potion(struct unit *u, const struct item_type *itype,
int use_potion(struct unit *u, const struct item_type *itype,
int amount, struct order *);
extern int use_potion_delayed(struct unit *u, const struct item_type *itype,
int use_potion_delayed(struct unit *u, const struct item_type *itype,
int amount, struct order *);
extern void init_potions(void);
extern int get_effect(const struct unit *u, const struct potion_type *effect);
extern int change_effect(struct unit *u, const struct potion_type *effect,
int get_effect(const struct unit *u, const struct item_type *effect);
int change_effect(struct unit *u, const struct item_type *effect,
int value);
extern struct attrib_type at_effect;
bool display_potions(struct unit *u);
/* rausnehmen, sobald man attribute splitten kann: */
/* TODO: rausnehmen, sobald man attribute splitten kann: */
typedef struct effect_data {
const struct potion_type *type;
const struct item_type *type;
int value;
} effect_data;

View file

@ -26,13 +26,14 @@ static void test_herbsearch(CuTest * tc)
const item_type *itype;
test_setup();
r = test_create_region(0, 0, 0);
test_inject_messagetypes();
r = test_create_region(0, 0, NULL);
rc = rc_get_or_create("dragon");
rc->flags |= RCF_UNARMEDGUARD;
u2 = test_create_unit(test_create_faction(rc), r);
setguard(u2, true);
f = test_create_faction(0);
f = test_create_faction(NULL);
u = test_create_unit(f, r);
itype = test_create_itemtype("rosemary");
@ -78,7 +79,7 @@ static void test_herbsearch(CuTest * tc)
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
test_cleanup();
test_teardown();
}
CuSuite *get_alchemy_suite(void)

View file

@ -7,7 +7,6 @@ otherfaction.test.c
SET(_FILES
attributes.c
fleechance.c
follow.c
hate.c
iceberg.c

View file

@ -25,7 +25,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* attributes includes */
#include "follow.h"
#include "fleechance.h"
#include "hate.h"
#include "iceberg.h"
#include "key.h"
@ -56,6 +55,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/attrib.h>
#include <util/event.h>
#include <util/gamedata.h>
#include <util/macros.h>
#include <util/resolve.h>
#include <storage.h>

View file

@ -34,6 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/log.h>
#include <util/gamedata.h>
#include <util/resolve.h>
#include <util/strings.h>
#include <storage.h>
@ -69,7 +70,7 @@ static int dict_read(attrib * a, void *owner, gamedata *data)
int n;
READ_STR(store, name, sizeof(name));
dd->name = strdup(name);
dd->name = str_strdup(name);
READ_INT(store, &n);
dd->type = (dict_type)n;
if (dd->type == TINTEGER) {
@ -135,7 +136,13 @@ static void dict_upgrade(attrib **alist, attrib *abegin) {
assert(!"invalid input");
}
if (i == 4) {
keys = realloc(keys, sizeof(int) * (n + i + 1));
int *k;
k = realloc(keys, sizeof(int) * (n + i + 1));
if (!k) {
free(keys);
abort();
}
keys = k;
memcpy(keys + n + 1, val, sizeof(val));
n += i;
i = 0;
@ -164,7 +171,7 @@ attrib_type at_dict = {
void dict_set(attrib * a, const char * name, int value)
{
dict_data *dd = (dict_data *)a->data.v;
dd->name = strdup(name);
dd->name = str_strdup(name);
dd->type = TINTEGER;
dd->data.i = value;
}

View file

@ -1,40 +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 "fleechance.h"
#include <util/attrib.h>
#include <stdlib.h>
attrib_type at_fleechance = {
"fleechance",
NULL,
NULL,
NULL,
NULL,
NULL,
};
attrib *make_fleechance(float fleechance)
{
attrib *a = a_new(&at_fleechance);
a->data.flt = fleechance;
return a;
}

View file

@ -1,32 +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_FLEECHANCE
#define H_ATTRIBUTE_FLEECHANCE
#ifdef __cplusplus
extern "C" {
#endif
extern struct attrib_type at_fleechance;
struct attrib *make_fleechance(float fleechance);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -24,6 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/attrib.h>
#include <util/gamedata.h>
#include <util/macros.h>
#include <util/resolve.h>
#include <storage.h>

View file

@ -123,8 +123,14 @@ static int a_readkeys(attrib * a, void *owner, gamedata *data) {
if (e != n) {
int sz = keys_size(n);
if (e > sz) {
int *k;
sz = keys_size(e);
keys = realloc(keys, sizeof(int)*(2 * sz + 1));
k = realloc(keys, sizeof(int)*(2 * sz + 1));
if (!k) {
free(keys);
abort();
}
keys = k;
keys[0] = e;
}
}

View file

@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/attrib.h>
#include <util/gamedata.h>
#include <util/macros.h>
#include <storage.h>

View file

@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/attrib.h>
#include <util/gamedata.h>
#include <util/macros.h>
#include <storage.h>

View file

@ -30,7 +30,7 @@ static void test_rules(CuTest *tc) {
CuAssertIntEquals(tc, false, rule_stealth_anon());
config_set("stealth.faction.anon", "1");
CuAssertIntEquals(tc, true, rule_stealth_anon());
test_cleanup();
test_teardown();
}
static void test_otherfaction(CuTest *tc) {
@ -38,14 +38,14 @@ static void test_otherfaction(CuTest *tc) {
faction *f;
test_setup();
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
f = test_create_faction(0);
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
f = test_create_faction(NULL);
config_set("stealth.faction.other", "1");
CuAssertIntEquals(tc, true, rule_stealth_other());
CuAssertPtrEquals(tc, u->faction, visible_faction(f, u));
a_add(&u->attribs, make_otherfaction(f));
CuAssertPtrEquals(tc, f, visible_faction(f, u));
test_cleanup();
test_teardown();
}
CuSuite *get_otherfaction_suite(void)

View file

@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "racename.h"
#include <util/attrib.h>
#include <util/strings.h>
/* libc includes */
#include <stdlib.h>
@ -43,7 +44,7 @@ void set_racename(attrib ** palist, const char *name)
attrib *a = a_find(*palist, &at_racename);
if (!a && name) {
a = a_add(palist, a_new(&at_racename));
a->data.v = strdup(name);
a->data.v = str_strdup(name);
}
else if (a && !name) {
a_remove(palist, a);
@ -51,7 +52,7 @@ void set_racename(attrib ** palist, const char *name)
else if (a) {
if (strcmp(a->data.v, name) != 0) {
free(a->data.v);
a->data.v = strdup(name);
a->data.v = str_strdup(name);
}
}
}

View file

@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "raceprefix.h"
#include <util/attrib.h>
#include <util/strings.h>
#include <assert.h>
#include <string.h>
@ -41,7 +42,7 @@ void set_prefix(attrib ** ap, const char *str)
free(a->data.v);
}
assert(a->type == &at_raceprefix);
a->data.v = strdup(str);
a->data.v = str_strdup(str);
}
const char *get_prefix(attrib * a)
@ -53,7 +54,7 @@ const char *get_prefix(attrib * a)
str = (char *)a->data.v;
/* conversion of old prefixes */
if (strncmp(str, "prefix_", 7) == 0) {
((attrib *)a)->data.v = strdup(str + 7);
((attrib *)a)->data.v = str_strdup(str + 7);
free(str);
str = (char *)a->data.v;
}

View file

@ -14,8 +14,8 @@
static void test_stealth(CuTest *tc) {
unit *u;
test_cleanup();
u = test_create_unit(test_create_faction(test_create_race("human")), test_create_region(0, 0, 0));
test_setup();
u = test_create_unit(test_create_faction(test_create_race("human")), test_create_region(0, 0, NULL));
set_level(u, SK_STEALTH, 2);
CuAssertIntEquals(tc, -1, u_geteffstealth(u));
CuAssertIntEquals(tc, 2, eff_stealth(u, u->region));
@ -28,7 +28,7 @@ static void test_stealth(CuTest *tc) {
u_seteffstealth(u, -1);
CuAssertIntEquals(tc, -1, u_geteffstealth(u));
CuAssertIntEquals(tc, 2, eff_stealth(u, u->region));
test_cleanup();
test_teardown();
}
CuSuite *get_stealth_suite(void)

View file

@ -55,7 +55,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* attributes includes */
#include <attributes/key.h>
#include <attributes/fleechance.h>
#include <attributes/racename.h>
#include <attributes/otherfaction.h>
#include <attributes/moved.h>
@ -64,15 +63,17 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/assert.h>
#include <util/attrib.h>
#include <util/base36.h>
#include <util/bsdstring.h>
#include <util/language.h>
#include <util/lists.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/parser.h>
#include <selist.h>
#include <util/strings.h>
#include <util/rand.h>
#include <util/rng.h>
#include <selist.h>
/* libc includes */
#include <ctype.h>
#include <limits.h>
@ -141,11 +142,14 @@ static int rule_tactics_formula;
static int rule_nat_armor;
static int rule_cavalry_mode;
static int rule_vampire;
static const item_type *it_mistletoe;
/** initialize rules from configuration.
*/
static void init_rules(void)
{
it_mistletoe = it_find("mistletoe");
rule_nat_armor = config_get_int("rules.combat.nat_armor", 0);
rule_tactics_formula = config_get_int("rules.tactics.formula", 0);
rule_goblin_bonus = config_get_int("rules.combat.goblinbonus", 10);
@ -182,14 +186,14 @@ static int army_index(side * s)
return s->index;
}
static char *sidename(side * s)
const char *sidename(const side * s)
{
#define SIDENAMEBUFLEN 256
static int bufno; /* STATIC_XCALL: used across calls */
static char sidename_buf[4][SIDENAMEBUFLEN]; /* STATIC_RESULT: used for return, not across calls */
bufno = bufno % 4;
strlcpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN);
str_strlcpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN);
return sidename_buf[bufno++];
}
@ -199,11 +203,11 @@ static const char *sideabkz(side * s, bool truename)
const faction *f = (s->stealthfaction
&& !truename) ? s->stealthfaction : s->faction;
strlcpy(sideabkz_buf, itoa36(f->no), sizeof(sideabkz_buf));
str_strlcpy(sideabkz_buf, itoa36(f->no), sizeof(sideabkz_buf));
return sideabkz_buf;
}
static void message_faction(battle * b, faction * f, struct message *m)
void battle_message_faction(battle * b, faction * f, struct message *m)
{
region *r = b->region;
@ -224,14 +228,14 @@ void message_all(battle * b, message * m)
for (bf = b->factions; bf; bf = bf->next) {
assert(bf->faction);
message_faction(b, bf->faction, m);
battle_message_faction(b, bf->faction, m);
}
}
static void fbattlerecord(battle * b, faction * f, const char *s)
{
message *m = msg_message("battle_msg", "string", s);
message_faction(b, f, m);
battle_message_faction(b, f, m);
msg_release(m);
}
@ -639,8 +643,6 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking)
if (!i_canuse(u, wtype->itype))
return -1;
skill = effskill(u, wtype->skill, 0);
if (skill < wtype->minskill)
skill = 0;
if (skill > 0) {
if (attacking) {
skill += u_race(u)->at_bonus;
@ -679,7 +681,7 @@ static int CavalryBonus(const unit * u, troop enemy, int type)
/* only half against trolls */
if (skl > 0) {
if (type == BONUS_SKILL) {
int dmg = MIN(skl, 8);
int dmg = (skl < 8) ? skl : 8;
if (u_race(enemy.fighter->unit) == get_race(RC_TROLL)) {
dmg = dmg / 4;
}
@ -690,7 +692,8 @@ static int CavalryBonus(const unit * u, troop enemy, int type)
}
else {
skl = skl / 2;
return MIN(skl, 4);
if (skl > 4) skl = 4;
return skl;
}
}
}
@ -887,7 +890,7 @@ static void rmtroop(troop dt)
{
fighter *df = dt.fighter;
/* troop ist immer eine einzele Person */
/* troop ist immer eine einzelne Person */
rmfighter(df, 1);
assert(dt.index >= 0 && dt.index < df->unit->number);
@ -943,8 +946,8 @@ void drain_exp(struct unit *u, int n)
skill_t sk = (skill_t)(rng_int() % MAXSKILLS);
skill_t ssk;
/* TODO (enno): we can use u->skill_size to find a random skill */
ssk = sk;
while (get_level(u, sk) == 0) {
sk++;
if (sk == MAXSKILLS)
@ -984,8 +987,10 @@ static void vampirism(troop at, int damage)
++gain;
if (gain > 0) {
int maxhp = unit_max_hp(at.fighter->unit);
at.fighter->person[at.index].hp =
MIN(gain + at.fighter->person[at.index].hp, maxhp);
gain += at.fighter->person[at.index].hp;
if (maxhp > gain) maxhp = gain;
at.fighter->person[at.index].hp = maxhp;
}
}
}
@ -1009,7 +1014,7 @@ int natural_armor(unit * du)
static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_type *wtype)
{
const race *ar = u_race(au);
int m, modifier = 0;
int modifier = 0;
if (wtype != NULL) {
if (fval(u_race(du), RCF_DRAGON)) {
static int cache;
@ -1022,6 +1027,7 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_
}
}
if (wtype->modifiers != NULL) {
int m;
for (m = 0; wtype->modifiers[m].value; ++m) {
/* weapon damage for this weapon, possibly by race */
if (wtype->modifiers[m].flags & WMF_DAMAGE) {
@ -1141,7 +1147,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
const weapon_type *dwtype = NULL;
const weapon_type *awtype = NULL;
const weapon *weapon;
variant res = frac_make(1, 1);
variant res = frac_one;
int rda, sk = 0, sd;
bool magic = false;
@ -1185,6 +1191,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
}
if (magic) {
res = frac_sub(frac_one, res);
res = frac_mul(frac_make(da, 1), res);
da = res.sa[0] / res.sa[1];
}
@ -1194,8 +1201,8 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
double kritchance = (sk * 3 - sd) / 200.0;
int maxk = 4;
kritchance = MAX(kritchance, 0.005);
kritchance = MIN(0.9, kritchance);
kritchance = fmax(kritchance, 0.005);
kritchance = fmin(0.9, kritchance);
while (maxk-- && chance(kritchance)) {
da += dice_rand(damage);
@ -1294,11 +1301,11 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
}
if (oldpotiontype[P_HEAL] && !fval(&df->person[dt.index], FL_HEALING_USED)) {
if (i_get(du->items, oldpotiontype[P_HEAL]->itype) > 0) {
if (i_get(du->items, oldpotiontype[P_HEAL]) > 0) {
message *m = msg_message("potionsave", "unit", du);
message_faction(b, du->faction, m);
battle_message_faction(b, du->faction, m);
msg_release(m);
i_change(&du->items, oldpotiontype[P_HEAL]->itype, -1);
i_change(&du->items, oldpotiontype[P_HEAL], -1);
fset(&df->person[dt.index], FL_HEALING_USED);
df->person[dt.index].hp = u_race(du)->hitpoints * 5; /* give the person a buffer */
return false;
@ -1641,7 +1648,6 @@ static castorder * create_castorder_combat(castorder *co, fighter *fig, const sp
return co;
}
#ifdef FFL_CURSED
static void summon_igjarjuk(battle *b, spellrank spellranks[]) {
side *s;
castorder *co;
@ -1679,7 +1685,6 @@ static void summon_igjarjuk(battle *b, spellrank spellranks[]) {
}
}
}
#endif
void do_combatmagic(battle * b, combatmagic_t was)
{
@ -1691,11 +1696,9 @@ void do_combatmagic(battle * b, combatmagic_t was)
memset(spellranks, 0, sizeof(spellranks));
#ifdef FFL_CURSED
if (was == DO_PRECOMBATSPELL) {
summon_igjarjuk(b, spellranks);
}
#endif
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig;
for (fig = s->fighters; fig; fig = fig->next) {
@ -1734,8 +1737,9 @@ void do_combatmagic(battle * b, combatmagic_t was)
}
level = eff_spelllevel(mage, sp, level, 1);
if (sl > 0)
level = MIN(sl, level);
if (sl > 0 && sl < level) {
level = sl;
}
if (level < 0) {
report_failed_spell(b, mage, sp);
free_order(ord);
@ -1815,8 +1819,10 @@ static void do_combatspell(troop at)
}
level = eff_spelllevel(caster, sp, fi->magic, 1);
if ((sl = get_combatspelllevel(caster, 1)) > 0)
level = MIN(level, sl);
sl = get_combatspelllevel(caster, 1);
if (sl > 0 && sl < level) {
level = sl;
}
if (fumble(r, caster, sp, level)) {
report_failed_spell(b, caster, sp);
@ -2008,11 +2014,6 @@ void dazzle(battle * b, troop * td)
{
UNUSED_ARG(b);
/* Nicht kumulativ ! */
#ifdef TODO_RUNESWORD
if (td->fighter->weapon[WP_RUNESWORD].count > td->index) {
return;
}
#endif
if (td->fighter->person[td->index].flags & (FL_COURAGE|FL_DAZZLED)) {
return;
}
@ -2284,21 +2285,6 @@ void do_attack(fighter * af)
}
}
void do_regenerate(fighter * af)
{
troop ta;
unit *au = af->unit;
ta.fighter = af;
ta.index = af->fighting;
while (ta.index--) {
struct person *p = af->person + ta.index;
p->hp += effskill(au, SK_STAMINA, 0);
p->hp = MIN(unit_max_hp(au), p->hp);
}
}
static void add_tactics(tactics * ta, fighter * fig, int value)
{
if (value == 0 || value < ta->value)
@ -2345,28 +2331,22 @@ static double horse_fleeing_bonus(const unit * u)
double fleechance(unit * u)
{
double c = 0.20; /* Fluchtwahrscheinlichkeit in % */
attrib *a = a_find(u->attribs, &at_fleechance);
double p = 0.20; /* Fluchtwahrscheinlichkeit in % */
/* Einheit u versucht, dem Get<65>mmel zu entkommen */
c += (effskill(u, SK_STEALTH, 0) * 0.05);
c += horse_fleeing_bonus(u);
p += (effskill(u, SK_STEALTH, 0) * 0.05);
p += horse_fleeing_bonus(u);
if (u_race(u) == get_race(RC_HALFLING)) {
c += 0.20;
c = MIN(c, 0.90);
p += 0.20;
if (p > 0.9) {
p = 0.9;
}
}
else {
c = MIN(c, 0.75);
}
if (a != NULL)
c += a->data.flt;
return c;
return p;
}
/** add a new army to the conflict
/** add a new army to the conflict.
* beware: armies need to be added _at the beginning_ of the list because
* otherwise join_allies() will get into trouble */
side *make_side(battle * b, const faction * f, const group * g,
@ -2482,7 +2462,7 @@ static void loot_items(fighter * corpse)
float lootfactor = (float)dead / (float)u->number; /* only loot the dead! */
int maxloot = (int)((float)itm->number * lootfactor);
if (maxloot > 0) {
int i = MIN(10, maxloot);
int i = (maxloot > 10) ? 10 : maxloot;
for (; i != 0; --i) {
int loot = maxloot / i;
@ -2545,7 +2525,7 @@ static void loot_items(fighter * corpse)
}
}
static bool seematrix(const faction * f, const side * s)
bool seematrix(const faction * f, const side * s)
{
if (f == s->faction)
return true;
@ -2562,12 +2542,18 @@ static double PopulationDamage(void)
static void battle_effects(battle * b, int dead_players)
{
region *r = b->region;
int dead_peasants =
MIN(rpeasants(r), (int)(dead_players * PopulationDamage()));
if (dead_peasants) {
deathcounts(r, dead_peasants + dead_players);
add_chaoscount(r, dead_peasants / 2);
rsetpeasants(r, rpeasants(r) - dead_peasants);
int rp = rpeasants(r);
if (rp > 0) {
int dead_peasants = (int)(dead_players * PopulationDamage());
if (dead_peasants > rp) {
dead_peasants = rp;
}
if (dead_peasants) {
deathcounts(r, dead_peasants + dead_players);
add_chaoscount(r, dead_peasants / 2);
rsetpeasants(r, rp - dead_peasants);
}
}
}
@ -2623,7 +2609,7 @@ static void aftermath(battle * b)
struct message *m =
msg_message("killsandhits", "unit hits kills", du, df->hits,
df->kills);
message_faction(b, du->faction, m);
battle_message_faction(b, du->faction, m);
msg_release(m);
}
}
@ -2654,14 +2640,14 @@ static void aftermath(battle * b)
}
}
snumber += du->number;
if (relevant) {
flags = UFL_LONGACTION | UFL_NOTMOVING;
if (du->status == ST_FLEE) {
flags -= UFL_NOTMOVING;
}
}
if (df->alive == 0) {
flags |= UFL_DEAD;
flags = UFL_DEAD;
}
else if (relevant) {
flags = UFL_LONGACTION;
if ((du->status != ST_FLEE) && (df->run.hp <= 0)) {
flags |= UFL_NOTMOVING;
}
}
if (flags) {
fset(du, flags);
@ -2763,7 +2749,7 @@ static void aftermath(battle * b)
faction *f = bf->faction;
message *m = seematrix(f, s) ? seen : unseen;
message_faction(b, f, m);
battle_message_faction(b, f, m);
}
msg_release(seen);
@ -2787,7 +2773,7 @@ static void aftermath(battle * b)
message *m =
msg_message("battle_loot", "unit amount item", du, l->number,
itype->rtype);
message_faction(b, du->faction, m);
battle_message_faction(b, du->faction, m);
msg_release(m);
i_change(&du->items, itype, l->number);
}
@ -2885,54 +2871,6 @@ static void set_attacker(fighter * fig)
fset(fig, FIG_ATTACKER);
}
static void print_header(battle * b)
{
bfaction *bf;
char zText[32 * MAXSIDES];
for (bf = b->factions; bf; bf = bf->next) {
message *m;
faction *f = bf->faction;
const char *lastf = NULL;
bool first = false;
side *s;
char *bufp = zText;
size_t size = sizeof(zText) - 1;
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *df;
for (df = s->fighters; df; df = df->next) {
if (is_attacker(df)) {
if (first) {
bufp = STRLCPY(bufp, ", ", size);
}
if (lastf) {
bufp = STRLCPY(bufp, lastf, size);
first = true;
}
if (seematrix(f, s))
lastf = sidename(s);
else
lastf = LOC(f->locale, "unknown_faction_dative");
break;
}
}
}
if (first) {
bufp = STRLCPY(bufp, " ", size);
bufp = STRLCPY(bufp, LOC(f->locale, "and"), size);
bufp = STRLCPY(bufp, " ", size);
}
if (lastf) {
bufp = STRLCPY(bufp, lastf, size);
}
m = msg_message("start_battle", "factions", zText);
message_faction(b, f, m);
msg_release(m);
}
}
static void print_stats(battle * b)
{
side *s2;
@ -2955,10 +2893,10 @@ static void print_stats(battle * b)
message *msg;
char buf[1024];
message_faction(b, f, msg_separator);
battle_message_faction(b, f, msg_separator);
msg = msg_message("battle_army", "index name", army_index(s), sname);
message_faction(b, f, msg);
battle_message_faction(b, f, msg);
msg_release(msg);
bufp = buf;
@ -3195,7 +3133,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
/* change_effect wird in ageing gemacht */
/* Effekte von Artefakten */
strongmen = MIN(fig->unit->number, trollbelts(u));
strongmen = trollbelts(u);
if (strongmen > fig->unit->number) strongmen = fig->unit->number;
/* Hitpoints, Attack- und Defence-Boni f<>r alle Personen */
for (i = 0; i < fig->alive; i++) {
@ -3415,24 +3354,14 @@ fighter * get_fighter(battle * b, const struct unit * u)
static int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
{
side *s;
fighter *c = NULL;
if (!attack) {
attrib *a = a_find(u->attribs, &at_fleechance);
if (a != NULL) {
if (rng_double() <= a->data.flt) {
*cp = NULL;
return false;
}
}
}
fighter *fc = NULL;
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig;
if (s->faction == u->faction) {
for (fig = s->fighters; fig; fig = fig->next) {
if (fig->unit == u) {
c = fig;
fc = fig;
if (attack) {
set_attacker(fig);
}
@ -3441,11 +3370,11 @@ static int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
}
}
}
if (!c) {
if (!fc) {
*cp = make_fighter(b, u, NULL, attack);
return *cp != NULL;
}
*cp = c;
*cp = fc;
return false;
}
@ -3572,17 +3501,17 @@ static int battle_report(battle * b)
for (bf = b->factions; bf; bf = bf->next) {
faction *fac = bf->faction;
char buf[32 * MAXSIDES];
char *bufp = buf;
size_t size = sizeof(buf) - 1;
message *m;
sbstring sbs;
message_faction(b, fac, msg_separator);
sbs_init(&sbs, buf, sizeof(buf));
battle_message_faction(b, fac, msg_separator);
if (cont)
m = msg_message("lineup_battle", "turn", b->turn);
else
m = msg_message("after_battle", "");
message_faction(b, fac, m);
battle_message_faction(b, fac, m);
msg_release(m);
komma = false;
@ -3595,24 +3524,22 @@ static int battle_report(battle * b)
char buffer[32];
if (komma) {
bufp = STRLCPY(bufp, ", ", size);
sbs_strcat(&sbs, ", ");
}
slprintf(buffer, sizeof(buffer), "%s %2d(%s): ",
snprintf(buffer, sizeof(buffer), "%s %2d(%s): ",
loc_army, army_index(s), abbrev);
bufp = STRLCPY(bufp, buffer, size);
sbs_strcat(&sbs, buffer);
for (r = FIGHT_ROW; r != NUMROWS; ++r) {
if (alive[r]) {
if (l != FIGHT_ROW) {
bufp = STRLCPY(bufp, "+", size);
sbs_strcat(&sbs, "+");
}
while (k--) {
bufp = STRLCPY(bufp, "0+", size);
sbs_strcat(&sbs, "0+");
}
sprintf(buffer, "%d", alive[r]);
bufp = STRLCPY(bufp, buffer, size);
sbs_strcat(&sbs, buffer);
k = 0;
l = r + 1;
@ -3624,7 +3551,6 @@ static int battle_report(battle * b)
komma = true;
}
}
*bufp = 0;
fbattlerecord(b, fac, buf);
}
return cont;
@ -3841,7 +3767,7 @@ static bool start_battle(region * r, battle ** bp)
/* Ende Fehlerbehandlung Angreifer */
init_order(ord);
init_order_depr(ord);
/* attackierte Einheit ermitteln */
getunit(r, u->faction, &u2);
@ -3885,13 +3811,27 @@ static bool start_battle(region * r, battle ** bp)
join_battle(b, u, true, &c1);
join_battle(b, u2, false, &c2);
if (u2->attribs) {
if (it_mistletoe) {
int effect = get_effect(u2, it_mistletoe);
if (effect >= u->number) {
change_effect(u2, it_mistletoe, -u2->number);
c2->run.hp = u2->hp;
c2->run.number = u2->number;
c2->side->flee += u2->number;
setguard(u2, false);
rmfighter(c2, u2->number);
}
}
}
/* Hat die attackierte Einheit keinen Noaid-Status,
* wird das Flag von der Faction genommen, andere
* Einheiten greifen ein. */
if (!fval(u2, UFL_NOAID))
freset(u2->faction, FFL_NOAID);
if (c1 != NULL && c2 != NULL) {
if (c1 && c2 && c2->run.number < c2->unit->number) {
/* Merken, wer Angreifer ist, f<>r die R<>ckzahlung der
* Pr<EFBFBD>combataura bei kurzem Kampf. */
c1->side->bf->attacker = true;
@ -3967,7 +3907,8 @@ static void battle_flee(battle * b)
troop dt;
int runners = 0;
/* Flucht nicht bei mehr als 600 HP. Damit Wyrme t<>tbar bleiben. */
int runhp = MIN(600, (int)(0.9 + unit_max_hp(u) * hpflee(u->status)));
int runhp = (int)(0.9 + unit_max_hp(u) * hpflee(u->status));
if (runhp > 600) runhp = 600;
if (u->ship && fval(u->region->terrain, SEA_REGION)) {
/* keine Flucht von Schiffen auf hoher See */
@ -4010,7 +3951,7 @@ static void battle_flee(battle * b)
if (fig->person[dt.index].flags & FL_PANICED) {
ispaniced = EFFECT_PANIC_SPELL;
}
if (chance(MIN(fleechance(u) + ispaniced, 0.90))) {
if (chance(fmin(fleechance(u) + ispaniced, 0.90))) {
++runners;
flee(dt);
}
@ -4084,7 +4025,7 @@ void do_battle(region * r)
/* Bevor wir die alliierten hineinziehen, sollten wir schauen, *
* Ob jemand fliehen kann. Dann er<EFBFBD>brigt sich das ganze ja
* vielleicht schon. */
print_header(b);
report_battle_start(b);
if (!fighting) {
/* Niemand mehr da, Kampf kann nicht stattfinden. */
message *m = msg_message("aborted_battle", "");

View file

@ -47,7 +47,6 @@ extern "C" {
#define LAST_ROW FLEE_ROW
#define MAXSIDES 192 /* if there are ever more than this, we're fucked. */
typedef struct bfaction {
struct bfaction *next;
struct side *sides;
@ -172,17 +171,6 @@ extern "C" {
int catmsg; /* Merkt sich, ob Katapultmessage schon generiert. */
struct person {
int hp; /* Trefferpunkte der Personen */
#ifdef LOMEM
int attack : 8; /* (Magie) Attackenbonus der Personen */
int defence : 8; /* (Magie) Paradenbonus der Personen */
int damage : 8; /* (Magie) Schadensbonus der Personen im Nahkampf */
int damage_rear : 8; /* (Magie) Schadensbonus der Personen im Fernkampf */
int flags : 8; /* (Magie) Diverse Flags auf Kaempfern */
int speed : 8; /* (Magie) Geschwindigkeitsmultiplkator. */
int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss.
* dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */
int last_action : 4; /* In welcher Runde haben wir zuletzt etwas getan */
#else
int attack;
int defence;
int damage;
@ -191,7 +179,6 @@ extern "C" {
int speed;
int reload;
int last_action;
#endif
struct weapon *missile; /* missile weapon */
struct weapon *melee; /* melee weapon */
} *person;
@ -278,6 +265,9 @@ extern "C" {
const struct faction * stealthfaction);
int skilldiff(troop at, troop dt, int dist);
void force_leave(struct region *r, struct battle *b);
bool seematrix(const struct faction * f, const struct side * s);
const char *sidename(const struct side * s);
void battle_message_faction(struct battle * b, struct faction * f, struct message *m);
#ifdef __cplusplus
}

View file

@ -36,7 +36,7 @@ static void test_make_fighter(CuTest * tc)
test_setup();
test_create_horse();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
f = test_create_faction(NULL);
au = test_create_unit(f, r);
enable_skill(SK_MAGIC, true);
@ -65,7 +65,7 @@ static void test_make_fighter(CuTest * tc)
CuAssertIntEquals(tc, 1, af->horses);
CuAssertIntEquals(tc, 0, af->elvenhorses);
free_battle(b);
test_cleanup();
test_teardown();
}
static building_type * setup_castle(void) {
@ -94,7 +94,7 @@ static void test_defenders_get_building_bonus(CuTest * tc)
test_setup();
btype = setup_castle();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
bld = test_create_building(r, btype);
du = test_create_unit(test_create_faction(NULL), r);
@ -124,7 +124,7 @@ static void test_defenders_get_building_bonus(CuTest * tc)
CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0));
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_attackers_get_no_building_bonus(CuTest * tc)
@ -138,7 +138,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
building_type * btype;
test_setup();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
btype = setup_castle();
btype->flags |= BTF_FORTIFICATION;
bld = test_create_building(r, btype);
@ -153,7 +153,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
CuAssertPtrEquals(tc, 0, af->building);
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_building_bonus_respects_size(CuTest * tc)
@ -169,7 +169,7 @@ static void test_building_bonus_respects_size(CuTest * tc)
test_setup();
btype = setup_castle();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
btype->flags |= BTF_FORTIFICATION;
bld = test_create_building(r, btype);
bld->size = 10;
@ -190,7 +190,7 @@ static void test_building_bonus_respects_size(CuTest * tc)
CuAssertPtrEquals(tc, bld, af->building);
CuAssertPtrEquals(tc, 0, df->building);
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_building_defence_bonus(CuTest * tc)
@ -214,7 +214,7 @@ static void test_building_defence_bonus(CuTest * tc)
CuAssertIntEquals(tc, 1, building_protection(btype, 1));
CuAssertIntEquals(tc, 2, building_protection(btype, 2));
CuAssertIntEquals(tc, 2, building_protection(btype, 3));
test_cleanup();
test_teardown();
}
static fighter *setup_fighter(battle **bp, unit *u) {
@ -235,7 +235,7 @@ static void test_natural_armor(CuTest * tc)
test_setup();
rc = test_create_race("human");
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
set_level(u, SK_STAMINA, 2);
CuAssertIntEquals(tc, 0, rc_armor_bonus(rc));
CuAssertIntEquals(tc, 0, natural_armor(u));
@ -245,7 +245,7 @@ static void test_natural_armor(CuTest * tc)
rc_set_param(rc, "armor.stamina", "2");
CuAssertIntEquals(tc, 2, rc_armor_bonus(rc));
CuAssertIntEquals(tc, 1, natural_armor(u));
test_cleanup();
test_teardown();
}
static void test_calculate_armor(CuTest * tc)
@ -262,13 +262,13 @@ static void test_calculate_armor(CuTest * tc)
variant v50p = frac_make(1, 2);
test_setup();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
ibelt = it_get_or_create(rt_get_or_create("trollbelt"));
ishield = it_get_or_create(rt_get_or_create("shield"));
ashield = new_armortype(ishield, 0.0, v50p, 1, ATF_SHIELD);
ichain = it_get_or_create(rt_get_or_create("chainmail"));
achain = new_armortype(ichain, 0.0, v50p, 3, ATF_NONE);
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, v50p, 0, 0, 0, 0, SK_MELEE, 1);
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, v50p, 0, 0, 0, 0, SK_MELEE);
rc = test_create_race("human");
du = test_create_unit(test_create_faction(rc), r);
dt.index = 0;
@ -316,7 +316,7 @@ static void test_calculate_armor(CuTest * tc)
CuAssertIntEquals_Msg(tc, "laen armor", 3, calculate_armor(dt, 0, 0, &magres));
CuAssertIntEquals_Msg(tc, "laen magres bonus", 4, magres.sa[1]);
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_magic_resistance(CuTest *tc)
@ -333,7 +333,7 @@ static void test_magic_resistance(CuTest *tc)
variant v10p = frac_make(1, 10);
test_setup();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
ishield = it_get_or_create(rt_get_or_create("shield"));
ashield = new_armortype(ishield, 0.0, v50p, 1, ATF_SHIELD);
ichain = it_get_or_create(rt_get_or_create("chainmail"));
@ -388,7 +388,7 @@ static void test_magic_resistance(CuTest *tc)
CuAssert(tc, "damage reduction is never < 0.1", frac_equal(magres, frac_make(1, 10)));
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_projectile_armor(CuTest * tc)
@ -404,12 +404,12 @@ static void test_projectile_armor(CuTest * tc)
variant v50p = frac_make(1, 2);
test_setup();
r = test_create_region(0, 0, 0);
r = test_create_region(0, 0, NULL);
ishield = it_get_or_create(rt_get_or_create("shield"));
ashield = new_armortype(ishield, 0.0, v50p, 1, ATF_SHIELD);
ichain = it_get_or_create(rt_get_or_create("chainmail"));
achain = new_armortype(ichain, 0.0, v50p, 3, ATF_NONE);
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, v50p, 0, 0, 0, 0, SK_MELEE, 1);
wtype = new_weapontype(it_get_or_create(rt_get_or_create("sword")), 0, v50p, 0, 0, 0, 0, SK_MELEE);
rc = test_create_race("human");
rc->battle_flags |= BF_EQUIPMENT;
du = test_create_unit(test_create_faction(rc), r);
@ -427,7 +427,7 @@ static void test_projectile_armor(CuTest * tc)
wtype->flags = WTF_NONE;
CuAssertIntEquals_Msg(tc, "no projectiles", 4, calculate_armor(dt, 0, wtype, 0));
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_battle_skilldiff(CuTest *tc)
@ -439,14 +439,14 @@ static void test_battle_skilldiff(CuTest *tc)
test_setup();
r = test_create_region(0, 0, 0);
ud = test_create_unit(test_create_faction(0), r);
ua = test_create_unit(test_create_faction(0), r);
r = test_create_region(0, 0, NULL);
ud = test_create_unit(test_create_faction(NULL), r);
ua = test_create_unit(test_create_faction(NULL), r);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;
ua = test_create_unit(test_create_faction(0), r);
ua = test_create_unit(test_create_faction(NULL), r);
CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
ta.fighter->person[0].attack = 2;
@ -461,7 +461,7 @@ static void test_battle_skilldiff(CuTest *tc)
/* TODO: weapon modifiers, missiles, skill_formula */
free_battle(b);
test_cleanup();
test_teardown();
}
static void test_battle_skilldiff_building(CuTest *tc)
@ -475,15 +475,15 @@ static void test_battle_skilldiff_building(CuTest *tc)
test_setup();
btype = setup_castle();
r = test_create_region(0, 0, 0);
ud = test_create_unit(test_create_faction(0), r);
r = test_create_region(0, 0, NULL);
ud = test_create_unit(test_create_faction(NULL), r);
ud->building = test_create_building(ud->region, btype);
ua = test_create_unit(test_create_faction(0), r);
ua = test_create_unit(test_create_faction(NULL), r);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;
ua = test_create_unit(test_create_faction(0), r);
ua = test_create_unit(test_create_faction(NULL), r);
CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
ud->building->size = 10;
@ -496,36 +496,37 @@ static void test_battle_skilldiff_building(CuTest *tc)
CuAssertIntEquals(tc, -4, skilldiff(ta, td, 0));
free_battle(b);
test_cleanup();
test_teardown();
}
static void assert_skill(CuTest *tc, char *msg, unit *u, skill_t sk, int level, int week, int weekmax)
static void assert_skill(CuTest *tc, const char *msg, unit *u, skill_t sk, int level, int week, int weekmax)
{
skill *sv = unit_skill(u, sk);
char buf[256];
if (sv) {
sprintf(buf, "%s level %d != %d", msg, sv->level, level);
CuAssertIntEquals_Msg(tc, (const char *)&buf, level, sv->level);
sprintf(buf, "%s week %d !<= %d !<= %d", msg, week, sv->weeks, weekmax);
CuAssert(tc, (const char *)&buf, sv->weeks >= week && sv->weeks <=weekmax);
} else {
CuAssertIntEquals_Msg(tc, msg, level, 0);
CuAssertIntEquals_Msg(tc, msg, week, 0);
}
skill *sv = unit_skill(u, sk);
char buf[256];
if (sv) {
sprintf(buf, "%s level %d != %d", msg, sv->level, level);
CuAssertIntEquals_Msg(tc, buf, level, sv->level);
sprintf(buf, "%s week %d !<= %d !<= %d", msg, week, sv->weeks, weekmax);
CuAssert(tc, buf, sv->weeks >= week && sv->weeks <= weekmax);
}
else {
CuAssertIntEquals_Msg(tc, msg, level, 0);
CuAssertIntEquals_Msg(tc, msg, week, 0);
}
}
static void test_drain_exp(CuTest *tc)
static void test_drain_exp(CuTest *tc)
{
unit *u;
char *msg;
const char *msg;
int i;
double rand;
test_setup();
config_set("study.random_progress", "0");
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
set_level(u, SK_STAMINA, 3);
CuAssertIntEquals(tc, 3, unit_skill(u, SK_STAMINA)->level);
CuAssertIntEquals(tc, 4, unit_skill(u, SK_STAMINA)->weeks);
@ -533,46 +534,47 @@ static void test_drain_exp(CuTest *tc)
assert_skill(tc, msg, u, SK_STAMINA, 3, 4, 4);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
for (i=0; i<10; ++i) {
set_level(u, SK_STAMINA, 3);
drain_exp(u, 0);
assert_skill(tc, msg = "0 change", u, SK_STAMINA, 3, 4, 4);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
for (i = 0; i < 10; ++i) {
set_level(u, SK_STAMINA, 3);
drain_exp(u, 0);
assert_skill(tc, msg = "0 change", u, SK_STAMINA, 3, 4, 4);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
for (rand = 0.0; rand < 2.0; rand += 1) {
random_source_inject_constant(rand);
for (rand = 0.0; rand < 2.0; rand += 1) {
random_source_inject_constant(rand);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 29);
assert_skill(tc, msg = "no change yet", u, SK_STAMINA, 3, 4, rand == 0.0?4:5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 1);
assert_skill(tc, msg = "random change", u, SK_STAMINA, 3, 4, rand == 0.0?4:5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 29);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 30);
assert_skill(tc, msg = "plus one", u, SK_STAMINA, 3, 5, 5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
}
set_level(u, SK_STAMINA, 3);
drain_exp(u, 90);
assert_skill(tc, msg = "plus three", u, SK_STAMINA, 3, 7, 7);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 120);
assert_skill(tc, msg = "plus four", u, SK_STAMINA, 2, 5, 5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
assert_skill(tc, msg = "no change yet", u, SK_STAMINA, 3, 4, rand == 0.0 ? 4 : 5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 1);
assert_skill(tc, msg = "random change", u, SK_STAMINA, 3, 4, rand == 0.0 ? 4 : 5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 30);
assert_skill(tc, msg = "plus one", u, SK_STAMINA, 3, 5, 5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
}
set_level(u, SK_STAMINA, 3);
drain_exp(u, 90);
assert_skill(tc, msg = "plus three", u, SK_STAMINA, 3, 7, 7);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
set_level(u, SK_STAMINA, 3);
drain_exp(u, 120);
assert_skill(tc, msg = "plus four", u, SK_STAMINA, 2, 5, 5);
assert_skill(tc, msg, u, SK_MINING, 0, 0, 0);
}
test_teardown();
}
CuSuite *get_battle_suite(void)
@ -589,6 +591,6 @@ CuSuite *get_battle_suite(void)
SUITE_ADD_TEST(suite, test_natural_armor);
SUITE_ADD_TEST(suite, test_magic_resistance);
SUITE_ADD_TEST(suite, test_projectile_armor);
SUITE_ADD_TEST(suite, test_drain_exp);
DISABLE_TEST(suite, test_drain_exp);
return suite;
}

View file

@ -1,16 +1,7 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_building.h"
#include "bind_unit.h"
@ -21,6 +12,8 @@ without prior permission by the authors of Eressea.
#include <util/log.h>
#include <util/language.h>
#include <util/macros.h>
#include <util/strings.h>
#include <tolua.h>
#include <stdlib.h>
@ -84,7 +77,7 @@ static int tolua_building_set_info(lua_State * L)
const char *info = tolua_tostring(L, 2, 0);
free(self->display);
if (info)
self->display = strdup(info);
self->display = str_strdup(info);
else
self->display = NULL;
return 0;

View file

@ -1,24 +1,32 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_config.h"
#include <platform.h>
#include "jsonconf.h"
#include <kernel/config.h>
#include <kernel/jsonconf.h>
#include <util/bsdstring.h>
#include <util/nrmessage.h>
#include <kernel/building.h>
#include <kernel/race.h>
#include <kernel/ship.h>
#include <kernel/spell.h>
#include <kernel/spellbook.h>
#include <kernel/terrain.h>
#include <util/log.h>
#include <util/language.h>
#include <util/nrmessage.h>
#include <util/path.h>
#include <util/strings.h>
#include <cJSON.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "kernel/building.h"
#include "kernel/race.h"
#include "kernel/ship.h"
#include "kernel/spell.h"
#include "kernel/spellbook.h"
#include "kernel/terrain.h"
void config_reset(void) {
free_config();
free_nrmesssages();
@ -46,7 +54,7 @@ int config_parse(const char *json)
if (xp >= ep) break;
}
xp = (ep > json + 10) ? ep - 10 : json;
strlcpy(buffer, xp, sizeof(buffer));
str_strlcpy(buffer, xp, sizeof(buffer));
buffer[9] = 0;
log_error("json parse error in line %d, position %d, near `%s`\n", line, ep - lp, buffer);
}
@ -55,12 +63,12 @@ int config_parse(const char *json)
int config_read(const char *filename, const char * relpath)
{
char name[MAX_PATH];
char name[PATH_MAX];
FILE *F;
json_relpath = relpath;
if (relpath) {
join_path(relpath, filename, name, sizeof(name));
path_join(relpath, filename, name, sizeof(name));
F = fopen(name, "r");
}
else {

View file

@ -1,3 +1,6 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_eressea.h"
#include <platform.h>

View file

@ -10,7 +10,10 @@ This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_faction.h"
#include "bind_unit.h"
#include "bindings.h"
@ -31,6 +34,7 @@ without prior permission by the authors of Eressea.
#include <util/base36.h>
#include <util/language.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/password.h>
#include <tolua.h>

View file

@ -1,4 +1,7 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include <curses.h>
#include "bind_gmtool.h"
@ -9,6 +12,7 @@
#include <kernel/terrain.h>
#include <modules/autoseed.h>
#include <util/log.h>
#include <util/macros.h>
#include <tolua.h>
@ -16,6 +20,7 @@
static int tolua_run_mapper(lua_State * L)
{
UNUSED_ARG(L);
run_mapper();
return 0;
}
@ -24,6 +29,7 @@ static int tolua_highlight_region(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
int select = tolua_toboolean(L, 2, 0);
UNUSED_ARG(L);
highlight_region(r, select);
return 0;
}
@ -41,6 +47,7 @@ static int tolua_select_coordinate(lua_State * L)
int nx = (int)tolua_tonumber(L, 1, 0);
int ny = (int)tolua_tonumber(L, 2, 0);
int select = tolua_toboolean(L, 3, 0);
UNUSED_ARG(L);
if (current_state) {
select_coordinate(current_state->selected, nx, ny, select);
}
@ -186,8 +193,8 @@ static void lua_paint_info(struct window *wnd, const struct state *st)
if (!end)
break;
else {
size_t len = end - str;
int bytes = MIN((int)len, size);
int bytes = (int)(end - str);
if (bytes < size) bytes = size;
mvwaddnstr(win, line++, 1, str, bytes);
wclrtoeol(win);
str = end + 1;

View file

@ -1,3 +1,7 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_locale.h"
#include "util/language.h"
#include "direction.h"

View file

@ -1,4 +1,7 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "spells.h"
/* kernel includes */
@ -10,6 +13,7 @@
/* util includes */
#include <util/language.h>
#include <util/macros.h>
#include <util/message.h>
#include <util/nrmessage.h>

View file

@ -1,4 +1,7 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "spells/shipcurse.h"
#include "monsters.h"
@ -11,6 +14,8 @@
#include <kernel/spellbook.h>
#include <kernel/unit.h>
#include <util/macros.h>
#include <tolua.h>
#include <stdlib.h>
@ -40,6 +45,7 @@ static int tolua_planmonsters(lua_State * L)
static int tolua_spawn_dragons(lua_State * L)
{
UNUSED_ARG(L);
spawn_dragons();
return 0;
}
@ -52,6 +58,7 @@ static int tolua_get_monsters(lua_State * L)
static int tolua_spawn_undead(lua_State * L)
{
UNUSED_ARG(L);
spawn_undead();
return 0;
}

View file

@ -1,8 +1,11 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
/* kernel includes */
#include <kernel/order.h>
#include <util/parser.h>
#include <util/macros.h>
/* lua includes */
#include <tolua.h>
@ -13,7 +16,7 @@ static int tolua_order_get_token(lua_State *L) {
order *ord = (order *)tolua_tousertype(L, 1, 0);
int n = (int)tolua_tonumber(L, 2, 0);
const char * str = 0;
init_order(ord);
init_order_depr(ord);
while (n-->0) {
str = getstrtoken();
if (!str) {

View file

@ -1,6 +1,9 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_process.h"
#include <platform.h>
#include <kernel/alliance.h>
#include <kernel/config.h>
#include <kernel/order.h>

View file

@ -1,16 +1,7 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_region.h"
#include "bind_unit.h"
#include "bind_ship.h"
@ -39,6 +30,8 @@ without prior permission by the authors of Eressea.
#include <util/base36.h>
#include <util/language.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/strings.h>
#include <critbit.h>
@ -536,6 +529,27 @@ static int tolua_region_get_age(lua_State * L)
return 0;
}
static int tolua_region_get_peasants(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
if (self) {
lua_pushinteger(L, self->land ? self->land->peasants : 0);
return 1;
}
return 0;
}
static int tolua_region_set_peasants(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
if (self && self->land) {
self->land->peasants = lua_tointeger(L, 2);
}
return 0;
}
static int tolua_region_getkey(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
@ -614,7 +628,7 @@ static int tolua_plane_set_name(lua_State * L)
const char *str = tolua_tostring(L, 2, 0);
free(self->name);
if (str)
self->name = strdup(str);
self->name = str_strdup(str);
else
self->name = 0;
return 0;
@ -734,6 +748,8 @@ void tolua_region_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "age", tolua_region_get_age, NULL);
tolua_variable(L, TOLUA_CAST "buildings", tolua_region_get_buildings,
NULL);
tolua_variable(L, TOLUA_CAST "peasants", tolua_region_get_peasants,
tolua_region_set_peasants);
tolua_variable(L, TOLUA_CAST "terrain", tolua_region_get_terrain,
tolua_region_set_terrain);
tolua_function(L, TOLUA_CAST "get_resourcelevel",

View file

@ -1,19 +1,11 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_ship.h"
#include "bind_unit.h"
#include "direction.h"
#include "move.h"
#include <kernel/curse.h>
@ -25,9 +17,12 @@ without prior permission by the authors of Eressea.
#include <util/attrib.h>
#include <util/language.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/strings.h>
#include <tolua.h>
#include <string.h>
#include <lauxlib.h>
#include <lua.h>
#include <stdlib.h>
int tolua_shiplist_next(lua_State * L)
@ -45,28 +40,35 @@ int tolua_shiplist_next(lua_State * L)
static int tolua_ship_get_id(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->no);
return 1;
}
static int tolua_ship_get_name(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, ship_getname(self));
return 1;
}
static int tolua_ship_get_size(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->size);
return 1;
}
static int tolua_ship_get_display(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, self->display);
return 1;
}
static int tolua_ship_get_region(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
if (self) {
tolua_pushusertype(L, self->region, TOLUA_CAST "region");
return 1;
@ -76,8 +78,8 @@ static int tolua_ship_get_region(lua_State * L)
static int tolua_ship_set_region(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
region *r = (region *)tolua_tousertype(L, 2, NULL);
if (self) {
move_ship(self, self->region, r, NULL);
}
@ -86,22 +88,29 @@ static int tolua_ship_set_region(lua_State * L)
static int tolua_ship_set_name(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship_setname(self, tolua_tostring(L, 2, 0));
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
ship_setname(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_ship_set_size(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
self->size = lua_tointeger(L, 2);
return 0;
}
static int tolua_ship_set_display(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
free(self->display);
self->display = strdup(tolua_tostring(L, 2, 0));
self->display = str_strdup(tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_ship_get_units(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *));
unit *u = self->region->units;
@ -118,8 +127,8 @@ static int tolua_ship_get_units(lua_State * L)
static int tolua_ship_create(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
const char *sname = tolua_tostring(L, 2, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
const char *sname = tolua_tostring(L, 2, NULL);
if (sname) {
const ship_type *stype = st_find(sname);
if (stype) {
@ -138,40 +147,40 @@ static int tolua_ship_create(lua_State * L)
static int
tolua_ship_tostring(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, shipname(self));
return 1;
}
static int tolua_ship_get_flags(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->flags);
return 1;
}
static int tolua_ship_set_flags(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
self->flags = (int)tolua_tonumber(L, 2, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
self->flags = (int)lua_tointeger(L, 2);
return 0;
}
static int tolua_ship_set_coast(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
if (lua_isnil(L, 2)) {
self->coast = NODIRECTION;
}
else if (lua_isnumber(L, 2)) {
self->coast = (direction_t)tolua_tonumber(L, 2, 0);
self->coast = (direction_t)lua_tointeger(L, 2);
}
return 0;
}
static int tolua_ship_get_coast(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
if (self->coast) {
lua_pushinteger(L, self->coast);
return 1;
@ -181,28 +190,28 @@ static int tolua_ship_get_coast(lua_State * L)
static int tolua_ship_get_type(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, self->type->_name);
return 1;
}
static int tolua_ship_get_damage(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->damage);
return 1;
}
static int tolua_ship_set_damage(lua_State * L)
{
ship *self = (ship *)tolua_tousertype(L, 1, 0);
self->damage = (int)tolua_tonumber(L, 2, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
self->damage = (int)lua_tointeger(L, 2);
return 0;
}
static int tolua_ship_get_curse(lua_State *L) {
ship *self = (ship *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
if (self->attribs) {
curse * c = get_curse(self->attribs, ct_find(name));
if (c) {
@ -214,8 +223,8 @@ static int tolua_ship_get_curse(lua_State *L) {
}
static int tolua_ship_has_attrib(lua_State *L) {
ship *self = (ship *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
attrib * a = a_find(self->attribs, at_find(name));
lua_pushboolean(L, a != NULL);
return 1;
@ -236,6 +245,8 @@ void tolua_ship_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "id", tolua_ship_get_id, NULL);
tolua_variable(L, TOLUA_CAST "name", tolua_ship_get_name,
tolua_ship_set_name);
tolua_variable(L, TOLUA_CAST "size", tolua_ship_get_size,
tolua_ship_set_size);
tolua_variable(L, TOLUA_CAST "info", tolua_ship_get_display,
tolua_ship_set_display);
tolua_variable(L, TOLUA_CAST "units", tolua_ship_get_units, NULL);

View file

@ -1,95 +0,0 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <platform.h>
#include "bind_unit.h"
#include "bindings.h"
#include <kernel/config.h>
#include <sqlite3.h>
#include <tolua.h>
#define LTYPE_DB TOLUA_CAST "db"
extern int db_update_factions(sqlite3 * db, bool force, int game);
static int tolua_db_update_factions(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
db_update_factions(db, tolua_toboolean(L, 2, 0), game_id());
return 0;
}
extern int db_update_scores(sqlite3 * db, bool force);
static int tolua_db_update_scores(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
db_update_scores(db, tolua_toboolean(L, 2, 0));
return 0;
}
static int tolua_db_execute(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
const char *sql = tolua_tostring(L, 2, 0);
int res = sqlite3_exec(db, sql, 0, 0, 0);
lua_pushinteger(L, res);
return 1;
}
static int tolua_db_close(lua_State * L)
{
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
sqlite3_close(db);
return 0;
}
static int tolua_db_create(lua_State * L)
{
sqlite3 *db;
const char *dbname = tolua_tostring(L, 1, 0);
int result = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READWRITE, 0);
if (result == SQLITE_OK) {
tolua_pushusertype(L, (void *)db, LTYPE_DB);
return 1;
}
return 0;
}
int tolua_sqlite_open(lua_State * L)
{
/* register user types */
tolua_usertype(L, LTYPE_DB);
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
{
tolua_cclass(L, LTYPE_DB, LTYPE_DB, TOLUA_CAST "", NULL);
tolua_beginmodule(L, LTYPE_DB);
{
tolua_function(L, TOLUA_CAST "open", &tolua_db_create);
tolua_function(L, TOLUA_CAST "close", &tolua_db_close);
tolua_function(L, TOLUA_CAST "update_factions",
&tolua_db_update_factions);
tolua_function(L, TOLUA_CAST "update_scores", &tolua_db_update_scores);
tolua_function(L, TOLUA_CAST "execute", &tolua_db_execute);
}
tolua_endmodule(L);
}
tolua_endmodule(L);
return 0;
}

View file

@ -1,22 +1,14 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_storage.h"
#include <kernel/save.h>
#include <util/gamedata.h>
#include <util/log.h>
#include <util/macros.h>
#include <storage.h>
#include <stream.h>

View file

@ -1,4 +1,6 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#pragma warning(push)
#pragma warning(disable: 4100)
#include "config.pkg.c"

View file

@ -1,16 +1,6 @@
/*
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "bind_unit.h"
#include "alchemy.h"
@ -46,6 +36,8 @@ without prior permission by the authors of Eressea.
#include <util/event.h>
#include <util/lists.h>
#include <util/log.h>
#include <util/macros.h>
#include <selist.h>
#include <tolua.h>
@ -57,14 +49,18 @@ without prior permission by the authors of Eressea.
#include <limits.h>
static int tolua_bufunit(lua_State * L) {
char buf[8192];
unit *self = (unit *)tolua_tousertype(L, 1, 0);
int mode = (int)tolua_tonumber(L, 2, (int)seen_unit);
if (!self) return 0;
bufunit(self->faction, self, 0, mode, buf, sizeof(buf));
tolua_pushstring(L, buf);
return 1;
unit *u = (unit *)tolua_tousertype(L, 1, 0);
if (u) {
faction *f = (faction *)tolua_tousertype(L, 2, u->faction);
if (f) {
char buf[8192];
int mode = (int)tolua_tonumber(L, 3, (int)seen_unit);
bufunit(f, u, 0, mode, buf, sizeof(buf));
tolua_pushstring(L, buf);
return 1;
}
}
return 0;
}
@ -286,7 +282,7 @@ static int tolua_unit_get_magic(lua_State * L)
static void unit_setmagic(unit * u, const char *type)
{
sc_mage *mage = get_mage_depr(u);
sc_mage *mage = get_mage(u);
int mtype;
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
if (strcmp(magic_school[mtype], type) == 0)
@ -331,7 +327,7 @@ static int tolua_unit_get_age(lua_State * L)
static int tolua_unit_set_age(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
self->age = (short)tolua_tonumber(L, 2, 0);
self->age = (int)tolua_tonumber(L, 2, 0);
return 0;
}
@ -370,13 +366,10 @@ static int tolua_unit_get_effect(lua_State * L)
const unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *potion_name = tolua_tostring(L, 2, 0);
int result = -1;
const potion_type *pt_potion;
const item_type *it_potion = it_find(potion_name);
if (it_potion != NULL) {
pt_potion = it_potion->rtype->ptype;
if (pt_potion != NULL)
result = get_effect(self, pt_potion);
result = get_effect(self, it_potion);
}
lua_pushinteger(L, result);
@ -512,6 +505,19 @@ static int tolua_unit_addnotice(lua_State * L)
return 0;
}
static int bind_unit_effect(lua_State * L)
{
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
const item_type *itype = it_find(str);
if (itype) {
int effect = get_effect(u, itype);
lua_pushinteger(L, effect);
return 1;
}
return 0;
}
static void unit_castspell(unit * u, const char *name, int level)
{
spell *sp = find_spell(name);
@ -718,6 +724,30 @@ static int tolua_unit_set_region(lua_State * L)
return 0;
}
static int tolua_unit_get_order(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, -1);
order *ord = NULL;
if (index < 0) {
ord = self->thisorder;
}
else {
int i;
ord = self->orders;
for (i = 0; ord && i != index; ++i) {
ord = ord->next;
}
}
if (ord) {
char buffer[1024];
get_command(ord, self->faction->locale, buffer, sizeof(buffer));
lua_pushstring(L, buffer);
return 1;
}
return 0;
}
static int tolua_unit_add_order(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
@ -763,22 +793,6 @@ static int tolua_unit_get_spells(lua_State * L)
return tolua_selist_push(L, "spellbook", "spell_entry", slist);
}
static int tolua_unit_get_orders(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
order **order_ptr = (order **)lua_newuserdata(L, sizeof(order *));
luaL_getmetatable(L, TOLUA_CAST "order");
lua_setmetatable(L, -2);
*order_ptr = self->orders;
lua_pushcclosure(L, tolua_orderlist_next, 1);
return 1;
}
static int tolua_unit_get_curse(lua_State *L) {
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
@ -960,95 +974,95 @@ void tolua_unit_open(lua_State * L)
NULL);
tolua_beginmodule(L, TOLUA_CAST "event");
{
tolua_function(L, TOLUA_CAST "get_type", &tolua_event_gettype);
tolua_function(L, TOLUA_CAST "get", &tolua_event_get);
tolua_function(L, TOLUA_CAST "get_type", tolua_event_gettype);
tolua_function(L, TOLUA_CAST "get", tolua_event_get);
}
tolua_endmodule(L);
tolua_cclass(L, TOLUA_CAST "unit", TOLUA_CAST "unit", TOLUA_CAST "", NULL);
tolua_beginmodule(L, TOLUA_CAST "unit");
{
tolua_function(L, TOLUA_CAST "__tostring", &tolua_unit_tostring);
tolua_function(L, TOLUA_CAST "create", &tolua_unit_create);
tolua_function(L, TOLUA_CAST "destroy", &tolua_unit_destroy);
tolua_function(L, TOLUA_CAST "__tostring", tolua_unit_tostring);
tolua_function(L, TOLUA_CAST "create", tolua_unit_create);
tolua_function(L, TOLUA_CAST "destroy", tolua_unit_destroy);
tolua_variable(L, TOLUA_CAST "name", &tolua_unit_get_name,
tolua_variable(L, TOLUA_CAST "name", tolua_unit_get_name,
tolua_unit_set_name);
tolua_variable(L, TOLUA_CAST "faction", &tolua_unit_get_faction,
tolua_variable(L, TOLUA_CAST "faction", tolua_unit_get_faction,
tolua_unit_set_faction);
tolua_variable(L, TOLUA_CAST "id", tolua_unit_get_id, tolua_unit_set_id);
tolua_variable(L, TOLUA_CAST "group", tolua_unit_get_group, tolua_unit_set_group);
tolua_variable(L, TOLUA_CAST "info", tolua_unit_get_info, tolua_unit_set_info);
tolua_variable(L, TOLUA_CAST "hp", &tolua_unit_get_hp, tolua_unit_set_hp);
tolua_variable(L, TOLUA_CAST "status", &tolua_unit_get_status,
tolua_variable(L, TOLUA_CAST "hp", tolua_unit_get_hp, tolua_unit_set_hp);
tolua_variable(L, TOLUA_CAST "status", tolua_unit_get_status,
tolua_unit_set_status);
tolua_variable(L, TOLUA_CAST "familiar", &tolua_unit_get_familiar,
tolua_variable(L, TOLUA_CAST "familiar", tolua_unit_get_familiar,
tolua_unit_set_familiar);
tolua_variable(L, TOLUA_CAST "weight", &tolua_unit_get_weight, 0);
tolua_variable(L, TOLUA_CAST "capacity", &tolua_unit_get_capacity, 0);
tolua_variable(L, TOLUA_CAST "weight", tolua_unit_get_weight, 0);
tolua_variable(L, TOLUA_CAST "capacity", tolua_unit_get_capacity, 0);
tolua_function(L, TOLUA_CAST "add_order", &tolua_unit_add_order);
tolua_function(L, TOLUA_CAST "clear_orders", &tolua_unit_clear_orders);
tolua_variable(L, TOLUA_CAST "orders", &tolua_unit_get_orders, 0);
tolua_function(L, TOLUA_CAST "get_curse", &tolua_unit_get_curse);
tolua_function(L, TOLUA_CAST "has_attrib", &tolua_unit_has_attrib);
tolua_function(L, TOLUA_CAST "get_order", tolua_unit_get_order);
tolua_function(L, TOLUA_CAST "add_order", tolua_unit_add_order);
tolua_function(L, TOLUA_CAST "clear_orders", tolua_unit_clear_orders);
tolua_function(L, TOLUA_CAST "get_curse", tolua_unit_get_curse);
tolua_function(L, TOLUA_CAST "has_attrib", tolua_unit_has_attrib);
/* key-attributes for named flags: */
tolua_function(L, TOLUA_CAST "set_flag", &tolua_unit_set_flag);
tolua_function(L, TOLUA_CAST "get_flag", &tolua_unit_get_flag);
tolua_variable(L, TOLUA_CAST "guard", &tolua_unit_get_guard,
&tolua_unit_set_guard);
tolua_variable(L, TOLUA_CAST "flags", &tolua_unit_get_flags,
&tolua_unit_set_flags);
tolua_variable(L, TOLUA_CAST "age", &tolua_unit_get_age,
tolua_function(L, TOLUA_CAST "set_flag", tolua_unit_set_flag);
tolua_function(L, TOLUA_CAST "get_flag", tolua_unit_get_flag);
tolua_variable(L, TOLUA_CAST "guard", tolua_unit_get_guard,
tolua_unit_set_guard);
tolua_variable(L, TOLUA_CAST "flags", tolua_unit_get_flags,
tolua_unit_set_flags);
tolua_variable(L, TOLUA_CAST "age", tolua_unit_get_age,
tolua_unit_set_age);
/* items: */
tolua_function(L, TOLUA_CAST "get_item", &tolua_unit_get_item);
tolua_function(L, TOLUA_CAST "add_item", &tolua_unit_add_item);
tolua_variable(L, TOLUA_CAST "items", &tolua_unit_get_items, 0);
tolua_function(L, TOLUA_CAST "get_pooled", &tolua_unit_get_pooled);
tolua_function(L, TOLUA_CAST "use_pooled", &tolua_unit_use_pooled);
tolua_function(L, TOLUA_CAST "get_item", tolua_unit_get_item);
tolua_function(L, TOLUA_CAST "add_item", tolua_unit_add_item);
tolua_variable(L, TOLUA_CAST "items", tolua_unit_get_items, 0);
tolua_function(L, TOLUA_CAST "get_pooled", tolua_unit_get_pooled);
tolua_function(L, TOLUA_CAST "use_pooled", tolua_unit_use_pooled);
/* effects */
tolua_function(L, TOLUA_CAST "get_potion", &tolua_unit_get_effect);
tolua_function(L, TOLUA_CAST "get_potion", tolua_unit_get_effect);
/* skills: */
tolua_function(L, TOLUA_CAST "get_skill", &tolua_unit_getskill);
tolua_function(L, TOLUA_CAST "eff_skill", &tolua_unit_effskill);
tolua_function(L, TOLUA_CAST "set_skill", &tolua_unit_setskill);
tolua_function(L, TOLUA_CAST "get_skill", tolua_unit_getskill);
tolua_function(L, TOLUA_CAST "eff_skill", tolua_unit_effskill);
tolua_function(L, TOLUA_CAST "set_skill", tolua_unit_setskill);
tolua_function(L, TOLUA_CAST "add_notice", &tolua_unit_addnotice);
tolua_function(L, TOLUA_CAST "add_notice", tolua_unit_addnotice);
/* npc logic: */
tolua_function(L, TOLUA_CAST "add_handler", &tolua_unit_addhandler);
tolua_function(L, TOLUA_CAST "add_handler", tolua_unit_addhandler);
tolua_variable(L, TOLUA_CAST "race_name", &tolua_unit_get_racename,
&tolua_unit_set_racename);
tolua_function(L, TOLUA_CAST "add_spell", &tolua_unit_addspell);
tolua_variable(L, TOLUA_CAST "spells", &tolua_unit_get_spells, 0);
tolua_function(L, TOLUA_CAST "cast_spell", &tolua_unit_castspell);
tolua_variable(L, TOLUA_CAST "race_name", tolua_unit_get_racename,
tolua_unit_set_racename);
tolua_function(L, TOLUA_CAST "add_spell", tolua_unit_addspell);
tolua_variable(L, TOLUA_CAST "spells", tolua_unit_get_spells, 0);
tolua_function(L, TOLUA_CAST "cast_spell", tolua_unit_castspell);
tolua_function(L, TOLUA_CAST "effect", bind_unit_effect);
tolua_variable(L, TOLUA_CAST "magic", &tolua_unit_get_magic,
tolua_variable(L, TOLUA_CAST "magic", tolua_unit_get_magic,
tolua_unit_set_magic);
tolua_variable(L, TOLUA_CAST "aura", &tolua_unit_get_aura,
tolua_variable(L, TOLUA_CAST "aura", tolua_unit_get_aura,
tolua_unit_set_aura);
tolua_variable(L, TOLUA_CAST "building", &tolua_unit_get_building,
tolua_variable(L, TOLUA_CAST "building", tolua_unit_get_building,
tolua_unit_set_building);
tolua_variable(L, TOLUA_CAST "ship", &tolua_unit_get_ship,
tolua_variable(L, TOLUA_CAST "ship", tolua_unit_get_ship,
tolua_unit_set_ship);
tolua_variable(L, TOLUA_CAST "region", &tolua_unit_get_region,
tolua_variable(L, TOLUA_CAST "region", tolua_unit_get_region,
tolua_unit_set_region);
tolua_variable(L, TOLUA_CAST "number", &tolua_unit_get_number,
tolua_variable(L, TOLUA_CAST "number", tolua_unit_get_number,
tolua_unit_set_number);
tolua_variable(L, TOLUA_CAST "race", &tolua_unit_get_race,
tolua_variable(L, TOLUA_CAST "race", tolua_unit_get_race,
tolua_unit_set_race);
tolua_variable(L, TOLUA_CAST "hp_max", &tolua_unit_get_hpmax, 0);
tolua_variable(L, TOLUA_CAST "aura_max", &tolua_unit_get_auramax, 0);
tolua_variable(L, TOLUA_CAST "hp_max", tolua_unit_get_hpmax, 0);
tolua_variable(L, TOLUA_CAST "aura_max", tolua_unit_get_auramax, 0);
tolua_function(L, TOLUA_CAST "show", &tolua_bufunit);
tolua_function(L, TOLUA_CAST "show", tolua_bufunit);
}
tolua_endmodule(L);
}

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