diff --git a/.editorconfig b/.editorconfig
index cd3315bd8..fafe79d54 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -24,3 +24,8 @@ indent_style = tab
[.travis.yml]
indent_style = space
indent_size = 2
+
+# Matches exact files
+[CMakeLists.txt]
+indent_style = space
+indent_size = 2
diff --git a/.gitignore b/.gitignore
index d5e8e1b10..75ec9a227 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ ipch/
*.user
*~
+*.pyc
*.bak
bin/
build*/
@@ -36,6 +37,7 @@ Thumbs.db
*.cfg
*.cmd
tmp/
+tests/orders.txt
tests/config.lua
tests/reports/
tests/data/185.dat
diff --git a/.travis.yml b/.travis.yml
index 62e60194f..c6a21d0e4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,7 @@ addons:
apt:
packages:
- libbsd-dev
+ - libdb-dev
- liblua5.1-dev
- libtolua-dev
- libncurses5-dev
diff --git a/conf/e3/config.json b/conf/e3/config.json
index b4b6d0e48..dcc3e9f53 100644
--- a/conf/e3/config.json
+++ b/conf/e3/config.json
@@ -28,7 +28,6 @@
"stealth",
"taxation",
"trade",
- "besiege",
"steal",
"buy",
"teach",
diff --git a/conf/keywords.json b/conf/keywords.json
index 4f8f27f5b..11376ea95 100644
--- a/conf/keywords.json
+++ b/conf/keywords.json
@@ -12,7 +12,6 @@
"work": [ "ARBEITE", "ARBEITEN" ],
"attack": ["ATTACKIERE", "ATTACKIEREN"],
"steal": [ "BEKLAUE", "BEKLAUEN" ],
- "besiege": ["BELAGERE", "BELAGERN" ],
"name": [ "BENENNE", "BENENNEN" ],
"use": [ "BENUTZE", "BENUTZEN" ],
"describe": [ "BESCHREIBE", "BESCHREIBEN" ],
diff --git a/process/CMakeLists.txt b/process/CMakeLists.txt
index 0ffb7b4a2..bbd9b8c38 100644
--- a/process/CMakeLists.txt
+++ b/process/CMakeLists.txt
@@ -1,7 +1,7 @@
install(PROGRAMS create-orders backup-eressea run-turn send-zip-report
send-bz2-report compress.py compress.sh epasswd.py orders-process
-process-orders.py accept-orders.py
-checkpasswd.py sendreport.sh sendreports.sh orders-accept DESTINATION bin)
+process-orders.py accept-orders.py getemail.py checkpasswd.py
+sendreport.sh sendreports.sh orders-accept DESTINATION bin)
install(DIRECTORY cron/ DESTINATION bin USE_SOURCE_PERMISSIONS
FILES_MATCHING PATTERN "*.cron")
diff --git a/process/checkpasswd.py b/process/checkpasswd.py
index f797dcfde..dd4924b32 100755
--- a/process/checkpasswd.py
+++ b/process/checkpasswd.py
@@ -6,14 +6,19 @@ from epasswd import EPasswd
if len(sys.argv)<4:
sys.exit(-2)
-passfile=sys.argv[1]
+filename=sys.argv[1]
myfaction=sys.argv[2]
mypasswd=sys.argv[3]
-if mypasswd[0]=='"':
- mypasswd=mypasswd[1:len(mypasswd)-1]
+if mypasswd[0] == '"':
+ mypasswd = mypasswd.strip('"')
+
+pw_data = EPasswd()
+try:
+ pw_data.load_database(filename)
+except:
+ pw_data.load_file(filename)
-pw_data=EPasswd(passfile)
if pw_data.fac_exists(myfaction):
if pw_data.check(myfaction, mypasswd):
sys.exit(0)
diff --git a/process/epasswd.py b/process/epasswd.py
index aa3d79fa6..4cac6e1ce 100755
--- a/process/epasswd.py
+++ b/process/epasswd.py
@@ -4,47 +4,82 @@ from string import split
from string import strip
from string import lower
import subprocess
+import bcrypt
+import sqlite3
+
+def baseconvert(n, base):
+ """convert positive decimal integer n to equivalent in another base (2-36)"""
+
+ digits = "0123456789abcdefghijkLmnopqrstuvwxyz"
+
+ try:
+ n = int(n)
+ base = int(base)
+ except:
+ return ""
+
+ if n < 0 or base < 2 or base > 36:
+ return ""
+
+ s = ""
+ while True:
+ r = n % base
+ s = digits[r] + s
+ n = n / base
+ if n == 0:
+ break
+
+ return s
class EPasswd:
- def _check_apr1(self, pwhash, pw):
- spl = split(pwhash, '$')
- salt = spl[2]
- hash = subprocess.check_output(['openssl', 'passwd', '-apr1', '-salt', salt, pw]).decode('utf-8').strip()
- return hash==pwhash
+ def __init__(self):
+ self.data = {}
- def __init__(self, file):
- self.data = {}
- try:
- fp = open(file,"r")
- except:
- fp = None
- if fp != None:
- while True:
- line = fp.readline()
- if not line: break
- line = strip(line)
- [id, email, passwd] = split(line, ":")[0:3]
- lc_id = lower(id)
- self.data[lc_id] = {}
- self.data[lc_id]["id"] = id
- self.data[lc_id]["email"] = email
- self.data[lc_id]["passwd"] = passwd
- fp.close()
+ def set_data(self, no, email, passwd):
+ lc_id = lower(no)
+ self.data[lc_id] = {}
+ self.data[lc_id]["id"] = no
+ self.data[lc_id]["email"] = email
+ self.data[lc_id]["passwd"] = passwd
- def check(self, id, passwd):
- pw = self.get_passwd(id)
- if pw[0:6]=='$apr1$':
- return self._check_apr1(pw, passwd)
- return pw == passwd
+ def load_database(self, file):
+ conn = sqlite3.connect(file)
+ c = conn.cursor()
+ c.execute('SELECT MAX(turn) FROM factions')
+ args = c.fetchone()
+ for row in c.execute('SELECT no, email, password FROM factions WHERE turn=?', args):
+ (no, email, passwd) = row
+ self.set_data(baseconvert(no, 36), email, passwd)
+ conn.close()
- def get_passwd(self, id):
- return self.data[lower(id)]["passwd"]
-
- def get_email(self, id):
- return self.data[lower(id)]["email"]
-
- def get_canon_id(self, id):
- return self.data[lower(id)]["id"]
+ def load_file(self, file):
+ try:
+ fp = open(file,"r")
+ except:
+ fp = None
+ if fp != None:
+ while True:
+ line = fp.readline()
+ if not line: break
+ line = strip(line)
+ [id, email, passwd] = split(line, ":")[0:3]
+ self.set_data(id, email, passwd)
+ fp.close()
- def fac_exists(self, id):
- return self.data.has_key(lower(id))
+ def check(self, id, passwd):
+ pw = self.get_passwd(id)
+ if pw[0:4]=='$2a$' or pw[0:4]=='$2y$':
+ return bcrypt.checkpw(passwd, pw)
+ return pw == passwd
+
+ def get_passwd(self, id):
+ return self.data[lower(id)]["passwd"]
+
+ def get_email(self, id):
+ return self.data[lower(id)]["email"]
+
+ def get_canon_id(self, id):
+ return self.data[lower(id)]["id"]
+
+ def fac_exists(self, id):
+ return self.data.has_key(lower(id))
diff --git a/process/getemail.py b/process/getemail.py
new file mode 100755
index 000000000..d9951bcb0
--- /dev/null
+++ b/process/getemail.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+import sys, re
+from epasswd import EPasswd
+
+if len(sys.argv)<3:
+ sys.exit(-2)
+
+filename=sys.argv[1]
+myfaction=sys.argv[2]
+
+pw_data = EPasswd()
+try:
+ pw_data.load_database(filename)
+except:
+ pw_data.load_file(filename)
+
+if pw_data.fac_exists(myfaction):
+ email = pw_data.get_email(myfaction)
+ print(email)
+ sys.exit(0)
+sys.exit(-1)
diff --git a/process/process-orders.py b/process/process-orders.py
index 8ed5e8625..3c741bfeb 100755
--- a/process/process-orders.py
+++ b/process/process-orders.py
@@ -128,7 +128,11 @@ def echeck(filename, locale, rules):
return mail
#print "reading password file..."
-pw_data = EPasswd(os.path.join(game_dir,"passwd"))
+pw_data = EPasswd()
+try:
+ pw_data.load_database(os.path.join(game_dir,"eressea.db"))
+except:
+ pw_data.load_file(os.path.join(game_dir,"passwd"))
#print "reading orders.queue..."
# move the queue file to a save space while locking it:
diff --git a/process/procmail/rules b/process/procmail/rules
index 32626fe56..7c70c84bb 100644
--- a/process/procmail/rules
+++ b/process/procmail/rules
@@ -2,26 +2,6 @@
## Eressea Reportversand
##
-:0:server.lock
-* ^Subject:.*ERE.*2.*PASSWOR.*
-| sendpassword.py $HOME/eressea/game-2/passwd
-
-:0:server.lock
-* ^Subject:.*ERE.*3.*PASSWOR.*
-| sendpassword.py $HOME/eressea/game-3/passwd
-
-:0:server.lock
-* ^Subject:.*ERE.*4.*PASSWOR.*
-| sendpassword.py $HOME/eressea/game-4/passwd
-
-:0:server.lock
-* ^Subject:.*ERE.*PASSWOR.*
-| sendpassword.py $HOME/eressea/game-2/passwd
-
-:0:server.lock
-* ^Subject:.*E3.*PASSWOR.*
-| sendpassword.py $HOME/eressea/game-3/passwd
-
:0:server.lock
* ^Subject:.*ERE.*2.*REPORT \/.*
* !From: .*eressea.*@eressea.de
diff --git a/process/sendreport.sh b/process/sendreport.sh
index d98ed505e..7b1afccf0 100755
--- a/process/sendreport.sh
+++ b/process/sendreport.sh
@@ -30,7 +30,11 @@ LOCKFILE="$ERESSEA/.report.lock"
echo "$(date):report:$GAME:$EMAIL:$FACTION:$PASSWD" >> "$ERESSEA/request.log"
cd "$ERESSEA" || exit
-checkpasswd.py "game-$GAME/passwd" "$FACTION" "$PASSWD" || reply "Das Passwort fuer die Partei $FACTION ist ungueltig"
+PWFILE="game-$GAME/eressea.db"
+if [ ! -e "$PWFILE" ]; then
+ PWFILE="game-$GAME/passwd"
+fi
+checkpasswd.py "$PWFILE" "$FACTION" "$PASSWD" || reply "Das Passwort fuer die Partei $FACTION ist ungueltig"
cd "$ERESSEA/game-$GAME/reports" || exit
if [ ! -e "${FACTION}.sh" ]; then
@@ -41,12 +45,8 @@ fi
bash "${FACTION}.sh" "$EMAIL" || reply "Unbekannte Partei $FACTION"
-if [ -e "$ERESSEA/game-$GAME/eressea.db" ]; then
- SQL="select email from faction f left join faction_data fd on fd.faction_id=f.id where f.game_id=$GAME AND fd.code='$FACTION' and fd.turn=(select max(turn) from faction_data fx where fx.faction_id=f.id)"
- OWNER=$(sqlite3 "$ERESSEA/game-$GAME/eressea.db" "$SQL")
- if [ ! -z "$OWNER" ]; then
- echo "Der Report Deiner Partei wurde an ${EMAIL} gesandt." \
- | mutt -s "Reportnachforderung Partei ${FACTION}" "$OWNER"
- fi
+OWNER=$(getfaction.py "$PWFILE" "$FACTION")
+if [ ! -z "$OWNER" ]; then
+ echo "Der Report Deiner Partei wurde an ${EMAIL} gesandt." \
+ | mutt -s "Reportnachforderung Partei ${FACTION}" "$OWNER"
fi
-
diff --git a/res/core/messages.xml b/res/core/messages.xml
index 1e4e977e0..d2c40f9b3 100644
--- a/res/core/messages.xml
+++ b/res/core/messages.xml
@@ -710,12 +710,6 @@
-
-
-
-
-
-
@@ -2684,19 +2678,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -3351,14 +3332,6 @@
-
-
-
-
-
-
-
-
@@ -3890,13 +3863,6 @@
-
-
-
-
-
-
-
@@ -4002,13 +3968,6 @@
-
-
-
-
-
-
-
@@ -4993,20 +4952,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po
index 507f0e39d..76ff0afc9 100644
--- a/res/translations/messages.de.po
+++ b/res/translations/messages.de.po
@@ -257,9 +257,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier kann man k
msgid "error165"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Trank bekommt der Einheit nicht.\""
-msgid "siege_catapults"
-msgstr "\"$unit($unit) belagert $building($building). Dabei richten die Katapulte Zerstörungen von $int($destruction) Größenpunkten an.\""
-
msgid "curseinfo::magicstreet"
msgstr "\"Die Straßen sind erstaunlich trocken und gut begehbar. ($int36($id))\""
@@ -638,9 +635,6 @@ msgstr "\"$unit($unit) erscheint plötzlich.\""
msgid "magicresistance_effect"
msgstr "\"$unit($unit) wird kurz von einem magischen Licht umhüllt.\""
-msgid "siege"
-msgstr "\"$unit($unit) belagert $building($building).\""
-
msgid "missing_force"
msgstr "\"$unit($unit) schafft es nicht, genug Kraft aufzubringen, um $spell($spell) auf Stufe $int($level) zu zaubern.\""
@@ -977,9 +971,6 @@ msgstr "\"$unit($mage) kümmert sich um die Verletzten und benutzt ein $resource
msgid "error276"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier kann man keine Schiffe bauen.\""
-msgid "error166"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Diese Rasse kann eine Burg nicht belagern.\""
-
msgid "chaosgate_effect_2"
msgstr "\"Ein Wirbel aus blendendem Licht erscheint.\""
@@ -998,9 +989,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit ist
msgid "error82"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Es gibt keine Abstimmung mit dieser Nummer.\""
-msgid "error60"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit wird belagert.\""
-
msgid "error162"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Heiltrank wird automatisch bei Bedarf benutzt.\""
@@ -1457,9 +1445,6 @@ msgstr "\"$unit($unit) öffnet eines der Schlösser in $region($region) mit $if(
msgid "error255"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - So etwas kann man nicht opfern.\""
-msgid "entrance_besieged"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - $building($building) wird belagert.\""
-
msgid "error260"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Besitzer eines Schiffes oder Gebäudes kann nicht neu sortiert werden.\""
@@ -1550,9 +1535,6 @@ msgstr "\"In $region($region) findet ein Kampf statt.\""
msgid "wormhole_dissolve"
msgstr "\"Das Wurmloch in $region($region) schließt sich.\""
-msgid "error23"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Belagerungszustand macht die Kontaktaufnahme unmöglich.\""
-
msgid "error12"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Das Schiff gehört uns nicht.\""
@@ -2135,9 +2117,6 @@ msgstr "\"Seit $int($age) Wochen Mitglied der Allianz '$name ($int36($id))', ang
msgid "deathcloud_effect"
msgstr "\"$unit($mage) beschwört einen Giftelementar in $region($region).\""
-msgid "nr_building_besieged"
-msgstr "\", belagert von $int($soldiers) Personen$if($lt($diff,0),\"\",\" (abgeschnitten)\")\""
-
msgid "nr_population"
msgstr "\"Deine Partei hat $int($population) Personen in $int($units) von maximal $int($limit) Einheiten.\""
@@ -2414,9 +2393,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Das Schiff hat
msgid "aborted_battle"
msgstr "\"Der Kampf wurde abgebrochen, da alle Verteidiger flohen.\""
-msgid "error24"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Belagerungszustand macht Spionage unmöglich.\""
-
msgid "usecatapult"
msgstr "\"$int($amount) Krieger von $unit($unit) feuern ihre Katapulte ab.\""
diff --git a/res/translations/messages.en.po b/res/translations/messages.en.po
index bf9d8e3c9..50108fc03 100644
--- a/res/translations/messages.en.po
+++ b/res/translations/messages.en.po
@@ -257,9 +257,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Buildings canno
msgid "error165"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The potion does not agree with the unit.\""
-msgid "siege_catapults"
-msgstr "\"$building($building) is under siege by $unit($unit). During siege, catapults caused $int($destruction) points destruction.\""
-
msgid "curseinfo::magicstreet"
msgstr "\"The roads are extremely dry and well-kept. ($int36($id))\""
@@ -638,9 +635,6 @@ msgstr "\"$unit($unit) appears.\""
msgid "magicresistance_effect"
msgstr "\"$unit($unit) is briefly surrounded by a magical light.\""
-msgid "siege"
-msgstr "\"$building($building) is under siege by $unit($unit).\""
-
msgid "missing_force"
msgstr "\"$unit($unit) cannot muster enough energy to cast $spell($spell) on level $int($level).\""
@@ -977,9 +971,6 @@ msgstr "\"$unit($mage) sees after the wounded and heals $int($amount). A $resour
msgid "error276"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Ships cannot be built here.\""
-msgid "error166"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - This race cannot besiege a castle.\""
-
msgid "chaosgate_effect_2"
msgstr "\"A vortex of blinding light appears.\""
@@ -998,9 +989,6 @@ msgstr "\"'$order($command)' - $unit($unit) marched into $region($region) during
msgid "error82"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - There is no agreement with this number.\""
-msgid "error60"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit is under siege.\""
-
msgid "error162"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - This healing potion will be automatically used when needed.\""
@@ -1457,9 +1445,6 @@ msgstr "\"$unit($unit) unlocks one of the locks in $region($region) with $if($eq
msgid "error255"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - You cannot sacrifice this.\""
-msgid "entrance_besieged"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - $building($building) is under siege.\""
-
msgid "error260"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The owner of a ship or a building cannot be sorted.\""
@@ -1550,9 +1535,6 @@ msgstr "\"There is a battle in $region($region).\""
msgid "wormhole_dissolve"
msgstr "\"The wormhole in $region($region) disappears.\""
-msgid "error23"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Contact was not possible due to siege.\""
-
msgid "error12"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The ship is not ours.\""
@@ -2135,9 +2117,6 @@ msgstr "\"Member of '$name ($int36($id))' for $int($age) weeks, led by $faction(
msgid "deathcloud_effect"
msgstr "\"$unit($mage) summons a poison elemental in $region($region).\""
-msgid "nr_building_besieged"
-msgstr "\", besieged by $int($soldiers) soldiers$if($lt($diff,0),\"\",\" (cut off)\")\""
-
msgid "nr_population"
msgstr "\"Your faction has $int($population) people in $int($units) of $int($limit) possible units.\""
@@ -2414,9 +2393,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - The ship has mo
msgid "aborted_battle"
msgstr "\"The battle was aborted because all enemies escaped.\""
-msgid "error24"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Espionage was not possible due to siege.\""
-
msgid "usecatapult"
msgstr "\"$int($amount) fighters of $unit($unit) launch their catapults.\""
diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po
index f4b166221..89875baf5 100644
--- a/res/translations/strings.de.po
+++ b/res/translations/strings.de.po
@@ -1437,7 +1437,7 @@ msgstr "Goblins"
msgctxt "spellinfo"
msgid "song_of_slavery"
-msgstr "Dieser mächtige Bann raubt dem Opfer seinen freien Willen und unterwirft sie den Befehlen des Barden. Für einige Zeit wird das Opfer sich völlig von seinen eigenen Leuten abwenden und der Partei des Barden zugehörig fühlen."
+msgstr "Dieser mächtige Bann raubt dem Opfer seinen freien Willen und unterwirft es den Befehlen des Barden. Für einige Zeit wird das Opfer sich völlig von seinen eigenen Leuten abwenden und der Partei des Barden zugehörig fühlen."
msgctxt "spell"
msgid "healingzone"
@@ -2772,10 +2772,6 @@ msgstr "Dieser wunderschoen geschmueckte Baum entfaltet in den Wintermonaten ein
msgid "h10"
msgstr "Kakteenschwitz"
-msgctxt "keyword"
-msgid "besiege"
-msgstr "BELAGERE"
-
msgid "h11"
msgstr "Sandfäule"
diff --git a/res/translations/strings.en.po b/res/translations/strings.en.po
index 32924310c..8a5dcb30f 100644
--- a/res/translations/strings.en.po
+++ b/res/translations/strings.en.po
@@ -2421,10 +2421,6 @@ msgctxt "iteminfo"
msgid "xmastree"
msgstr "In the winter months, this beautifully decorated tree has a magical effect on the entire forest."
-msgctxt "keyword"
-msgid "besiege"
-msgstr "BESIEGE"
-
msgid "h10"
msgstr "peyote"
diff --git a/s/cmake-init b/s/cmake-init
index 337490f07..eea222334 100755
--- a/s/cmake-init
+++ b/s/cmake-init
@@ -1,16 +1,46 @@
#!/bin/sh
-ERESSEA_DB=db
-if [ -e /usr/include/sqlite3.h ] ; then
-ERESSEA_DB=sqlite
+ERESSEA_DB=memory
+pkg-config --exists sqlite3 && ERESSEA_DB=sqlite
+
+GETOPT=getopt
+GETOPT_LONG=1
+
+if [ "Darwin" = "$(uname)" ] ; then
+ if [ -x "/usr/local/opt/gnu-getopt/bin/getopt" ] ; then
+ GETOPT="/usr/local/opt/gnu-getopt/bin/getopt"
+ else
+ GETOPT_LONG=0
+ fi
+fi
+
+if [ $GETOPT_LONG -eq 1 ]; then
+ options=$(${GETOPT} -o d: -l db: -- "$@")
+else # assume GNU getopt (long arguments)
+ options=$(${GETOPT} d: "$@")
fi
# Parse command line arguments
+eval set -- "$options"
+until [ -z "$1" ] ; do
+ case $1 in
+ -d|--db)
+ ERESSEA_DB=$2
+ shift
+ ;;
+ --) shift; break;;
+ (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
+ (*) break;;
+ esac
+ shift
+done
while [ ! -z "$1" ] ; do
if [ "$1" = "--with-db" ] ; then
ERESSEA_DB=db
elif [ "$1" = "--with-sqlite" ] ; then
ERESSEA_DB=sqlite
+elif [ "$1" = "--with-memory" ] ; then
+ERESSEA_DB=memory
fi
shift 1
done
diff --git a/s/preview b/s/preview
index 39d5466d0..2fde22cda 100755
--- a/s/preview
+++ b/s/preview
@@ -22,11 +22,12 @@ exit $2 # otherwise
function build() {
assert_dir $SOURCE
cd $SOURCE
-rm -rf crypto tolua
+rm -rf tolua
git fetch || abort "failed to update source. do you have local changes?"
[ -z $1 ] || git checkout $1
git pull -q
git submodule update
+s/cmake-init
s/build > /dev/null || abort "build failed."
}
@@ -54,7 +55,8 @@ cd $TESTROOT
cat >| eressea.ini <
-#include
+#include "platform.h"
+#include "kernel/config.h"
#include
#include
#include
diff --git a/src/alchemy.c b/src/alchemy.c
index 4b7e961a6..1673d5196 100644
--- a/src/alchemy.c
+++ b/src/alchemy.c
@@ -33,8 +33,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
/* util includes */
-#include
-#include
+#include
+#include
#include
#include
#include
@@ -66,7 +66,8 @@ void new_potiontype(item_type * itype, int level)
{
potion_type *ptype;
- ptype = (potion_type *)calloc(sizeof(potion_type), 1);
+ ptype = (potion_type *)calloc(1, sizeof(potion_type));
+ assert(ptype);
itype->flags |= ITF_POTION;
ptype->itype = itype;
ptype->level = level;
@@ -181,7 +182,7 @@ int use_potion(unit * u, const item_type * itype, int amount, struct order *ord)
static void a_initeffect(variant *var)
{
- var->v = calloc(sizeof(effect_data), 1);
+ var->v = calloc(1, sizeof(effect_data));
}
static void
diff --git a/src/alchemy.test.c b/src/alchemy.test.c
index 32024ba1c..e7d9206c4 100644
--- a/src/alchemy.test.c
+++ b/src/alchemy.test.c
@@ -44,16 +44,16 @@ static void test_herbsearch(CuTest * tc)
CuAssertPtrEquals(tc, u2, is_guarded(r, u));
herbsearch(u, INT_MAX);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error70"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
setguard(u2, false);
- CuAssertPtrEquals(tc, 0, is_guarded(r, u));
- CuAssertPtrEquals(tc, 0, (void *)rherbtype(r));
+ CuAssertPtrEquals(tc, NULL, is_guarded(r, u));
+ CuAssertPtrEquals(tc, NULL, (void *)rherbtype(r));
herbsearch(u, INT_MAX);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error108"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error70"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
rsetherbtype(r, itype);
@@ -61,9 +61,9 @@ static void test_herbsearch(CuTest * tc)
CuAssertIntEquals(tc, 0, rherbs(r));
herbsearch(u, INT_MAX);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "researchherb_none"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error108"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error70"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
rsetherbs(r, 100);
@@ -72,10 +72,10 @@ static void test_herbsearch(CuTest * tc)
CuAssertIntEquals(tc, 99, rherbs(r));
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "herbfound"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "researchherb_none"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70"));
- CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "researchherb_none"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error108"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error70"));
+ CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
test_teardown();
diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c
index fa6f15d73..12cb9131f 100644
--- a/src/attributes/attributes.c
+++ b/src/attributes/attributes.c
@@ -53,9 +53,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
/* util includes */
-#include
-#include
-#include
+#include
+#include
+#include
#include
#include
@@ -98,7 +98,7 @@ static int obs_read(variant *var, void *owner, struct gamedata *data)
obs_data *od = (obs_data *)var->v;
UNUSED_ARG(owner);
- read_faction_reference(data, &od->f, NULL);
+ read_faction_reference(data, &od->f);
READ_INT(data->store, &od->skill);
READ_INT(data->store, &od->timer);
return AT_READ_OK;
@@ -182,13 +182,13 @@ void register_attributes(void)
at_register(&at_seenspell);
at_register(&at_seenspells);
- /* neue REGION-Attribute */
+ /* REGION Attribute */
at_register(&at_moveblock);
at_register(&at_deathcount);
at_register(&at_woodcount);
+ at_register(&at_germs);
- /* neue UNIT-Attribute */
- at_register(&at_siege);
+ /* UNIT Attribute */
at_register(&at_effect);
at_register(&at_private);
@@ -205,8 +205,7 @@ void register_attributes(void)
register_bordertype(&bt_illusionwall);
register_bordertype(&bt_road);
- at_register(&at_germs);
-
+ at_deprecate("siege", a_readint);
at_deprecate("maxmagicians", a_readint); /* factions with differnt magician limits, probably unused */
at_deprecate("hurting", a_readint); /* an old arena attribute */
at_deprecate("chaoscount", a_readint); /* used to increase the chance of monster spawns */
diff --git a/src/attributes/dict.c b/src/attributes/dict.c
index bc5e94204..70e88219d 100644
--- a/src/attributes/dict.c
+++ b/src/attributes/dict.c
@@ -29,10 +29,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
/* util includes */
-#include
+#include
#include
#include
-#include
+#include
#include
#include
diff --git a/src/attributes/follow.c b/src/attributes/follow.c
index 8c5e14526..caeecee54 100644
--- a/src/attributes/follow.c
+++ b/src/attributes/follow.c
@@ -22,8 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include
-#include
-#include
+#include
+#include
#include
#include
diff --git a/src/attributes/hate.c b/src/attributes/hate.c
index c260de335..cef483cf6 100644
--- a/src/attributes/hate.c
+++ b/src/attributes/hate.c
@@ -22,8 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
-#include
-#include
+#include
+#include
#include
#include
diff --git a/src/attributes/iceberg.c b/src/attributes/iceberg.c
index e36e6303a..192ae9032 100644
--- a/src/attributes/iceberg.c
+++ b/src/attributes/iceberg.c
@@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include "iceberg.h"
-#include
+#include
attrib_type at_iceberg = {
"iceberg_drift",
diff --git a/src/attributes/key.c b/src/attributes/key.c
index 75958a6fb..76a18c876 100644
--- a/src/attributes/key.c
+++ b/src/attributes/key.c
@@ -20,11 +20,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include "key.h"
-#include
-#include
+#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -76,25 +77,83 @@ static int keys_size(int n) {
return 4096;
}
+static int read_flags(gamedata *data, int *keys, int n) {
+ int i;
+ for (i = 0; i != n; ++i) {
+ int key;
+ READ_INT(data->store, &key);
+ keys[i * 2] = key;
+ keys[i * 2 + 1] = 1;
+ }
+ return n;
+}
+
+#ifdef KEYVAL_VERSION
+static int read_keyval(gamedata *data, int *keys, int n) {
+ int i;
+ for (i = 0; i != n; ++i) {
+ int key, val;
+ READ_INT(data->store, &key);
+ READ_INT(data->store, &val);
+ keys[i * 2] = key;
+ keys[i * 2 + 1] = val;
+ }
+ return n;
+}
+#endif
+
+#ifdef FIXATKEYS_VERSION
+static int read_keyval_orig(gamedata *data, int *keys, int n) {
+ int i, j = 0, dk = -1;
+ for (i = 0; i != n; ++i) {
+ int key, val;
+ READ_INT(data->store, &key);
+ READ_INT(data->store, &val);
+ if (key > dk) {
+ keys[j * 2] = key;
+ keys[j * 2 + 1] = val;
+ dk = key;
+ ++j;
+ }
+ }
+ return j;
+}
+#endif
+
static int a_readkeys(variant *var, void *owner, gamedata *data) {
- int i, n, *keys;
+ int i, n, ksn, *keys;
READ_INT(data->store, &n);
assert(n < 4096 && n >= 0);
if (n == 0) {
return AT_READ_FAIL;
}
- keys = malloc(sizeof(int)*(keys_size(n) * 2 + 1));
- *keys = n;
- for (i = 0; i != n; ++i) {
- READ_INT(data->store, keys + i * 2 + 1);
- if (data->version >= KEYVAL_VERSION) {
- READ_INT(data->store, keys + i * 2 + 2);
- }
- else {
- keys[i * 2 + 2] = 1;
+ ksn = keys_size(n);
+ keys = malloc((ksn * 2 + 1) * sizeof(int));
+ if (data->version >= FIXATKEYS_VERSION) {
+ n = read_keyval(data, keys + 1, n);
+ }
+ else if (data->version >= KEYVAL_VERSION) {
+ int m = read_keyval_orig(data, keys + 1, n);
+ if (n != m) {
+ int ksm = keys_size(m);
+ if (ksm != ksn) {
+ int *nkeys = (int *)realloc(keys, (ksm * 2 + 1) * sizeof(int));
+ if (nkeys != NULL) {
+ keys = nkeys;
+ }
+ else {
+ log_error("a_readkeys allocation failed: %s", strerror(errno));
+ return AT_READ_FAIL;
+ }
+ }
+ n = m;
}
}
+ else {
+ n = read_flags(data, keys + 1, n);
+ }
+ keys[0] = n;
if (data->version < SORTKEYS_VERSION) {
int e = 1;
for (i = 1; i != n; ++i) {
diff --git a/src/attributes/key.test.c b/src/attributes/key.test.c
index 79a7bde1d..fc09fc391 100644
--- a/src/attributes/key.test.c
+++ b/src/attributes/key.test.c
@@ -2,7 +2,7 @@
#include "key.h"
#include "dict.h"
-#include
+#include
#include
#include
#include
diff --git a/src/attributes/movement.c b/src/attributes/movement.c
index 7b49291c2..01c75ffae 100644
--- a/src/attributes/movement.c
+++ b/src/attributes/movement.c
@@ -20,8 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include "movement.h"
-#include
-#include
+#include
+#include
#include
#include
diff --git a/src/attributes/otherfaction.c b/src/attributes/otherfaction.c
index 343460057..fcf05da05 100644
--- a/src/attributes/otherfaction.c
+++ b/src/attributes/otherfaction.c
@@ -23,8 +23,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include
#include
-#include
-#include
+#include
+#include
#include
#include
diff --git a/src/attributes/otherfaction.test.c b/src/attributes/otherfaction.test.c
index 8417ed3e3..e4f7c95b9 100644
--- a/src/attributes/otherfaction.test.c
+++ b/src/attributes/otherfaction.test.c
@@ -7,7 +7,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/src/attributes/overrideroads.c b/src/attributes/overrideroads.c
index ef466de2d..d96d115d9 100644
--- a/src/attributes/overrideroads.c
+++ b/src/attributes/overrideroads.c
@@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include "overrideroads.h"
-#include
+#include
attrib_type at_overrideroads = {
"roads_override", NULL, NULL, NULL, a_writestring, a_readstring
diff --git a/src/attributes/racename.c b/src/attributes/racename.c
index c46fb0c4b..9374f1238 100644
--- a/src/attributes/racename.c
+++ b/src/attributes/racename.c
@@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include "racename.h"
-#include
+#include
#include
/* libc includes */
diff --git a/src/attributes/raceprefix.c b/src/attributes/raceprefix.c
index 233d17e40..84997b909 100644
--- a/src/attributes/raceprefix.c
+++ b/src/attributes/raceprefix.c
@@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include "raceprefix.h"
-#include
+#include
#include
#include
diff --git a/src/attributes/reduceproduction.c b/src/attributes/reduceproduction.c
index 01041380a..0ae0abbea 100644
--- a/src/attributes/reduceproduction.c
+++ b/src/attributes/reduceproduction.c
@@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include
#include
-#include
+#include
#include
static int age_reduceproduction(attrib * a, void *owner)
diff --git a/src/attributes/seenspell.c b/src/attributes/seenspell.c
index 82bdf22ca..ae46980c3 100644
--- a/src/attributes/seenspell.c
+++ b/src/attributes/seenspell.c
@@ -23,8 +23,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include
#include
-#include
-#include
+#include
+#include
#include
#include
diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c
index db2ec5304..ae00e8721 100644
--- a/src/attributes/stealth.c
+++ b/src/attributes/stealth.c
@@ -1,7 +1,7 @@
#include
#include
#include
-#include
+#include
#include
#include
diff --git a/src/attributes/targetregion.c b/src/attributes/targetregion.c
index 7ef1fe84a..4f5a2101a 100644
--- a/src/attributes/targetregion.c
+++ b/src/attributes/targetregion.c
@@ -22,8 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#include
-#include
-#include
+#include
+#include
#include
#include
@@ -36,7 +36,7 @@ write_targetregion(const variant *var, const void *owner, struct storage *store)
static int read_targetregion(variant *var, void *owner, gamedata *data)
{
- if (read_region_reference(data, (region **)&var->v, NULL) <= 0) {
+ if (read_region_reference(data, (region **)&var->v) <= 0) {
return AT_READ_FAIL;
}
return AT_READ_OK;
diff --git a/src/automate.c b/src/automate.c
index beb24a780..04230096d 100644
--- a/src/automate.c
+++ b/src/automate.c
@@ -6,10 +6,10 @@
#include "kernel/region.h"
#include "kernel/unit.h"
+#include "util/keyword.h"
#include "util/log.h"
#include "automate.h"
-#include "keyword.h"
#include "laws.h"
#include "study.h"
@@ -55,10 +55,6 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units)
unext = u;
}
}
- else {
- ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race",
- u_race(u)));
- }
}
u = u->next;
}
diff --git a/src/battle.c b/src/battle.c
index 9e2f841c0..00cece5b0 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -60,7 +60,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* util includes */
#include
-#include
+#include
#include
#include
#include
@@ -100,10 +100,8 @@ typedef enum combatmagic {
#define MINSPELLRANGE 1
#define MAXSPELLRANGE 7
-#ifndef ROW_FACTOR
-# define ROW_FACTOR 10
-#endif
-#define EFFECT_PANIC_SPELL 0.25
+#define ROW_FACTOR 3 /* factor for combat row advancement rule */
+#define EFFECT_PANIC_SPELL 25
#define TROLL_REGENERATION 0.10
/* Nach dem alten System: */
@@ -122,17 +120,21 @@ const troop no_troop = { 0, 0 };
#define DAMAGE_CRITICAL (1<<0)
#define DAMAGE_MELEE_BONUS (1<<1)
-#define DAMAGE_MISSILE_BONUS (1<<2)
+#define DAMAGE_MISSILE_BONUS (1<<2) /* deprecated */
#define DAMAGE_SKILL_BONUS (1<<4)
static int max_turns;
static int rule_damage;
static int rule_loot;
+static int flee_chance_max_percent;
+static int flee_chance_base;
+static int flee_chance_skill_bonus;
static int skill_formula;
static int rule_cavalry_skill;
static int rule_population_damage;
static int rule_hero_speed;
static bool rule_anon_battle;
+static bool rule_igjarjuk_curse;
static int rule_goblin_bonus;
static int rule_tactics_formula;
static int rule_nat_armor;
@@ -146,12 +148,16 @@ static void init_rules(void)
{
it_mistletoe = it_find("mistletoe");
+ flee_chance_skill_bonus = config_get_int("rules.combat.flee_chance_bonus", 5);
+ flee_chance_base = config_get_int("rules.combat.flee_chance_base", 20);
+ flee_chance_max_percent = config_get_int("rules.combat.flee_chance_limit", 90);
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);
rule_hero_speed = config_get_int("rules.combat.herospeed", 10);
rule_population_damage = config_get_int("rules.combat.populationdamage", 20);
rule_anon_battle = config_get_int("rules.stealth.anon_battle", 1) != 0;
+ rule_igjarjuk_curse = config_get_int("rules.combat.igjarjuk_curse", 0) != 0;
rule_cavalry_mode = config_get_int("rules.cavalry.mode", 1);
rule_cavalry_skill = config_get_int("rules.cavalry.skill", 2);
rule_vampire = config_get_int("rules.combat.demon_vampire", 0);
@@ -161,7 +167,7 @@ static void init_rules(void)
skill_formula = config_get_int("rules.combat.skill_formula",
FORMULA_ORIG);
/* maximum number of combat turns */
- max_turns = config_get_int("rules.combat.turns", COMBAT_TURNS);
+ max_turns = config_get_int("rules.combat.turns", 5);
/* damage calculation */
if (config_get_int("rules.combat.critical", 1)) {
rule_damage |= DAMAGE_CRITICAL;
@@ -169,7 +175,7 @@ static void init_rules(void)
if (config_get_int("rules.combat.melee_bonus", 1)) {
rule_damage |= DAMAGE_MELEE_BONUS;
}
- if (config_get_int("rules.combat.missile_bonus", 1)) {
+ if (config_get_int("rules.combat.missile_bonus", 1)) { /* deprecated */
rule_damage |= DAMAGE_MISSILE_BONUS;
}
if (config_get_int("rules.combat.skill_bonus", 1)) {
@@ -277,19 +283,15 @@ static void set_friendly(side * as, side * ds)
as->relations[ds->index] |= E_FRIEND;
}
-static int allysfm(const side * s, const faction * f, int mode)
+static bool alliedside(const side * s, const faction * f, int mode)
{
- if (s->faction == f)
- return mode;
- if (s->group) {
- return alliedgroup(s->battle->plane, s->faction, f, s->group->allies, mode);
+ if (s->faction == f) {
+ return true;
}
- return alliedfaction(s->battle->plane, s->faction, f, mode);
-}
-
-static int allysf(const side * s, const faction * f)
-{
- return allysfm(s, f, HELP_FIGHT);
+ if (s->group) {
+ return alliedgroup(s->faction, f, s->group, mode) != 0;
+ }
+ return alliedfaction(s->faction, f, mode) != 0;
}
static int dead_fighters(const fighter * df)
@@ -309,7 +311,7 @@ fighter *select_corpse(battle * b, fighter * af)
for (si = 0; si != b->nsides; ++si) {
side *s = b->sides + si;
- if (af == NULL || (!enemy_i(af->side, si) && allysf(af->side, s->faction))) {
+ if (af == NULL || (!enemy_i(af->side, si) && alliedside(af->side, s->faction, HELP_FIGHT))) {
maxcasualties += s->casualties;
}
}
@@ -340,7 +342,7 @@ bool helping(const side * as, const side * ds)
{
if (as->faction == ds->faction)
return true;
- return (bool)(!enemy(as, ds) && allysf(as, ds->faction));
+ return (!enemy(as, ds) && alliedside(as, ds->faction, HELP_FIGHT));
}
int statusrow(int status)
@@ -486,7 +488,7 @@ contest_classic(int skilldiff, const armor_type * ar, const armor_type * sh)
mod *= (1 + ar->penalty);
if (sh != NULL)
mod *= (1 + sh->penalty);
- vw = (int)(100 - ((100 - vw) * mod));
+ vw = (int)(100.0 - ((100.0 - (double)vw) * mod));
do {
p = (int)(rng_int() % 100);
@@ -555,8 +557,7 @@ static weapon *preferred_weapon(const troop t, bool attacking)
return melee;
}
-static weapon *select_weapon(const troop t, bool attacking,
- bool ismissile)
+weapon *select_weapon(const troop t, bool attacking, bool ismissile)
/* select the primary weapon for this trooper */
{
if (attacking) {
@@ -770,7 +771,7 @@ bool missile)
return skill;
}
-static const armor_type *select_armor(troop t, bool shield)
+const armor_type *select_armor(troop t, bool shield)
{
unsigned int type = shield ? ATF_SHIELD : 0;
unit *u = t.fighter->unit;
@@ -829,7 +830,7 @@ bool meffect_protection(battle * b, meffect * s, side * ds)
return false;
if (enemy(s->magician->side, ds))
return false;
- if (allysf(s->magician->side, ds->faction))
+ if (alliedside(s->magician->side, ds->faction, HELP_FIGHT))
return true;
return false;
}
@@ -950,6 +951,9 @@ void drain_exp(struct unit *u, int n)
static void vampirism(troop at, int damage)
{
+ const unit *au = at.fighter->unit;
+
+ if (u_race(au) == get_race(RC_DAEMON)) {
if (rule_vampire > 0) {
int gain = damage / rule_vampire;
int chance = damage - rule_vampire * gain;
@@ -963,6 +967,16 @@ static void vampirism(troop at, int damage)
at.fighter->person[at.index].hp = maxhp;
}
}
+ }
+}
+
+static void ship_damage(int turn, unit *du) {
+ if (turn>1) {
+ /* someone on the ship got damaged, damage the ship */
+ ship *sh = du->ship ? du->ship : leftship(du);
+ if (sh)
+ fset(sh, SF_DAMAGED);
+ }
}
#define MAXRACES 128
@@ -1012,85 +1026,94 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_
return modifier;
}
-int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, variant *magres) {
- fighter *df = dt.fighter;
+int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype,
+ const armor_type *armor, const armor_type *shield, bool magic) {
+
+ const fighter *df = dt.fighter;
unit *du = df->unit;
- int ar = 0, an, am;
- const armor_type *armor = select_armor(dt, false);
- const armor_type *shield = select_armor(dt, true);
+ int total_armor = 0, nat_armor, magic_armor;
bool missile = awtype && (awtype->flags&WTF_MISSILE);
if (armor) {
- ar += armor->prot;
+ total_armor += armor->prot;
if (missile && armor->projectile > 0 && chance(armor->projectile)) {
return -1;
}
}
if (shield) {
- ar += shield->prot;
+ total_armor += shield->prot;
if (missile && shield->projectile > 0 && chance(shield->projectile)) {
return -1;
}
}
+ if (magic) {
+ /* gegen Magie wirkt nur natuerliche und magische Ruestung */
+ total_armor = 0;
+ }
+
/* nat�rliche R�stung */
- an = natural_armor(du);
+ nat_armor = natural_armor(du);
/* magische R�stung durch Artefakte oder Spr�che */
/* Momentan nur Trollg�rtel und Werwolf-Eigenschaft */
- am = select_magicarmor(dt);
+ magic_armor = select_magicarmor(dt);
if (rule_nat_armor == 0) {
/* nat�rliche R�stung ist halbkumulativ */
- if (ar > 0) {
- ar += an / 2;
+ if (total_armor > 0) {
+ total_armor += nat_armor / 2;
}
else {
- ar = an;
+ total_armor = nat_armor;
}
}
else {
/* use the higher value, add half the other value */
- ar = (ar > an) ? (ar + an / 2) : (an + ar / 2);
+ total_armor = (total_armor > nat_armor) ? (total_armor + nat_armor / 2) : (nat_armor + total_armor / 2);
}
if (awtype && fval(awtype, WTF_ARMORPIERCING)) {
/* crossbows */
- ar /= 2;
+ total_armor /= 2;
}
- ar += am;
+ total_armor += magic_armor;
- if (magres) {
- /* calculate damage multiplier for magical damage */
- variant res;
-
- res = frac_sub(frac_one, magic_resistance(du));
+ assert(total_armor >= 0 || !"armor < 0 means hit denied");
- if (u_race(du)->battle_flags & BF_EQUIPMENT) {
- /* der Effekt von Laen steigt nicht linear */
- if (armor && fval(armor, ATF_LAEN)) {
- res = frac_mul(res, frac_sub(frac_one, armor->magres));
- }
- if (shield && fval(shield, ATF_LAEN)) {
- res = frac_mul(res, frac_sub(frac_one, shield->magres));
- }
- if (dwtype) {
- res = frac_mul(res, frac_sub(frac_one, dwtype->magres));
- }
- }
+ return total_armor;
+}
- /* gegen Magie wirkt nur natuerliche und magische Ruestung */
- ar = an + am;
- if (res.sa[0] >= 0) {
- *magres = res;
- }
- else {
- *magres = frac_make(0, 1);
- }
+int apply_resistance(int damage, troop dt, const weapon_type *dwtype, const armor_type *armor, const armor_type *shield, bool magic) {
+ const fighter *df = dt.fighter;
+ unit *du = df->unit;
+
+ if (!magic)
+ return damage;
+
+ /* calculate damage multiplier for magical damage */
+ variant resistance_factor = frac_sub(frac_one, magic_resistance(du));
+
+ if (u_race(du)->battle_flags & BF_EQUIPMENT) {
+ /* der Effekt von Laen steigt nicht linear */
+ if (armor && fval(armor, ATF_LAEN)) {
+ resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, armor->magres));
}
+ if (shield && fval(shield, ATF_LAEN)) {
+ resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, shield->magres));
+ }
+ if (dwtype) {
+ resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, dwtype->magres));
+ }
+ }
+ if (resistance_factor.sa[0] <= 0) {
+ return 0;
+ }
+
+ variant reduced_damage = frac_mul(frac_make(damage, 1), resistance_factor);
+ return reduced_damage.sa[0] / reduced_damage.sa[1];
- return ar;
}
static bool resurrect_troop(troop dt)
@@ -1108,174 +1131,30 @@ static bool resurrect_troop(troop dt)
return false;
}
-bool
-terminate(troop dt, troop at, int type, const char *damage, bool missile)
-{
- item **pitm;
- fighter *df = dt.fighter;
- fighter *af = at.fighter;
- unit *au = af->unit;
- unit *du = df->unit;
- battle *b = df->side->battle;
-
- /* Schild */
- side *ds = df->side;
- int ar;
-
- const weapon_type *dwtype = NULL;
- const weapon_type *awtype = NULL;
- const weapon *weapon;
- variant res = frac_one;
-
- int rda, sk = 0, sd;
- bool magic = false;
- int da = dice_rand(damage);
-
- assert(du->number > 0);
- ++at.fighter->hits;
-
- switch (type) {
- case AT_STANDARD:
- weapon = select_weapon(at, true, missile);
- sk = weapon_effskill(at, dt, weapon, true, missile);
- if (weapon)
- awtype = weapon->type;
- if (awtype && fval(awtype, WTF_MAGICAL))
- magic = true;
- break;
- case AT_NATURAL:
- sk = weapon_effskill(at, dt, NULL, true, missile);
- break;
- case AT_SPELL:
- case AT_COMBATSPELL:
- magic = true;
- break;
- default:
- break;
- }
- weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
- sd = weapon_effskill(dt, at, weapon, false, false);
- if (weapon != NULL)
- dwtype = weapon->type;
-
- if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS)
- && !fval(awtype, WTF_MISSILE)))) {
- da += CavalryBonus(au, dt, BONUS_DAMAGE);
- }
-
- ar = calculate_armor(dt, dwtype, awtype, magic ? &res : 0);
- if (ar < 0) {
- return false;
- }
-
- if (magic) {
- res = frac_sub(frac_one, res);
- res = frac_mul(frac_make(da, 1), res);
- da = res.sa[0] / res.sa[1];
- }
-
- if (type != AT_COMBATSPELL && type != AT_SPELL) {
- if (rule_damage & DAMAGE_CRITICAL) {
- double kritchance = (sk * 3 - sd) / 200.0;
- int maxk = 4;
-
- kritchance = fmax(kritchance, 0.005);
- kritchance = fmin(0.9, kritchance);
-
- while (maxk-- && chance(kritchance)) {
- da += dice_rand(damage);
- }
- }
-
- da += rc_specialdamage(au, du, awtype);
-
- if (awtype != NULL && fval(awtype, WTF_MISSILE)) {
- /* missile weapon bonus */
- if (rule_damage & DAMAGE_MISSILE_BONUS) {
- da += af->person[at.index].damage_rear;
- }
- }
- else {
- /* melee bonus */
- if (rule_damage & DAMAGE_MELEE_BONUS) {
- da += af->person[at.index].damage;
- }
- }
-
- /* Skilldifferenzbonus */
- if (rule_damage & DAMAGE_SKILL_BONUS) {
- da += MAX(0, (sk - sd) / DAMAGE_QUOTIENT);
+static void demon_dazzle(fighter *af, troop dt) {
+ const fighter *df = dt.fighter;
+ if (u_race(af->unit) == get_race(RC_DAEMON)) {
+ if (!(df->person[dt.index].flags & (FL_COURAGE | FL_DAZZLED))) {
+ df->person[dt.index].flags |= FL_DAZZLED;
+ df->person[dt.index].defense--;
}
}
+}
- rda = MAX(da - ar, 0);
+static bool survives(fighter *af, troop dt, battle *b) {
+ const unit *du = af->unit;
+ const fighter *df = dt.fighter;
- if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic)
- rda = 0;
- else {
- int qi;
- selist *ql;
- unsigned int i = 0;
-
- if (u_race(du)->battle_flags & BF_RES_PIERCE)
- i |= WTF_PIERCE;
- if (u_race(du)->battle_flags & BF_RES_CUT)
- i |= WTF_CUT;
- if (u_race(du)->battle_flags & BF_RES_BASH)
- i |= WTF_BLUNT;
-
- if (i && awtype && fval(awtype, i))
- rda /= 2;
-
- /* Schilde */
- for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
- meffect *me = (meffect *)selist_get(ql, qi);
- if (meffect_protection(b, me, ds) != 0) {
- assert(0 <= rda); /* rda sollte hier immer mindestens 0 sein */
- /* jeder Schaden wird um effect% reduziert bis der Schild duration
- * Trefferpunkte aufgefangen hat */
- if (me->typ == SHIELD_REDUCE) {
- int hp = rda * (me->effect / 100);
- rda -= hp;
- me->duration -= hp;
- }
- /* gibt R�stung +effect f�r duration Treffer */
- if (me->typ == SHIELD_ARMOR) {
- rda = MAX(rda - me->effect, 0);
- me->duration--;
- }
- }
- }
- }
-
- assert(dt.index >= 0 && dt.index < du->number);
- if (rda>0) {
- df->person[dt.index].hp -= rda;
- if (u_race(au) == get_race(RC_DAEMON)) {
- vampirism(at, rda);
- }
- if (b->turn>1) {
- /* someone on the ship got damaged, damage the ship */
- ship *sh = du->ship ? du->ship : leftship(du);
- if (sh)
- fset(sh, SF_DAMAGED);
- }
-
- }
if (df->person[dt.index].hp > 0) { /* Hat �berlebt */
- if (u_race(au) == get_race(RC_DAEMON)) {
- if (!(df->person[dt.index].flags & (FL_COURAGE | FL_DAZZLED))) {
- df->person[dt.index].flags |= FL_DAZZLED;
- df->person[dt.index].defence--;
- }
- }
- return false;
+ demon_dazzle(af, dt);
+
+ return true;
}
/* Sieben Leben */
if (u_race(du) == get_race(RC_CAT) && (chance(1.0 / 7))) {
df->person[dt.index].hp = unit_max_hp(du);
- return false;
+ return true;
}
/* healing potions can avert a killing blow */
@@ -1283,23 +1162,218 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
message *m = msg_message("potionsave", "unit", du);
battle_message_faction(b, du->faction, m);
msg_release(m);
+ return true;
+ }
+
+ return false;
+}
+
+static void destroy_items(troop dt) {
+ unit *du = dt.fighter->unit;
+
+ item **pitm;
+
+ for (pitm = &du->items; *pitm;) {
+ item *itm = *pitm;
+ const item_type *itype = itm->type;
+ if (!(itype->flags & ITF_CURSED) && dt.index < itm->number) {
+ /* 25% Grundchance, das ein Item kaputtgeht. */
+ if (rng_int() % 4 < 1) {
+ i_change(pitm, itype, -1);
+ }
+ }
+ if (*pitm == itm) {
+ pitm = &itm->next;
+ }
+ }
+
+}
+
+static void calculate_defense_type(troop dt, troop at, int type, bool missile,
+ const weapon_type **dwtype, int *defskill) {
+ const weapon *weapon;
+ weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
+ *defskill = weapon_effskill(dt, at, weapon, false, false);
+ if (weapon != NULL)
+ *dwtype = weapon->type;
+}
+
+static void calculate_attack_type(troop dt, troop at, int type, bool missile,
+ const weapon_type **awtype, int *attskill, bool *magic) {
+ const weapon *weapon;
+
+ switch (type) {
+ case AT_STANDARD:
+ weapon = select_weapon(at, true, missile);
+ *attskill = weapon_effskill(at, dt, weapon, true, missile);
+ if (weapon)
+ *awtype = weapon->type;
+ if (*awtype && fval(*awtype, WTF_MAGICAL))
+ *magic = true;
+ break;
+ case AT_NATURAL:
+ *attskill = weapon_effskill(at, dt, NULL, true, missile);
+ break;
+ case AT_SPELL:
+ case AT_COMBATSPELL:
+ *magic = true;
+ break;
+ default:
+ break;
+ }
+}
+
+static int crit_damage(int attskill, int defskill, const char *damage_formula) {
+ int damage = 0;
+ if (rule_damage & DAMAGE_CRITICAL) {
+ double kritchance = ((double)attskill * 3.0 - (double)defskill) / 200.0;
+ int maxk = 4;
+
+ kritchance = fmax(kritchance, 0.005);
+ kritchance = fmin(0.9, kritchance);
+
+ while (maxk-- && chance(kritchance)) {
+ damage += dice_rand(damage_formula);
+ }
+ }
+ return damage;
+}
+
+static int apply_race_resistance(int reduced_damage, fighter *df,
+ const weapon_type *awtype, bool magic) {
+ unit *du = df->unit;
+
+ if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic)
+ reduced_damage = 0;
+ else {
+ unsigned int i = 0;
+
+ if (u_race(du)->battle_flags & BF_RES_PIERCE)
+ i |= WTF_PIERCE;
+ if (u_race(du)->battle_flags & BF_RES_CUT)
+ i |= WTF_CUT;
+ if (u_race(du)->battle_flags & BF_RES_BASH)
+ i |= WTF_BLUNT;
+
+ if (i && awtype && fval(awtype, i))
+ reduced_damage /= 2;
+ }
+ return reduced_damage;
+}
+
+static int apply_magicshield(int reduced_damage, fighter *df,
+ const weapon_type *awtype, battle *b, bool magic) {
+ side *ds = df->side;
+ selist *ql;
+ int qi;
+
+ if (reduced_damage <= 0)
+ return 0;
+
+ /* Schilde */
+ for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
+ meffect *me = (meffect *) selist_get(ql, qi);
+ if (meffect_protection(b, me, ds) != 0) {
+ assert(0 <= reduced_damage); /* rda sollte hier immer mindestens 0 sein */
+ /* jeder Schaden wird um effect% reduziert bis der Schild duration
+ * Trefferpunkte aufgefangen hat */
+ if (me->typ == SHIELD_REDUCE) {
+ int hp = reduced_damage * (me->effect / 100);
+ reduced_damage -= hp;
+ me->duration -= hp;
+ }
+ /* gibt R�stung +effect f�r duration Treffer */
+ if (me->typ == SHIELD_ARMOR) {
+ reduced_damage = MAX(reduced_damage - me->effect, 0);
+ me->duration--;
+ }
+ }
+ }
+
+ return reduced_damage;
+}
+
+bool
+terminate(troop dt, troop at, int type, const char *damage_formula, bool missile)
+{
+ fighter *df = dt.fighter;
+ fighter *af = at.fighter;
+ unit *au = af->unit;
+ unit *du = df->unit;
+ battle *b = df->side->battle;
+
+ int armor_value;
+
+ const weapon_type *dwtype = NULL;
+ const weapon_type *awtype = NULL;
+ const armor_type *armor = NULL;
+ const armor_type *shield = NULL;
+
+ int reduced_damage, attskill = 0, defskill = 0;
+ bool magic = false;
+
+ int damage = dice_rand(damage_formula);
+
+ assert(du->number > 0);
+ ++at.fighter->hits;
+
+ calculate_attack_type(at, dt, type, missile, &awtype, &attskill, &magic);
+ calculate_defense_type(at, dt, type, missile, &awtype, &attskill);
+
+ if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS)
+ && !fval(awtype, WTF_MISSILE)))) {
+ damage += CavalryBonus(au, dt, BONUS_DAMAGE);
+ }
+
+ armor = select_armor(dt, false);
+ shield = select_armor(dt, true);
+
+ armor_value = calculate_armor(dt, dwtype, awtype, armor, shield, magic);
+ if (armor_value < 0) {
return false;
}
- ++at.fighter->kills;
- for (pitm = &du->items; *pitm;) {
- item *itm = *pitm;
- const item_type *itype = itm->type;
- if (!(itype->flags & ITF_CURSED) && dt.index < itm->number) {
- /* 25% Grundchance, das ein Item kaputtgeht. */
- if (rng_int() % 4 < 1) {
- i_change(pitm, itype, -1);
+ damage = apply_resistance(damage, dt, dwtype, armor, shield, magic);
+
+ if (type != AT_COMBATSPELL && type != AT_SPELL) {
+ damage += crit_damage(attskill, defskill, damage_formula);
+
+ damage += rc_specialdamage(au, du, awtype);
+
+ if (awtype == NULL || !fval(awtype, WTF_MISSILE)) {
+ /* melee bonus */
+ if (rule_damage & DAMAGE_MELEE_BONUS) {
+ damage += af->person[at.index].damage;
}
}
- if (*pitm == itm) {
- pitm = &itm->next;
+
+ /* Skilldifferenzbonus */
+ if (rule_damage & DAMAGE_SKILL_BONUS) {
+ damage += MAX(0, (attskill - defskill) / DAMAGE_QUOTIENT);
}
}
+
+ reduced_damage = MAX(damage - armor_value, 0);
+
+ reduced_damage = apply_race_resistance(reduced_damage, df, awtype, magic);
+ reduced_damage = apply_magicshield(reduced_damage, df, awtype, b, magic);
+
+ assert(dt.index >= 0 && dt.index < du->number);
+ if (reduced_damage > 0) {
+ df->person[dt.index].hp -= reduced_damage;
+
+ vampirism(at, reduced_damage);
+
+ ship_damage(b->turn, du);
+ }
+
+ if (survives(af, dt, b))
+ return false;
+
+ ++at.fighter->kills;
+
+ destroy_items(dt);
+
kill_troop(dt);
return true;
@@ -1578,7 +1652,7 @@ selist *select_fighters(battle * b, const side * vs, int mask, select_fun cb, vo
continue;
}
else if (mask == FS_HELP) {
- if (enemy(s, vs) || !allysf(s, vs->faction)) {
+ if (enemy(s, vs) || !alliedside(s, vs->faction, HELP_FIGHT)) {
continue;
}
}
@@ -1676,13 +1750,14 @@ void do_combatmagic(battle * b, combatmagic_t was)
memset(spellranks, 0, sizeof(spellranks));
- if (was == DO_PRECOMBATSPELL) {
+ if (rule_igjarjuk_curse && was == DO_PRECOMBATSPELL) {
summon_igjarjuk(b, spellranks);
}
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig;
for (fig = s->fighters; fig; fig = fig->next) {
unit *mage = fig->unit;
+ unit *caster = mage;
if (fig->alive <= 0)
continue; /* fighter kann im Kampf get�tet worden sein */
@@ -1716,7 +1791,7 @@ void do_combatmagic(battle * b, combatmagic_t was)
continue;
}
- level = eff_spelllevel(mage, sp, level, 1);
+ level = eff_spelllevel(mage, caster, sp, level, 1);
if (sl > 0 && sl < level) {
level = sl;
}
@@ -1730,11 +1805,11 @@ void do_combatmagic(battle * b, combatmagic_t was)
free_order(ord);
if (power <= 0) { /* Effekt von Antimagie */
report_failed_spell(b, mage, sp);
- pay_spell(mage, sp, level, 1);
+ pay_spell(mage, NULL, sp, level, 1);
}
else if (fumble(r, mage, sp, level)) {
report_failed_spell(b, mage, sp);
- pay_spell(mage, sp, level, 1);
+ pay_spell(mage, NULL, sp, level, 1);
}
else {
co = create_castorder_combat(0, fig, sp, level, power);
@@ -1750,7 +1825,7 @@ void do_combatmagic(battle * b, combatmagic_t was)
level = cast_spell(co);
if (level > 0) {
- pay_spell(fig->unit, sp, level, 1);
+ pay_spell(fig->unit, NULL, sp, level, 1);
}
}
}
@@ -1767,7 +1842,7 @@ static int cast_combatspell(troop at, const spell * sp, int level, double force)
level = cast_spell(&co);
free_castorder(&co);
if (level > 0) {
- pay_spell(at.fighter->unit, sp, level, 1);
+ pay_spell(at.fighter->unit, NULL, sp, level, 1);
}
return level;
}
@@ -1776,7 +1851,7 @@ static void do_combatspell(troop at)
{
const spell *sp;
fighter *fi = at.fighter;
- unit *caster = fi->unit;
+ unit *mage = fi->unit;
battle *b = fi->side->battle;
region *r = b->region;
selist *ql;
@@ -1785,28 +1860,28 @@ static void do_combatspell(troop at)
int fumblechance = 0;
order *ord;
int sl;
- const struct locale *lang = caster->faction->locale;
+ const struct locale *lang = mage->faction->locale;
- sp = get_combatspell(caster, 1);
+ sp = get_combatspell(mage, 1);
if (sp == NULL) {
fi->magic = 0; /* Hat keinen Kampfzauber, k�mpft nichtmagisch weiter */
return;
}
ord = create_order(K_CAST, lang, "'%s'", spell_name(sp, lang));
- if (!cancast(caster, sp, 1, 1, ord)) {
+ if (!cancast(mage, sp, 1, 1, ord)) {
fi->magic = 0; /* Kann nicht mehr Zaubern, k�mpft nichtmagisch weiter */
return;
}
- level = eff_spelllevel(caster, sp, fi->magic, 1);
- sl = get_combatspelllevel(caster, 1);
+ level = eff_spelllevel(mage, mage, sp, fi->magic, 1);
+ sl = get_combatspelllevel(mage, 1);
if (sl > 0 && sl < level) {
level = sl;
}
- if (fumble(r, caster, sp, level)) {
- report_failed_spell(b, caster, sp);
- pay_spell(caster, sp, level, 1);
+ if (fumble(r, mage, sp, level)) {
+ report_failed_spell(b, mage, sp);
+ pay_spell(mage, NULL, sp, level, 1);
return;
}
@@ -1822,16 +1897,16 @@ static void do_combatspell(troop at)
/* Antimagie die Fehlschlag erh�ht */
if (rng_int() % 100 < fumblechance) {
- report_failed_spell(b, caster, sp);
- pay_spell(caster, sp, level, 1);
+ report_failed_spell(b, mage, sp);
+ pay_spell(mage, NULL, sp, level, 1);
free_order(ord);
return;
}
- power = spellpower(r, caster, sp, level, ord);
+ power = spellpower(r, mage, sp, level, ord);
free_order(ord);
if (power <= 0) { /* Effekt von Antimagie */
- report_failed_spell(b, caster, sp);
- pay_spell(caster, sp, level, 1);
+ report_failed_spell(b, mage, sp);
+ pay_spell(mage, NULL, sp, level, 1);
return;
}
@@ -1870,7 +1945,7 @@ int skilldiff(troop at, troop dt, int dist)
rc_goblin = get_race(RC_GOBLIN);
}
skdiff += af->person[at.index].attack;
- skdiff -= df->person[dt.index].defence;
+ skdiff -= df->person[dt.index].defense;
if (df->person[dt.index].flags & FL_SLEEPING)
skdiff += 2;
@@ -1999,11 +2074,12 @@ void dazzle(battle * b, troop * td)
}
td->fighter->person[td->index].flags |= FL_DAZZLED;
- td->fighter->person[td->index].defence--;
+ td->fighter->person[td->index].defense--;
}
void damage_building(battle * b, building * bldg, int damage_abs)
{
+ assert(bldg);
bldg->size = MAX(1, bldg->size - damage_abs);
/* Wenn Burg, dann gucken, ob die Leute alle noch in das Geb�ude passen. */
@@ -2165,7 +2241,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
td.fighter->person[td.index].attack -= 1;
}
else {
- td.fighter->person[td.index].defence -= 1;
+ td.fighter->person[td.index].defense -= 1;
}
c--;
}
@@ -2278,7 +2354,7 @@ static void add_tactics(tactics * ta, fighter * fig, int value)
ta->value = value;
}
-static double horse_fleeing_bonus(const unit * u)
+static int horse_fleeing_bonus(const unit * u)
{
const item_type *it_horse, *it_elvenhorse, *it_charger;
int n1 = 0, n2 = 0, n3 = 0;
@@ -2301,26 +2377,26 @@ static double horse_fleeing_bonus(const unit * u)
}
}
if (skl >= 5 && n3 >= u->number)
- return 0.30;
+ return 30;
if (skl >= 2 && n2 + n3 >= u->number)
- return 0.20;
+ return 20;
if (n1 + n2 + n3 >= u->number)
- return 0.10;
- return 0.0F;
+ return 10;
+ return 0;
}
-double fleechance(unit * u)
+static int fleechance(unit * u)
{
- double p = 0.20; /* Fluchtwahrscheinlichkeit in % */
+ int p = flee_chance_base; /* Fluchtwahrscheinlichkeit in % */
/* Einheit u versucht, dem Get�mmel zu entkommen */
- p += (effskill(u, SK_STEALTH, 0) * 0.05);
+ p += (effskill(u, SK_STEALTH, 0) * flee_chance_skill_bonus);
p += horse_fleeing_bonus(u);
if (u_race(u) == get_race(RC_HALFLING)) {
- p += 0.20;
- if (p > 0.9) {
- p = 0.9;
+ p += flee_chance_base;
+ if (p > flee_chance_max_percent) {
+ p = flee_chance_max_percent;
}
}
return p;
@@ -2568,7 +2644,7 @@ static void aftermath(battle * b)
side *s;
int dead_players = 0;
bfaction *bf;
- bool ships_damaged = (bool)(b->turn + (b->has_tactics_turn ? 1 : 0) > 2); /* only used for ship damage! */
+ bool ships_damaged = (b->turn + (b->has_tactics_turn ? 1 : 0) > 2); /* only used for ship damage! */
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *df;
@@ -2619,7 +2695,7 @@ static void aftermath(battle * b)
}
}
snumber += du->number;
- if (df->alive == 0) {
+ if (dead == df->unit->number) {
flags = UFL_DEAD;
}
else if (relevant) {
@@ -3036,9 +3112,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
if (fval(u, UFL_ANON_FACTION) != 0)
flags |= SIDE_STEALTH;
if (!(AllianceAuto() & HELP_FIGHT) && fval(u, UFL_GROUP)) {
- const attrib *agroup = a_find(u->attribs, &at_group);
- if (agroup != NULL)
- g = (const group *)agroup->data.v;
+ g = get_group(u);
}
/* Illusionen und Zauber kaempfen nicht */
@@ -3108,7 +3182,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
strongmen = trollbelts(u);
if (strongmen > fig->unit->number) strongmen = fig->unit->number;
- /* Hitpoints, Attack- und Defence-Boni f�r alle Personen */
+ /* Hitpoints, Attack- und Defense-Boni fuer alle Personen */
for (i = 0; i < fig->alive; i++) {
assert(i < fig->unit->number);
fig->person[i].hp = h;
@@ -3150,7 +3224,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
assert(w != WMAX);
}
assert(w >= 0);
- fig->weapons = (weapon *)calloc(sizeof(weapon), (size_t)(w + 1));
+ fig->weapons = (weapon *)calloc((size_t)(w + 1), sizeof(weapon));
memcpy(fig->weapons, weapons, (size_t)w * sizeof(weapon));
for (i = 0; i != w; ++i) {
@@ -3355,11 +3429,12 @@ int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
battle *make_battle(region * r)
{
- battle *b = (battle *)calloc(1, sizeof(battle));
unit *u;
bfaction *bf;
building * bld;
+ battle *b = (battle *)calloc(1, sizeof(battle));
+ assert(b);
/* Alle Mann raus aus der Burg! */
for (bld = r->buildings; bld != NULL; bld = bld->next)
bld->sizeleft = bld->size;
@@ -3376,7 +3451,8 @@ battle *make_battle(region * r)
break;
}
if (!bf) {
- bf = (bfaction *)calloc(sizeof(bfaction), 1);
+ bf = (bfaction *)calloc(1, sizeof(bfaction));
+ assert(bf);
++b->nfactions;
bf->faction = u->faction;
bf->next = b->factions;
@@ -3400,14 +3476,15 @@ static void free_side(side * si)
static void free_fighter(fighter * fig)
{
+ armor **ap = &fig->armors;
+ while (*ap) {
+ armor *a = *ap;
+ *ap = a->next;
+ free(a);
+ }
while (fig->loot) {
i_free(i_remove(&fig->loot, fig->loot));
}
- while (fig->armors) {
- armor *a = fig->armors;
- fig->armors = a->next;
- free(a);
- }
free(fig->person);
free(fig->weapons);
@@ -3419,13 +3496,14 @@ static void battle_free(battle * b) {
assert(b);
for (s = b->sides; s != b->sides + b->nsides; ++s) {
- fighter *fnext = s->fighters;
- while (fnext) {
- fighter *fig = fnext;
- fnext = fig->next;
+ fighter **fp = &s->fighters;
+ while (*fp) {
+ fighter *fig = *fp;
+ *fp = fig->next;
free_fighter(fig);
free(fig);
}
+ s->fighters = NULL;
free_side(s);
}
free(b);
@@ -3560,7 +3638,7 @@ static void join_allies(battle * b)
* vorgespiegelt wird, und er sich uns gegen�ber nicht zu
* erkennen gibt, helfen wir ihm nicht */
if (s->stealthfaction) {
- if (!allysfm(s, u->faction, HELP_FSTEALTH)) {
+ if (!alliedside(s, u->faction, HELP_FSTEALTH)) {
continue;
}
}
@@ -3579,17 +3657,6 @@ static void join_allies(battle * b)
}
if (se == s_end)
continue;
- /* Wenn die Einheit belagert ist, mu� auch einer der Alliierten belagert sein: */
- if (besieged(u)) {
- fighter *ally;
- for (ally = s->fighters; ally; ally = ally->next) {
- if (besieged(ally->unit)) {
- break;
- }
- }
- if (ally == NULL)
- continue;
- }
/* keine Einw�nde, also soll er mitmachen: */
if (c == NULL) {
if (!join_battle(b, u, false, &c)) {
@@ -3625,17 +3692,13 @@ static void join_allies(battle * b)
}
for (sa = s + 1; sa != b->sides + b->nsides; ++sa) {
- plane *pl = rplane(r);
- if (enemy(s, sa))
- continue;
- if (friendly(s, sa))
- continue;
- if (!alliedgroup(pl, f, sa->faction, f->allies, HELP_FIGHT))
- continue;
- if (!alliedgroup(pl, sa->faction, f, sa->faction->allies, HELP_FIGHT))
- continue;
-
- set_friendly(s, sa);
+ if (!enemy(s, sa) && !friendly(s, sa)) {
+ if (alliedfaction(f, sa->faction, HELP_FIGHT)) {
+ if (alliedfaction(sa->faction, f, HELP_FIGHT)) {
+ set_friendly(s, sa);
+ }
+ }
+ }
}
}
}
@@ -3644,13 +3707,21 @@ static void flee(const troop dt)
{
fighter *fig = dt.fighter;
unit *u = fig->unit;
+ int fchance = fleechance(u);
- fig->run.hp += fig->person[dt.index].hp;
- ++fig->run.number;
+ if (fig->person[dt.index].flags & FL_PANICED) {
+ fchance += EFFECT_PANIC_SPELL;
+ }
+ if (fchance > flee_chance_max_percent) {
+ fchance = flee_chance_max_percent;
+ }
+ if (rng_int() % 100 < fchance) {
+ fig->run.hp += fig->person[dt.index].hp;
+ ++fig->run.number;
- setguard(u, false);
-
- kill_troop(dt);
+ setguard(u, false);
+ kill_troop(dt);
+ }
}
static bool is_calmed(const unit *u, const faction *f) {
@@ -3658,7 +3729,7 @@ static bool is_calmed(const unit *u, const faction *f) {
while (a && a->type == &at_curse) {
curse *c = (curse *)a->data.v;
- if (c->type == &ct_calmmonster && curse_geteffect_int(c) == f->subscription) {
+ if (c->type == &ct_calmmonster && curse_geteffect_int(c) == f->uid) {
if (curse_active(c)) {
return true;
}
@@ -3878,7 +3949,6 @@ static void battle_flee(battle * b)
for (fig = s->fighters; fig; fig = fig->next) {
unit *u = fig->unit;
troop dt;
- int runners = 0;
/* Flucht nicht bei mehr als 600 HP. Damit Wyrme t�tbar bleiben. */
int runhp = (int)(0.9 + unit_max_hp(u) * hpflee(u->status));
if (runhp > 600) runhp = 600;
@@ -3895,7 +3965,6 @@ static void battle_flee(battle * b)
dt.fighter = fig;
dt.index = fig->alive - fig->removed;
while (s->size[SUM_ROW] && dt.index != 0) {
- double ispaniced = 0.0;
--dt.index;
assert(dt.index >= 0 && dt.index < fig->unit->number);
assert(fig->person[dt.index].hp > 0);
@@ -3920,14 +3989,7 @@ static void battle_flee(battle * b)
}
continue;
}
-
- if (fig->person[dt.index].flags & FL_PANICED) {
- ispaniced = EFFECT_PANIC_SPELL;
- }
- if (chance(fmin(fleechance(u) + ispaniced, 0.90))) {
- ++runners;
- flee(dt);
- }
+ flee(dt);
}
}
}
@@ -3981,8 +4043,7 @@ void force_leave(region *r, battle *b) {
}
-void do_battle(region * r)
-{
+static void do_battle(region * r) {
battle *b = NULL;
bool fighting;
ship *sh;
diff --git a/src/battle.h b/src/battle.h
index 48fa7c63a..eb6335bce 100644
--- a/src/battle.h
+++ b/src/battle.h
@@ -173,9 +173,8 @@ extern "C" {
struct person {
int hp; /* Trefferpunkte der Personen */
int attack;
- int defence;
+ int defense;
int damage;
- int damage_rear;
int flags;
int speed;
int reload;
@@ -233,7 +232,10 @@ extern "C" {
int count_enemies(struct battle *b, const struct fighter *af,
int minrow, int maxrow, int select);
int natural_armor(struct unit * u);
- int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, union variant *magres);
+ const struct armor_type *select_armor(struct troop t, bool shield);
+ struct weapon *select_weapon(const struct troop t, bool attacking, bool ismissile);
+ int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, const struct armor_type *armor, const struct armor_type *shield, bool magic);
+ int apply_resistance(int damage, struct troop dt, const struct weapon_type *dwtype, const struct armor_type *armor, const struct armor_type *shield, bool magic);
bool terminate(troop dt, troop at, int type, const char *damage,
bool missile);
void message_all(battle * b, struct message *m);
diff --git a/src/battle.test.c b/src/battle.test.c
index 7c7012e77..92a26e692 100644
--- a/src/battle.test.c
+++ b/src/battle.test.c
@@ -2,6 +2,7 @@
#include "battle.h"
+#include "guard.h"
#include "reports.h"
#include "skill.h"
@@ -10,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -17,7 +19,9 @@
#include
+#include
#include
+#include "util/keyword.h"
#include
#include
#include
@@ -31,6 +35,21 @@
#include "tests.h"
+static void setup_messages(void) {
+ mt_create_va(mt_new("start_battle", NULL), "factions:string", MT_NEW_END);
+ mt_create_va(mt_new("para_army_index", NULL), "index:int", "name:string", MT_NEW_END);
+ mt_create_va(mt_new("battle_msg", NULL), "string:string", MT_NEW_END);
+ mt_create_va(mt_new("battle_row", NULL), "row:int", MT_NEW_END);
+ mt_create_va(mt_new("para_lineup_battle", NULL), "turn:int", MT_NEW_END);
+ mt_create_va(mt_new("para_after_battle", NULL), MT_NEW_END);
+ mt_create_va(mt_new("army_report", NULL),
+ "index:int", "abbrev:string", "dead:int", "fled:int", "survived:int",
+ MT_NEW_END);
+ mt_create_va(mt_new("casualties", NULL),
+ "unit:unit", "runto:region", "run:int", "alive:int", "fallen:int",
+ MT_NEW_END);
+}
+
static void test_make_fighter(CuTest * tc)
{
unit *au;
@@ -59,7 +78,7 @@ static void test_make_fighter(CuTest * tc)
af = make_fighter(b, au, as, false);
CuAssertIntEquals(tc, 1, b->nfighters);
- CuAssertPtrEquals(tc, 0, af->building);
+ CuAssertPtrEquals(tc, NULL, af->building);
CuAssertPtrEquals(tc, as, af->side);
CuAssertIntEquals(tc, 0, af->run.hp);
CuAssertIntEquals(tc, ST_BEHIND, af->status);
@@ -197,7 +216,7 @@ static void test_defenders_get_building_bonus(CuTest * tc)
af = make_fighter(b, au, as, true);
CuAssertPtrEquals(tc, bld, df->building);
- CuAssertPtrEquals(tc, 0, af->building);
+ CuAssertPtrEquals(tc, NULL, af->building);
dt.fighter = df;
dt.index = 0;
@@ -242,7 +261,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
as = make_side(b, au->faction, 0, 0, 0);
af = make_fighter(b, au, as, true);
- CuAssertPtrEquals(tc, 0, af->building);
+ CuAssertPtrEquals(tc, NULL, af->building);
free_battle(b);
test_teardown();
}
@@ -279,12 +298,12 @@ static void test_building_bonus_respects_size(CuTest * tc)
df = make_fighter(b, du, as, false);
CuAssertPtrEquals(tc, bld, af->building);
- CuAssertPtrEquals(tc, 0, df->building);
+ CuAssertPtrEquals(tc, NULL, df->building);
free_battle(b);
test_teardown();
}
-static void test_building_defence_bonus(CuTest * tc)
+static void test_building_defense_bonus(CuTest * tc)
{
building_type * btype;
@@ -339,6 +358,16 @@ static void test_natural_armor(CuTest * tc)
test_teardown();
}
+static int test_armor(troop dt, weapon_type *awtype, bool magic) {
+ return calculate_armor(dt, 0, awtype, select_armor(dt, false), select_armor(dt, true), magic);
+}
+
+static int test_resistance(troop dt) {
+ return apply_resistance(1000, dt,
+ select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0,
+ select_armor(dt, false), select_armor(dt, true), true);
+}
+
static void test_calculate_armor(CuTest * tc)
{
troop dt;
@@ -349,7 +378,6 @@ static void test_calculate_armor(CuTest * tc)
armor_type *ashield, *achain;
item_type *ibelt, *ishield, *ichain;
race *rc;
- variant magres = frac_zero;
variant v50p = frac_make(1, 2);
test_setup();
@@ -365,18 +393,19 @@ static void test_calculate_armor(CuTest * tc)
dt.index = 0;
dt.fighter = setup_fighter(&b, du);
- CuAssertIntEquals_Msg(tc, "default ac", 0, calculate_armor(dt, 0, 0, &magres));
- CuAssertIntEquals_Msg(tc, "magres unmodified", magres.sa[0], magres.sa[1]);
+ CuAssertIntEquals_Msg(tc, "default ac", 0, test_armor(dt, 0, false));
+
+ CuAssertIntEquals_Msg(tc, "magres unmodified", 1000, test_resistance(dt));
free_battle(b);
b = NULL;
i_change(&du->items, ibelt, 1);
dt.fighter = setup_fighter(&b, du);
CuAssertIntEquals_Msg(tc, "without natural armor", 0, natural_armor(du));
- CuAssertIntEquals_Msg(tc, "magical armor", 1, calculate_armor(dt, 0, 0, 0));
+ CuAssertIntEquals_Msg(tc, "magical armor", 1, test_armor(dt, 0, false));
rc->armor = 2;
CuAssertIntEquals_Msg(tc, "with natural armor", 2, natural_armor(du));
- CuAssertIntEquals_Msg(tc, "natural armor", 3, calculate_armor(dt, 0, 0, 0));
+ CuAssertIntEquals_Msg(tc, "natural armor", 3, test_armor(dt, 0, false));
rc->armor = 0;
free_battle(b);
@@ -385,29 +414,30 @@ static void test_calculate_armor(CuTest * tc)
i_change(&du->items, ichain, 1);
dt.fighter = setup_fighter(&b, du);
rc->battle_flags &= ~BF_EQUIPMENT;
- CuAssertIntEquals_Msg(tc, "require BF_EQUIPMENT", 1, calculate_armor(dt, 0, 0, 0));
+ CuAssertIntEquals_Msg(tc, "require BF_EQUIPMENT", 1, test_armor(dt, 0, false));
free_battle(b);
b = NULL;
rc->battle_flags |= BF_EQUIPMENT;
dt.fighter = setup_fighter(&b, du);
- CuAssertIntEquals_Msg(tc, "stack equipment rc", 5, calculate_armor(dt, 0, 0, 0));
+ CuAssertIntEquals_Msg(tc, "stack equipment rc", 5, test_armor(dt, 0, false));
rc->armor = 2;
- CuAssertIntEquals_Msg(tc, "natural armor adds 50%", 6, calculate_armor(dt, 0, 0, 0));
+ CuAssertIntEquals_Msg(tc, "natural armor adds 50%", 6, test_armor(dt, 0, false));
wtype->flags = WTF_NONE;
- CuAssertIntEquals_Msg(tc, "regular weapon has no effect", 6, calculate_armor(dt, 0, wtype, 0));
+ CuAssertIntEquals_Msg(tc, "regular weapon has no effect", 6, test_armor(dt, wtype, false));
wtype->flags = WTF_ARMORPIERCING;
- CuAssertIntEquals_Msg(tc, "armor piercing weapon", 3, calculate_armor(dt, 0, wtype, 0));
+ CuAssertIntEquals_Msg(tc, "armor piercing weapon", 3, test_armor(dt, wtype, false));
wtype->flags = WTF_NONE;
- CuAssertIntEquals_Msg(tc, "magical attack", 3, calculate_armor(dt, 0, 0, &magres));
- CuAssertIntEquals_Msg(tc, "magres unmodified", magres.sa[1], magres.sa[0]);
+ CuAssertIntEquals_Msg(tc, "magical attack", 3, test_armor(dt, wtype, true));
+ CuAssertIntEquals_Msg(tc, "magres unmodified", 1000,
+ test_resistance(dt));
ashield->flags |= ATF_LAEN;
achain->flags |= ATF_LAEN;
- magres = frac_one;
- CuAssertIntEquals_Msg(tc, "laen armor", 3, calculate_armor(dt, 0, 0, &magres));
- CuAssertIntEquals_Msg(tc, "laen magres bonus", 4, magres.sa[1]);
+
+ CuAssertIntEquals_Msg(tc, "laen armor", 3, test_armor(dt, wtype, true));
+ CuAssertIntEquals_Msg(tc, "laen magres bonus", 250, test_resistance(dt));
free_battle(b);
test_teardown();
}
@@ -437,15 +467,17 @@ static void test_magic_resistance(CuTest *tc)
i_change(&du->items, ishield, 1);
dt.fighter = setup_fighter(&b, du);
- calculate_armor(dt, 0, 0, &magres);
- CuAssertIntEquals_Msg(tc, "no magres reduction", magres.sa[1], magres.sa[0]);
+ CuAssertIntEquals_Msg(tc, "no magres reduction", 1000, test_resistance(dt));
magres = magic_resistance(du);
CuAssertIntEquals_Msg(tc, "no magres reduction", 0, magres.sa[0]);
ashield->flags |= ATF_LAEN;
ashield->magres = v10p;
- calculate_armor(dt, 0, 0, &magres);
- CuAssert(tc, "laen reduction => 10%%", frac_equal(frac_make(9, 10), magres));
+ CuAssertIntEquals_Msg(tc, "laen reduction => 10%%", 900, test_resistance(dt));
+ CuAssertIntEquals_Msg(tc, "no magic, no resistance", 1000,
+ apply_resistance(1000, dt,
+ select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0,
+ select_armor(dt, false), select_armor(dt, true), false));
free_battle(b);
b = NULL;
@@ -455,8 +487,7 @@ static void test_magic_resistance(CuTest *tc)
ashield->flags |= ATF_LAEN;
ashield->magres = v10p;
dt.fighter = setup_fighter(&b, du);
- calculate_armor(dt, 0, 0, &magres);
- CuAssert(tc, "2x laen reduction => 81%%", frac_equal(frac_make(81, 100), magres));
+ CuAssertIntEquals_Msg(tc, "2x laen reduction => 81%%", 810, test_resistance(dt));
free_battle(b);
b = NULL;
@@ -464,21 +495,18 @@ static void test_magic_resistance(CuTest *tc)
i_change(&du->items, ichain, -1);
set_level(du, SK_MAGIC, 2);
dt.fighter = setup_fighter(&b, du);
- calculate_armor(dt, 0, 0, &magres);
- CuAssert(tc, "skill reduction => 90%%", frac_equal(magres, frac_make(9, 10)));
+ CuAssertIntEquals_Msg(tc, "skill reduction => 90%%", 900, test_resistance(dt));
magres = magic_resistance(du);
CuAssert(tc, "skill reduction", frac_equal(magres, v10p));
rc->magres = v50p; /* percentage, gets added to skill bonus */
- calculate_armor(dt, 0, 0, &magres);
- CuAssert(tc, "race reduction => 40%%", frac_equal(magres, frac_make(4, 10)));
+ CuAssertIntEquals_Msg(tc, "race reduction => 40%%", 400, test_resistance(dt));
magres = magic_resistance(du);
CuAssert(tc, "race bonus => 60%%", frac_equal(magres, frac_make(60, 100)));
rc->magres = frac_make(15, 10); /* 150% resistance should not cause negative damage multiplier */
magres = magic_resistance(du);
CuAssert(tc, "magic resistance is never > 0.9", frac_equal(magres, frac_make(9, 10)));
- calculate_armor(dt, 0, 0, &magres);
- CuAssert(tc, "damage reduction is never < 0.1", frac_equal(magres, frac_make(1, 10)));
+ CuAssertIntEquals_Msg(tc, "damage reduction is never < 0.1", 100, test_resistance(dt));
free_battle(b);
test_teardown();
@@ -513,12 +541,12 @@ static void test_projectile_armor(CuTest * tc)
dt.fighter = setup_fighter(&b, du);
wtype->flags = WTF_MISSILE;
achain->projectile = 1.0;
- CuAssertIntEquals_Msg(tc, "projectile armor", -1, calculate_armor(dt, 0, wtype, 0));
+ CuAssertIntEquals_Msg(tc, "projectile armor", -1, test_armor(dt, wtype, false));
achain->projectile = 0.0;
ashield->projectile = 1.0;
- CuAssertIntEquals_Msg(tc, "projectile shield", -1, calculate_armor(dt, 0, wtype, 0));
+ CuAssertIntEquals_Msg(tc, "projectile shield", -1, test_armor(dt, wtype, false));
wtype->flags = WTF_NONE;
- CuAssertIntEquals_Msg(tc, "no projectiles", 4, calculate_armor(dt, 0, wtype, 0));
+ CuAssertIntEquals_Msg(tc, "no projectiles", 4, test_armor(dt, wtype, false));
free_battle(b);
test_teardown();
}
@@ -542,7 +570,7 @@ static void test_battle_skilldiff(CuTest *tc)
CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
ta.fighter->person[0].attack = 2;
- td.fighter->person[0].defence = 1;
+ td.fighter->person[0].defense = 1;
CuAssertIntEquals(tc, 1, skilldiff(ta, td, 0));
td.fighter->person[0].flags |= FL_SLEEPING;
@@ -556,6 +584,38 @@ static void test_battle_skilldiff(CuTest *tc)
test_teardown();
}
+static void test_terminate(CuTest * tc)
+{
+ troop at, dt;
+ battle *b = NULL;
+ region *r;
+ unit *au, *du;
+ race *rc;
+
+ test_setup();
+ r = test_create_region(0, 0, NULL);
+
+ rc = test_create_race("human");
+ au = test_create_unit(test_create_faction(rc), r);
+ du = test_create_unit(test_create_faction(rc), r);
+ dt.index = 0;
+ at.index = 0;
+
+ at.fighter = setup_fighter(&b, au);
+ dt.fighter = setup_fighter(&b, du);
+
+ CuAssertIntEquals_Msg(tc, "not killed", 0, terminate(dt, at, AT_STANDARD, "1d1", false));
+ b = NULL;
+ at.fighter = setup_fighter(&b, au);
+ dt.fighter = setup_fighter(&b, du);
+ CuAssertIntEquals_Msg(tc, "killed", 1, terminate(dt, at, AT_STANDARD, "100d1", false));
+ CuAssertIntEquals_Msg(tc, "number", 0, dt.fighter->person[0].hp);
+
+ free_battle(b);
+ test_teardown();
+}
+
+
static void test_battle_report_one(CuTest *tc)
{
battle * b = NULL;
@@ -566,7 +626,7 @@ static void test_battle_report_one(CuTest *tc)
fighter *fig;
test_setup();
- mt_create_va(mt_new("start_battle", NULL), "factions:string", MT_NEW_END);
+ setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(test_create_faction(NULL), r);
@@ -597,7 +657,7 @@ static void test_battle_report_two(CuTest *tc)
test_setup();
lang = test_create_locale();
locale_setstring(lang, "and", "and");
- mt_create_va(mt_new("start_battle", NULL), "factions:string", MT_NEW_END);
+ setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction(NULL), r);
u1->faction->locale = lang;
@@ -630,7 +690,7 @@ static void test_battle_report_three(CuTest *tc)
test_setup();
lang = test_create_locale();
locale_setstring(lang, "and", "and");
- mt_create_va(mt_new("start_battle", NULL), "factions:string", MT_NEW_END);
+ setup_messages();
r = test_create_plain(0, 0);
u1 = test_create_unit(test_create_faction(NULL), r);
u1->faction->locale = lang;
@@ -783,12 +843,43 @@ static void test_tactics_chance(CuTest *tc) {
test_teardown();
}
+static void test_battle_fleeing(CuTest *tc) {
+ region *r;
+ unit *u1, *u2;
+ test_setup();
+ setup_messages();
+ r = test_create_plain(0, 0);
+ u1 = test_create_unit(test_create_faction(NULL), r);
+ u2 = test_create_unit(test_create_faction(NULL), r);
+ u1->status = ST_FLEE;
+ u2->status = ST_AGGRO;
+#if 0
+ setguard(u1, true);
+ CuAssertIntEquals(tc, UFL_GUARD, (u1->flags & UFL_GUARD));
+ CuAssertIntEquals(tc, RF_GUARDED, (r->flags & RF_GUARDED));
+#endif
+ config_set_int("rules.combat.flee_chance_base", 100);
+ config_set_int("rules.combat.flee_chance_limit", 100);
+ unit_addorder(u2, create_order(K_ATTACK, u2->faction->locale, itoa36(u1->no)));
+ do_battles();
+ CuAssertIntEquals(tc, 1, u1->number);
+ CuAssertIntEquals(tc, 1, u2->number);
+#if 0
+ CuAssertIntEquals(tc, 0, (u1->flags & UFL_GUARD));
+ CuAssertIntEquals(tc, 0, (r->flags & RF_GUARDED));
+#endif
+ CuAssertIntEquals(tc, UFL_LONGACTION, (u1->flags & UFL_LONGACTION));
+ CuAssertIntEquals(tc, UFL_LONGACTION | UFL_NOTMOVING, (u2->flags & (UFL_LONGACTION | UFL_NOTMOVING)));
+ test_teardown();
+}
+
CuSuite *get_battle_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_make_fighter);
SUITE_ADD_TEST(suite, test_select_weapon_restricted);
SUITE_ADD_TEST(suite, test_select_armor);
+ SUITE_ADD_TEST(suite, test_battle_fleeing);
SUITE_ADD_TEST(suite, test_battle_skilldiff);
SUITE_ADD_TEST(suite, test_battle_skilldiff_building);
SUITE_ADD_TEST(suite, test_battle_report_one);
@@ -797,12 +888,13 @@ CuSuite *get_battle_suite(void)
SUITE_ADD_TEST(suite, test_defenders_get_building_bonus);
SUITE_ADD_TEST(suite, test_attackers_get_no_building_bonus);
SUITE_ADD_TEST(suite, test_building_bonus_respects_size);
- SUITE_ADD_TEST(suite, test_building_defence_bonus);
+ SUITE_ADD_TEST(suite, test_building_defense_bonus);
SUITE_ADD_TEST(suite, test_calculate_armor);
SUITE_ADD_TEST(suite, test_natural_armor);
SUITE_ADD_TEST(suite, test_magic_resistance);
SUITE_ADD_TEST(suite, test_projectile_armor);
SUITE_ADD_TEST(suite, test_tactics_chance);
+ SUITE_ADD_TEST(suite, test_terminate);
DISABLE_TEST(suite, test_drain_exp);
return suite;
}
diff --git a/src/bind_building.c b/src/bind_building.c
index 9e39a54a5..93576ed3b 100644
--- a/src/bind_building.c
+++ b/src/bind_building.c
@@ -5,7 +5,6 @@
#include "bind_building.h"
#include "bind_unit.h"
-#include
#include
#include
#include
@@ -15,9 +14,12 @@
#include
#include
+#include
+#include
#include
+
+#include
#include
-#include
int tolua_buildinglist_next(lua_State * L)
{
diff --git a/src/bind_config.c b/src/bind_config.c
index 2d4086ccf..31ffcc287 100644
--- a/src/bind_config.c
+++ b/src/bind_config.c
@@ -5,17 +5,15 @@
#include "bind_config.h"
#include "jsonconf.h"
+#include "magic.h"
#include
#include
#include
#include
#include
-#include
-#include
#include
-#include
#include
#include
#include
diff --git a/src/bind_eressea.c b/src/bind_eressea.c
index 11c03898d..f76d0a903 100755
--- a/src/bind_eressea.c
+++ b/src/bind_eressea.c
@@ -3,8 +3,6 @@
#endif
#include "bind_eressea.h"
-#include
-
#include "json.h"
#include "orderfile.h"
@@ -14,15 +12,17 @@
#include
#include
+#include
#include
+#include
#include
void eressea_free_game(void) {
free_gamedata();
init_resources();
- init_locales();
+ init_locales(init_locale);
}
int eressea_read_game(const char * filename) {
@@ -35,7 +35,17 @@ int eressea_write_game(const char * filename) {
}
int eressea_read_orders(const char * filename) {
- return readorders(filename);
+ FILE * F = fopen(filename, "r");
+ int result;
+
+ if (!F) {
+ perror(filename);
+ return -1;
+ }
+ log_info("reading orders from %s", filename);
+ result = parseorders(F);
+ fclose(F);
+ return result;
}
int eressea_export_json(const char * filename, int flags) {
diff --git a/src/bind_faction.c b/src/bind_faction.c
index ac797093d..9cc6bdd97 100644
--- a/src/bind_faction.c
+++ b/src/bind_faction.c
@@ -17,47 +17,32 @@ without prior permission by the authors of Eressea.
#include "bind_faction.h"
#include "bind_unit.h"
#include "bindings.h"
-#include "helpers.h"
+#include "magic.h"
#include
#include
#include
#include
-#include
#include
#include
#include
#include
-#include
-#include
+#include "kernel/types.h"
#include
#include
#include
#include
+#include
#include
+#include "attributes/key.h"
+
+#include
+#include
#include
#include
#include
-#include
-
-typedef struct helpmode {
- const char *name;
- int status;
-} helpmode;
-
-static helpmode helpmodes[] = {
- { "all", HELP_ALL },
- { "money", HELP_MONEY },
- { "fight", HELP_FIGHT },
- { "observe", HELP_OBSERVE },
- { "give", HELP_GIVE },
- { "guard", HELP_GUARD },
- { "stealth", HELP_FSTEALTH },
- { "travel", HELP_TRAVEL },
- { NULL, 0 }
-};
int tolua_factionlist_next(lua_State * L)
{
@@ -74,7 +59,7 @@ int tolua_factionlist_next(lua_State * L)
static int tolua_faction_get_units(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *));
luaL_getmetatable(L, TOLUA_CAST "unit");
@@ -88,8 +73,8 @@ static int tolua_faction_get_units(lua_State * L)
int tolua_faction_add_item(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *iname = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *iname = tolua_tostring(L, 2, NULL);
int number = (int)tolua_tonumber(L, 3, 0);
int result = -1;
@@ -106,35 +91,35 @@ int tolua_faction_add_item(lua_State * L)
static int tolua_faction_get_maxheroes(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, maxheroes(self));
return 1;
}
static int tolua_faction_get_heroes(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, countheroes(self));
return 1;
}
static int tolua_faction_get_score(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushnumber(L, (lua_Number)self->score);
return 1;
}
static int tolua_faction_get_id(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->no);
return 1;
}
static int tolua_faction_set_id(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int id = (int)tolua_tonumber(L, 2, 0);
if (findfaction(id) == NULL) {
renumber_faction(self, id);
@@ -148,15 +133,15 @@ static int tolua_faction_set_id(lua_State * L)
static int tolua_faction_get_magic(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, magic_school[self->magiegebiet]);
return 1;
}
static int tolua_faction_set_magic(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *type = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *type = tolua_tostring(L, 2, NULL);
int mtype;
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
@@ -170,14 +155,14 @@ static int tolua_faction_set_magic(lua_State * L)
static int tolua_faction_get_age(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->age);
return 1;
}
static int tolua_faction_set_age(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int age = (int)tolua_tonumber(L, 2, 0);
self->age = age;
return 0;
@@ -185,14 +170,14 @@ static int tolua_faction_set_age(lua_State * L)
static int tolua_faction_get_flags(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->flags);
return 1;
}
static int tolua_faction_set_flags(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int flags = (int)tolua_tonumber(L, 2, self->flags);
self->flags = flags;
return 1;
@@ -200,14 +185,14 @@ static int tolua_faction_set_flags(lua_State * L)
static int tolua_faction_get_options(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->options);
return 1;
}
static int tolua_faction_set_options(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int options = (int)tolua_tonumber(L, 2, self->options);
self->options = options;
return 1;
@@ -215,14 +200,14 @@ static int tolua_faction_set_options(lua_State * L)
static int tolua_faction_get_lastturn(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->lastorders);
return 1;
}
static int tolua_faction_set_lastturn(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
if (self) {
self->lastorders = (int)tolua_tonumber(L, 2, self->lastorders);
}
@@ -231,7 +216,7 @@ static int tolua_faction_set_lastturn(lua_State * L)
static int tolua_faction_renumber(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int no = (int)tolua_tonumber(L, 2, 0);
renumber_faction(self, no);
@@ -240,8 +225,8 @@ static int tolua_faction_renumber(lua_State * L)
static int tolua_faction_addnotice(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *str = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *str = tolua_tostring(L, 2, NULL);
addmessage(NULL, self, str, MSG_MESSAGE, ML_IMPORTANT);
return 0;
@@ -249,19 +234,22 @@ static int tolua_faction_addnotice(lua_State * L)
static int tolua_faction_getkey(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *name = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *name = tolua_tostring(L, 2, NULL);
int flag = atoi36(name);
-
- lua_pushinteger(L, key_get(self->attribs, flag));
- return 1;
+ int value = key_get(self->attribs, flag);
+ if (value != 0) {
+ lua_pushinteger(L, value);
+ return 1;
+ }
+ return 0;
}
static int tolua_faction_setkey(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *name = tolua_tostring(L, 2, 0);
- int value = (int)tolua_tonumber(L, 3, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *name = tolua_tostring(L, 2, NULL);
+ int value = (int)tolua_tonumber(L, 3, 1);
int flag = atoi36(name);
if (value) {
@@ -275,7 +263,7 @@ static int tolua_faction_setkey(lua_State * L)
static int tolua_faction_get_messages(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int i = 1;
mlist *ml;
if (!self->msgs) {
@@ -291,8 +279,8 @@ static int tolua_faction_get_messages(lua_State * L)
}
static int tolua_faction_count_msg_type(lua_State *L) {
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *str = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *str = tolua_tostring(L, 2, NULL);
int n = 0;
if (self->msgs) {
mlist * ml = self->msgs->begin;
@@ -307,53 +295,10 @@ static int tolua_faction_count_msg_type(lua_State *L) {
return 1;
}
-static int tolua_faction_get_policy(lua_State * L)
-{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- faction *other = (faction *)tolua_tousertype(L, 2, 0);
- const char *policy = tolua_tostring(L, 3, 0);
-
- int result = 0, mode;
- for (mode = 0; helpmodes[mode].name != NULL; ++mode) {
- if (strcmp(policy, helpmodes[mode].name) == 0) {
- result = get_alliance(self, other) & mode;
- break;
- }
- }
-
- lua_pushinteger(L, result);
- return 1;
-}
-
-static int tolua_faction_set_policy(lua_State * L)
-{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- faction *other = (faction *)tolua_tousertype(L, 2, 0);
- const char *policy = tolua_tostring(L, 3, 0);
- int value = tolua_toboolean(L, 4, 0);
-
- int mode;
- for (mode = 0; helpmodes[mode].name != NULL; ++mode) {
- if (strcmp(policy, helpmodes[mode].name) == 0) {
- if (value) {
- set_alliance(self, other, get_alliance(self,
- other) | helpmodes[mode].status);
- }
- else {
- set_alliance(self, other, get_alliance(self,
- other) & ~helpmodes[mode].status);
- }
- break;
- }
- }
-
- return 0;
-}
-
static int tolua_faction_normalize(lua_State * L)
{
- faction *f = (faction *)tolua_tousertype(L, 1, 0);
- region *r = (region *)tolua_tousertype(L, 2, 0);
+ faction *f = (faction *)tolua_tousertype(L, 1, NULL);
+ region *r = (region *)tolua_tousertype(L, 2, NULL);
if (r) {
plane *pl = rplane(r);
int nx = r->x, ny = r->y;
@@ -368,8 +313,8 @@ static int tolua_faction_normalize(lua_State * L)
static int tolua_faction_set_origin(lua_State * L)
{
- faction *f = (faction *)tolua_tousertype(L, 1, 0);
- region *r = (region *)tolua_tousertype(L, 2, 0);
+ faction *f = (faction *)tolua_tousertype(L, 1, NULL);
+ region *r = (region *)tolua_tousertype(L, 2, NULL);
plane *pl = rplane(r);
int id = pl ? pl->id : 0;
@@ -379,21 +324,9 @@ static int tolua_faction_set_origin(lua_State * L)
static int tolua_faction_get_origin(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
-
- ursprung *origin = self->ursprung;
- int x, y;
- while (origin != NULL && origin->id != 0) {
- origin = origin->next;
- }
- if (origin) {
- x = origin->x;
- y = origin->y;
- }
- else {
- x = 0;
- y = 0;
- }
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ int x = 0, y = 0;
+ faction_getorigin(self, 0, &x, &y);
lua_pushinteger(L, x);
lua_pushinteger(L, y);
@@ -402,7 +335,7 @@ static int tolua_faction_get_origin(lua_State * L)
static int tolua_faction_destroy(lua_State * L)
{
- faction **fp, *f = (faction *)tolua_tousertype(L, 1, 0);
+ faction **fp, *f = (faction *)tolua_tousertype(L, 1, NULL);
/* TODO: this loop is slow af, but what can we do? */
for (fp = &factions; *fp; fp = &(*fp)->next) {
if (*fp == f) {
@@ -423,14 +356,14 @@ static int tolua_faction_get(lua_State * L)
static int tolua_faction_create(lua_State * L)
{
- const char *racename = tolua_tostring(L, 1, 0);
- const char *email = tolua_tostring(L, 2, 0);
- const char *lang = tolua_tostring(L, 3, 0);
+ const char *racename = tolua_tostring(L, 1, NULL);
+ const char *email = tolua_tostring(L, 2, NULL);
+ const char *lang = tolua_tostring(L, 3, NULL);
struct locale *loc = lang ? get_locale(lang) : default_locale;
faction *f = NULL;
const struct race *frace = rc_find(racename ? racename : "human");
if (frace != NULL) {
- f = addfaction(email, NULL, frace, loc, 0);
+ f = addfaction(email, NULL, frace, loc);
}
if (!f) {
log_error("cannot create %s faction for %s, unknown race.", racename, email);
@@ -441,44 +374,44 @@ static int tolua_faction_create(lua_State * L)
static int tolua_faction_get_password(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- tolua_pushstring(L, self->_password);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ tolua_pushstring(L, faction_getpassword(self));
return 1;
}
static int tolua_faction_set_password(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char * passw = tolua_tostring(L, 2, 0);
- faction_setpassword(self, password_encode(passw, PASSWORD_DEFAULT));
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char * passw = tolua_tostring(L, 2, NULL);
+ faction_setpassword(self, password_hash(passw, PASSWORD_DEFAULT));
return 0;
}
static int tolua_faction_get_email(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getemail(self));
return 1;
}
static int tolua_faction_set_email(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- faction_setemail(self, tolua_tostring(L, 2, 0));
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ faction_setemail(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_faction_get_locale(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, locale_name(self->locale));
return 1;
}
static int tolua_faction_set_locale(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *name = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *name = tolua_tostring(L, 2, NULL);
const struct locale *loc = get_locale(name);
if (loc) {
self->locale = loc;
@@ -492,15 +425,15 @@ static int tolua_faction_set_locale(lua_State * L)
static int tolua_faction_get_race(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, self->race->_name);
return 1;
}
static int tolua_faction_set_race(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- const char *name = tolua_tostring(L, 2, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ const char *name = tolua_tostring(L, 2, NULL);
const race *rc = rc_find(name);
if (rc != NULL) {
self->race = rc;
@@ -511,57 +444,57 @@ static int tolua_faction_set_race(lua_State * L)
static int tolua_faction_get_name(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getname(self));
return 1;
}
static int tolua_faction_set_name(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- faction_setname(self, tolua_tostring(L, 2, 0));
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ faction_setname(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_faction_get_uid(lua_State * L)
{
- faction *f = (faction *)tolua_tousertype(L, 1, 0);
- lua_pushinteger(L, f->subscription);
+ faction *f = (faction *)tolua_tousertype(L, 1, NULL);
+ lua_pushinteger(L, f->uid);
return 1;
}
static int tolua_faction_set_uid(lua_State * L)
{
- faction *f = (faction *)tolua_tousertype(L, 1, 0);
- f->subscription = (int)tolua_tonumber(L, 2, 0);
+ faction *f = (faction *)tolua_tousertype(L, 1, NULL);
+ f->uid = (int)tolua_tonumber(L, 2, 0);
return 0;
}
static int tolua_faction_get_info(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getbanner(self));
return 1;
}
static int tolua_faction_set_info(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
- faction_setbanner(self, tolua_tostring(L, 2, 0));
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
+ faction_setbanner(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_faction_get_alliance(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushusertype(L, f_get_alliance(self), TOLUA_CAST "alliance");
return 1;
}
static int tolua_faction_set_alliance(lua_State * L)
{
- struct faction *self = (struct faction *)tolua_tousertype(L, 1, 0);
- struct alliance *alli = (struct alliance *) tolua_tousertype(L, 2, 0);
+ struct faction *self = (struct faction *)tolua_tousertype(L, 1, NULL);
+ struct alliance *alli = (struct alliance *) tolua_tousertype(L, 2, NULL);
setalliance(self, alli);
@@ -570,7 +503,7 @@ static int tolua_faction_set_alliance(lua_State * L)
static int tolua_faction_get_items(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
item **item_ptr = (item **)lua_newuserdata(L, sizeof(item *));
luaL_getmetatable(L, TOLUA_CAST "item");
@@ -585,7 +518,7 @@ static int tolua_faction_get_items(lua_State * L)
static int tolua_faction_tostring(lua_State * L)
{
- faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, factionname(self));
return 1;
}
@@ -642,8 +575,6 @@ void tolua_faction_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "lastturn", tolua_faction_get_lastturn,
tolua_faction_set_lastturn);
- tolua_function(L, TOLUA_CAST "set_policy", tolua_faction_set_policy);
- tolua_function(L, TOLUA_CAST "get_policy", tolua_faction_get_policy);
tolua_function(L, TOLUA_CAST "get_origin", tolua_faction_get_origin);
tolua_function(L, TOLUA_CAST "set_origin", tolua_faction_set_origin);
tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize);
diff --git a/src/bind_gmtool.c b/src/bind_gmtool.c
index 5c08f6e2c..d0a023a5b 100644
--- a/src/bind_gmtool.c
+++ b/src/bind_gmtool.c
@@ -14,6 +14,8 @@
#include
#include
+#include
+#include
#include
#include
diff --git a/src/bind_message.c b/src/bind_message.c
index 8eee85bc1..bf82ddd02 100644
--- a/src/bind_message.c
+++ b/src/bind_message.c
@@ -16,14 +16,18 @@
#include
#include
#include
+#include
/* lua includes */
+#include
#include
#include
#include
#include
+struct order;
+
#define E_OK 0
#define E_INVALID_MESSAGE 1
#define E_INVALID_PARAMETER_NAME 2
diff --git a/src/bind_monsters.c b/src/bind_monsters.c
index af630bb41..f9aef4a2a 100644
--- a/src/bind_monsters.c
+++ b/src/bind_monsters.c
@@ -2,20 +2,19 @@
#include
#endif
-#include "spells/shipcurse.h"
#include "monsters.h"
#include
#include
-#include
#include
-#include
#include
#include
+#include
#include
+
#include
static int tolua_levitate_ship(lua_State * L)
@@ -62,7 +61,7 @@ static int tolua_spawn_undead(lua_State * L)
return 0;
}
-void bind_monsters(struct lua_State *L)
+void bind_monsters(lua_State *L)
{
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
diff --git a/src/bind_order.c b/src/bind_order.c
index 407e29037..dd38f4adb 100644
--- a/src/bind_order.c
+++ b/src/bind_order.c
@@ -8,6 +8,7 @@
#include
/* lua includes */
+#include
#include
#include
diff --git a/src/bind_process.c b/src/bind_process.c
index 947458ce5..f9f99284e 100755
--- a/src/bind_process.c
+++ b/src/bind_process.c
@@ -4,20 +4,22 @@
#include "bind_process.h"
+#include "battle.h"
+#include "economy.h"
+#include "laws.h"
+#include "magic.h"
+#include "market.h"
+#include "move.h"
+#include "study.h"
+
#include
#include
#include
#include
#include
#include
-#include "battle.h"
-#include "economy.h"
-#include "keyword.h"
-#include "laws.h"
-#include "magic.h"
-#include "market.h"
-#include "move.h"
-#include "study.h"
+
+#include "util/keyword.h"
#define PROC_LAND_REGION 0x0001
#define PROC_LONG_ORDER 0x0002
@@ -76,10 +78,6 @@ void process_battle(void) {
do_battles();
}
-void process_siege(void) {
- process_cmd(K_BESIEGE, siege_cmd, PROC_LAND_REGION);
-}
-
void process_update_long_order(void) {
region * r;
for (r = regions; r; r = r->next) {
diff --git a/src/bind_region.c b/src/bind_region.c
index b49ceb078..4a466b46f 100644
--- a/src/bind_region.c
+++ b/src/bind_region.c
@@ -8,43 +8,41 @@
#include "bind_building.h"
#include "teleport.h"
+#include "direction.h"
+#include
#include
-#include
#include
#include
#include
#include
-#include
#include
-#include
-#include
#include
#include
#include
#include